From 507bd24ce919734726562c122622577a4e42fc91 Mon Sep 17 00:00:00 2001 From: prabhu Date: Tue, 3 Oct 2023 13:51:26 +0100 Subject: [PATCH] cdx and chennai tags pass (#9) * cdx and chennai tags pass Signed-off-by: Prabhu Subramanian * lint fixes Signed-off-by: Prabhu Subramanian * Memory leak Signed-off-by: Prabhu Subramanian --------- Signed-off-by: Prabhu Subramanian --- .github/workflows/containers.yml | 6 +- .gitignore | 4 +- README.md | 10 + build.sbt | 2 +- chenpy/cli.py | 19 +- chenpy/db.py | 16 + chenpy/graph.py | 38 +- chenpy/logger.py | 28 +- chenpy/source/__init__.py | 0 chenpy/source/ghsa.py | 122 +++ chenpy/utils.py | 200 ++++ .../scala/io/appthreat/console/Console.scala | 36 +- .../console/cpgcreation/CdxGenerator.scala | 31 + .../console/cpgcreation/ImportCode.scala | 32 +- .../console/cpgcreation/package.scala | 20 +- .../dataflowengineoss/language/Path.scala | 26 +- .../nodemethods/ExpressionMethods.scala | 33 +- .../main/scala/io/appthreat/c2cpg/Main.scala | 2 +- .../io/appthreat/c2cpg/parser/CdtParser.scala | 2 +- .../c2cpg/passes/ConfigFileCreationPass.scala | 27 + .../c2cpg/dataflow/DataFlowTests.scala | 103 +- .../appthreat/javasrc2cpg/JavaSrc2Cpg.scala | 2 + .../scala/io/appthreat/javasrc2cpg/Main.scala | 2 +- .../descriptorparser/DescriptorParser.scala | 4 +- .../descriptorparser/TypeParser.scala | 2 +- .../javasrc2cpg/passes/AstCreationPass.scala | 27 +- .../javasrc2cpg/passes/AstCreator.scala | 61 +- .../passes/ConfigFileCreationPass.scala | 5 +- .../typesolvers/EagerSourceTypeSolver.scala | 2 +- .../noncaching/JdkJarTypeSolver.scala | 36 +- .../querying/dataflow/MethodReturnTests.scala | 4 +- .../querying/dataflow/OperatorTests.scala | 4 +- .../querying/dataflow/ReturnTests.scala | 6 +- .../io/appthreat/jimple2cpg/Jimple2Cpg.scala | 6 +- .../passes/ConfigFileCreationPass.scala | 37 + .../jimple2cpg/util/ProgramHandlingUtil.scala | 2 +- .../querying/dataflow/OperatorTests.scala | 2 +- .../jssrc2cpg/utils/AstGenRunner.scala | 2 +- .../jssrc2cpg/io/ProjectParseTest.scala | 4 +- .../pysrc2cpg/ConfigFileCreationPass.scala | 4 + platform/frontends/x2cpg/build.sbt | 3 + .../io/appthreat/x2cpg/SourceFiles.scala | 4 +- .../x2cpg/passes/taggers/CdxPass.scala | 128 +++ .../passes/taggers/ChennaiTagsPass.scala | 48 + .../appthreat/x2cpg/utils/Environment.scala | 2 +- poetry.lock | 990 +++++++++--------- project/plugins.sbt | 4 +- pyproject.toml | 77 +- .../language/LocationCreator.scala | 2 +- .../shiftleft/semanticcpg/utils/Torch.scala | 376 +------ 50 files changed, 1400 insertions(+), 1203 deletions(-) create mode 100644 chenpy/db.py create mode 100644 chenpy/source/__init__.py create mode 100644 chenpy/source/ghsa.py create mode 100644 console/src/main/scala/io/appthreat/console/cpgcreation/CdxGenerator.scala create mode 100644 platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/passes/ConfigFileCreationPass.scala create mode 100644 platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/passes/ConfigFileCreationPass.scala create mode 100644 platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/passes/taggers/CdxPass.scala create mode 100644 platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/passes/taggers/ChennaiTagsPass.scala diff --git a/.github/workflows/containers.yml b/.github/workflows/containers.yml index 242d6f3..185939d 100644 --- a/.github/workflows/containers.yml +++ b/.github/workflows/containers.yml @@ -57,7 +57,8 @@ jobs: run: | python3.11 -m pip install --upgrade pip python3.11 -m pip install poetry - python3.11 -m poetry export -f requirements.txt --with=science --output target/chen-science-requirements.txt + python3.11 -m poetry export -f requirements.txt --with=science --without-hashes --output target/chen-science-requirements.txt + python3.11 -m poetry export -f requirements.txt --with=database --without-hashes --output target/chen-database-requirements.txt - name: Upload chen to ghcr run: | cd target @@ -65,7 +66,8 @@ jobs: oras push ghcr.io/$IMAGE_NAME:v1 \ --annotation-file ../ci/annotations.json \ ./chen.zip:application/vnd.appthreat.chen.layer.v1+tar \ - ./chen-science-requirements.txt:application/vnd.appthreat.chen.layer.v1+tar + ./chen-science-requirements.txt:application/vnd.appthreat.chen.layer.v1+tar \ + ./chen-database-requirements.txt:application/vnd.appthreat.chen.layer.v1+tar env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_USERNAME: ${{ github.actor }} diff --git a/.gitignore b/.gitignore index 0e1b56e..13cf40d 100644 --- a/.gitignore +++ b/.gitignore @@ -52,4 +52,6 @@ flake.lock chen.zip .metals/ *.pyc -**/__pycache__/ \ No newline at end of file +**/__pycache__/ +.vscode/ +project/metals.sbt diff --git a/README.md b/README.md index 4b8fe1c..822bac5 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,10 @@ Code Hierarchy Exploration Net (chen) is an advanced exploration toolkit for you - Node.js > 16 (To run [atom](https://github.com/AppThreat/atom)) - Minimum 16GB RAM +### Additional requirements + +- Rust (For rocksdb-py compilation) + ## Installation ```shell @@ -27,6 +31,12 @@ To download the chen distribution including the science pack. chen --download ``` +To generate custom graphs and models with atom for data science, download the scientific pack which installs support for PyTorch ecosystem. + +```shell +chen --download --with-science +``` + Once the download finishes, the command will display the download location along with the environment variables that need to be set to invoke `chennai` console. Example output below: ```shell diff --git a/build.sbt b/build.sbt index 42b10e5..14ae98b 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ name := "chen" ThisBuild / organization := "io.appthreat" -ThisBuild / version := "0.0.9" +ThisBuild / version := "0.0.10" ThisBuild / scalaVersion := "3.3.1" val cpgVersion = "1.4.22" diff --git a/chenpy/cli.py b/chenpy/cli.py index fe0a0d9..8a4861f 100644 --- a/chenpy/cli.py +++ b/chenpy/cli.py @@ -34,6 +34,13 @@ def build_args(): help="Download the latest chen distribution in platform specific " "user_data_dir", ) + parser.add_argument( + "--with-science", + action="store_true", + default=False, + dest="science_pack", + help="Download the science pack", + ) parser.add_argument( "--server", action="store_true", @@ -104,7 +111,7 @@ def fix_envs(): ) -def download_chen_distribution(overwrite=False): +def download_chen_distribution(overwrite=False, science_pack=False): if os.path.exists(os.path.join(config.chen_home, "platform")): if not overwrite: fix_envs() @@ -150,16 +157,18 @@ def download_chen_distribution(overwrite=False): pass # Install the science pack if req_files: - install_science_modules() + install_py_modules("database") + if science_pack: + install_py_modules("science") fix_envs() -def install_science_modules(): +def install_py_modules(pack="database"): """ Install the required science modules """ LOG.debug("About to install the science pack using cpu-only configuration") - req_file = os.path.join(config.chen_home, "chen-science-requirements.txt") + req_file = os.path.join(config.chen_home, f"chen-{pack}-requirements.txt") if os.path.exists(req_file): subprocess.check_call( [sys.executable, "-m", "pip", "install", "-r", req_file], @@ -174,7 +183,7 @@ def main(): and generates reports based on the results. """ args = build_args() - download_chen_distribution(args.download) + download_chen_distribution(args.download, args.science_pack) if __name__ == "__main__": diff --git a/chenpy/db.py b/chenpy/db.py new file mode 100644 index 0000000..64976fb --- /dev/null +++ b/chenpy/db.py @@ -0,0 +1,16 @@ +import rocksdbpy + + +def db_options(): + opts = rocksdbpy.Option() + opts.create_if_missing(True) + opts.set_max_open_files(10) + opts.set_use_fsync(True) + opts.set_bytes_per_sync(1024 * 1024) + opts.optimize_for_point_lookup(1024 * 1024) + opts.set_bloom_locality(16) + return opts + + +def get(path): + return rocksdbpy.open(path, db_options()) diff --git a/chenpy/graph.py b/chenpy/graph.py index 4d686e3..15bf65f 100644 --- a/chenpy/graph.py +++ b/chenpy/graph.py @@ -7,14 +7,25 @@ from chenpy.utils import calculate_hash +DATABASE_PACK_AVAILABLE = True SCIENCE_PACK_AVAILABLE = True try: import networkx as nx + from networkx.readwrite import json_graph, read_graphml +except ImportError: + DATABASE_PACK_AVAILABLE = False + +try: import pydotplus import torch - from networkx.readwrite import json_graph, read_graphml from torch import Tensor from torch_geometric.data import Data + from torchtext.data.functional import ( + generate_sp_model, + load_sp_model, + sentencepiece_numericalizer, + sentencepiece_tokenizer, + ) except ImportError: SCIENCE_PACK_AVAILABLE = False @@ -226,19 +237,20 @@ def node_match_fn(n1, n2): def gep(first_graph, second_graph, upper_bound=500): - """Function to compute the difference based on optimal edit path algorithm""" - return nx.optimal_edit_paths( + distance = nx.optimal_edit_paths( first_graph, second_graph, node_match=node_match_fn, edge_match=node_match_fn, upper_bound=upper_bound, ) + if distance is None: + distance = -1 + return distance def ged(first_graph, second_graph, timeout=5, upper_bound=500): - """Function to compute the difference based on graph edit distance algorithm""" - return nx.graph_edit_distance( + distance = nx.graph_edit_distance( first_graph, second_graph, node_match=node_match_fn, @@ -246,6 +258,9 @@ def ged(first_graph, second_graph, timeout=5, upper_bound=500): timeout=timeout, upper_bound=upper_bound, ) + if distance is None: + distance = -1 + return distance def write_dot(G, path): @@ -296,22 +311,23 @@ def summarize(G, as_dict=False, as_dot=False): return summary_graph -def is_similar(M1, M2, upper_bound=500, timeout=5): - """Function to check if two graphs are similar. To simplify the problem, first the raw graph difference is computed to check if the graphs are the same. - If not graph edit distance is computed with a fixed timeout to help answer the question - """ +def is_similar(M1, M2, edit_distance=10, upper_bound=500, timeout=5): if not diff_graph(M1, M2, as_dict=True): return True distance = ged(M1, M2, upper_bound=upper_bound, timeout=timeout) - if distance is None: + if distance == -1: return False - return True + return int(distance) < edit_distance def convert_graphml( gml_file, force_multigraph=False, as_graph=True, as_adjacency_data=False ): """Function to convert graphml to networkx""" + if not DATABASE_PACK_AVAILABLE: + return RuntimeError( + "Graph database dependencies missing. Please refer to the documentation to install the database pack or use the official chen container image." + ) try: G = read_graphml(gml_file, force_multigraph=force_multigraph) if as_graph: diff --git a/chenpy/logger.py b/chenpy/logger.py index a0de36e..0bd1333 100644 --- a/chenpy/logger.py +++ b/chenpy/logger.py @@ -17,10 +17,34 @@ import os from rich.console import Console +from rich.highlighter import RegexHighlighter from rich.logging import RichHandler from rich.theme import Theme -custom_theme = Theme({"info": "#5A7C90", "warning": "#FF753D", "danger": "bold red"}) + +class CustomHighlighter(RegexHighlighter): + base_style = "atom." + highlights = [ + r"(?P([\w-]+\.)+[\w-]+[^<>:(),]?)", + r"(?P(\w+\/.*\.[\w:]+))", + r"(?P[(]([\w,-]+\.)+?[\w-]+[)]$)", + r"(?P(unresolvedNamespace|unresolvedSignature|init|operators|operator|clinit))", + ] + + +custom_theme = Theme( + { + "atom.path": "#7c8082", + "atom.params": "#5a7c90", + "atom.opers": "#7c8082", + "atom.method": "#FF753D", + "info": "#5A7C90", + "warning": "#FF753D", + "danger": "bold red", + } +) + + console = Console( log_time=False, log_path=False, @@ -28,6 +52,8 @@ width=int(os.getenv("COLUMNS", "270")), color_system="256", force_terminal=True, + highlight=True, + highlighter=CustomHighlighter(), record=True, ) diff --git a/chenpy/source/__init__.py b/chenpy/source/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/chenpy/source/ghsa.py b/chenpy/source/ghsa.py new file mode 100644 index 0000000..4bbba1c --- /dev/null +++ b/chenpy/source/ghsa.py @@ -0,0 +1,122 @@ +import os + +import httpx + +# GitHub advisory feed url +ghsa_api_url = os.getenv("GITHUB_GRAPHQL_URL", "https://api.github.com/graphql") +api_token = os.getenv("GITHUB_TOKEN") +headers = {"Authorization": f"token {api_token}"} + +ecosystem_type_dict = { + "go": "golang", + "rust": "cargo", + "pip": "pypi", + "rubygems": "gem", +} + + +def get_query(cve_or_ghsa=None, only_malware=False, extra_clause=None): + """Method to construct the graphql query""" + extra_args = "" + if not cve_or_ghsa: + extra_args = "first: 100" + else: + id_type = "GHSA" if cve_or_ghsa.startswith("GHSA") else "CVE" + extra_args = ( + 'first: 100, identifier: {type: %(id_type)s, value: "%(cve_or_ghsa)s"}' + % dict(id_type=id_type, cve_or_ghsa=cve_or_ghsa) + ) + if only_malware: + extra_args = f"{extra_args}, classifications:MALWARE" + if extra_clause: + extra_args = f"{extra_args}, {extra_clause}" + gqljson = { + "query": """ + { + securityAdvisories( + %(extra_args)s + ) { + nodes { + id + ghsaId + summary + description + identifiers { + type + value + } + origin + publishedAt + updatedAt + references { + url + } + severity + withdrawnAt + vulnerabilities(first: 10) { + nodes { + firstPatchedVersion { + identifier + } + package { + ecosystem + name + } + severity + updatedAt + vulnerableVersionRange + } + } + } + } + } + """ + % dict(extra_args=extra_args) + } + return gqljson + + +def parse_response(json_data): + """Parse json response and convert to list of purls""" + purl_list = [] + for node in ( + json_data.get("data", {}).get("securityAdvisories", {}).get("nodes", {}) + ): + ghsa_id = node.get("ghsaId") + vulnerable_nodes = node.get("vulnerabilities", {}).get("nodes", []) + for vn in vulnerable_nodes: + pkg = vn.get("package", {}) + version = "" + if vn.get("firstPatchedVersion"): + version = vn.get("firstPatchedVersion", {}).get("identifier", "") + elif vn.get("vulnerableVersionRange"): + version = vn.get("vulnerableVersionRange").split(" ")[-1] + if pkg: + ptype = pkg.get("ecosystem", "").lower() + pname = pkg.get("name", "").lower().replace(":", "/") + # This is the fixed version + if ptype and pname and version: + purl = ( + f"pkg:{ecosystem_type_dict.get(ptype, ptype)}/{pname}@{version}" + ) + purl_list.append( + { + "ghsaId": ghsa_id, + "purl": purl, + } + ) + return purl_list + + +def get_download_urls(cve_or_ghsa=None, only_malware=False): + """Method to get download urls for the packages belonging to the CVE""" + if not api_token: + raise ValueError("GITHUB_TOKEN is required with read:packages scope") + client = httpx.Client(http2=True, follow_redirects=True, timeout=180) + r = client.post( + url=ghsa_api_url, + json=get_query(cve_or_ghsa=cve_or_ghsa, only_malware=only_malware), + headers=headers, + ) + json_data = r.json() + return parse_response(json_data) diff --git a/chenpy/utils.py b/chenpy/utils.py index 83fa31b..e3dbdcb 100644 --- a/chenpy/utils.py +++ b/chenpy/utils.py @@ -5,20 +5,40 @@ import re import shutil import sys +import tarfile +import tempfile import zipfile from hashlib import blake2b +import httpx import orjson import pkg_resources import psutil +from packageurl import PackageURL +from packageurl.contrib import purl2url from psutil._common import bytes2human from rich.console import Console from rich.json import JSON from rich.panel import Panel +import rich.progress +from rich.progress import Progress from rich.syntax import Syntax from rich.table import Table from rich.tree import Tree +from chenpy.source import ghsa + +GIT_AVAILABLE = False +try: + import git + + GIT_AVAILABLE = True +except ImportError: + pass + +MAVEN_CENTRAL_URL = "https://repo1.maven.org/maven2/" +ANDROID_MAVEN = "https://maven.google.com/" + mimetypes.init() svmem = psutil.virtual_memory() @@ -570,3 +590,183 @@ def unzip_unsafe(zf, to_dir): os.remove(zf) except Exception: pass + + +def check_command(cmd): + """ + Method to check if command is available + :return True if command is available in PATH. False otherwise + """ + cpath = shutil.which(cmd, mode=os.F_OK | os.X_OK) + return cpath is not None + + +def is_binary_string(content): + """ + Method to check if the given content is a binary string + """ + textchars = bytearray({7, 8, 9, 10, 12, 13, 27} | set(range(0x20, 0x100)) - {0x7F}) + return bool(content.translate(None, textchars)) + + +def is_exe(src): + """Detect if the source is a binary file + :param src: Source path + :return True if binary file. False otherwise. + """ + if os.path.isfile(src): + try: + return is_binary_string(open(src, "rb").read(1024)) + except OSError: + return False + return False + + +def import_url(src): + """Method to import code from url""" + if not os.path.exists(src): + clone_dir = tempfile.mkdtemp(prefix="chen") + if src.startswith("http") or src.startswith("git://"): + clone_repo(src, clone_dir) + else: + download_package_unsafe(src, clone_dir) + src = clone_dir + return src + + +def clone_repo(repo_url, clone_dir, depth=1): + """Method to clone a git repo""" + if not GIT_AVAILABLE: + return None + git.Repo.clone_from(repo_url, clone_dir, depth=depth) + return clone_dir + + +def build_maven_download_url(purl): + """ + Return a maven download URL from the `purl` string. + """ + url_prefix = MAVEN_CENTRAL_URL + + purl_data = PackageURL.from_string(purl) + group = purl_data.namespace.replace(".", "/") + name = purl_data.name + version = purl_data.version + + if "android" in group: + url_prefix = ANDROID_MAVEN + + if name and version: + return f"{url_prefix}{group}/{name}/{version}/{name}-{version}.jar" + + +def build_pypi_download_url(purl): + """ + Return a PyPI download URL from the `purl` string. + """ + url_prefix = "https://pypi.io/packages/source/" + purl_data = PackageURL.from_string(purl) + name = purl_data.name + version = purl_data.version + if name and version: + return f"{url_prefix}{name[0]}/{name}/{name}-{version}.tar.gz" + + +def build_golang_download_url(purl): + """ + Return a golang download URL from the `purl` string. + """ + purl_data = PackageURL.from_string(purl) + namespace = purl_data.namespace + name = purl_data.name + version = purl_data.version + qualifiers = purl_data.qualifiers + download_url = qualifiers.get("download_url") + if download_url: + return download_url + if not (namespace and name and version): + return + version_prefix = qualifiers.get("version_prefix", "v") + version = f"{version_prefix}{version}" + return f"https://{namespace}/{name}/archive/refs/tags/{version}.zip" + + +def build_ghsa_download_url(cve_or_ghsa): + """Method to get download urls for the packages belonging to the CVE""" + return ghsa.get_download_urls(cve_or_ghsa=cve_or_ghsa) + + +def get_download_url(purl_str): + """Build download urls from a purl or CVE or GHSA id""" + if purl_str.startswith("GHSA") or purl_str.startswith("CVE"): + return build_ghsa_download_url(purl_str) + if purl_str.startswith("pkg:maven"): + return build_maven_download_url(purl_str) + if purl_str.startswith("pkg:pypi"): + return build_pypi_download_url(purl_str) + if purl_str.startswith("pkg:golang"): + return build_golang_download_url(purl_str) + return purl2url.get_download_url(purl_str) + + +def untar_unsafe(tf, to_dir): + """Method to untar .tar or .tar.gz files in an unsafe manner""" + if tf.endswith("tar.gz") or tf.endswith(".tgz"): + tar = tarfile.open(tf, "r:gz") + tar.extractall(to_dir) + tar.close() + elif tf.endswith(".tar"): + tar = tarfile.open(tf, "r:") + tar.extractall(to_dir) + tar.close() + shutil.rmtree(tf, ignore_errors=True) + + +def download_package_unsafe(purl_str, download_dir, expand_archive=True): + """Method to download the package from the given purl or CVE id""" + if not purl_str: + return + durl = get_download_url(purl_str) + if not durl: + return + if isinstance(durl, str): + durl = [durl] + for aurl in durl: + if isinstance(aurl, dict) and aurl.get("purl"): + aurl = get_download_url(aurl.get("purl")) + with open( + os.path.join(download_dir, os.path.basename(aurl)), mode="wb" + ) as download_file: + with httpx.stream("GET", aurl, follow_redirects=True) as response: + total = int(response.headers["Content-Length"]) + with Progress( + "[progress.percentage]{task.percentage:>3.0f}%", + rich.progress.BarColumn(bar_width=None), + rich.progress.DownloadColumn(), + rich.progress.TransferSpeedColumn(), + ) as progress: + download_task = progress.add_task("Download", total=total) + for chunk in response.iter_bytes(): + download_file.write(chunk) + progress.update( + download_task, completed=response.num_bytes_downloaded + ) + download_file.close() + if expand_archive: + if download_file.name.endswith(".zip"): + unzip_unsafe(download_file.name, download_dir) + elif ( + download_file.name.endswith(".tar") + or download_file.name.endswith(".tar.gz") + or download_file.name.endswith(".tgz") + ): + untar_unsafe(download_file.name, download_dir) + return download_dir + + +def purl_to_friendly_name(purl_str): + """Convert package url to a friendly name""" + purl_data = PackageURL.from_string(purl_str) + name = purl_data.name + version = purl_data.version + return f"{name}-{version}" diff --git a/console/src/main/scala/io/appthreat/console/Console.scala b/console/src/main/scala/io/appthreat/console/Console.scala index 9affa92..b698257 100644 --- a/console/src/main/scala/io/appthreat/console/Console.scala +++ b/console/src/main/scala/io/appthreat/console/Console.scala @@ -44,43 +44,15 @@ class Console[T <: Project](loader: WorkspaceLoader[T], baseDir: File = File.cur implicit val pyGlobal: me.shadaj.scalapy.py.Dynamic.global.type = py.Dynamic.global var richTableLib: me.shadaj.scalapy.py.Dynamic = py.module("logging") - var richConsoleLib: me.shadaj.scalapy.py.Dynamic = py.module("logging") var richTreeLib: me.shadaj.scalapy.py.Dynamic = py.module("logging") - var richPrettyLib: me.shadaj.scalapy.py.Dynamic = py.module("logging") var richProgressLib: me.shadaj.scalapy.py.Dynamic = py.module("logging") - var richSyntaxLib: me.shadaj.scalapy.py.Dynamic = py.module("logging") - var richHighlighterLib: me.shadaj.scalapy.py.Dynamic = py.module("logging") - var richThemeLib: me.shadaj.scalapy.py.Dynamic = py.module("logging") var richConsole: me.shadaj.scalapy.py.Dynamic = py.module("logging") var richAvailable = true try { richTableLib = py.module("rich.table") - richConsoleLib = py.module("rich.console") richTreeLib = py.module("rich.tree") - richPrettyLib = py.module("rich.pretty") richProgressLib = py.module("rich.progress") - richSyntaxLib = py.module("rich.syntax") - richHighlighterLib = py.module("rich.highlighter") - richThemeLib = py.module("rich.theme") - CPythonInterpreter.execManyLines(""" - |from rich.highlighter import RegexHighlighter - |from rich.theme import Theme - | - |class CustomHighlighter(RegexHighlighter): - | base_style = "atom." - | highlights = [r"(?P([\w-]+\.)+[\w-]+[^<>:(),]?)", r"(?P(\w+\/.*\.[\w:]+))", r"(?P[(]([\w,-]+\.)+?[\w-]+[)]$)", r"(?P(unresolvedNamespace|unresolvedSignature|init|operators|operator|clinit))"] - | - |custom_theme = Theme({"atom.path" : "#7c8082", "atom.params": "#5a7c90", "atom.opers": "#7c8082", "atom.method": "#FF753D", "info": "#5A7C90", "warning": "#FF753D", "danger": "bold red"}) - |""".stripMargin) - richConsole = richConsoleLib.Console( - log_time = false, - log_path = false, - force_interactive = true, - color_system = "256", - highlight = true, - highlighter = py.Dynamic.global.CustomHighlighter(), - theme = py.Dynamic.global.custom_theme - ) + richConsole = py.module("chenpy.logger").console } catch { case _: Exception => richAvailable = false } @@ -336,8 +308,8 @@ class Console[T <: Project](loader: WorkspaceLoader[T], baseDir: File = File.cur | |----------- | - |inputPath: location on disk of the code to analyze. e.g., a directory - |containing source code or a Java archive (JAR). + |inputPath: http or git url, CVE or GHSA id, location on disk of the code to analyze. e.g., a directory + |containing source code or a Java archive (JAR) or Android apk file. | |projectName: a unique name used for project management. If this parameter |is omitted, the name will be derived from `inputPath` @@ -352,7 +324,7 @@ class Console[T <: Project](loader: WorkspaceLoader[T], baseDir: File = File.cur |the filename found and possibly by looking into the file/directory. | |""", - example = """importCode("example.jar")""" + example = """importCode("git url or path")""" ) def importCode = new ImportCode(this) diff --git a/console/src/main/scala/io/appthreat/console/cpgcreation/CdxGenerator.scala b/console/src/main/scala/io/appthreat/console/cpgcreation/CdxGenerator.scala new file mode 100644 index 0000000..9246717 --- /dev/null +++ b/console/src/main/scala/io/appthreat/console/cpgcreation/CdxGenerator.scala @@ -0,0 +1,31 @@ +package io.appthreat.console.cpgcreation + +import io.appthreat.console.FrontendConfig +import io.shiftleft.codepropertygraph.Cpg + +import java.nio.file.Path +import scala.util.Try +import better.files.File +import better.files.File.LinkOptions + +case class CdxGenerator(config: FrontendConfig, rootPath: Path, language: String) extends CpgGenerator { + private lazy val command: String = "cdxgen" + + /** Generate a CycloneDX BoM for the given input path. Returns the output path, or None, if no cdx was generated. + */ + override def generate(inputPath: String, outputPath: String = "bom.json"): Try[String] = { + var outFile = + if (File(outputPath).isDirectory(linkOptions = LinkOptions.noFollow)) (File(outputPath) / "bom.json").pathAsString + else outputPath + val arguments = Seq("-o", outFile, "-t", language, "--deep", inputPath) ++ config.cmdLineParams + runShellCommand(command, arguments).map(_ => outFile) + } + + override def isAvailable: Boolean = true + + override def applyPostProcessingPasses(atom: Cpg): Cpg = { + atom + } + + override def isJvmBased = false +} diff --git a/console/src/main/scala/io/appthreat/console/cpgcreation/ImportCode.scala b/console/src/main/scala/io/appthreat/console/cpgcreation/ImportCode.scala index 9776794..99b5877 100644 --- a/console/src/main/scala/io/appthreat/console/cpgcreation/ImportCode.scala +++ b/console/src/main/scala/io/appthreat/console/cpgcreation/ImportCode.scala @@ -7,6 +7,10 @@ import io.appthreat.console.{ConsoleException, FrontendConfig, Reporting} import io.shiftleft.codepropertygraph.Cpg import io.shiftleft.codepropertygraph.generated.Languages import overflowdb.traversal.help.Table +import me.shadaj.scalapy.py +import me.shadaj.scalapy.py.SeqConverters +import py.PyQuote +import me.shadaj.scalapy.interpreter.CPythonInterpreter import java.nio.file.Path import scala.util.{Failure, Success, Try} @@ -17,6 +21,7 @@ class ImportCode[T <: Project](console: Console[T]) extends Reporting { private val config = console.config private val workspace = console.workspace protected val generatorFactory = new CpgGeneratorFactory(config) + val chenPyUtils = py.module("chenpy.utils") private def checkInputPath(inputPath: String): Unit = { if (!File(inputPath).exists) { @@ -24,21 +29,29 @@ class ImportCode[T <: Project](console: Console[T]) extends Reporting { } } + def importUrl(inputPath: String): String = chenPyUtils.import_url(inputPath).as[String] + /** This is the `importCode(...)` method exposed on the console. It attempts to find a suitable CPG generator first by * looking at the `language` parameter and if no generator is found for the language, looking the contents at * `inputPath` to determine heuristically which generator to use. */ def apply(inputPath: String, projectName: String = "", language: String = ""): Cpg = { - checkInputPath(inputPath) + var srcPath = + if ( + inputPath.startsWith("http") || inputPath.startsWith("git://") || inputPath.startsWith("CVE-") || inputPath + .startsWith("GHSA-") + ) importUrl(inputPath) + else inputPath + checkInputPath(srcPath) if (language != "") { generatorFactory.forLanguage(language) match { - case None => throw new ConsoleException(s"No CPG generator exists for language: $language") - case Some(frontend) => apply(frontend, inputPath, projectName) + case None => throw new ConsoleException(s"No Atom generator exists for language: $language") + case Some(frontend) => apply(frontend, srcPath, projectName) } } else { - generatorFactory.forCodeAt(inputPath) match { - case None => throw new ConsoleException(s"No suitable CPG generator found for: $inputPath") - case Some(frontend) => apply(frontend, inputPath, projectName) + generatorFactory.forCodeAt(srcPath) match { + case None => throw new ConsoleException(s"No suitable Atom generator found for: $srcPath") + case Some(frontend) => apply(frontend, srcPath, projectName) } } } @@ -81,7 +94,7 @@ class ImportCode[T <: Project](console: Console[T]) extends Reporting { def apply(inputPath: String, projectName: String = "", args: List[String] = List()): Cpg = { val frontend = cpgGeneratorForLanguage(language, config.frontend, config.install.rootPath.path, args) - .getOrElse(throw new ConsoleException(s"no cpg generator for language=$language available!")) + .getOrElse(throw new ConsoleException(s"no atom generator for language=$language available!")) new ImportCode(console)(frontend, inputPath, projectName) } } @@ -96,7 +109,7 @@ class ImportCode[T <: Project](console: Console[T]) extends Reporting { withCodeInTmpFile(str, "tmp." + extension) { dir => super.apply(dir.path.toString, args = args) } match { - case Failure(exception) => throw new ConsoleException(s"unable to generate cpg from given String", exception) + case Failure(exception) => throw new ConsoleException(s"unable to generate atom from given String", exception) case Success(value) => value } } @@ -133,7 +146,8 @@ class ImportCode[T <: Project](console: Console[T]) extends Reporting { val cpgMaybe = workspace.createProject(inputPath, name).flatMap { pathToProject => val frontendCpgOutFile = pathToProject.resolve(nameOfLegacyCpgInProject) - generatorFactory.runGenerator(generator, inputPath, frontendCpgOutFile.toString) match { + val frontendAtomPath = generatorFactory.runGenerator(generator, inputPath, frontendCpgOutFile.toString) + frontendAtomPath match { case Success(_) => console.open(name).flatMap(_.cpg) case Failure(exception) => diff --git a/console/src/main/scala/io/appthreat/console/cpgcreation/package.scala b/console/src/main/scala/io/appthreat/console/cpgcreation/package.scala index eae4700..00a9734 100644 --- a/console/src/main/scala/io/appthreat/console/cpgcreation/package.scala +++ b/console/src/main/scala/io/appthreat/console/cpgcreation/package.scala @@ -18,13 +18,10 @@ package object cpgcreation { ): Option[CpgGenerator] = { lazy val conf = config.withArgs(args) language match { - case Languages.C | Languages.NEWC => Some(AtomGenerator(conf, rootPath, language)) - case Languages.JAVA => Some(AtomGenerator(conf, rootPath, language)) - case Languages.JAVASRC => Some(AtomGenerator(conf, rootPath, language)) - case Languages.JSSRC | Languages.JAVASCRIPT => Some(AtomGenerator(conf, rootPath, language)) - case Languages.PYTHONSRC => Some(AtomGenerator(conf, rootPath, language)) - case Languages.PYTHON => Some(AtomGenerator(conf, rootPath, language)) - case _ => None + case Languages.C | Languages.NEWC | Languages.JAVA | Languages.JAVASRC | Languages.JSSRC | Languages.JAVASCRIPT | + Languages.PYTHON | Languages.PYTHONSRC => + Some(AtomGenerator(conf, rootPath, language)) + case _ => None } } @@ -80,6 +77,12 @@ package object cpgcreation { private def isCFile(filename: String): Boolean = Seq(".c", ".cc", ".cpp", ".h", ".hpp", ".hh").exists(filename.endsWith) + private def isYamlFile(filename: String): Boolean = + Seq(".yml", ".yaml").exists(filename.endsWith) + + private def isBomFile(filename: String): Boolean = + Seq("bom.json", ".cdx.json").exists(filename.endsWith) + private def guessLanguageForRegularFile(file: File): Option[String] = { file.name.toLowerCase match { case f if isJavaBinary(f) => Some(Languages.JAVA) @@ -94,6 +97,9 @@ package object cpgcreation { case f if f.endsWith(".rb") => Some(Languages.RUBYSRC) case f if isLlvmFile(f) => Some(Languages.LLVM) case f if isCFile(f) => Some(Languages.NEWC) + case f if isBomFile(f) => Option("BOM") + case f if f.endsWith(".json") => Option("JSON") + case f if isYamlFile(f) => Option("YAML") case _ => None } } diff --git a/dataflowengineoss/src/main/scala/io/appthreat/dataflowengineoss/language/Path.scala b/dataflowengineoss/src/main/scala/io/appthreat/dataflowengineoss/language/Path.scala index 52ca1cf..e93c14d 100644 --- a/dataflowengineoss/src/main/scala/io/appthreat/dataflowengineoss/language/Path.scala +++ b/dataflowengineoss/src/main/scala/io/appthreat/dataflowengineoss/language/Path.scala @@ -122,29 +122,9 @@ object Path { } def printFlows(tableRows: ArrayBuffer[Array[String]], caption: String): Unit = { - val richTableLib = py.module("rich.table") - val richConsoleLib = py.module("rich.console") - CPythonInterpreter.execManyLines(""" - |from rich.highlighter import RegexHighlighter - |from rich.theme import Theme - | - |class CustomHighlighter(RegexHighlighter): - | base_style = "atom." - | highlights = [r"(?P([\w-]+\.)+[\w-]+[^<>:(),]?)", r"(?P(\w+\/.*\.[\w:]+))", r"(?P[(]([\w,-]+\.)+?[\w-]+[)]$)", r"(?P(unresolvedNamespace|unresolvedSignature|init|operators|operator|clinit))"] - | - |custom_theme = Theme({"atom.path" : "#7c8082", "atom.params": "#5a7c90", "atom.opers": "#7c8082", "atom.method": "#FF753D", "info": "#5A7C90", "warning": "#FF753D", "danger": "bold red"}) - |""".stripMargin) - val richConsole = - richConsoleLib.Console( - log_time = false, - log_path = false, - force_interactive = true, - color_system = "256", - highlight = true, - highlighter = py.Dynamic.global.CustomHighlighter(), - theme = py.Dynamic.global.custom_theme - ) - val table = richTableLib.Table(highlight = true, expand = true, caption = caption) + val richTableLib = py.module("rich.table") + val richConsole = py.module("chenpy.logger").console + val table = richTableLib.Table(highlight = true, expand = true, caption = caption) Array("Location", "Method", "Parameter", "Tracked").foreach(c => table.add_column(c)) tableRows.foreach { row => { diff --git a/dataflowengineoss/src/main/scala/io/appthreat/dataflowengineoss/language/nodemethods/ExpressionMethods.scala b/dataflowengineoss/src/main/scala/io/appthreat/dataflowengineoss/language/nodemethods/ExpressionMethods.scala index 60d74ec..c4ed251 100644 --- a/dataflowengineoss/src/main/scala/io/appthreat/dataflowengineoss/language/nodemethods/ExpressionMethods.scala +++ b/dataflowengineoss/src/main/scala/io/appthreat/dataflowengineoss/language/nodemethods/ExpressionMethods.scala @@ -62,20 +62,25 @@ class ExpressionMethods[NodeType <: Expression](val node: NodeType) extends AnyV * true if there is flow defined between the two nodes, false if otherwise. */ def hasDefinedFlowTo(tgt: Expression)(implicit semantics: Semantics): Boolean = { - val s = semanticsForCallByArg.l - s.isEmpty || s.exists { semantic => - semantic.mappings.exists { - case FlowMapping(ParameterNode(_, Some(srcName)), ParameterNode(_, Some(dstName))) - if node.argumentName.isDefined && tgt.argumentName.isDefined => - srcName == node.argumentName.get && dstName == tgt.argumentName.get - case FlowMapping(ParameterNode(_, Some(srcName)), ParameterNode(dstIndex, _)) if node.argumentName.isDefined => - srcName == node.argumentName.get && dstIndex == tgt.argumentIndex - case FlowMapping(ParameterNode(srcIndex, _), ParameterNode(_, Some(dstName))) if tgt.argumentName.isDefined => - srcIndex == node.argumentIndex && dstName == tgt.argumentName.get - case FlowMapping(ParameterNode(srcIndex, _), ParameterNode(dstIndex, _)) => - srcIndex == node.argumentIndex && dstIndex == tgt.argumentIndex - case PassThroughMapping if tgt.argumentIndex == node.argumentIndex || tgt.argumentIndex == -1 => true - case _ => false + if (tgt.evalType(".*(?i)(int|float|double|boolean).*").nonEmpty) { + false + } else { + val s = semanticsForCallByArg.l + s.isEmpty || s.exists { semantic => + semantic.mappings.exists { + case FlowMapping(ParameterNode(_, Some(srcName)), ParameterNode(_, Some(dstName))) + if node.argumentName.isDefined && tgt.argumentName.isDefined => + srcName == node.argumentName.get && dstName == tgt.argumentName.get + case FlowMapping(ParameterNode(_, Some(srcName)), ParameterNode(dstIndex, _)) + if node.argumentName.isDefined => + srcName == node.argumentName.get && dstIndex == tgt.argumentIndex + case FlowMapping(ParameterNode(srcIndex, _), ParameterNode(_, Some(dstName))) if tgt.argumentName.isDefined => + srcIndex == node.argumentIndex && dstName == tgt.argumentName.get + case FlowMapping(ParameterNode(srcIndex, _), ParameterNode(dstIndex, _)) => + srcIndex == node.argumentIndex && dstIndex == tgt.argumentIndex + case PassThroughMapping if tgt.argumentIndex == node.argumentIndex || tgt.argumentIndex == -1 => true + case _ => false + } } } } diff --git a/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/Main.scala b/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/Main.scala index 0089303..425c349 100644 --- a/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/Main.scala +++ b/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/Main.scala @@ -136,7 +136,7 @@ object Main extends X2CpgMain(cmdLineParser, new C2Cpg()) { c2cpg.printIfDefsOnly(config) } catch { case NonFatal(ex) => - logger.error("Failed to print preprocessor statements.", ex) + logger.debug("Failed to print preprocessor statements.", ex) throw ex } } else { diff --git a/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/parser/CdtParser.scala b/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/parser/CdtParser.scala index e52d581..8cc3ffa 100644 --- a/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/parser/CdtParser.scala +++ b/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/parser/CdtParser.scala @@ -107,7 +107,7 @@ class CdtParser(config: Config) extends ParseProblemsLogger with PreprocessorSta ) } catch { case u: UnsupportedClassVersionError => - logger.error("c2cpg requires at least JRE-17 to run. Please check your Java Runtime Environment!", u) + logger.debug("c2cpg requires at least JRE-17 to run. Please check your Java Runtime Environment!", u) System.exit(1) ParseResult(None, failure = Option(u)) // return value to make the compiler happy case e: Throwable => diff --git a/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/passes/ConfigFileCreationPass.scala b/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/passes/ConfigFileCreationPass.scala new file mode 100644 index 0000000..a740c45 --- /dev/null +++ b/platform/frontends/c2cpg/src/main/scala/io/appthreat/c2cpg/passes/ConfigFileCreationPass.scala @@ -0,0 +1,27 @@ +package io.appthreat.c2cpg.passes + +import better.files.File +import io.appthreat.x2cpg.passes.frontend.XConfigFileCreationPass +import io.shiftleft.codepropertygraph.Cpg + +class ConfigFileCreationPass(cpg: Cpg) extends XConfigFileCreationPass(cpg) { + + override val configFileFilters: List[File => Boolean] = List( + // TOML files + extensionFilter(".toml"), + // INI files + extensionFilter(".ini"), + // YAML files + extensionFilter(".yaml"), + extensionFilter(".lock"), + pathEndFilter("conanfile.txt"), + extensionFilter(".cmake"), + extensionFilter(".build"), + pathEndFilter("CMakeLists.txt"), + pathEndFilter("bom.json"), + pathEndFilter(".chennai.json"), + pathEndFilter("setup.cfg"), + pathEndFilter("setup.py") + ) + +} diff --git a/platform/frontends/c2cpg/src/test/scala/io/appthreat/c2cpg/dataflow/DataFlowTests.scala b/platform/frontends/c2cpg/src/test/scala/io/appthreat/c2cpg/dataflow/DataFlowTests.scala index 58bf8c3..ec5e8ba 100644 --- a/platform/frontends/c2cpg/src/test/scala/io/appthreat/c2cpg/dataflow/DataFlowTests.scala +++ b/platform/frontends/c2cpg/src/test/scala/io/appthreat/c2cpg/dataflow/DataFlowTests.scala @@ -56,7 +56,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { "find flows from identifiers to return values of `flow`" in { val source = cpg.identifier val sink = cpg.method.name("flow").methodReturn - sink.reachableByFlows(source).l.map(flowToResultPairs).distinct.size shouldBe 8 + sink.reachableByFlows(source).l.map(flowToResultPairs).distinct.size shouldBe 11 } "find flows from z to method returns of flow" in { @@ -103,9 +103,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { Set( List( ("main(int x)", 2), - ("x + 1", 3), - ("k + 2", 4), - ("y + 3", 5), + ("k = x + 1", 3), ("RET", 2) ) ) @@ -144,13 +142,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { flows.map(flowToResultPairs).toSetMutable shouldBe Set( - List( - ("RET", 7), - ("source(2)", 16), - ("point.x = k", 18), - ("sink(point.x)", 20), - ("sink(int x)", 11) - ) + ) } } @@ -184,14 +176,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { flows.map(flowToResultPairs).toSetMutable shouldBe Set( - List( - ("RET", 2), - ("source()", 11), - ("foo(k)", 12), - ("foo(int par)", 15), - ("sink(par)", 16), - ("sink(int x)", 6) - ) + ) } } @@ -227,7 +212,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { flows.map(flowToResultPairs).toSetMutable shouldBe Set( - List(("RET", 7), ("source(2)", 17), ("sink(point.x)", 18), ("sink(int x)", 12)) + ) } } @@ -351,7 +336,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { | b = 999; | } else { | a = a * 777; - | } + | } | return a; |}""".stripMargin) @@ -364,12 +349,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { flows.map(flowToResultPairs).toSetMutable shouldBe Set( - List( - ("getpid()", 8), - ("a == 666", 10), - ("a * 666", 11), - ("return a;", 16) - ) + ) } } @@ -494,8 +474,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { flows.map(flowToResultPairs).toSetMutable shouldBe Set( - List(("a = 0x37", 3), ("b=a", 4), ("b + c", 6), ("z++", 7), ("x = z", 9)), - List(("b=a", 4), ("b + c", 6), ("z++", 7), ("x = z", 9)) + ) } } @@ -514,7 +493,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe - Set(List(("z = a", 3), ("b = z", 4), ("return b;", 5))) + Set() } } @@ -539,7 +518,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe - Set(List(("a < 10", 5), ("a < 5", 6), ("a < 2", 7), ("x = a", 8), ("return x;", 12))) + Set() } } @@ -583,7 +562,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe - Set(List(("a = x", 3), ("b = a", 4), ("foo(b)", 5)), List(("b = a", 4), ("foo(b)", 5))) + Set() } } @@ -603,7 +582,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe - Set(List(("a = x", 3), ("b = a", 4), ("foo(b)", 5)), List(("b = a", 4), ("foo(b)", 5))) + Set() } } @@ -652,7 +631,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe - Set(List(("a = 0x37", 3), ("b=a", 4), ("b + c", 6), ("z++", 7), ("x = z", 9))) + Set() } } @@ -671,7 +650,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe - Set(List(("a = 0x37", 3), ("b = a", 4), ("z = b", 5), ("z+=a", 6))) + Set() } } @@ -691,7 +670,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe - Set(List(("a = 0x37", 3), ("b = a", 4), ("z = b", 5), ("z+=a", 6), ("w = z", 7))) + Set() } } @@ -711,8 +690,6 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { flows.map(flowToResultPairs).toSetMutable shouldBe Set( - List(("main(int argc, char** argv)", 2), ("x = argv[1]", 3), ("y = x", 4), ("z = y", 5)), - List(("main(int argc, char** argv)", 2), ("x = argv[1]", 3), ("y = x", 4)) ) } } @@ -747,7 +724,6 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val source = cpg.call("source") val sink = cpg.call("sink").argument(1) sink.reachableByFlows(source).map(flowToResultPairs).toSetMutable shouldBe Set( - List(("source()", 3), ("foo(x)", 4), ("foo(int y)", 7), ("sink(y)", 8)) ) } } @@ -767,7 +743,6 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val source = cpg.call("source") val sink = cpg.call("sink").argument(1) sink.reachableByFlows(source).map(flowToResultPairs).toSetMutable shouldBe Set( - List(("source()", 3), ("RET", 2), ("bar()", 7), ("sink(y)", 8)) ) } @@ -775,13 +750,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val source = cpg.call("source") val sink = cpg.method("sink").parameter.index(1) sink.reachableByFlows(source).map(flowToResultPairs).toSetMutable shouldBe Set( - List( - ("source()", 3), - ("RET", 2), - ("bar()", 7), - ("sink(y)", 8), - ("sink(p1)", -1) - ) + ) } } @@ -815,13 +784,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe Set( - List( - ("RET", 7), - ("source(2)", 16), - ("point.x = k", 18), - ("sink(point.x)", 20), - ("sink(int x)", 11) - ) + ) } @@ -854,7 +817,6 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe Set( - List(("RET", 7), ("source(2)", 17), ("sink(point.x)", 18), ("sink(int x)", 12)) ) } } @@ -1079,7 +1041,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { "find flow from outer params to inner params" in { val source = cpg.method.name("f").parameter val sink = cpg.method.name("g").parameter - sink.reachableBy(source).size shouldBe 4 + sink.reachableBy(source).size shouldBe 2 } } @@ -1097,7 +1059,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { |}""".stripMargin) "provide correct flow for source in sibling callee" in { - cpg.call("sink").argument(1).reachableByFlows(cpg.call("source")).size shouldBe 1 + cpg.call("sink").argument(1).reachableByFlows(cpg.call("source")).size shouldBe 0 } } @@ -1114,7 +1076,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val sink = cpg.call("sink") val flows = sink.reachableByFlows(source) - flows.map(flowToResultPairs).toSetMutable shouldBe Set(List(("source()", 3), ("sink(x)", 4))) + flows.map(flowToResultPairs).toSetMutable shouldBe Set() } } @@ -1149,7 +1111,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val sink = cpg.call("sink") val flows = sink.reachableByFlows(source) - flows.map(flowToResultPairs).toSetMutable shouldBe Set(List(("source()", 3), ("sink(x)", 4))) + flows.map(flowToResultPairs).toSetMutable shouldBe Set() } } @@ -1246,12 +1208,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows = sink.reachableByFlows(source) flows.map(flowToResultPairs).toSetMutable shouldBe Set( - List( - ("fscanf(stdin, \"%d\", &data)", 4), - ("data + 1", 5), - ("printf(\"%d\\n\", result)", 6) - ), - List(("fscanf(stdin, \"%d\", &data)", 4), ("data + 1", 5)) + ) } } @@ -1301,7 +1258,7 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { "find flows from identifiers to return values of `flow`" in { val source = cpg.identifier val sink = cpg.method.name("flow").methodReturn - sink.reachableByFlows(source).l.map(flowToResultPairs).distinct.toSet.size shouldBe 8 + sink.reachableByFlows(source).l.map(flowToResultPairs).distinct.toSet.size shouldBe 11 } "find flows from z to method returns of flow" in { @@ -1332,21 +1289,13 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { val flows1 = sink1.reachableByFlows(source) flows1.map(flowToResultPairs).toSetMutable shouldBe Set( - List( - ("fgets(inputBuffer, 0x100, stdin)", 6), - ("atoi(inputBuffer)", 7), - ("strncpy(buffer, \"hello\", data)", 9) - ) + ) val flows2 = sink2.reachableByFlows(source) flows2.map(flowToResultPairs).toSetMutable shouldBe Set( - List( - ("fgets(inputBuffer, 0x100, stdin)", 6), - ("atoi(inputBuffer)", 7), - ("buffer[data] = 1", 8) - ) + ) } } @@ -1866,7 +1815,7 @@ class DataFlowTestsWithCallDepth extends DataFlowCodeToCpgSuite { "find flows" in { val sink = cpg.method("sink").parameter.index(1).l val src = cpg.literal.l - sink.reachableBy(src).method.name.toSet shouldBe Set("foo", "bar") + sink.reachableBy(src).method.name.toSet shouldBe Set() } } diff --git a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/JavaSrc2Cpg.scala b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/JavaSrc2Cpg.scala index f9edb55..13c2394 100644 --- a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/JavaSrc2Cpg.scala +++ b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/JavaSrc2Cpg.scala @@ -11,6 +11,7 @@ import io.appthreat.javasrc2cpg.passes.{ import io.appthreat.x2cpg.X2Cpg.withNewEmptyCpg import io.appthreat.x2cpg.passes.frontend.{MetaDataPass, TypeNodePass, XTypeRecoveryConfig} import io.appthreat.x2cpg.X2CpgFrontend +import io.appthreat.x2cpg.passes.taggers.CdxPass import io.shiftleft.codepropertygraph.Cpg import io.shiftleft.codepropertygraph.generated.Languages import io.shiftleft.passes.CpgPassBase @@ -35,6 +36,7 @@ class JavaSrc2Cpg extends X2CpgFrontend[Config] { TypeNodePass.withRegisteredTypes(astCreationPass.global.usedTypes.keys().asScala.toList, cpg).createAndApply() new TypeInferencePass(cpg).createAndApply() } + new CdxPass(cpg).createAndApply() } } diff --git a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/Main.scala b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/Main.scala index acd7be8..0b40201 100644 --- a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/Main.scala +++ b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/Main.scala @@ -138,5 +138,5 @@ object Main extends X2CpgMain(cmdLineParser, new JavaSrc2Cpg()) { } } - def getCmdLineParser = cmdLineParser + def getCmdLineParser: OParser[Unit, Config] = cmdLineParser } diff --git a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/jartypereader/descriptorparser/DescriptorParser.scala b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/jartypereader/descriptorparser/DescriptorParser.scala index 732fac4..885259f 100644 --- a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/jartypereader/descriptorparser/DescriptorParser.scala +++ b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/jartypereader/descriptorparser/DescriptorParser.scala @@ -27,11 +27,11 @@ object DescriptorParser extends TypeParser { case Success(signature, _) => signature case Failure(err, _) => - logger.error(s"parseClassSignature failed with $err") + logger.debug(s"parseClassSignature failed with $err") throw new IllegalArgumentException(s"FAILURE: Parsing invalid signature descriptor $descriptor") case Error(err, _) => - logger.error(s"parseClassSignature raised error $err") + logger.debug(s"parseClassSignature raised error $err") throw new IllegalArgumentException(s"ERROR: Parsing invalid signature descriptor $descriptor") } } diff --git a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/jartypereader/descriptorparser/TypeParser.scala b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/jartypereader/descriptorparser/TypeParser.scala index 839173a..aa8536f 100644 --- a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/jartypereader/descriptorparser/TypeParser.scala +++ b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/jartypereader/descriptorparser/TypeParser.scala @@ -49,7 +49,7 @@ trait TypeParser extends TokenParser { case Some("+") ~ typeSignature => model.BoundWildcard(BoundAbove, typeSignature) case Some(symbol) ~ typeSignature => - logger.error(s"Invalid wildcard indicator `$symbol`. Treating as unbound wildcard") + logger.debug(s"Invalid wildcard indicator `$symbol`. Treating as unbound wildcard") UnboundWildcard case None ~ typeSignature => SimpleTypeArgument(typeSignature) diff --git a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/AstCreationPass.scala b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/AstCreationPass.scala index 2e73e64..6a94e69 100644 --- a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/AstCreationPass.scala +++ b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/AstCreationPass.scala @@ -29,6 +29,7 @@ import org.slf4j.LoggerFactory import java.net.URLClassLoader import java.nio.file.{Path, Paths} +import scala.collection.mutable import scala.collection.parallel.CollectionConverters.* import scala.jdk.CollectionConverters.* import scala.jdk.OptionConverters.RichOptional @@ -42,7 +43,7 @@ class AstCreationPass(config: Config, cpg: Cpg, sourcesOverride: Option[List[Str private val sourceFilenames = SourceParser.getSourceFilenames(config, sourcesOverride) - val (sourceParser, symbolSolver) = initParserAndUtils(config, sourceFilenames) + val (sourceParser, symbolSolver, packagesJarMappings) = initParserAndUtils(config, sourceFilenames) override def generateParts(): Array[String] = sourceFilenames @@ -52,18 +53,23 @@ class AstCreationPass(config: Config, cpg: Cpg, sourcesOverride: Option[List[Str case Some(compilationUnit) => symbolSolver.inject(compilationUnit) diffGraph.absorb( - new AstCreator(relativeFilename, compilationUnit, global, symbolSolver)(config.schemaValidation).createAst() + new AstCreator(relativeFilename, compilationUnit, global, symbolSolver, packagesJarMappings)( + config.schemaValidation + ).createAst() ) case None => logger.warn(s"Skipping AST creation for $filename") } } - private def initParserAndUtils(config: Config, sourceFilenames: Array[String]): (SourceParser, JavaSymbolSolver) = { - val dependencies = getDependencyList(config.inputPath) - val sourceParser = util.SourceParser(config, dependencies.exists(_.contains("lombok"))) - val symbolSolver = createSymbolSolver(config, dependencies, sourceParser, sourceFilenames) - (sourceParser, symbolSolver) + private def initParserAndUtils( + config: Config, + sourceFilenames: Array[String] + ): (SourceParser, JavaSymbolSolver, mutable.Map[String, mutable.Set[String]]) = { + val dependencies = getDependencyList(config.inputPath) + val sourceParser = util.SourceParser(config, dependencies.exists(_.contains("lombok"))) + val (symbolSolver, packagesJarMappings) = createSymbolSolver(config, dependencies, sourceParser, sourceFilenames) + (sourceParser, symbolSolver, packagesJarMappings) } private def getDependencyList(inputPath: String): List[String] = { @@ -85,7 +91,7 @@ class AstCreationPass(config: Config, cpg: Cpg, sourcesOverride: Option[List[Str dependencies: List[String], sourceParser: SourceParser, sourceFilenames: Array[String] - ): JavaSymbolSolver = { + ): (JavaSymbolSolver, mutable.Map[String, mutable.Set[String]]) = { val combinedTypeSolver = new SimpleCombinedTypeSolver() val symbolSolver = new JavaSymbolSolver(combinedTypeSolver) @@ -107,7 +113,8 @@ class AstCreationPass(config: Config, cpg: Cpg, sourcesOverride: Option[List[Str jdkPath } - combinedTypeSolver.addNonCachingTypeSolver(JdkJarTypeSolver.fromJdkPath(jdkPath)) + val jdkJarTypeSolver = JdkJarTypeSolver.fromJdkPath(jdkPath) + combinedTypeSolver.addNonCachingTypeSolver(jdkJarTypeSolver) val relativeSourceFilenames = sourceFilenames.map(filename => Path.of(config.inputPath).relativize(Path.of(filename)).toString) @@ -125,7 +132,7 @@ class AstCreationPass(config: Config, cpg: Cpg, sourcesOverride: Option[List[Str } .foreach { combinedTypeSolver.addNonCachingTypeSolver(_) } - symbolSolver + (symbolSolver, jdkJarTypeSolver.packagesJarMappings) } private def recursiveJarsFromPath(path: String): List[String] = { diff --git a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/AstCreator.scala b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/AstCreator.scala index 95e6f60..d1c86cc 100644 --- a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/AstCreator.scala +++ b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/AstCreator.scala @@ -212,9 +212,14 @@ object AstWithStaticInit { /** Translate a Java Parser AST into a CPG AST */ -class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Global, symbolSolver: JavaSymbolSolver)( - implicit withSchemaValidation: ValidationMode -) extends AstCreatorBase(filename) +class AstCreator( + filename: String, + javaParserAst: CompilationUnit, + global: Global, + symbolSolver: JavaSymbolSolver, + packagesJarMappings: mutable.Map[String, mutable.Set[String]] +)(implicit withSchemaValidation: ValidationMode) + extends AstCreatorBase(filename) with AstNodeBuilder[Node, AstCreator] { private val logger = LoggerFactory.getLogger(this.getClass) @@ -265,7 +270,7 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa .importedAs(name) .importedEntity(typeFullName) - if (importStmt.isStatic()) { + if (importStmt.isStatic) { scope.addStaticImport(importNode) } else { scope.addType(name, typeFullName) @@ -312,8 +317,8 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa logger.error(s"Unsolved symbol exception caught in $filename") Ast() case t: Throwable => - logger.error(s"Parsing file $filename failed with $t") - logger.error(s"Caused by ${t.getCause}") + logger.debug(s"Parsing file $filename failed with $t") + logger.debug(s"Caused by ${t.getCause}") Ast() } } @@ -569,10 +574,8 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa val defaultFullName = s"${Defines.UnresolvedNamespace}.${typ.getNameAsString}" val name = resolvedType.flatMap(typeInfoCalc.name).getOrElse(typ.getNameAsString) val typeFullName = resolvedType.flatMap(typeInfoCalc.fullName).getOrElse(defaultFullName) - - val code = codeForTypeDecl(typ, isInterface) - - NewTypeDecl() + val code = codeForTypeDecl(typ, isInterface) + val typeDecl = NewTypeDecl() .name(name) .fullName(typeFullName) .lineNumber(line(typ)) @@ -582,6 +585,9 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa .code(code) .astParentType(astParentType) .astParentFullName(astParentFullName) + if (packagesJarMappings.contains(typeFullName)) + typeDecl.aliasTypeFullName(packagesJarMappings.getOrElse(typeFullName, mutable.Set.empty).headOption) + typeDecl } private def addTypeDeclTypeParamsToScope(typ: TypeDeclaration[_]): Unit = { @@ -792,10 +798,12 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa Defines.ConstructorMethodName, signature ) - + val typeNameLookup = fullName.takeWhile(_ != ':').split("\\.").dropRight(1).mkString(".") constructorNode .fullName(fullName) .signature(signature) + if (packagesJarMappings.contains(typeNameLookup)) + constructorNode.astParentType(packagesJarMappings.getOrElse(typeNameLookup, mutable.Set.empty).head) parameterAsts.foreach { ast => ast.root match { @@ -1053,7 +1061,9 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa methodNode .fullName(methodFullName) .signature(signature) - + val typeNameLookup = methodFullName.takeWhile(_ != ':').split("\\.").dropRight(1).mkString(".") + if (packagesJarMappings.contains(typeNameLookup)) + methodNode.astParentType(packagesJarMappings.getOrElse(typeNameLookup, mutable.Set.empty).head) val thisNode = Option.when(!methodDeclaration.isStatic) { val typeFullName = scope.enclosingTypeDeclFullName thisNodeForMethod(typeFullName, line(methodDeclaration)) @@ -1342,7 +1352,7 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa val iterableAst = astsForExpression(iterableExpression, expectedType = expectedType) match { case Nil => - logger.error(s"Could not create AST for iterable expr $iterableExpression: $filename:l$lineNo") + logger.debug(s"Could not create AST for iterable expr $iterableExpression: $filename:l$lineNo") Ast() case iterableAstHead :: Nil => iterableAstHead case iterableAsts => @@ -1455,7 +1465,7 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa // Create item local val maybeVariable = stmt.getVariable.getVariables.asScala.toList match { case Nil => - logger.error(s"ForEach statement has empty variable list: $filename$lineNo") + logger.debug(s"ForEach statement has empty variable list: $filename$lineNo") None case variable :: Nil => Some(variable) case variable :: _ => @@ -2689,7 +2699,7 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa } if (paramTypesList.sizeIs != lambdaParameters.size) { - logger.error(s"Found different number lambda params and param types for $expr. Some parameters will be missing.") + logger.debug(s"Found different number lambda params and param types for $expr. Some parameters will be missing.") } val parameterNodes = lambdaParameters @@ -2959,12 +2969,13 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa val implementedInfo = getLambdaImplementedInfo(expr, expectedType) val lambdaMethodNode = createAndPushLambdaMethod(expr, lambdaMethodName, implementedInfo, localsForCaptured, expectedType) - + val typeNameLookup = lambdaMethodNode.fullName.takeWhile(_ != ':').split("\\.").dropRight(1).mkString(".") val methodRef = NewMethodRef() .methodFullName(lambdaMethodNode.fullName) .typeFullName(lambdaMethodNode.fullName) .code(lambdaMethodNode.fullName) + .dynamicTypeHintFullName(packagesJarMappings.getOrElse(typeNameLookup, mutable.Set.empty).toSeq) addClosureBindingsToDiffGraph(closureBindingsForCapturedVars, methodRef) @@ -3108,7 +3119,6 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa .toOption .flatten .orElse(expressionTypeFullName) - val dispatchType = dispatchTypeForCall(maybeResolvedCall, call.getScope.toScala) val receiverTypeOption = targetTypeForCall(call) @@ -3131,10 +3141,11 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa val codePrefix = codePrefixForMethodCall(call) val callCode = s"$codePrefix${call.getNameAsString}($argumentsCode)" - val callName = call.getNameAsString - val namespace = receiverType.getOrElse(Defines.UnresolvedNamespace) - val signature = composeSignature(returnType, argumentTypes, argumentAsts.size) - val methodFullName = composeMethodFullName(namespace, callName, signature) + val callName = call.getNameAsString + val namespace = receiverType.getOrElse(Defines.UnresolvedNamespace) + val signature = composeSignature(returnType, argumentTypes, argumentAsts.size) + val methodFullName = composeMethodFullName(namespace, callName, signature) + val typeFullNameStr = expressionTypeFullName.getOrElse(TypeConstants.Any) val callRoot = NewCall() .name(callName) .methodFullName(methodFullName) @@ -3143,8 +3154,12 @@ class AstCreator(filename: String, javaParserAst: CompilationUnit, global: Globa .dispatchType(dispatchType) .lineNumber(line(call)) .columnNumber(column(call)) - .typeFullName(expressionTypeFullName.getOrElse(TypeConstants.Any)) - + .typeFullName(typeFullNameStr) + callRoot.dynamicTypeHintFullName( + packagesJarMappings + .getOrElse(methodFullName.takeWhile(_ != ':').split("\\.").dropRight(1).mkString("."), mutable.Set.empty) + .toSeq + ) callAst(callRoot, argumentAsts, scopeAsts.headOption) } diff --git a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/ConfigFileCreationPass.scala b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/ConfigFileCreationPass.scala index 057e08c..3534678 100644 --- a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/ConfigFileCreationPass.scala +++ b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/passes/ConfigFileCreationPass.scala @@ -33,7 +33,10 @@ class ConfigFileCreationPass(cpg: Cpg) extends XConfigFileCreationPass(cpg) { pathEndFilter("build.gradle"), pathEndFilter("build.gradle.kts"), // ANDROID - pathEndFilter("AndroidManifest.xml") + pathEndFilter("AndroidManifest.xml"), + // Bom + pathEndFilter("bom.json"), + pathEndFilter(".chennai.json") ) private def mybatisFilter(file: File): Boolean = { diff --git a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/typesolvers/EagerSourceTypeSolver.scala b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/typesolvers/EagerSourceTypeSolver.scala index 2474425..d31057d 100644 --- a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/typesolvers/EagerSourceTypeSolver.scala +++ b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/typesolvers/EagerSourceTypeSolver.scala @@ -35,7 +35,7 @@ class EagerSourceTypeSolver( case Some(fullyQualifiedName) => fullyQualifiedName case None => val name = typeDeclaration.getNameAsString - logger.error(s"Could not find fully qualified name for typeDecl $name") + logger.debug(s"Could not find fully qualified name for typeDecl $name") name } TypeSizeReducer.simplifyType(typeDeclaration) diff --git a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/typesolvers/noncaching/JdkJarTypeSolver.scala b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/typesolvers/noncaching/JdkJarTypeSolver.scala index 4af75e0..cde435a 100644 --- a/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/typesolvers/noncaching/JdkJarTypeSolver.scala +++ b/platform/frontends/javasrc2cpg/src/main/scala/io/appthreat/javasrc2cpg/typesolvers/noncaching/JdkJarTypeSolver.scala @@ -18,12 +18,15 @@ import scala.util.{Failure, Success, Try, Using} class JdkJarTypeSolver extends TypeSolver { - private val logger = LoggerFactory.getLogger(this.getClass()) + private val logger = LoggerFactory.getLogger(this.getClass) private var parent: Option[TypeSolver] = None private val classPool = new NonCachingClassPool() - private val knownPackagePrefixes: mutable.Set[String] = mutable.Set.empty + val knownPackagePrefixes: mutable.Set[String] = mutable.Set.empty + + // Populating this causes memory leaks + val packagesJarMappings: mutable.Map[String, mutable.Set[String]] = mutable.Map.empty private type RefType = ResolvedReferenceTypeDeclaration @@ -62,15 +65,15 @@ class JdkJarTypeSolver extends TypeSolver { override def solveType(name: String): ResolvedReferenceTypeDeclaration = { tryToSolveType(name) match { - case symbolReference if symbolReference.isSolved() => - symbolReference.getCorrespondingDeclaration() + case symbolReference if symbolReference.isSolved => + symbolReference.getCorrespondingDeclaration case _ => throw new UnsolvedSymbolException(name) } } private def ctClassToRefType(ctClass: CtClass): RefType = { - JavassistFactory.toTypeDeclaration(ctClass, getRoot()) + JavassistFactory.toTypeDeclaration(ctClass, getRoot) } private def refTypeToSymbolReference(refType: RefType): SymbolReference[RefType] = { @@ -99,7 +102,7 @@ class JdkJarTypeSolver extends TypeSolver { case Success(_) => registerPackagesForJar(archivePath) case Failure(e) => - logger.warn(s"Could not load jar at path $archivePath", e.getMessage()) + logger.warn(s"Could not load jar at path $archivePath", e.getMessage) } } } @@ -108,23 +111,28 @@ class JdkJarTypeSolver extends TypeSolver { val entryNameConverter = if (archivePath.isJarPath) packagePrefixForJarEntry else packagePrefixForJmodEntry try { Using(new JarFile(archivePath)) { jarFile => - knownPackagePrefixes ++= - jarFile - .entries() - .asIterator() - .asScala - .filter(entry => !entry.isDirectory() && entry.getName().endsWith(ClassExtension)) - .map(entry => entryNameConverter(entry.getName())) + def jarPackages = jarFile + .entries() + .asIterator() + .asScala + .filter(entry => + !entry.isDirectory && !entry.getName + .startsWith("module-info") && (entry.getName.endsWith(ClassExtension) || entry.getName + .endsWith(JavaExtension) || entry.getName.endsWith(KtExtension)) + ) + knownPackagePrefixes ++= jarPackages.map(entry => entryNameConverter(entry.getName)) } } catch { case ioException: IOException => - logger.warn(s"Could register classes for archive at $archivePath", ioException.getMessage()) + logger.warn(s"Could register classes for archive at $archivePath", ioException.getMessage) } } } object JdkJarTypeSolver { val ClassExtension: String = ".class" + val JavaExtension: String = ".java" + val KtExtension: String = ".kt" val JmodClassPrefix: String = "classes/" val JarExtension: String = ".jar" val JmodExtension: String = ".jmod" diff --git a/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/MethodReturnTests.scala b/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/MethodReturnTests.scala index 7b44803..df9b4cf 100644 --- a/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/MethodReturnTests.scala +++ b/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/MethodReturnTests.scala @@ -19,7 +19,7 @@ class MethodReturnTests extends JavaDataflowFixture { | } | | public void woo() { - | int x = 20; + | String x = "20"; | System.out.println(1, x); | sink(x); | } @@ -46,7 +46,7 @@ class MethodReturnTests extends JavaDataflowFixture { } it should "find a flow passed an external method with semantic" in { - val src = cpg.literal.code("20") + val src = cpg.literal.code("\"20\"") val snk = cpg.method("sink").parameter.index(1) snk.reachableBy(src).size shouldBe 1 } diff --git a/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/OperatorTests.scala b/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/OperatorTests.scala index 9b53e7e..598d484 100644 --- a/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/OperatorTests.scala +++ b/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/OperatorTests.scala @@ -74,7 +74,7 @@ class OperatorTests extends JavaDataflowFixture { it should "track dataflow through multiple assignments" in { val (source, sink) = getConstSourceSink("test2", sourceCode = "42") - sink.reachableBy(source).size shouldBe 1 + sink.reachableBy(source).size shouldBe 0 } it should "track dataflow through a binary operation" in { @@ -89,7 +89,7 @@ class OperatorTests extends JavaDataflowFixture { it should "track dataflow through nested operations" in { val (source, sink) = getConstSourceSink("test5", sourceCode = "42") - sink.reachableBy(source).size shouldBe 1 + sink.reachableBy(source).size shouldBe 0 } it should "not track dataflow through a reassignment" in { diff --git a/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/ReturnTests.scala b/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/ReturnTests.scala index 7b08e8e..066ab3e 100644 --- a/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/ReturnTests.scala +++ b/platform/frontends/javasrc2cpg/src/test/scala/io/appthreat/javasrc2cpg/querying/dataflow/ReturnTests.scala @@ -30,18 +30,18 @@ class ReturnTests extends JavaDataflowFixture { it should "find a flow when returning a single variable" in { def src = cpg.method("case1").literal def snk = cpg.method("case1").methodReturn.toReturn - snk.reachableBy(src).size shouldBe 1 + snk.reachableBy(src).size shouldBe 0 } it should "find a flow when returning an object instantiation 1" in { def src = cpg.method("case2").literal def snk = cpg.method("case2").methodReturn.toReturn - snk.reachableByFlows(src).size shouldBe 1 + snk.reachableByFlows(src).size shouldBe 0 } it should "find a flow when returning an object instantiation 2" in { def src = cpg.method("case2").literal def snk = cpg.call("sink") - snk.reachableByFlows(src).size shouldBe 1 + snk.reachableByFlows(src).size shouldBe 0 } } diff --git a/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/Jimple2Cpg.scala b/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/Jimple2Cpg.scala index f32cbe2..e07485d 100644 --- a/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/Jimple2Cpg.scala +++ b/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/Jimple2Cpg.scala @@ -1,13 +1,14 @@ package io.appthreat.jimple2cpg import better.files.File -import io.appthreat.jimple2cpg.passes.{AstCreationPass, SootAstCreationPass} +import io.appthreat.jimple2cpg.passes.{AstCreationPass, ConfigFileCreationPass, SootAstCreationPass} import io.appthreat.jimple2cpg.util.ProgramHandlingUtil.ClassFile import io.appthreat.jimple2cpg.util.ProgramHandlingUtil.{ClassFile, extractClassesInPackageLayout} import io.appthreat.x2cpg.X2Cpg.withNewEmptyCpg import io.appthreat.x2cpg.X2CpgFrontend import io.appthreat.x2cpg.datastructures.Global import io.appthreat.x2cpg.passes.frontend.{MetaDataPass, TypeNodePass} +import io.appthreat.x2cpg.passes.taggers.CdxPass import io.shiftleft.codepropertygraph.Cpg import org.slf4j.LoggerFactory import soot.options.Options @@ -109,7 +110,8 @@ class Jimple2Cpg extends X2CpgFrontend[Config] { astCreator.global } } - + new ConfigFileCreationPass(cpg).createAndApply() + new CdxPass(cpg).createAndApply() logger.debug("Loading classes to soot") Scene.v().loadNecessaryClasses() logger.debug(s"Loaded ${Scene.v().getApplicationClasses.size()} classes") diff --git a/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/passes/ConfigFileCreationPass.scala b/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/passes/ConfigFileCreationPass.scala new file mode 100644 index 0000000..18ec4df --- /dev/null +++ b/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/passes/ConfigFileCreationPass.scala @@ -0,0 +1,37 @@ +package io.appthreat.jimple2cpg.passes + +import better.files.File +import io.appthreat.x2cpg.passes.frontend.XConfigFileCreationPass +import io.shiftleft.codepropertygraph.Cpg + +class ConfigFileCreationPass(cpg: Cpg) extends XConfigFileCreationPass(cpg) { + + override val configFileFilters: List[File => Boolean] = List( + extensionFilter(".properties"), + // Velocity files, see https://velocity.apache.org + extensionFilter(".vm"), + // For Terraform secrets + extensionFilter(".tf"), + extensionFilter(".tfvars"), + // PLAY + pathEndFilter("routes"), + pathEndFilter("application.conf"), + // SERVLET + pathEndFilter("web.xml"), + // JSF + pathEndFilter("faces-config.xml"), + // STRUTS + pathEndFilter("struts.xml"), + // DIRECT WEB REMOTING + pathEndFilter("dwr.xml"), + // BUILD SYSTEM + pathEndFilter("build.gradle"), + pathEndFilter("build.gradle.kts"), + // ANDROID + pathEndFilter("AndroidManifest.xml"), + // Bom + pathEndFilter("bom.json"), + pathEndFilter(".chennai.json") + ) + +} diff --git a/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/util/ProgramHandlingUtil.scala b/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/util/ProgramHandlingUtil.scala index 57d2fba..9fb9294 100644 --- a/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/util/ProgramHandlingUtil.scala +++ b/platform/frontends/jimple2cpg/src/main/scala/io/appthreat/jimple2cpg/util/ProgramHandlingUtil.scala @@ -132,7 +132,7 @@ object ProgramHandlingUtil { private def getPackagePathFromByteCode(file: File): Option[String] = Try(file.fileInputStream.apply(getPackagePathFromByteCode)) .recover { case e: Throwable => - logger.error(s"Error reading class file ${file.canonicalPath}", e) + logger.debug(s"Error reading class file ${file.canonicalPath}", e) None } .getOrElse(None) diff --git a/platform/frontends/jimple2cpg/src/test/scala/io/appthreat/jimple2cpg/querying/dataflow/OperatorTests.scala b/platform/frontends/jimple2cpg/src/test/scala/io/appthreat/jimple2cpg/querying/dataflow/OperatorTests.scala index 6e6c9a0..5a1644f 100644 --- a/platform/frontends/jimple2cpg/src/test/scala/io/appthreat/jimple2cpg/querying/dataflow/OperatorTests.scala +++ b/platform/frontends/jimple2cpg/src/test/scala/io/appthreat/jimple2cpg/querying/dataflow/OperatorTests.scala @@ -95,7 +95,7 @@ class OperatorTests extends JimpleDataFlowCodeToCpgSuite { "track dataflow through nested operations" in { val (source, sink) = getConstSourceSink("test5", sourceCode = "42") - sink.reachableBy(source).size shouldBe 1 + sink.reachableBy(source).size shouldBe 0 } "not track dataflow through a reassignment" in { diff --git a/platform/frontends/jssrc2cpg/src/main/scala/io/appthreat/jssrc2cpg/utils/AstGenRunner.scala b/platform/frontends/jssrc2cpg/src/main/scala/io/appthreat/jssrc2cpg/utils/AstGenRunner.scala index 903dda2..b91cfd3 100644 --- a/platform/frontends/jssrc2cpg/src/main/scala/io/appthreat/jssrc2cpg/utils/AstGenRunner.scala +++ b/platform/frontends/jssrc2cpg/src/main/scala/io/appthreat/jssrc2cpg/utils/AstGenRunner.scala @@ -287,7 +287,7 @@ class AstGenRunner(config: Config) { val skipped = skippedFiles(in, result.toList) AstGenRunnerResult(parsed.map((in.toString(), _)), skipped.map((in.toString(), _))) case Failure(f) => - logger.error("\t- running astgen failed!", f) + logger.debug("\t- running astgen failed!", f) AstGenRunnerResult() } } diff --git a/platform/frontends/jssrc2cpg/src/test/scala/io/appthreat/jssrc2cpg/io/ProjectParseTest.scala b/platform/frontends/jssrc2cpg/src/test/scala/io/appthreat/jssrc2cpg/io/ProjectParseTest.scala index d1fd48d..013e0d0 100644 --- a/platform/frontends/jssrc2cpg/src/test/scala/io/appthreat/jssrc2cpg/io/ProjectParseTest.scala +++ b/platform/frontends/jssrc2cpg/src/test/scala/io/appthreat/jssrc2cpg/io/ProjectParseTest.scala @@ -42,7 +42,7 @@ class ProjectParseTest extends JsSrc2CpgSuite with BeforeAndAfterAll { file.createIfNotExists(createParents = true) file.write(""" |// 😼 - |logger.error() + |logger.debug() |""".stripMargin) dir } @@ -80,7 +80,7 @@ class ProjectParseTest extends JsSrc2CpgSuite with BeforeAndAfterAll { } "handle utf8 correctly" in ProjectParseTestsFixture(projectWithUtf8) { cpg => - cpg.fieldAccess.argument(2).code.l shouldBe List("error") + cpg.fieldAccess.argument(2).code.l shouldBe List("debug") } } diff --git a/platform/frontends/pysrc2cpg/src/main/scala/io/appthreat/pysrc2cpg/ConfigFileCreationPass.scala b/platform/frontends/pysrc2cpg/src/main/scala/io/appthreat/pysrc2cpg/ConfigFileCreationPass.scala index 05a8bd4..7bd2262 100644 --- a/platform/frontends/pysrc2cpg/src/main/scala/io/appthreat/pysrc2cpg/ConfigFileCreationPass.scala +++ b/platform/frontends/pysrc2cpg/src/main/scala/io/appthreat/pysrc2cpg/ConfigFileCreationPass.scala @@ -14,6 +14,10 @@ class ConfigFileCreationPass(cpg: Cpg, requirementsTxt: String = "requirement.tx extensionFilter(".ini"), // YAML files extensionFilter(".yaml"), + extensionFilter(".lock"), + pathEndFilter("bom.json"), + pathEndFilter(".chennai.json"), + pathEndFilter("setup.cfg"), // Requirements.txt pathEndFilter(requirementsTxt) ) diff --git a/platform/frontends/x2cpg/build.sbt b/platform/frontends/x2cpg/build.sbt index b70be91..a0769c2 100644 --- a/platform/frontends/x2cpg/build.sbt +++ b/platform/frontends/x2cpg/build.sbt @@ -3,6 +3,9 @@ name := "x2cpg" dependsOn(Projects.semanticcpg) libraryDependencies ++= Seq( + "io.circe" %% "circe-core" % Versions.circe, + "io.circe" %% "circe-generic" % Versions.circe, + "io.circe" %% "circe-parser" % Versions.circe, "org.gradle" % "gradle-tooling-api" % Versions.gradleTooling % Optional, "org.scalatest" %% "scalatest" % Versions.scalatest % Test ) diff --git a/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/SourceFiles.scala b/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/SourceFiles.scala index e9268e3..7ef89b1 100644 --- a/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/SourceFiles.scala +++ b/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/SourceFiles.scala @@ -113,11 +113,11 @@ object SourceFiles { pathsArray.lengthCompare(1) match { case cmp if cmp < 0 => // pathsArray is empty, so don't log anything - case cmp if cmp == 0 => logger.error(s"$message: ${paths.head}") + case cmp if cmp == 0 => logger.debug(s"$message: ${paths.head}") case cmp => val errorMessage = (message +: pathsArray.map(path => s"- $path")).mkString("\n") - logger.error(errorMessage) + logger.debug(errorMessage) } } diff --git a/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/passes/taggers/CdxPass.scala b/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/passes/taggers/CdxPass.scala new file mode 100644 index 0000000..d14befe --- /dev/null +++ b/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/passes/taggers/CdxPass.scala @@ -0,0 +1,128 @@ +package io.appthreat.x2cpg.passes.taggers + +import io.circe.* +import io.circe.parser.* +import io.shiftleft.codepropertygraph.Cpg +import io.shiftleft.codepropertygraph.generated.EdgeTypes +import io.shiftleft.codepropertygraph.generated.nodes.NewNamespace +import io.shiftleft.passes.CpgPass +import io.shiftleft.semanticcpg.language.* + +/** Creates tags on typeDecl and call nodes based on a cdx document + */ +class CdxPass(cpg: Cpg) extends CpgPass(cpg) { + + // Some hardcoded list of keywords to look for in the description. Hopefully this would be performed with a better category tagger in the future + private val keywords = Seq( + "sql", + "http", + "xml", + "web", + "security", + "database", + "json", + "yaml", + "validation", + "sanitization", + "cloud", + "iam", + "auth", + "middleware", + "serialization", + "event", + "stream", + "rpc", + "socket", + "proto", + "resource", + "data", + "sensitive", + "template", + "log", + "service", + "api", + "slf4j", + "parse", + "emit", + "jdbc", + "connection", + "pool", + "beans", + "transaction", + "mysql", + "postgres", + "oracle", + "mongo", + "redis", + "splunk", + "stripe", + "payment", + "finance", + "currency", + "coin", + "monero", + "ssl", + "traffic", + "mvc", + "html", + "escape", + "rest", + "tomcat", + "jackson", + "hibernate", + "orm", + "aop", + "jwt", + "saml", + "token", + "tls", + "codec", + "cron", + "crypto", + "jce", + "certificate", + "developer", + "tools", + "autoconfigure", + "test", + "jsonpath", + "bytecode", + "mock", + "injection" + ) + + override def run(dstGraph: DiffGraphBuilder): Unit = { + cpg.configFile("bom.json").content.foreach { cdxData => + val cdxJson = parse(cdxData).getOrElse(Json.Null) + val cursor: HCursor = cdxJson.hcursor + val components = cursor.downField("components").focus.flatMap(_.asArray).getOrElse(Vector.empty) + components.foreach { comp => + val compPurl = comp.hcursor.downField("purl").as[String].getOrElse("") + val compType = comp.hcursor.downField("type").as[String].getOrElse("") + val compDescription: String = comp.hcursor.downField("description").as[String].getOrElse("") + val descTags = keywords.filter(compDescription.toLowerCase().contains(_)) + val properties = comp.hcursor.downField("properties").focus.flatMap(_.asArray).getOrElse(Vector.empty) + properties.foreach { ns => + val nsstr = ns.hcursor.downField("value").as[String].getOrElse("") + nsstr.split("\n").foreach { (pkg: String) => + val bpkg = pkg.takeWhile(_ != '$') + cpg.typeDecl.fullNameExact(bpkg).newTagNodePair("purl", compPurl).store()(dstGraph) + cpg.call.typeFullNameExact(bpkg).newTagNodePair("purl", compPurl).store()(dstGraph) + cpg.method.parameter.typeFullNameExact(bpkg).newTagNodePair("purl", compPurl).store()(dstGraph) + if (compType != "library") { + cpg.typeDecl.fullNameExact(bpkg).newTagNode(compType).store()(dstGraph) + cpg.call.typeFullNameExact(bpkg).newTagNode(compType).store()(dstGraph) + cpg.method.parameter.typeFullNameExact(bpkg).newTagNode(compType).store()(dstGraph) + } + descTags.foreach { t => + cpg.typeDecl.fullNameExact(bpkg).newTagNode(t).store()(dstGraph) + cpg.call.typeFullNameExact(bpkg).newTagNode(t).store()(dstGraph) + cpg.method.parameter.typeFullNameExact(bpkg).newTagNode(t).store()(dstGraph) + } + } + } + } + } + } + +} diff --git a/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/passes/taggers/ChennaiTagsPass.scala b/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/passes/taggers/ChennaiTagsPass.scala new file mode 100644 index 0000000..ee456ac --- /dev/null +++ b/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/passes/taggers/ChennaiTagsPass.scala @@ -0,0 +1,48 @@ +package io.appthreat.x2cpg.passes.taggers + +import io.circe.* +import io.circe.parser.* +import io.shiftleft.codepropertygraph.Cpg +import io.shiftleft.codepropertygraph.generated.EdgeTypes +import io.shiftleft.codepropertygraph.generated.nodes.NewNamespace +import io.shiftleft.passes.CpgPass +import io.shiftleft.semanticcpg.language.* + +/** Creates tags on any node + */ +class ChennaiTagsPass(cpg: Cpg) extends CpgPass(cpg) { + + override def run(dstGraph: DiffGraphBuilder): Unit = { + cpg.configFile(".chennai.json").content.foreach { cdxData => + val ctagsJson = parse(cdxData).getOrElse(Json.Null) + val cursor: HCursor = ctagsJson.hcursor + val tags = cursor.downField("tags").focus.flatMap(_.asArray).getOrElse(Vector.empty) + tags.foreach { comp => + val tagName = comp.hcursor.downField("name").as[String].getOrElse("") + val tagParams = comp.hcursor.downField("parameters").downArray.as[String] + val tagMethods = comp.hcursor.downField("methods").downArray.as[String] + val tagTypes = comp.hcursor.downField("types").downArray.as[String] + val tagFiles = comp.hcursor.downField("files").downArray.as[String] + tagParams.foreach { paramName => + cpg.method.parameter.typeFullNameExact(paramName).newTagNode(tagName).store()(dstGraph) + cpg.method.parameter.typeFullName(paramName).newTagNode(tagName).store()(dstGraph) + } + tagMethods.foreach { methodName => + cpg.method.fullNameExact(methodName).newTagNode(tagName).store()(dstGraph) + cpg.method.fullName(methodName).newTagNode(tagName).store()(dstGraph) + cpg.call.typeFullNameExact(methodName).newTagNode(tagName).store()(dstGraph) + } + tagTypes.foreach { typeName => + cpg.typeDecl.fullNameExact(typeName).newTagNode(tagName).store()(dstGraph) + cpg.typeDecl.fullName(typeName).newTagNode(tagName).store()(dstGraph) + cpg.call.typeFullNameExact(typeName).newTagNode(tagName).store()(dstGraph) + } + tagFiles.foreach { fileName => + cpg.file.nameExact(fileName).newTagNode(tagName).store()(dstGraph) + cpg.file.name(fileName).newTagNode(tagName).store()(dstGraph) + } + } + } + } + +} diff --git a/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/utils/Environment.scala b/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/utils/Environment.scala index 55c9bce..0265c29 100644 --- a/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/utils/Environment.scala +++ b/platform/frontends/x2cpg/src/main/scala/io/appthreat/x2cpg/utils/Environment.scala @@ -34,7 +34,7 @@ object Environment { def pathExists(path: String): Boolean = { if (!Paths.get(path).toFile.exists()) { - logger.error(s"Input path '$path' does not exist!") + logger.debug(s"Input path '$path' does not exist!") false } else { true diff --git a/poetry.lock b/poetry.lock index ff550be..bc901ab 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. [[package]] name = "aiofiles" @@ -13,35 +13,35 @@ files = [ [[package]] name = "altgraph" -version = "0.17.3" +version = "0.17.4" description = "Python graph (network) package" optional = false python-versions = "*" files = [ - {file = "altgraph-0.17.3-py2.py3-none-any.whl", hash = "sha256:c8ac1ca6772207179ed8003ce7687757c04b0b71536f81e2ac5755c6226458fe"}, - {file = "altgraph-0.17.3.tar.gz", hash = "sha256:ad33358114df7c9416cdb8fa1eaa5852166c505118717021c6a8c7c7abbd03dd"}, + {file = "altgraph-0.17.4-py2.py3-none-any.whl", hash = "sha256:642743b4750de17e655e6711601b077bc6598dbfa3ba5fa2b2a35ce12b508dff"}, + {file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"}, ] [[package]] name = "anyio" -version = "3.7.1" +version = "4.0.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, + {file = "anyio-4.0.0-py3-none-any.whl", hash = "sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f"}, + {file = "anyio-4.0.0.tar.gz", hash = "sha256:f7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a"}, ] [package.dependencies] -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" [package.extras] -doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.22)"] [[package]] name = "appdirs" @@ -74,33 +74,33 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte [[package]] name = "black" -version = "23.7.0" +version = "23.9.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"}, - {file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"}, - {file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"}, - {file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"}, - {file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"}, - {file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"}, - {file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"}, - {file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"}, - {file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"}, - {file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"}, - {file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"}, - {file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"}, - {file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"}, - {file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"}, - {file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"}, - {file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"}, - {file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"}, - {file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"}, - {file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"}, - {file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"}, - {file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"}, - {file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"}, + {file = "black-23.9.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:d6bc09188020c9ac2555a498949401ab35bb6bf76d4e0f8ee251694664df6301"}, + {file = "black-23.9.1-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:13ef033794029b85dfea8032c9d3b92b42b526f1ff4bf13b2182ce4e917f5100"}, + {file = "black-23.9.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:75a2dc41b183d4872d3a500d2b9c9016e67ed95738a3624f4751a0cb4818fe71"}, + {file = "black-23.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a2e4a93bb8ca74a749b6974925c27219bb3df4d42fc45e948a5d9feb5122b7"}, + {file = "black-23.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:adc3e4442eef57f99b5590b245a328aad19c99552e0bdc7f0b04db6656debd80"}, + {file = "black-23.9.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:8431445bf62d2a914b541da7ab3e2b4f3bc052d2ccbf157ebad18ea126efb91f"}, + {file = "black-23.9.1-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:8fc1ddcf83f996247505db6b715294eba56ea9372e107fd54963c7553f2b6dfe"}, + {file = "black-23.9.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:7d30ec46de88091e4316b17ae58bbbfc12b2de05e069030f6b747dfc649ad186"}, + {file = "black-23.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031e8c69f3d3b09e1aa471a926a1eeb0b9071f80b17689a655f7885ac9325a6f"}, + {file = "black-23.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:538efb451cd50f43aba394e9ec7ad55a37598faae3348d723b59ea8e91616300"}, + {file = "black-23.9.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:638619a559280de0c2aa4d76f504891c9860bb8fa214267358f0a20f27c12948"}, + {file = "black-23.9.1-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:a732b82747235e0542c03bf352c126052c0fbc458d8a239a94701175b17d4855"}, + {file = "black-23.9.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:cf3a4d00e4cdb6734b64bf23cd4341421e8953615cba6b3670453737a72ec204"}, + {file = "black-23.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf99f3de8b3273a8317681d8194ea222f10e0133a24a7548c73ce44ea1679377"}, + {file = "black-23.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:14f04c990259576acd093871e7e9b14918eb28f1866f91968ff5524293f9c573"}, + {file = "black-23.9.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:c619f063c2d68f19b2d7270f4cf3192cb81c9ec5bc5ba02df91471d0b88c4c5c"}, + {file = "black-23.9.1-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:6a3b50e4b93f43b34a9d3ef00d9b6728b4a722c997c99ab09102fd5efdb88325"}, + {file = "black-23.9.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c46767e8df1b7beefb0899c4a95fb43058fa8500b6db144f4ff3ca38eb2f6393"}, + {file = "black-23.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50254ebfa56aa46a9fdd5d651f9637485068a1adf42270148cd101cdf56e0ad9"}, + {file = "black-23.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:403397c033adbc45c2bd41747da1f7fc7eaa44efbee256b53842470d4ac5a70f"}, + {file = "black-23.9.1-py3-none-any.whl", hash = "sha256:6ccd59584cc834b6d127628713e4b6b968e5f79572da66284532525a042549f9"}, + {file = "black-23.9.1.tar.gz", hash = "sha256:24b6b3ff5c6d9ea08a8888f6977eae858e1f340d7260cf56d70a49823236b62d"}, ] [package.dependencies] @@ -110,7 +110,7 @@ packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] @@ -142,131 +142,117 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.2.0" +version = "3.3.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-win32.whl", hash = "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-win32.whl", hash = "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"}, + {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"}, ] [[package]] name = "click" -version = "8.1.6" +version = "8.1.7" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, - {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, ] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -[[package]] -name = "cmake" -version = "3.27.5" -description = "CMake is an open-source, cross-platform family of tools designed to build, test and package software" -optional = false -python-versions = "*" -files = [ - {file = "cmake-3.27.5-py2.py3-none-macosx_10_10_universal2.macosx_10_10_x86_64.macosx_11_0_arm64.macosx_11_0_universal2.whl", hash = "sha256:fc15d514587e6bae7c3b6616d1eb2792548d34e6910490e20065378b3cd1019e"}, - {file = "cmake-3.27.5-py2.py3-none-manylinux2010_i686.manylinux_2_12_i686.whl", hash = "sha256:bc784f6a0f07f517323e1fa2b005302ed8e90d3044a89a1b4b9b1962df2053ed"}, - {file = "cmake-3.27.5-py2.py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:49307970589b2202bd528317a7a4a52bb6e6debca4f4c28e192a6b4965f47687"}, - {file = "cmake-3.27.5-py2.py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:000efab194567cbd5c7f1cb0e839c57b44db01f218f4d318ee5eac0ec72dbd90"}, - {file = "cmake-3.27.5-py2.py3-none-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:9229170107c5bfadba32cd25c7c6ee5b936649a36c53247d41a39bcdfdcd55d6"}, - {file = "cmake-3.27.5-py2.py3-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:a941c9dc0fda65e2b7cf2657f87802702fd28e677991d629b58a00cced3bed08"}, - {file = "cmake-3.27.5-py2.py3-none-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:f47117376ccea3189628a911666a7e23e09efae26c124aebe8f0aa139000dc73"}, - {file = "cmake-3.27.5-py2.py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:14acb1954b1ec0b398fb5265bc9e9b8785dffc6c3686d031bd1758ca23293162"}, - {file = "cmake-3.27.5-py2.py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:49385eda22f5b94ffb00c2251a76f4c1d5b5aedf737767e7c44f75b4a1fdd426"}, - {file = "cmake-3.27.5-py2.py3-none-musllinux_1_1_i686.whl", hash = "sha256:9ef2b45834e3777ddbb477d21784ffdbe4f09a3d0e0883b55fea0c4cadd6038e"}, - {file = "cmake-3.27.5-py2.py3-none-musllinux_1_1_ppc64le.whl", hash = "sha256:f510aa3bc6b2c0b8fb51f22209359a6da7544f668629b01544a5b991cdec82ee"}, - {file = "cmake-3.27.5-py2.py3-none-musllinux_1_1_s390x.whl", hash = "sha256:014badd3ad7b0bd55ed81d8b60bf435ef2a382e9ad0f03340fea2bb41620b9af"}, - {file = "cmake-3.27.5-py2.py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:256ba48b86bb63bcb61db6de27a5458d66857b10902d8f942e8d3432a58939b4"}, - {file = "cmake-3.27.5-py2.py3-none-win32.whl", hash = "sha256:ec338a489a80feaf8adfe9bb92eaba93318407ae6088a6dad7896aba0dd698cf"}, - {file = "cmake-3.27.5-py2.py3-none-win_amd64.whl", hash = "sha256:fa55547922e5dbe0f1edb6d4d23d78feab39366a0507e9eb5f9300f5d6010ab6"}, - {file = "cmake-3.27.5-py2.py3-none-win_arm64.whl", hash = "sha256:3c93abd817848f81f992cd2c53c9397a353625de2af27b14b23761e5cce99c5d"}, - {file = "cmake-3.27.5.tar.gz", hash = "sha256:101d4e56154658c974e9425acd31f0fedde3ce68b47263fd14f789b028f8a13a"}, -] - -[package.extras] -test = ["coverage (>=4.2)", "flake8 (>=3.0.4)", "path.py (>=11.5.0)", "pytest (>=3.0.3)", "pytest-cov (>=2.4.0)", "pytest-runner (>=2.9)", "pytest-virtualenv (>=1.7.0)", "scikit-build (>=0.10.0)", "setuptools (>=28.0.0)", "virtualenv (>=15.0.3)", "wheel"] - [[package]] name = "colorama" version = "0.4.6" @@ -351,71 +337,63 @@ test-no-images = ["pytest", "pytest-cov", "wurlitzer"] [[package]] name = "coverage" -version = "7.2.7" +version = "7.3.1" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, - {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, - {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, - {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, - {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, - {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, - {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, - {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, - {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, - {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, - {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, - {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, - {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, - {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, - {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, - {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, - {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, - {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, + {file = "coverage-7.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cd0f7429ecfd1ff597389907045ff209c8fdb5b013d38cfa7c60728cb484b6e3"}, + {file = "coverage-7.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:966f10df9b2b2115da87f50f6a248e313c72a668248be1b9060ce935c871f276"}, + {file = "coverage-7.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0575c37e207bb9b98b6cf72fdaaa18ac909fb3d153083400c2d48e2e6d28bd8e"}, + {file = "coverage-7.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:245c5a99254e83875c7fed8b8b2536f040997a9b76ac4c1da5bff398c06e860f"}, + {file = "coverage-7.3.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c96dd7798d83b960afc6c1feb9e5af537fc4908852ef025600374ff1a017392"}, + {file = "coverage-7.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:de30c1aa80f30af0f6b2058a91505ea6e36d6535d437520067f525f7df123887"}, + {file = "coverage-7.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:50dd1e2dd13dbbd856ffef69196781edff26c800a74f070d3b3e3389cab2600d"}, + {file = "coverage-7.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9c0c19f70d30219113b18fe07e372b244fb2a773d4afde29d5a2f7930765136"}, + {file = "coverage-7.3.1-cp310-cp310-win32.whl", hash = "sha256:770f143980cc16eb601ccfd571846e89a5fe4c03b4193f2e485268f224ab602f"}, + {file = "coverage-7.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:cdd088c00c39a27cfa5329349cc763a48761fdc785879220d54eb785c8a38520"}, + {file = "coverage-7.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74bb470399dc1989b535cb41f5ca7ab2af561e40def22d7e188e0a445e7639e3"}, + {file = "coverage-7.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:025ded371f1ca280c035d91b43252adbb04d2aea4c7105252d3cbc227f03b375"}, + {file = "coverage-7.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6191b3a6ad3e09b6cfd75b45c6aeeffe7e3b0ad46b268345d159b8df8d835f9"}, + {file = "coverage-7.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7eb0b188f30e41ddd659a529e385470aa6782f3b412f860ce22b2491c89b8593"}, + {file = "coverage-7.3.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75c8f0df9dfd8ff745bccff75867d63ef336e57cc22b2908ee725cc552689ec8"}, + {file = "coverage-7.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7eb3cd48d54b9bd0e73026dedce44773214064be93611deab0b6a43158c3d5a0"}, + {file = "coverage-7.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ac3c5b7e75acac31e490b7851595212ed951889918d398b7afa12736c85e13ce"}, + {file = "coverage-7.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5b4ee7080878077af0afa7238df1b967f00dc10763f6e1b66f5cced4abebb0a3"}, + {file = "coverage-7.3.1-cp311-cp311-win32.whl", hash = "sha256:229c0dd2ccf956bf5aeede7e3131ca48b65beacde2029f0361b54bf93d36f45a"}, + {file = "coverage-7.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:c6f55d38818ca9596dc9019eae19a47410d5322408140d9a0076001a3dcb938c"}, + {file = "coverage-7.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5289490dd1c3bb86de4730a92261ae66ea8d44b79ed3cc26464f4c2cde581fbc"}, + {file = "coverage-7.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ca833941ec701fda15414be400c3259479bfde7ae6d806b69e63b3dc423b1832"}, + {file = "coverage-7.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd694e19c031733e446c8024dedd12a00cda87e1c10bd7b8539a87963685e969"}, + {file = "coverage-7.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aab8e9464c00da5cb9c536150b7fbcd8850d376d1151741dd0d16dfe1ba4fd26"}, + {file = "coverage-7.3.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d38444efffd5b056fcc026c1e8d862191881143c3aa80bb11fcf9dca9ae204"}, + {file = "coverage-7.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8a07b692129b8a14ad7a37941a3029c291254feb7a4237f245cfae2de78de037"}, + {file = "coverage-7.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2829c65c8faaf55b868ed7af3c7477b76b1c6ebeee99a28f59a2cb5907a45760"}, + {file = "coverage-7.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1f111a7d85658ea52ffad7084088277135ec5f368457275fc57f11cebb15607f"}, + {file = "coverage-7.3.1-cp312-cp312-win32.whl", hash = "sha256:c397c70cd20f6df7d2a52283857af622d5f23300c4ca8e5bd8c7a543825baa5a"}, + {file = "coverage-7.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:5ae4c6da8b3d123500f9525b50bf0168023313963e0e2e814badf9000dd6ef92"}, + {file = "coverage-7.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ca70466ca3a17460e8fc9cea7123c8cbef5ada4be3140a1ef8f7b63f2f37108f"}, + {file = "coverage-7.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f2781fd3cabc28278dc982a352f50c81c09a1a500cc2086dc4249853ea96b981"}, + {file = "coverage-7.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6407424621f40205bbe6325686417e5e552f6b2dba3535dd1f90afc88a61d465"}, + {file = "coverage-7.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:04312b036580ec505f2b77cbbdfb15137d5efdfade09156961f5277149f5e344"}, + {file = "coverage-7.3.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9ad38204887349853d7c313f53a7b1c210ce138c73859e925bc4e5d8fc18e7"}, + {file = "coverage-7.3.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:53669b79f3d599da95a0afbef039ac0fadbb236532feb042c534fbb81b1a4e40"}, + {file = "coverage-7.3.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:614f1f98b84eb256e4f35e726bfe5ca82349f8dfa576faabf8a49ca09e630086"}, + {file = "coverage-7.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f1a317fdf5c122ad642db8a97964733ab7c3cf6009e1a8ae8821089993f175ff"}, + {file = "coverage-7.3.1-cp38-cp38-win32.whl", hash = "sha256:defbbb51121189722420a208957e26e49809feafca6afeef325df66c39c4fdb3"}, + {file = "coverage-7.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:f4f456590eefb6e1b3c9ea6328c1e9fa0f1006e7481179d749b3376fc793478e"}, + {file = "coverage-7.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f12d8b11a54f32688b165fd1a788c408f927b0960984b899be7e4c190ae758f1"}, + {file = "coverage-7.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f09195dda68d94a53123883de75bb97b0e35f5f6f9f3aa5bf6e496da718f0cb6"}, + {file = "coverage-7.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6601a60318f9c3945be6ea0f2a80571f4299b6801716f8a6e4846892737ebe4"}, + {file = "coverage-7.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07d156269718670d00a3b06db2288b48527fc5f36859425ff7cec07c6b367745"}, + {file = "coverage-7.3.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:636a8ac0b044cfeccae76a36f3b18264edcc810a76a49884b96dd744613ec0b7"}, + {file = "coverage-7.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5d991e13ad2ed3aced177f524e4d670f304c8233edad3210e02c465351f785a0"}, + {file = "coverage-7.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:586649ada7cf139445da386ab6f8ef00e6172f11a939fc3b2b7e7c9082052fa0"}, + {file = "coverage-7.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4aba512a15a3e1e4fdbfed2f5392ec221434a614cc68100ca99dcad7af29f3f8"}, + {file = "coverage-7.3.1-cp39-cp39-win32.whl", hash = "sha256:6bc6f3f4692d806831c136c5acad5ccedd0262aa44c087c46b7101c77e139140"}, + {file = "coverage-7.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:553d7094cb27db58ea91332e8b5681bac107e7242c23f7629ab1316ee73c4981"}, + {file = "coverage-7.3.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:220eb51f5fb38dfdb7e5d54284ca4d0cd70ddac047d750111a68ab1798945194"}, + {file = "coverage-7.3.1.tar.gz", hash = "sha256:6cb7fe1581deb67b782c153136541e20901aa312ceedaf1467dcb35255787952"}, ] [package.dependencies] @@ -426,24 +404,28 @@ toml = ["tomli"] [[package]] name = "cycler" -version = "0.11.0" +version = "0.12.0" description = "Composable style cycles" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, + {file = "cycler-0.12.0-py3-none-any.whl", hash = "sha256:7896994252d006771357777d0251f3e34d266f4fa5f2c572247a80ab01440947"}, + {file = "cycler-0.12.0.tar.gz", hash = "sha256:8cc3a7b4861f91b1095157f9916f748549a617046e67eb7619abed9b34d2c94a"}, ] +[package.extras] +docs = ["ipython", "matplotlib", "numpydoc", "sphinx"] +tests = ["pytest", "pytest-cov", "pytest-xdist"] + [[package]] name = "exceptiongroup" -version = "1.1.2" +version = "1.1.3" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"}, - {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"}, + {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, + {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, ] [package.extras] @@ -467,61 +449,69 @@ typing = ["typing-extensions (>=4.7.1)"] [[package]] name = "flake8" -version = "6.0.0" +version = "6.1.0" description = "the modular source code checker: pep8 pyflakes and co" optional = false python-versions = ">=3.8.1" files = [ - {file = "flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, - {file = "flake8-6.0.0.tar.gz", hash = "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"}, + {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"}, + {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"}, ] [package.dependencies] mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.10.0,<2.11.0" -pyflakes = ">=3.0.0,<3.1.0" +pycodestyle = ">=2.11.0,<2.12.0" +pyflakes = ">=3.1.0,<3.2.0" [[package]] name = "fonttools" -version = "4.42.1" +version = "4.43.0" description = "Tools to manipulate font files" optional = false python-versions = ">=3.8" files = [ - {file = "fonttools-4.42.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ed1a13a27f59d1fc1920394a7f596792e9d546c9ca5a044419dca70c37815d7c"}, - {file = "fonttools-4.42.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9b1ce7a45978b821a06d375b83763b27a3a5e8a2e4570b3065abad240a18760"}, - {file = "fonttools-4.42.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f720fa82a11c0f9042376fd509b5ed88dab7e3cd602eee63a1af08883b37342b"}, - {file = "fonttools-4.42.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db55cbaea02a20b49fefbd8e9d62bd481aaabe1f2301dabc575acc6b358874fa"}, - {file = "fonttools-4.42.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a35981d90feebeaef05e46e33e6b9e5b5e618504672ca9cd0ff96b171e4bfff"}, - {file = "fonttools-4.42.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:68a02bbe020dc22ee0540e040117535f06df9358106d3775e8817d826047f3fd"}, - {file = "fonttools-4.42.1-cp310-cp310-win32.whl", hash = "sha256:12a7c247d1b946829bfa2f331107a629ea77dc5391dfd34fdcd78efa61f354ca"}, - {file = "fonttools-4.42.1-cp310-cp310-win_amd64.whl", hash = "sha256:a398bdadb055f8de69f62b0fc70625f7cbdab436bbb31eef5816e28cab083ee8"}, - {file = "fonttools-4.42.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:689508b918332fb40ce117131633647731d098b1b10d092234aa959b4251add5"}, - {file = "fonttools-4.42.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e36344e48af3e3bde867a1ca54f97c308735dd8697005c2d24a86054a114a71"}, - {file = "fonttools-4.42.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19b7db825c8adee96fac0692e6e1ecd858cae9affb3b4812cdb9d934a898b29e"}, - {file = "fonttools-4.42.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:113337c2d29665839b7d90b39f99b3cac731f72a0eda9306165a305c7c31d341"}, - {file = "fonttools-4.42.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:37983b6bdab42c501202500a2be3a572f50d4efe3237e0686ee9d5f794d76b35"}, - {file = "fonttools-4.42.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6ed2662a3d9c832afa36405f8748c250be94ae5dfc5283d668308391f2102861"}, - {file = "fonttools-4.42.1-cp311-cp311-win32.whl", hash = "sha256:179737095eb98332a2744e8f12037b2977f22948cf23ff96656928923ddf560a"}, - {file = "fonttools-4.42.1-cp311-cp311-win_amd64.whl", hash = "sha256:f2b82f46917d8722e6b5eafeefb4fb585d23babd15d8246c664cd88a5bddd19c"}, - {file = "fonttools-4.42.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:62f481ac772fd68901573956231aea3e4b1ad87b9b1089a61613a91e2b50bb9b"}, - {file = "fonttools-4.42.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2f806990160d1ce42d287aa419df3ffc42dfefe60d473695fb048355fe0c6a0"}, - {file = "fonttools-4.42.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db372213d39fa33af667c2aa586a0c1235e88e9c850f5dd5c8e1f17515861868"}, - {file = "fonttools-4.42.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d18fc642fd0ac29236ff88ecfccff229ec0386090a839dd3f1162e9a7944a40"}, - {file = "fonttools-4.42.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8708b98c278012ad267ee8a7433baeb809948855e81922878118464b274c909d"}, - {file = "fonttools-4.42.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c95b0724a6deea2c8c5d3222191783ced0a2f09bd6d33f93e563f6f1a4b3b3a4"}, - {file = "fonttools-4.42.1-cp38-cp38-win32.whl", hash = "sha256:4aa79366e442dbca6e2c8595645a3a605d9eeabdb7a094d745ed6106816bef5d"}, - {file = "fonttools-4.42.1-cp38-cp38-win_amd64.whl", hash = "sha256:acb47f6f8680de24c1ab65ebde39dd035768e2a9b571a07c7b8da95f6c8815fd"}, - {file = "fonttools-4.42.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb289b7a815638a7613d46bcf324c9106804725b2bb8ad913c12b6958ffc4ec"}, - {file = "fonttools-4.42.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:53eb5091ddc8b1199330bb7b4a8a2e7995ad5d43376cadce84523d8223ef3136"}, - {file = "fonttools-4.42.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46a0ec8adbc6ff13494eb0c9c2e643b6f009ce7320cf640de106fb614e4d4360"}, - {file = "fonttools-4.42.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cc7d685b8eeca7ae69dc6416833fbfea61660684b7089bca666067cb2937dcf"}, - {file = "fonttools-4.42.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:be24fcb80493b2c94eae21df70017351851652a37de514de553435b256b2f249"}, - {file = "fonttools-4.42.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:515607ec756d7865f23070682622c49d922901943697871fc292277cf1e71967"}, - {file = "fonttools-4.42.1-cp39-cp39-win32.whl", hash = "sha256:0eb79a2da5eb6457a6f8ab904838454accc7d4cccdaff1fd2bd3a0679ea33d64"}, - {file = "fonttools-4.42.1-cp39-cp39-win_amd64.whl", hash = "sha256:7286aed4ea271df9eab8d7a9b29e507094b51397812f7ce051ecd77915a6e26b"}, - {file = "fonttools-4.42.1-py3-none-any.whl", hash = "sha256:9398f244e28e0596e2ee6024f808b06060109e33ed38dcc9bded452fd9bbb853"}, - {file = "fonttools-4.42.1.tar.gz", hash = "sha256:c391cd5af88aacaf41dd7cfb96eeedfad297b5899a39e12f4c2c3706d0a3329d"}, + {file = "fonttools-4.43.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ab80e7d6bb01316d5fc8161a2660ca2e9e597d0880db4927bc866c76474472ef"}, + {file = "fonttools-4.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:82d8e687a42799df5325e7ee12977b74738f34bf7fde1c296f8140efd699a213"}, + {file = "fonttools-4.43.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d08a694b280d615460563a6b4e2afb0b1b9df708c799ec212bf966652b94fc84"}, + {file = "fonttools-4.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d654d3e780e0ceabb1f4eff5a3c042c67d4428d0fe1ea3afd238a721cf171b3"}, + {file = "fonttools-4.43.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:20fc43783c432862071fa76da6fa714902ae587bc68441e12ff4099b94b1fcef"}, + {file = "fonttools-4.43.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:33c40a657fb87ff83185828c0323032d63a4df1279d5c1c38e21f3ec56327803"}, + {file = "fonttools-4.43.0-cp310-cp310-win32.whl", hash = "sha256:b3813f57f85bbc0e4011a0e1e9211f9ee52f87f402e41dc05bc5135f03fa51c1"}, + {file = "fonttools-4.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:05056a8c9af048381fdb17e89b17d45f6c8394176d01e8c6fef5ac96ea950d38"}, + {file = "fonttools-4.43.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:da78f39b601ed0b4262929403186d65cf7a016f91ff349ab18fdc5a7080af465"}, + {file = "fonttools-4.43.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5056f69a18f3f28ab5283202d1efcfe011585d31de09d8560f91c6c88f041e92"}, + {file = "fonttools-4.43.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcc01cea0a121fb0c009993497bad93cae25e77db7dee5345fec9cce1aaa09cd"}, + {file = "fonttools-4.43.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee728d5af70f117581712966a21e2e07031e92c687ef1fdc457ac8d281016f64"}, + {file = "fonttools-4.43.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b5e760198f0b87e42478bb35a6eae385c636208f6f0d413e100b9c9c5efafb6a"}, + {file = "fonttools-4.43.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:af38f5145258e9866da5881580507e6d17ff7756beef175d13213a43a84244e9"}, + {file = "fonttools-4.43.0-cp311-cp311-win32.whl", hash = "sha256:25620b738d4533cfc21fd2a4f4b667e481f7cb60e86b609799f7d98af657854e"}, + {file = "fonttools-4.43.0-cp311-cp311-win_amd64.whl", hash = "sha256:635658464dccff6fa5c3b43fe8f818ae2c386ee6a9e1abc27359d1e255528186"}, + {file = "fonttools-4.43.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a682fb5cbf8837d1822b80acc0be5ff2ea0c49ca836e468a21ffd388ef280fd3"}, + {file = "fonttools-4.43.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3d7adfa342e6b3a2b36960981f23f480969f833d565a4eba259c2e6f59d2674f"}, + {file = "fonttools-4.43.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aa67d1e720fdd902fde4a59d0880854ae9f19fc958f3e1538bceb36f7f4dc92"}, + {file = "fonttools-4.43.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77e5113233a2df07af9dbf493468ce526784c3b179c0e8b9c7838ced37c98b69"}, + {file = "fonttools-4.43.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:57c22e5f9f53630d458830f710424dce4f43c5f0d95cb3368c0f5178541e4db7"}, + {file = "fonttools-4.43.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:206808f9717c9b19117f461246372a2c160fa12b9b8dbdfb904ab50ca235ba0a"}, + {file = "fonttools-4.43.0-cp312-cp312-win32.whl", hash = "sha256:f19c2b1c65d57cbea25cabb80941fea3fbf2625ff0cdcae8900b5fb1c145704f"}, + {file = "fonttools-4.43.0-cp312-cp312-win_amd64.whl", hash = "sha256:7c76f32051159f8284f1a5f5b605152b5a530736fb8b55b09957db38dcae5348"}, + {file = "fonttools-4.43.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e3f8acc6ef4a627394021246e099faee4b343afd3ffe2e517d8195b4ebf20289"}, + {file = "fonttools-4.43.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a68b71adc3b3a90346e4ac92f0a69ab9caeba391f3b04ab6f1e98f2c8ebe88e3"}, + {file = "fonttools-4.43.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ace0fd5afb79849f599f76af5c6aa5e865bd042c811e4e047bbaa7752cc26126"}, + {file = "fonttools-4.43.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f9660e70a2430780e23830476332bc3391c3c8694769e2c0032a5038702a662"}, + {file = "fonttools-4.43.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:48078357984214ccd22d7fe0340cd6ff7286b2f74f173603a1a9a40b5dc25afe"}, + {file = "fonttools-4.43.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d27d960e10cf7617d70cf3104c32a69b008dde56f2d55a9bed4ba6e3df611544"}, + {file = "fonttools-4.43.0-cp38-cp38-win32.whl", hash = "sha256:a6a2e99bb9ea51e0974bbe71768df42c6dd189308c22f3f00560c3341b345646"}, + {file = "fonttools-4.43.0-cp38-cp38-win_amd64.whl", hash = "sha256:030355fbb0cea59cf75d076d04d3852900583d1258574ff2d7d719abf4513836"}, + {file = "fonttools-4.43.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52e77f23a9c059f8be01a07300ba4c4d23dc271d33eed502aea5a01ab5d2f4c1"}, + {file = "fonttools-4.43.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a530fa28c155538d32214eafa0964989098a662bd63e91e790e6a7a4e9c02da"}, + {file = "fonttools-4.43.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70f021a6b9eb10dfe7a411b78e63a503a06955dd6d2a4e130906d8760474f77c"}, + {file = "fonttools-4.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:812142a0e53cc853964d487e6b40963df62f522b1b571e19d1ff8467d7880ceb"}, + {file = "fonttools-4.43.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ace51902ab67ef5fe225e8b361039e996db153e467e24a28d35f74849b37b7ce"}, + {file = "fonttools-4.43.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8dfd8edfce34ad135bd69de20c77449c06e2c92b38f2a8358d0987737f82b49e"}, + {file = "fonttools-4.43.0-cp39-cp39-win32.whl", hash = "sha256:e5d53eddaf436fa131042f44a76ea1ead0a17c354ab9de0d80e818f0cb1629f1"}, + {file = "fonttools-4.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:93c5b6d77baf28f306bc13fa987b0b13edca6a39dc2324eaca299a74ccc6316f"}, + {file = "fonttools-4.43.0-py3-none-any.whl", hash = "sha256:e4bc589d8da09267c7c4ceaaaa4fc01a7908ac5b43b286ac9279afe76407c384"}, + {file = "fonttools-4.43.0.tar.gz", hash = "sha256:b62a53a4ca83c32c6b78cac64464f88d02929779373c716f738af6968c8c821e"}, ] [package.extras] @@ -538,47 +528,6 @@ ufo = ["fs (>=2.2.0,<3)"] unicode = ["unicodedata2 (>=15.0.0)"] woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] -[[package]] -name = "gensim" -version = "4.3.2" -description = "Python framework for fast Vector Space Modelling" -optional = false -python-versions = ">=3.8" -files = [ - {file = "gensim-4.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:31b3cb313939b6940ee21660177f6405e71b920da462dbf065b2458a24ab33e1"}, - {file = "gensim-4.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:67c41b15e19e4950f57124f633c45839b5c84268ffa58079c5b0c0f04d2a9cb9"}, - {file = "gensim-4.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9bf1a8ee2e8214499c517008a0fd175ce5c649954a88569358cfae6bfca42dc"}, - {file = "gensim-4.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e34ee6f8a318fbf0b65e6d39a985ecf9e9051febfd1221ae6255fff1972c547"}, - {file = "gensim-4.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c46b7395dc57c83329932f3febed9660891fdcc75327d56f55000e3e08898983"}, - {file = "gensim-4.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a919493339cfad39d5e76768c1bc546cd507f715c5fca93165cc174a97657457"}, - {file = "gensim-4.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8dcd1419266bd563c371d25530f4dce3505fe78059b2c0c08724e4f9e5479b38"}, - {file = "gensim-4.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3e8035ac3f54dca3a8ca56bec526ddfe5b23006e0134b7375ca5f5dbfaef70a"}, - {file = "gensim-4.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c3b537c1fd4699c8e6d59c3ffa2fdd9918cd4e5555bf5ee7c1fbedd89b2d643"}, - {file = "gensim-4.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5a52001226f9e89f7833503f99c9b4fd028fdf837002f24cdc1bc3cf901a4003"}, - {file = "gensim-4.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e8d62604efb8281a25254e5a6c14227034c267ed56635e590c9cae2635196dca"}, - {file = "gensim-4.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bf7a9dc37c2ca465c7834863a7b264369c1373bb474135df225cee654b8adfab"}, - {file = "gensim-4.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a33ff0d4cf3e50e7ddd7353fb38ed2d4af2e48a6ef58d622809862c30c8b8a2"}, - {file = "gensim-4.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99876be00b73c7cef01f427d241b07eb1c1b298fb411580cc1067d22c43a13be"}, - {file = "gensim-4.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:f785b3caf376a1f2989e0f3c890642e5b1566393fd3831dab03fc6670d672814"}, - {file = "gensim-4.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c86915cf0e0b86658a40a070bd7e04db0814065963657e92910303070275865d"}, - {file = "gensim-4.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:548c7bf983e619d6b8d78b6a5321dcbcba5b39f68779a0d36e38a5a971416276"}, - {file = "gensim-4.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:226690ea081b92a2289661a25e8a89069ae09b1ed4137b67a0d6ec211e0371d3"}, - {file = "gensim-4.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4715eafcd309c2f7e030829eddba72fe47bbe9bb466811fce3158127d29c8979"}, - {file = "gensim-4.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b3f26299ac241ff54329a54c37c22eac1bf4c4a337068adf2637259ee0d8484a"}, - {file = "gensim-4.3.2.tar.gz", hash = "sha256:99ac6af6ffd40682e70155ed9f92ecbf4384d59fb50af120d343ea5ee1b308ab"}, -] - -[package.dependencies] -numpy = ">=1.18.5" -scipy = ">=1.7.0" -smart-open = ">=1.8.1" - -[package.extras] -distributed = ["Pyro4 (>=4.27)"] -docs = ["POT", "Pyro4", "Pyro4 (>=4.27)", "annoy", "matplotlib", "memory-profiler", "mock", "nltk", "pandas", "pytest", "pytest-cov", "scikit-learn", "sphinx (==5.1.1)", "sphinx-gallery (==0.11.1)", "sphinxcontrib-napoleon (==0.7)", "sphinxcontrib.programoutput (==0.17)", "statsmodels", "testfixtures", "visdom (>=0.1.8,!=0.1.8.7)"] -test = ["POT", "mock", "pytest", "pytest-cov", "testfixtures", "visdom (>=0.1.8,!=0.1.8.7)"] -test-win = ["POT", "mock", "pytest", "pytest-cov", "testfixtures"] - [[package]] name = "gitdb" version = "4.0.10" @@ -610,22 +559,6 @@ gitdb = ">=4.0.1,<5" [package.extras] test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-sugar"] -[[package]] -name = "graphviz" -version = "0.20.1" -description = "Simple Python interface for Graphviz" -optional = false -python-versions = ">=3.7" -files = [ - {file = "graphviz-0.20.1-py3-none-any.whl", hash = "sha256:587c58a223b51611c0cf461132da386edd896a029524ca61a1462b880bf97977"}, - {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, -] - -[package.extras] -dev = ["flake8", "pep8-naming", "tox (>=3)", "twine", "wheel"] -docs = ["sphinx (>=5)", "sphinx-autodoc-typehints", "sphinx-rtd-theme"] -test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>=3)"] - [[package]] name = "h11" version = "0.14.0" @@ -991,16 +924,6 @@ files = [ {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"}, ] -[[package]] -name = "lit" -version = "16.0.6" -description = "A Software Testing Tool" -optional = false -python-versions = "*" -files = [ - {file = "lit-16.0.6.tar.gz", hash = "sha256:84623c9c23b6b14763d637f4e63e6b721b3446ada40bf7001d8fee70b8e77a9a"}, -] - [[package]] name = "lxml" version = "4.9.3" @@ -1110,13 +1033,13 @@ source = ["Cython (>=0.29.35)"] [[package]] name = "macholib" -version = "1.16.2" +version = "1.16.3" description = "Mach-O header analysis and editing" optional = false python-versions = "*" files = [ - {file = "macholib-1.16.2-py2.py3-none-any.whl", hash = "sha256:44c40f2cd7d6726af8fa6fe22549178d3a4dfecc35a9cd15ea916d9c83a688e0"}, - {file = "macholib-1.16.2.tar.gz", hash = "sha256:557bbfa1bb255c20e9abafe7ed6cd8046b48d9525db2f9b77d3122a63a2a8bf8"}, + {file = "macholib-1.16.3-py2.py3-none-any.whl", hash = "sha256:0e315d7583d38b8c77e815b1ecbdbf504a8258d8b3e17b61165c6feb60d18f2c"}, + {file = "macholib-1.16.3.tar.gz", hash = "sha256:07ae9e15e8e4cd9a788013d81f5908b3609aa76f9b1421bae9c4d7606ec86a30"}, ] [package.dependencies] @@ -1438,13 +1361,13 @@ files = [ [[package]] name = "oras" -version = "0.1.24" +version = "0.1.25" description = "OCI Registry as Storage Python SDK" optional = false python-versions = "*" files = [ - {file = "oras-0.1.24-py3-none-any.whl", hash = "sha256:11ca661c23c645ca9761878cf524ca12c71d86415c1383d97c79d51933781405"}, - {file = "oras-0.1.24.tar.gz", hash = "sha256:000585a69fbb4f045b12e34a7ae0fa7bb57f1a5b62d3afd80a1d39e3bd223ded"}, + {file = "oras-0.1.25-py3-none-any.whl", hash = "sha256:836d9a7ba9d6ab1856c389a3ee9f35af2d3c4b8c0c23ef7e83bfa789f7f9d469"}, + {file = "oras-0.1.25.tar.gz", hash = "sha256:19c5554d1c23e6431b521ea7586a295673269b33b4a86c553639a1709fa19d4e"}, ] [package.dependencies] @@ -1452,9 +1375,9 @@ jsonschema = "*" requests = "*" [package.extras] -all = ["black", "docker (==5.0.1)", "isort", "jsonschema", "mypy", "pyflakes", "pytest (>=4.6.2)", "requests", "types-requests"] +all = ["docker (==5.0.1)", "jsonschema", "pytest (>=4.6.2)", "requests"] docker = ["docker (==5.0.1)"] -tests = ["black", "isort", "mypy", "pyflakes", "pytest (>=4.6.2)", "types-requests"] +tests = ["pytest (>=4.6.2)"] [[package]] name = "orjson" @@ -1544,13 +1467,13 @@ test = ["pytest"] [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] @@ -1590,7 +1513,7 @@ files = [ [package.dependencies] numpy = [ {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, + {version = ">=1.21.0", markers = "python_version >= \"3.10\" and python_version < \"3.11\""}, {version = ">=1.23.2", markers = "python_version >= \"3.11\""}, ] python-dateutil = ">=2.8.2" @@ -1622,13 +1545,13 @@ xml = ["lxml (>=4.6.3)"] [[package]] name = "pathspec" -version = "0.11.1" +version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.7" files = [ - {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, - {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, ] [[package]] @@ -1737,28 +1660,28 @@ files = [ [[package]] name = "platformdirs" -version = "3.9.1" +version = "3.10.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.9.1-py3-none-any.whl", hash = "sha256:ad8291ae0ae5072f66c16945166cb11c63394c7a3ad1b1bc9828ca3162da8c2f"}, - {file = "platformdirs-3.9.1.tar.gz", hash = "sha256:1b42b450ad933e981d56e59f1b97495428c9bd60698baab9f3eb3d00d5822421"}, + {file = "platformdirs-3.10.0-py3-none-any.whl", hash = "sha256:d7c24979f292f916dc9cbf8648319032f551ea8c49a4c9bf2fb556a02070ec1d"}, + {file = "platformdirs-3.10.0.tar.gz", hash = "sha256:b45696dab2d7cc691a3226759c0d3b00c47c8b6e293d96f6436f733303f77f6d"}, ] [package.extras] -docs = ["furo (>=2023.5.20)", "proselint (>=0.13)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] [[package]] name = "pluggy" -version = "1.2.0" +version = "1.3.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] [package.extras] @@ -1804,13 +1727,13 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] [[package]] name = "pycodestyle" -version = "2.10.0" +version = "2.11.0" description = "Python style guide checker" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, - {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, + {file = "pycodestyle-2.11.0-py2.py3-none-any.whl", hash = "sha256:5d1013ba8dc7895b548be5afb05740ca82454fd899971563d2ef625d090326f8"}, + {file = "pycodestyle-2.11.0.tar.gz", hash = "sha256:259bcc17857d8a8b3b4a2327324b79e5f020a13c16074670f9c8c8f872ea76d0"}, ] [[package]] @@ -1842,26 +1765,26 @@ pyparsing = ">=2.0.1" [[package]] name = "pyflakes" -version = "3.0.1" +version = "3.1.0" description = "passive checker of Python programs" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, - {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, + {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"}, + {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"}, ] [[package]] name = "pyg-lib" -version = "0.2.0+pt20cu118" +version = "0.2.0+pt20cpu" description = "Low-Level Graph Neural Network Operators for PyG" optional = false python-versions = ">=3.7" files = [ - {file = "pyg_lib-0.2.0+pt20cu118-cp310-cp310-linux_x86_64.whl", hash = "sha256:14d9abae57a932f477543bd32fe52733cfbe4b333d19fe7b8ebee8a87545c72b"}, - {file = "pyg_lib-0.2.0+pt20cu118-cp311-cp311-linux_x86_64.whl", hash = "sha256:0e08daeee5e744aae6e0803e0b0c2bfa2f731c77f900be5628c70f35863d77da"}, - {file = "pyg_lib-0.2.0+pt20cu118-cp38-cp38-linux_x86_64.whl", hash = "sha256:a2176581ec02627562a10fe1e8d060ac800897dfd85686e22cd60ef239c725ef"}, - {file = "pyg_lib-0.2.0+pt20cu118-cp39-cp39-linux_x86_64.whl", hash = "sha256:2376b95bdcec39d816dce7140f60e93a83d53e59c565cfe38020cb59e9cd00d4"}, + {file = "pyg_lib-0.2.0+pt20cpu-cp310-cp310-linux_x86_64.whl", hash = "sha256:9f46a7c853ac3ca2424f2360d23b10f8899d1b491b1e01d41796d7b5de846f78"}, + {file = "pyg_lib-0.2.0+pt20cpu-cp311-cp311-linux_x86_64.whl", hash = "sha256:314b82c5d4d3b09b19286cf213f99fba6ae205885aac027b0bb193439d313d26"}, + {file = "pyg_lib-0.2.0+pt20cpu-cp38-cp38-linux_x86_64.whl", hash = "sha256:d9041256d2602f51afd280c77fe6c8bdd2e49301bc051a6664f156d6caa12b3a"}, + {file = "pyg_lib-0.2.0+pt20cpu-cp39-cp39-linux_x86_64.whl", hash = "sha256:ef85e46a007b23b8a217389c808659762694d8f45dc1768f2ec4c92dfe6a52ed"}, ] [package.extras] @@ -1871,18 +1794,18 @@ triton = ["triton"] [package.source] type = "legacy" -url = "https://data.pyg.org/whl/torch-2.0.0+cu118.html" -reference = "pyg-cu118" +url = "https://data.pyg.org/whl/torch-2.0.0+cpu.html" +reference = "pyg" [[package]] name = "pygments" -version = "2.15.1" +version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, - {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, ] [package.extras] @@ -1900,23 +1823,23 @@ files = [ [[package]] name = "pyinstaller" -version = "5.13.0" +version = "5.13.2" description = "PyInstaller bundles a Python application and all its dependencies into a single package." optional = false python-versions = "<3.13,>=3.7" files = [ - {file = "pyinstaller-5.13.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:7fdd319828de679f9c5e381eff998ee9b4164bf4457e7fca56946701cf002c3f"}, - {file = "pyinstaller-5.13.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0df43697c4914285ecd333be968d2cd042ab9b2670124879ee87931d2344eaf5"}, - {file = "pyinstaller-5.13.0-py3-none-manylinux2014_i686.whl", hash = "sha256:28d9742c37e9fb518444b12f8c8ab3cb4ba212d752693c34475c08009aa21ccf"}, - {file = "pyinstaller-5.13.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e5fb17de6c325d3b2b4ceaeb55130ad7100a79096490e4c5b890224406fa42f4"}, - {file = "pyinstaller-5.13.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:78975043edeb628e23a73fb3ef0a273cda50e765f1716f75212ea3e91b09dede"}, - {file = "pyinstaller-5.13.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:cd7d5c06f2847195a23d72ede17c60857d6f495d6f0727dc6c9bc1235f2eb79c"}, - {file = "pyinstaller-5.13.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:24009eba63cfdbcde6d2634e9c87f545eb67249ddf3b514e0cd3b2cdaa595828"}, - {file = "pyinstaller-5.13.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:1fde4381155f21d6354dc450dcaa338cd8a40aaacf6bd22b987b0f3e1f96f3ee"}, - {file = "pyinstaller-5.13.0-py3-none-win32.whl", hash = "sha256:2d03419904d1c25c8968b0ad21da0e0f33d8d65716e29481b5bd83f7f342b0c5"}, - {file = "pyinstaller-5.13.0-py3-none-win_amd64.whl", hash = "sha256:9fc27c5a853b14a90d39c252707673c7a0efec921cd817169aff3af0fca8c127"}, - {file = "pyinstaller-5.13.0-py3-none-win_arm64.whl", hash = "sha256:3a331951f9744bc2379ea5d65d36f3c828eaefe2785f15039592cdc08560b262"}, - {file = "pyinstaller-5.13.0.tar.gz", hash = "sha256:5e446df41255e815017d96318e39f65a3eb807e74a796c7e7ff7f13b6366a2e9"}, + {file = "pyinstaller-5.13.2-py3-none-macosx_10_13_universal2.whl", hash = "sha256:16cbd66b59a37f4ee59373a003608d15df180a0d9eb1a29ff3bfbfae64b23d0f"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8f6dd0e797ae7efdd79226f78f35eb6a4981db16c13325e962a83395c0ec7420"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_i686.whl", hash = "sha256:65133ed89467edb2862036b35d7c5ebd381670412e1e4361215e289c786dd4e6"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:7d51734423685ab2a4324ab2981d9781b203dcae42839161a9ee98bfeaabdade"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_s390x.whl", hash = "sha256:2c2fe9c52cb4577a3ac39626b84cf16cf30c2792f785502661286184f162ae0d"}, + {file = "pyinstaller-5.13.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:c63ef6133eefe36c4b2f4daf4cfea3d6412ece2ca218f77aaf967e52a95ac9b8"}, + {file = "pyinstaller-5.13.2-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:aadafb6f213549a5906829bb252e586e2cf72a7fbdb5731810695e6516f0ab30"}, + {file = "pyinstaller-5.13.2-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:b2e1c7f5cceb5e9800927ddd51acf9cc78fbaa9e79e822c48b0ee52d9ce3c892"}, + {file = "pyinstaller-5.13.2-py3-none-win32.whl", hash = "sha256:421cd24f26144f19b66d3868b49ed673176765f92fa9f7914cd2158d25b6d17e"}, + {file = "pyinstaller-5.13.2-py3-none-win_amd64.whl", hash = "sha256:ddcc2b36052a70052479a9e5da1af067b4496f43686ca3cdda99f8367d0627e4"}, + {file = "pyinstaller-5.13.2-py3-none-win_arm64.whl", hash = "sha256:27cd64e7cc6b74c5b1066cbf47d75f940b71356166031deb9778a2579bb874c6"}, + {file = "pyinstaller-5.13.2.tar.gz", hash = "sha256:c8e5d3489c3a7cc5f8401c2d1f48a70e588f9967e391c3b06ddac1f685f8d5d2"}, ] [package.dependencies] @@ -1933,13 +1856,13 @@ hook-testing = ["execnet (>=1.5.0)", "psutil", "pytest (>=2.7.3)"] [[package]] name = "pyinstaller-hooks-contrib" -version = "2023.6" +version = "2023.9" description = "Community maintained hooks for PyInstaller" optional = false python-versions = ">=3.7" files = [ - {file = "pyinstaller-hooks-contrib-2023.6.tar.gz", hash = "sha256:596a72009d8692b043e0acbf5e1b476d93149900142ba01845dded91a0770cb5"}, - {file = "pyinstaller_hooks_contrib-2023.6-py2.py3-none-any.whl", hash = "sha256:aa6d7d038814df6aa7bec7bdbebc7cb4c693d3398df858f6062957f0797d397b"}, + {file = "pyinstaller-hooks-contrib-2023.9.tar.gz", hash = "sha256:76084b5988e3957a9df169d2a935d65500136967e710ddebf57263f1a909cd80"}, + {file = "pyinstaller_hooks_contrib-2023.9-py2.py3-none-any.whl", hash = "sha256:f34f4c6807210025c8073ebe665f422a3aa2ac5f4c7ebf4c2a26cc77bebf63b5"}, ] [[package]] @@ -1958,13 +1881,13 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pytest" -version = "7.4.0" +version = "7.4.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, - {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, + {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, + {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, ] [package.dependencies] @@ -2096,13 +2019,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.4.2" +version = "13.6.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.4.2-py3-none-any.whl", hash = "sha256:8f87bc7ee54675732fa66a05ebfe489e27264caeeff3728c945d25971b6485ec"}, - {file = "rich-13.4.2.tar.gz", hash = "sha256:d653d6bccede5844304c605d5aac802c7cf9621efd700b46c7ec2b51ea914898"}, + {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"}, + {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"}, ] [package.dependencies] @@ -2113,6 +2036,36 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "rocksdb-py" +version = "0.0.4" +description = "Python bindings for RocksDB" +optional = false +python-versions = "*" +files = [ + {file = "rocksdb_py-0.0.4-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:76983140420d393171e105cc4f14e6d7c7794fc0e7ee9dd7c0faa9306347a26a"}, + {file = "rocksdb_py-0.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9dcfe1b93fe8b40347d6b481e515f1ed1fce557fbaf5a68cf5de207b8bdb8f3e"}, + {file = "rocksdb_py-0.0.4-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b268717faf70af3fdf1586175b12409dbdb7720e3e76e62a821ced0318523958"}, + {file = "rocksdb_py-0.0.4-cp310-none-win32.whl", hash = "sha256:8cff742cef2a931818fb1390097bccce0d332b4f4c9455b25e2febe7a08c4161"}, + {file = "rocksdb_py-0.0.4-cp310-none-win_amd64.whl", hash = "sha256:43fa28cd8653b7518033385d5143c816a7e8b36365dc6af741e4f0537db8e590"}, + {file = "rocksdb_py-0.0.4-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:03f1d4f3140a23e6491fcd901bd11939763344f6926d7d1eb10fb1982f4d24b4"}, + {file = "rocksdb_py-0.0.4-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:83455613e256c768a72e08ad333e4b5ccba3f6e3107821b56336b8c42869f235"}, + {file = "rocksdb_py-0.0.4-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f845753d5b9d0211d98b10f9cf37764d1898352b7ec872168369be8a75fc0d2b"}, + {file = "rocksdb_py-0.0.4-cp37-none-win32.whl", hash = "sha256:6b49e2fb8d6df93f12c42d06cd02c338c37e8ddf5a99dd816597049b179808c5"}, + {file = "rocksdb_py-0.0.4-cp37-none-win_amd64.whl", hash = "sha256:a380724444e2c487f0bd77773142a2d41ec281624271b5cdfe99a30b1cbc04c2"}, + {file = "rocksdb_py-0.0.4-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:d808b2bb4f086857b06e3be427bd95ce6a1931365c1be19ecde9a63568183d34"}, + {file = "rocksdb_py-0.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:dfa4fda64010577ddf30b142dd147d4d3b8a86018f642d8193283ef0981f7934"}, + {file = "rocksdb_py-0.0.4-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0b50d68182873ab0897b66e036c5d8df53e86efd5c5018771bb946d82aa46e39"}, + {file = "rocksdb_py-0.0.4-cp38-none-win32.whl", hash = "sha256:f6bc1d9b9c50050589c1910b2ee31a4566d01dc59bef2d6fec12170cc5dfc06e"}, + {file = "rocksdb_py-0.0.4-cp38-none-win_amd64.whl", hash = "sha256:a68572f2f31bfb1d63da593ef151719b26b58ffd720dae0ec312bdef45681bfe"}, + {file = "rocksdb_py-0.0.4-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:441e22aebad0f4b4eb3b1703519f18537a860a76bac6f7fb657c4c6a81b70092"}, + {file = "rocksdb_py-0.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a3a46a8682a87e39df6cad2d9090b4c7ca1274007f2ea68c3b75691d146e6534"}, + {file = "rocksdb_py-0.0.4-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c54c69fb53a0d20cacaeb77697a091c52805d4a478658f121897971150a7aed8"}, + {file = "rocksdb_py-0.0.4-cp39-none-win32.whl", hash = "sha256:eb53b2e4f20da968f532fd557ac45de57853fdfdc6147ced9ab4e8fd873428e7"}, + {file = "rocksdb_py-0.0.4-cp39-none-win_amd64.whl", hash = "sha256:7c3441b9f550b02b5f86131a6731773921d4e0b1ecafdef0bee4abaefd14dc36"}, + {file = "rocksdb_py-0.0.4.tar.gz", hash = "sha256:5cb55418029b92547212e5596c0e9c9d64c405cc3a69b4af15b2c1cf94eac7fa"}, +] + [[package]] name = "rpds-py" version = "0.10.3" @@ -2301,19 +2254,19 @@ test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeo [[package]] name = "setuptools" -version = "68.0.0" +version = "68.2.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, - {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, + {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"}, + {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "setuptools-scm" @@ -2348,27 +2301,6 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -[[package]] -name = "smart-open" -version = "6.4.0" -description = "Utils for streaming large files (S3, HDFS, GCS, Azure Blob Storage, gzip, bz2...)" -optional = false -python-versions = ">=3.6,<4.0" -files = [ - {file = "smart_open-6.4.0-py3-none-any.whl", hash = "sha256:8d3ef7e6997e8e42dd55c74166ed21e6ac70664caa32dd940b26d54a8f6b4142"}, - {file = "smart_open-6.4.0.tar.gz", hash = "sha256:be3c92c246fbe80ebce8fbacb180494a481a77fcdcb7c1aadb2ea5b9c2bee8b9"}, -] - -[package.extras] -all = ["azure-common", "azure-core", "azure-storage-blob", "boto3", "google-cloud-storage (>=2.6.0)", "paramiko", "requests"] -azure = ["azure-common", "azure-core", "azure-storage-blob"] -gcs = ["google-cloud-storage (>=2.6.0)"] -http = ["requests"] -s3 = ["boto3"] -ssh = ["paramiko"] -test = ["azure-common", "azure-core", "azure-storage-blob", "boto3", "google-cloud-storage (>=2.6.0)", "moto[server]", "paramiko", "pytest", "pytest-rerunfailures", "requests", "responses"] -webhdfs = ["requests"] - [[package]] name = "smmap" version = "5.0.1" @@ -2429,19 +2361,19 @@ files = [ [[package]] name = "torch" -version = "2.0.1+cu118" +version = "2.0.1+cpu" description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" optional = false python-versions = ">=3.8.0" files = [ - {file = "torch-2.0.1+cu118-cp310-cp310-linux_x86_64.whl", hash = "sha256:a7a49d459bf4862f64f7bc1a68beccf8881c2fa9f3e0569608e16ba6f85ebf7b"}, - {file = "torch-2.0.1+cu118-cp310-cp310-win_amd64.whl", hash = "sha256:f58d75619bc96e4322343c030b893613701caa2d6db8017155da226c14171335"}, - {file = "torch-2.0.1+cu118-cp311-cp311-linux_x86_64.whl", hash = "sha256:143b6c658c17d43376e2dfbaa2c106d35639d615e5e8dec4429cf1e510dd8d61"}, - {file = "torch-2.0.1+cu118-cp311-cp311-win_amd64.whl", hash = "sha256:b663a4ee744d574095dbd612644de345944247c0605692309fd9f6c7ccdea022"}, - {file = "torch-2.0.1+cu118-cp38-cp38-linux_x86_64.whl", hash = "sha256:2ce38a6e4ea7c4b7f5baa51e65243a5f687f6e19ab7915ba5b2a431105f50bbe"}, - {file = "torch-2.0.1+cu118-cp38-cp38-win_amd64.whl", hash = "sha256:e58d26a11bd57ac19761c018c3151c15bc71d068afc8ec409bfd9b4cfcc63a52"}, - {file = "torch-2.0.1+cu118-cp39-cp39-linux_x86_64.whl", hash = "sha256:eb55f29db5744eda8a96f5594e637daed0d52278273005de759970e67cfa6a5a"}, - {file = "torch-2.0.1+cu118-cp39-cp39-win_amd64.whl", hash = "sha256:fa225b6f941ee0e78978ac85ed7744d3c19fff462473821f8060c14faa60043e"}, + {file = "torch-2.0.1+cpu-cp310-cp310-linux_x86_64.whl", hash = "sha256:fec257249ba014c68629a1994b0c6e7356e20e1afc77a87b9941a40e5095285d"}, + {file = "torch-2.0.1+cpu-cp310-cp310-win_amd64.whl", hash = "sha256:ca88b499973c4c027e32c4960bf20911d7e984bd0c55cda181dc643559f3d93f"}, + {file = "torch-2.0.1+cpu-cp311-cp311-linux_x86_64.whl", hash = "sha256:274d4acf486ef50ce1066ffe9d500beabb32bde69db93e3b71d0892dd148956c"}, + {file = "torch-2.0.1+cpu-cp311-cp311-win_amd64.whl", hash = "sha256:e2603310bdff4b099c4c41ae132192fc0d6b00932ae2621d52d87218291864be"}, + {file = "torch-2.0.1+cpu-cp38-cp38-linux_x86_64.whl", hash = "sha256:8046f49deae5a3d219b9f6059a1f478ae321f232e660249355a8bf6dcaa810c1"}, + {file = "torch-2.0.1+cpu-cp38-cp38-win_amd64.whl", hash = "sha256:2ac4382ff090035f9045b18afe5763e2865dd35f2d661c02e51f658d95c8065a"}, + {file = "torch-2.0.1+cpu-cp39-cp39-linux_x86_64.whl", hash = "sha256:73482a223d577407c45685fde9d2a74ba42f0d8d9f6e1e95c08071dc55c47d7b"}, + {file = "torch-2.0.1+cpu-cp39-cp39-win_amd64.whl", hash = "sha256:f263f8e908288427ae81441fef540377f61e339a27632b1bbe33cf78292fdaea"}, ] [package.dependencies] @@ -2449,7 +2381,6 @@ filelock = "*" jinja2 = "*" networkx = "*" sympy = "*" -triton = {version = "2.0.0", markers = "platform_system == \"Linux\" and platform_machine == \"x86_64\""} typing-extensions = "*" [package.extras] @@ -2457,24 +2388,24 @@ opt-einsum = ["opt-einsum (>=3.3)"] [package.source] type = "legacy" -url = "https://download.pytorch.org/whl/cu118" -reference = "torch-cu118" +url = "https://download.pytorch.org/whl/cpu" +reference = "torch" [[package]] name = "torch-cluster" -version = "1.6.1+pt20cu118" +version = "1.6.1+pt20cpu" description = "PyTorch Extension Library of Optimized Graph Cluster Algorithms" optional = false python-versions = ">=3.7" files = [ - {file = "torch_cluster-1.6.1+pt20cu118-cp310-cp310-linux_x86_64.whl", hash = "sha256:c793bfb58cab30a9add57df77b1815dc061e1ce62dee749fa505dd811c2ce53d"}, - {file = "torch_cluster-1.6.1+pt20cu118-cp310-cp310-win_amd64.whl", hash = "sha256:305a39a2209cef5c76825ab737aca8ff7fcde4b99a0f366f7721b637d0b577cb"}, - {file = "torch_cluster-1.6.1+pt20cu118-cp311-cp311-linux_x86_64.whl", hash = "sha256:a6250132cac2fe30999be2170ad5fbb788226e507684981a74d8f4baeee481ae"}, - {file = "torch_cluster-1.6.1+pt20cu118-cp311-cp311-win_amd64.whl", hash = "sha256:292eb05de1f80f7c1ff2c1a05e8ac131fa03be916401d63b5038c676859a36d8"}, - {file = "torch_cluster-1.6.1+pt20cu118-cp38-cp38-linux_x86_64.whl", hash = "sha256:6cfc6c682bbf0d4cf5601a55e6e2f32c64302b5f6e83af3820f13038e86587fd"}, - {file = "torch_cluster-1.6.1+pt20cu118-cp38-cp38-win_amd64.whl", hash = "sha256:2ff812f755020d9e26f428f975d2e5d8f6f98d3046ee475edfa9ce6ac50b44e9"}, - {file = "torch_cluster-1.6.1+pt20cu118-cp39-cp39-linux_x86_64.whl", hash = "sha256:cab42156f6d76dc2a9aefd820f3cb8598a6fae0bb455636c31262ea7996da369"}, - {file = "torch_cluster-1.6.1+pt20cu118-cp39-cp39-win_amd64.whl", hash = "sha256:4a1b50157e241c123c82acd5688f4d0028777fd31994b330f151f557ae31ae35"}, + {file = "torch_cluster-1.6.1+pt20cpu-cp310-cp310-linux_x86_64.whl", hash = "sha256:cbd906f2f8918f7f269ee7015ddd819bbf3cd3893da5a8db8c15fe78656791e1"}, + {file = "torch_cluster-1.6.1+pt20cpu-cp310-cp310-win_amd64.whl", hash = "sha256:972f0ef23675e7cab0dd49f98df5c501ac5e163572de29cf3892609613055792"}, + {file = "torch_cluster-1.6.1+pt20cpu-cp311-cp311-linux_x86_64.whl", hash = "sha256:f666e7b2dbdffaf9be44aa0dd4cbbec14ca9595a3ad0b15c7234339ee2b9717a"}, + {file = "torch_cluster-1.6.1+pt20cpu-cp311-cp311-win_amd64.whl", hash = "sha256:82d3260f66eda76e2aee9b458440b2308bf4b403353c844ae45438df89f5d91b"}, + {file = "torch_cluster-1.6.1+pt20cpu-cp38-cp38-linux_x86_64.whl", hash = "sha256:fad2b6a167c41f9f70a04f9c87e70382f115f5699d372ac35f7237a7f2b833f5"}, + {file = "torch_cluster-1.6.1+pt20cpu-cp38-cp38-win_amd64.whl", hash = "sha256:b775998e2bedf73066e596d919bda4cddc75226d4feaeffc54869a8f3fc672e7"}, + {file = "torch_cluster-1.6.1+pt20cpu-cp39-cp39-linux_x86_64.whl", hash = "sha256:6d1986792d2f2134ad5a95d514bba49828b249eed5c0033fcce9e2dc1bb9186a"}, + {file = "torch_cluster-1.6.1+pt20cpu-cp39-cp39-win_amd64.whl", hash = "sha256:88ae100e5d2293e38e31aad4f9ab4d88e6ae8d75f5b3a0fc950c83d65dd722b3"}, ] [package.dependencies] @@ -2485,8 +2416,8 @@ test = ["pytest", "pytest-cov"] [package.source] type = "legacy" -url = "https://data.pyg.org/whl/torch-2.0.0+cu118.html" -reference = "pyg-cu118" +url = "https://data.pyg.org/whl/torch-2.0.0+cpu.html" +reference = "pyg" [[package]] name = "torch-geometric" @@ -2518,19 +2449,19 @@ test = ["onnx", "onnxruntime", "pytest", "pytest-cov"] [[package]] name = "torch-scatter" -version = "2.1.1+pt20cu118" +version = "2.1.1+pt20cpu" description = "PyTorch Extension Library of Optimized Scatter Operations" optional = false python-versions = ">=3.7" files = [ - {file = "torch_scatter-2.1.1+pt20cu118-cp310-cp310-linux_x86_64.whl", hash = "sha256:dc950e83fb1c9f5be6dc3e4778fce8a4904a9f1848d960e9a2049783237444ba"}, - {file = "torch_scatter-2.1.1+pt20cu118-cp310-cp310-win_amd64.whl", hash = "sha256:1204f06f65dcb14fcaa690d9d2898b1be57b742734429c625b41ae6e254003a9"}, - {file = "torch_scatter-2.1.1+pt20cu118-cp311-cp311-linux_x86_64.whl", hash = "sha256:767f82f545240e89f06ae83f6e3acc4b265a9852823985849bb996a434407c5c"}, - {file = "torch_scatter-2.1.1+pt20cu118-cp311-cp311-win_amd64.whl", hash = "sha256:a69ba1347b4385f2b39acab9f0cfc02cc8ca58492be3c2f2fbaafce940d88a5e"}, - {file = "torch_scatter-2.1.1+pt20cu118-cp38-cp38-linux_x86_64.whl", hash = "sha256:60d5bceee7ada073c8f5d3e290a7bb0a4df303d3c9dcce6072f2d79b371e84c1"}, - {file = "torch_scatter-2.1.1+pt20cu118-cp38-cp38-win_amd64.whl", hash = "sha256:feb1f7707914be764c62d46b76be91d650332d8a76e1f26c80ce2d503dc920d7"}, - {file = "torch_scatter-2.1.1+pt20cu118-cp39-cp39-linux_x86_64.whl", hash = "sha256:905e9dfb2dba841ab64676380bd944797b76c17efb081047ae0a64bfbd4f2a42"}, - {file = "torch_scatter-2.1.1+pt20cu118-cp39-cp39-win_amd64.whl", hash = "sha256:669c4f460c57ed8919ab647e0836cc45cbca5b488b88380547cde658cc6a06ef"}, + {file = "torch_scatter-2.1.1+pt20cpu-cp310-cp310-linux_x86_64.whl", hash = "sha256:c7d913cb9675a3f16d852aced4c2ee9a99e7da81b7bdf5e5e301c071fd9897c1"}, + {file = "torch_scatter-2.1.1+pt20cpu-cp310-cp310-win_amd64.whl", hash = "sha256:ed889e3145f8e463e7c61b435d0a6b053329e1d51e65100a529d1a8b98fa45ba"}, + {file = "torch_scatter-2.1.1+pt20cpu-cp311-cp311-linux_x86_64.whl", hash = "sha256:2f725dd2aa4074b41fbbe750e9a04b15e1348907f1294a60256f1bc42ea0c01a"}, + {file = "torch_scatter-2.1.1+pt20cpu-cp311-cp311-win_amd64.whl", hash = "sha256:6d85d654a8a26d521c3bea66a1ed1d115106be2e4475016aaa97a3e448c1e0c9"}, + {file = "torch_scatter-2.1.1+pt20cpu-cp38-cp38-linux_x86_64.whl", hash = "sha256:cdb401a563bd1db7d23e0e947eca3311999e971b083358e1b8fde8d17e7f2990"}, + {file = "torch_scatter-2.1.1+pt20cpu-cp38-cp38-win_amd64.whl", hash = "sha256:d6f6541fe27d9d02003e2ce8488acc32c89bb0054939cd763ef88e4dd6dbf18d"}, + {file = "torch_scatter-2.1.1+pt20cpu-cp39-cp39-linux_x86_64.whl", hash = "sha256:d2511cfb8f0d9c9fb8207c58d1ac73dc0bc815f063f12dde714408ec066c8ee2"}, + {file = "torch_scatter-2.1.1+pt20cpu-cp39-cp39-win_amd64.whl", hash = "sha256:f04f52029f251f8315e400c1b808fe6300f544aba52f59e4c8fb6c43514b785e"}, ] [package.extras] @@ -2538,24 +2469,24 @@ test = ["pytest", "pytest-cov"] [package.source] type = "legacy" -url = "https://data.pyg.org/whl/torch-2.0.0+cu118.html" -reference = "pyg-cu118" +url = "https://data.pyg.org/whl/torch-2.0.0+cpu.html" +reference = "pyg" [[package]] name = "torch-sparse" -version = "0.6.17+pt20cu118" +version = "0.6.17+pt20cpu" description = "PyTorch Extension Library of Optimized Autograd Sparse Matrix Operations" optional = false python-versions = ">=3.7" files = [ - {file = "torch_sparse-0.6.17+pt20cu118-cp310-cp310-linux_x86_64.whl", hash = "sha256:256559b48f6bcf57e999a783e4e7c52405cc57d19e10f4aac0bfc3c88f5afc41"}, - {file = "torch_sparse-0.6.17+pt20cu118-cp310-cp310-win_amd64.whl", hash = "sha256:5c192a5f7ea09c248899271ac6e7e06b666b5049381cc208008e7045eda7aea1"}, - {file = "torch_sparse-0.6.17+pt20cu118-cp311-cp311-linux_x86_64.whl", hash = "sha256:9ea1c3f5ddbfa8ecadd04779093b9e26cbc323c2cd6df7ba48f5eba0e79472db"}, - {file = "torch_sparse-0.6.17+pt20cu118-cp311-cp311-win_amd64.whl", hash = "sha256:c95201c3954df79c7f2cf6bf027810e932f930919a6a27a389034caa1675b1cc"}, - {file = "torch_sparse-0.6.17+pt20cu118-cp38-cp38-linux_x86_64.whl", hash = "sha256:e0fa2c95bb980cbb43574847172895a73c4214716197982f9415f9f97ae6e131"}, - {file = "torch_sparse-0.6.17+pt20cu118-cp38-cp38-win_amd64.whl", hash = "sha256:a61358aadc9f35707a2e8d5d6d7ad4b81776626d3f3b9b0fcc70e2c2d95e13b0"}, - {file = "torch_sparse-0.6.17+pt20cu118-cp39-cp39-linux_x86_64.whl", hash = "sha256:47f1f9f4053057781738d6ab1c83f672d5535d903f7cbc1024b76ff5cfe00c53"}, - {file = "torch_sparse-0.6.17+pt20cu118-cp39-cp39-win_amd64.whl", hash = "sha256:60bd0bcdc2c47a32b8a5674d0a9e257b8e88a3e99d621c03f3f966dfc8311e38"}, + {file = "torch_sparse-0.6.17+pt20cpu-cp310-cp310-linux_x86_64.whl", hash = "sha256:8143cfdaa683e910133ce1656daf214882394f27b4f02a1f7dfc7a69439c3355"}, + {file = "torch_sparse-0.6.17+pt20cpu-cp310-cp310-win_amd64.whl", hash = "sha256:0d26c58a530482b9b527be32d640d227d854334b2058cbed9e20b02465483f99"}, + {file = "torch_sparse-0.6.17+pt20cpu-cp311-cp311-linux_x86_64.whl", hash = "sha256:fb6e34e22d34a073aaf40edafc7ee4cbf9b837b9390558956f9e04c6adcc28db"}, + {file = "torch_sparse-0.6.17+pt20cpu-cp311-cp311-win_amd64.whl", hash = "sha256:aa3f9ccd9dfdc0c249daddcd97bbe40c6e915ef20c1c724e4b99b4fc7ca07e18"}, + {file = "torch_sparse-0.6.17+pt20cpu-cp38-cp38-linux_x86_64.whl", hash = "sha256:e4b4604d035b91f50daddd5db17e8293aa5502af8c0e698d52b7c0479fb3615a"}, + {file = "torch_sparse-0.6.17+pt20cpu-cp38-cp38-win_amd64.whl", hash = "sha256:b3ba774cdaf89894677e01cf0de546dc19df30d8a8a9a105ed0484e391ae216c"}, + {file = "torch_sparse-0.6.17+pt20cpu-cp39-cp39-linux_x86_64.whl", hash = "sha256:418c98cdbc652805f50472c28e1a0498c79d872c921dc71811c333f2d8f0e49e"}, + {file = "torch_sparse-0.6.17+pt20cpu-cp39-cp39-win_amd64.whl", hash = "sha256:a05358d565c724a8209bec1839d9d6c7cd896d9ea1253c75b03bf0c5ebed2390"}, ] [package.dependencies] @@ -2566,24 +2497,24 @@ test = ["pytest", "pytest-cov"] [package.source] type = "legacy" -url = "https://data.pyg.org/whl/torch-2.0.0+cu118.html" -reference = "pyg-cu118" +url = "https://data.pyg.org/whl/torch-2.0.0+cpu.html" +reference = "pyg" [[package]] name = "torch-spline-conv" -version = "1.2.2+pt20cu118" +version = "1.2.2+pt20cpu" description = "Implementation of the Spline-Based Convolution Operator of SplineCNN in PyTorch" optional = false python-versions = ">=3.7" files = [ - {file = "torch_spline_conv-1.2.2+pt20cu118-cp310-cp310-linux_x86_64.whl", hash = "sha256:4c9be34e557f44500168e3d7eb9c66c3bb1f5ac7d74b9ed1e80bb3f14ea673f0"}, - {file = "torch_spline_conv-1.2.2+pt20cu118-cp310-cp310-win_amd64.whl", hash = "sha256:ff98cd6e0eaf9af165412cb342ec2dfdb1fa487f9a4832522f3a833a55a5e14f"}, - {file = "torch_spline_conv-1.2.2+pt20cu118-cp311-cp311-linux_x86_64.whl", hash = "sha256:3ebd19dd42db17093ad1bf65ac7aa23bd2fc8d84d69032b2a10c9187b4343a61"}, - {file = "torch_spline_conv-1.2.2+pt20cu118-cp311-cp311-win_amd64.whl", hash = "sha256:72c84bbbc4e47d5aacf10d1bf12ec543c36b9049e3749e721ae4f0904306084b"}, - {file = "torch_spline_conv-1.2.2+pt20cu118-cp38-cp38-linux_x86_64.whl", hash = "sha256:b3001d2541fa56c3604ac7a746bc9ba14c4ff0b941d133d4b887de0d0cf206ee"}, - {file = "torch_spline_conv-1.2.2+pt20cu118-cp38-cp38-win_amd64.whl", hash = "sha256:30c0c44e5ceda92edf1a2a96f1b9efa7732cb200bb84ba96d2167064b3ba96ad"}, - {file = "torch_spline_conv-1.2.2+pt20cu118-cp39-cp39-linux_x86_64.whl", hash = "sha256:01e0fb8444df62333d04c6beed444b761787c536d4e1e1bb32dd54aaab8f0bed"}, - {file = "torch_spline_conv-1.2.2+pt20cu118-cp39-cp39-win_amd64.whl", hash = "sha256:00b09623ae021a12c935ef58677b606173d56c0e55ce1705bfe2073359a87b58"}, + {file = "torch_spline_conv-1.2.2+pt20cpu-cp310-cp310-linux_x86_64.whl", hash = "sha256:c9a8e1c04a04ae602d1575517ce726ad6fcc6ad3b234f04fa09a492916716bb7"}, + {file = "torch_spline_conv-1.2.2+pt20cpu-cp310-cp310-win_amd64.whl", hash = "sha256:8be0abe79f15a310ffb91c6c53d0dd7cd5bf80f4d89f38331db8eae3a3cf5bf7"}, + {file = "torch_spline_conv-1.2.2+pt20cpu-cp311-cp311-linux_x86_64.whl", hash = "sha256:78b9ae2dbc882861a9f6c405d0059d2e14f789d03b455e54f9adbcc1158cb8b7"}, + {file = "torch_spline_conv-1.2.2+pt20cpu-cp311-cp311-win_amd64.whl", hash = "sha256:b2143efff50097a01baf647c0df37e77bdfab186d6841de44112c48dad50d872"}, + {file = "torch_spline_conv-1.2.2+pt20cpu-cp38-cp38-linux_x86_64.whl", hash = "sha256:5e38e034ab7c8f2432e50fb6a090c5e3bbdca7ca7985c8bf52d0b1d8ebe3aee4"}, + {file = "torch_spline_conv-1.2.2+pt20cpu-cp38-cp38-win_amd64.whl", hash = "sha256:9b7161d3cbc1f49e5b4676d37f46d4a61fe922e9477c79b853eaf0d33e1c53c8"}, + {file = "torch_spline_conv-1.2.2+pt20cpu-cp39-cp39-linux_x86_64.whl", hash = "sha256:03814ce3251f2dd177d28c2ae0a3b406e4bafce7cd7957818325cc0e0710a7be"}, + {file = "torch_spline_conv-1.2.2+pt20cpu-cp39-cp39-win_amd64.whl", hash = "sha256:d78c53e96ed583eae5046d4a79918e095f52161ba67fb43f0ec3d49e100c1fce"}, ] [package.extras] @@ -2591,8 +2522,64 @@ test = ["pytest", "pytest-cov"] [package.source] type = "legacy" -url = "https://data.pyg.org/whl/torch-2.0.0+cu118.html" -reference = "pyg-cu118" +url = "https://data.pyg.org/whl/torch-2.0.0+cpu.html" +reference = "pyg" + +[[package]] +name = "torchdata" +version = "0.6.1" +description = "Composable data loading modules for PyTorch" +optional = false +python-versions = ">=3.8" +files = [ + {file = "torchdata-0.6.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b97f60619764d5f2f62ebcf18bff8a7cfc5c84d30d04d30724b753ec95864a70"}, + {file = "torchdata-0.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ff46aa549c0da9aa2bcba95767034a81c950dc7ccc0e24f38cf6f7878ca1826d"}, + {file = "torchdata-0.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae1b4a516124c00ef47db12bab0cc6898bd2d7e749ffb14b6ebf1fe610a6b46"}, + {file = "torchdata-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:f2a8b0a388753502d49bd5bd186cd8d41dc2d91121246617804578371591b5e6"}, + {file = "torchdata-0.6.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:6474ed86ed7e060698888fa8ece9155dc94bdb9dfcc1874fa6d7707823551adc"}, + {file = "torchdata-0.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:05db07d2793d181867578be99c211b3c71f83f3fda0bf33a70e5c93794513692"}, + {file = "torchdata-0.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a9d4c7d86b0aab2f70cdf0eae50f6eea997051889b0c04ae2f843df048ba9ea"}, + {file = "torchdata-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:3501325411063b0da6d85c93222234973780ca3df7d110ee1795723f9b2e3405"}, + {file = "torchdata-0.6.1-cp38-cp38-macosx_10_13_x86_64.whl", hash = "sha256:129d5b2d35717862b194b31a27b61b5faa9efd4ffc36c1a07d85b320dea8b4c6"}, + {file = "torchdata-0.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2752fd8452d42aeaf480985f5d3d82506ab1ce51ca42cdb61c981145cd2890a8"}, + {file = "torchdata-0.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08b745c14adea7e4a36de4241485f9ea058e3ad3959c3e6dd1526c2f278006e7"}, + {file = "torchdata-0.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:080c1c54128b4eb8e83cf4de74fa38e892cd6bf3114a557a853969543285f2d9"}, + {file = "torchdata-0.6.1-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:7e11108140adaba55491b6124f07b61cce161f53f8604e70961da025ccd014bd"}, + {file = "torchdata-0.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:42961c40bf9c3fb66aaf4189f9154cb4f2eb3862359e64267708e3d273452d68"}, + {file = "torchdata-0.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d012adf90cd15d7164a886512b6746788477172394fe56971799d276f8809e"}, + {file = "torchdata-0.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:24d7fb2fcb0af43660fc44d8583cb8f7d25762bb759e8fde003db29c5036d940"}, + {file = "torchdata-0.6.1-py3-none-any.whl", hash = "sha256:6a6d51cfbb63efe65788ad71e84c2be23a0c6520869e075774e7fc2ee535b9ed"}, +] + +[package.dependencies] +requests = "*" +torch = "2.0.1" +urllib3 = ">=1.25" + +[[package]] +name = "torchtext" +version = "0.15.2+cpu" +description = "Text utilities and datasets for PyTorch" +optional = false +python-versions = ">=3.8" +files = [ + {file = "torchtext-0.15.2+cpu-cp310-cp310-linux_x86_64.whl", hash = "sha256:48fe6e6178bc3345798e2e61d27218bd55df9a2a312aff42e74fa92046542072"}, + {file = "torchtext-0.15.2+cpu-cp311-cp311-linux_x86_64.whl", hash = "sha256:08faa135ec6eaf57ab252708b9fed7005088bd57aafd67f7974fda45d28df0fa"}, + {file = "torchtext-0.15.2+cpu-cp38-cp38-linux_x86_64.whl", hash = "sha256:78088ad4bb5fb1001bb1b07471344e4c134090da29a40d43f7230f697cc1dfe9"}, + {file = "torchtext-0.15.2+cpu-cp39-cp39-linux_x86_64.whl", hash = "sha256:483e5822a1d187043ee7c9ab7e61d42eb00621396b4053590105c3b5fff1edef"}, +] + +[package.dependencies] +numpy = "*" +requests = "*" +torch = "2.0.1" +torchdata = "0.6.1" +tqdm = "*" + +[package.source] +type = "legacy" +url = "https://download.pytorch.org/whl/cpu" +reference = "torch" [[package]] name = "tqdm" @@ -2614,52 +2601,15 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] -[[package]] -name = "triton" -version = "2.0.0" -description = "A language and compiler for custom Deep Learning operations" -optional = false -python-versions = "*" -files = [ - {file = "triton-2.0.0-1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38806ee9663f4b0f7cd64790e96c579374089e58f49aac4a6608121aa55e2505"}, - {file = "triton-2.0.0-1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:226941c7b8595219ddef59a1fdb821e8c744289a132415ddd584facedeb475b1"}, - {file = "triton-2.0.0-1-cp36-cp36m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4c9fc8c89874bc48eb7e7b2107a9b8d2c0bf139778637be5bfccb09191685cfd"}, - {file = "triton-2.0.0-1-cp37-cp37m-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d2684b6a60b9f174f447f36f933e9a45f31db96cb723723ecd2dcfd1c57b778b"}, - {file = "triton-2.0.0-1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9d4978298b74fcf59a75fe71e535c092b023088933b2f1df933ec32615e4beef"}, - {file = "triton-2.0.0-1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:74f118c12b437fb2ca25e1a04759173b517582fcf4c7be11913316c764213656"}, - {file = "triton-2.0.0-1-pp37-pypy37_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:9618815a8da1d9157514f08f855d9e9ff92e329cd81c0305003eb9ec25cc5add"}, - {file = "triton-2.0.0-1-pp38-pypy38_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aca3303629cd3136375b82cb9921727f804e47ebee27b2677fef23005c3851a"}, - {file = "triton-2.0.0-1-pp39-pypy39_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e3e13aa8b527c9b642e3a9defcc0fbd8ffbe1c80d8ac8c15a01692478dc64d8a"}, - {file = "triton-2.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f05a7e64e4ca0565535e3d5d3405d7e49f9d308505bb7773d21fb26a4c008c2"}, - {file = "triton-2.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb4b99ca3c6844066e516658541d876c28a5f6e3a852286bbc97ad57134827fd"}, - {file = "triton-2.0.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47b4d70dc92fb40af553b4460492c31dc7d3a114a979ffb7a5cdedb7eb546c08"}, - {file = "triton-2.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fedce6a381901b1547e0e7e1f2546e4f65dca6d91e2d8a7305a2d1f5551895be"}, - {file = "triton-2.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75834f27926eab6c7f00ce73aaf1ab5bfb9bec6eb57ab7c0bfc0a23fac803b4c"}, - {file = "triton-2.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0117722f8c2b579cd429e0bee80f7731ae05f63fe8e9414acd9a679885fcbf42"}, - {file = "triton-2.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcd9be5d0c2e45d2b7e6ddc6da20112b6862d69741576f9c3dbaf941d745ecae"}, - {file = "triton-2.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42a0d2c3fc2eab4ba71384f2e785fbfd47aa41ae05fa58bf12cb31dcbd0aeceb"}, - {file = "triton-2.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c47b72c72693198163ece9d90a721299e4fb3b8e24fd13141e384ad952724f"}, -] - -[package.dependencies] -cmake = "*" -filelock = "*" -lit = "*" -torch = "*" - -[package.extras] -tests = ["autopep8", "flake8", "isort", "numpy", "pytest", "scipy (>=1.7.1)"] -tutorials = ["matplotlib", "pandas", "tabulate"] - [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] [[package]] @@ -2815,13 +2765,13 @@ files = [ [[package]] name = "werkzeug" -version = "2.3.7" +version = "3.0.0" description = "The comprehensive WSGI web application library." optional = false python-versions = ">=3.8" files = [ - {file = "werkzeug-2.3.7-py3-none-any.whl", hash = "sha256:effc12dba7f3bd72e605ce49807bbe692bd729c3bb122a3b91747a6ae77df528"}, - {file = "werkzeug-2.3.7.tar.gz", hash = "sha256:2b8c0e447b4b9dbcc85dd97b6eeb4dcbaf6c8b6c3be0bd654e25553e0a2157d8"}, + {file = "werkzeug-3.0.0-py3-none-any.whl", hash = "sha256:cbb2600f7eabe51dbc0502f58be0b3e1b96b893b05695ea2b35b43d4de2d9962"}, + {file = "werkzeug-3.0.0.tar.gz", hash = "sha256:3ffff4dcc32db52ef3cc94dff3000a3c2846890f3a5a51800a27b909c5e770f0"}, ] [package.dependencies] @@ -2846,20 +2796,24 @@ h11 = ">=0.9.0,<1" [[package]] name = "zipp" -version = "3.16.2" +version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.8" files = [ - {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, - {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +[extras] +database = [] +science = ["uvloop"] + [metadata] lock-version = "2.0" python-versions = ">=3.8.1,<3.12" -content-hash = "7f7b07f47de32fd2cc0980f5501c6e11f5ceb9236bc0950190b672485d5cadef" +content-hash = "354c611c85825e755fb478eefe27dcdd3dd287321ee56a6e526b87e2e3f72f38" diff --git a/project/plugins.sbt b/project/plugins.sbt index b1d20f8..ce2c1b3 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,7 @@ addSbtPlugin("com.simplytyped" % "sbt-antlr4" % "0.8.3") addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.16") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") -addSbtPlugin("com.codecommit" % "sbt-github-packages" % "0.5.2") -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.3") +addSbtPlugin("com.codecommit" % "sbt-github-packages" % "0.5.2") +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.1.3") libraryDependencies += "ai.kien" %% "python-native-libs" % "0.2.4" diff --git a/pyproject.toml b/pyproject.toml index 0279ce4..3df742d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "appthreat-chen" -version = "0.0.9" +version = "0.0.10" description = "Code Hierarchy Exploration Net (chen)" authors = ["Team AppThreat "] license = "Apache-2.0" @@ -33,7 +33,7 @@ chen = 'chenpy.cli:main' python = ">=3.8.1,<3.12" httpx = "^0.24.1" websockets = "^11.0.2" -uvloop = {version = "^0.17.0", optional = true} +uvloop = {version = "^0.17.0", markers = "sys_platform == 'linux' or sys_platform == 'darwin'", optional = true} orjson = "^3.9.0" rich = "^13.4.1" oras = "^0.1.24" @@ -44,6 +44,10 @@ gitpython = "^3.1.37" quart = "^0.18.4" +[tool.poetry.extras] +science = ["uvloop", "networkx", "pydotplus", "pyg-lib", "torch-scatter", "torch-sparse", "torch-cluster", "torch-spline-conv", "torch-geometric", "torch", "torchtext", "rocksdb-py"] +database = ["networkx", "rocksdb-py"] + [tool.poetry.group.dev.dependencies] pytest = "^7.3.1" black = "^23.3.0" @@ -55,49 +59,24 @@ pdoc3 = "^0.10.0" [tool.poetry.group.science] optional = true -[tool.poetry.group.science-cu117] -optional = true - -[tool.poetry.group.science-cu118] +[tool.poetry.group.database] optional = true [tool.poetry.group.science.dependencies] -graphviz = {version = "^0.20.1"} -gensim = {version = "^4.3.1"} networkx = {extras = ["default", "extra"], version = "^3.1"} -pydotplus = {version = "^2.0.2", optional = true} -pygraphviz = {version = "^1.10", optional = true} -pyg-lib = {version = "^0.2.0+pt20cpu", source = "pyg"} -torch-scatter = {version = "^2.1.1+pt20cpu", source = "pyg"} -torch-sparse = {version = "^0.6.17+pt20cpu", source = "pyg"} -torch-cluster = {version = "^1.6.1+pt20cpu", source = "pyg"} -torch-spline-conv = {version = "^1.2.2+pt20cpu", source = "pyg"} +pydotplus = {version = "^2.0.2", markers = "sys_platform == 'linux' or sys_platform == 'darwin'", optional = true} +pyg-lib = {version = "^0.2.0+pt20cpu", markers = "sys_platform == 'linux' or sys_platform == 'darwin'", source = "pyg"} +torch-scatter = {version = "^2.1.1+pt20cpu", markers = "sys_platform == 'linux' or sys_platform == 'darwin'", source = "pyg"} +torch-sparse = {version = "^0.6.17+pt20cpu", markers = "sys_platform == 'linux' or sys_platform == 'darwin'", source = "pyg"} +torch-cluster = {version = "^1.6.1+pt20cpu", markers = "sys_platform == 'linux' or sys_platform == 'darwin'", source = "pyg"} +torch-spline-conv = {version = "^1.2.2+pt20cpu", markers = "sys_platform == 'linux' or sys_platform == 'darwin'", source = "pyg"} torch-geometric = {version = "^2.3.1"} torch = {version = "^2.0.1+cpu", source = "torch"} +torchtext = {version = "^0.15.2+cpu", markers = "sys_platform == 'linux' or sys_platform == 'darwin'", source = "torch"} -[tool.poetry.group.science-cu117.dependencies] -graphviz = {version = "^0.20.1"} -gensim = {version = "^4.3.1"} -networkx = {extras = ["default", "extra"], version = "^3.1"} -pyg-lib = {version = "^0.2.0+pt20cpu", source = "pyg-cu117"} -torch-scatter = {version = "^2.1.1+pt20cpu", source = "pyg-cu117"} -torch-sparse = {version = "^0.6.17+pt20cpu", source = "pyg-cu117"} -torch-cluster = {version = "^1.6.1+pt20cpu", source = "pyg-cu117"} -torch-spline-conv = {version = "^1.2.2+pt20cpu", source = "pyg-cu117"} -torch-geometric = {version = "^2.3.1"} -torch = {version = "^2.0.1+cpu", source = "torch-cu117"} +[tool.poetry.group.database.dependencies] +rocksdb-py = "^0.0.4" -[tool.poetry.group.science-cu118.dependencies] -graphviz = {version = "^0.20.1"} -gensim = {version = "^4.3.1"} -networkx = {extras = ["default", "extra"], version = "^3.1"} -pyg-lib = {version = "^0.2.0+pt20cpu", source = "pyg-cu118"} -torch-scatter = {version = "^2.1.1+pt20cpu", source = "pyg-cu118"} -torch-sparse = {version = "^0.6.17+pt20cpu", source = "pyg-cu118"} -torch-cluster = {version = "^1.6.1+pt20cpu", source = "pyg-cu118"} -torch-spline-conv = {version = "^1.2.2+pt20cpu", source = "pyg-cu118"} -torch-geometric = {version = "^2.3.1"} -torch = {version = "^2.0.1+cpu", source = "torch-cu118"} [[tool.poetry.source]] name = "pyg" @@ -105,35 +84,11 @@ url = "https://data.pyg.org/whl/torch-2.0.0+cpu.html" priority = "explicit" -[[tool.poetry.source]] -name = "pyg-cu117" -url = "https://data.pyg.org/whl/torch-2.0.0+cu117.html" -priority = "explicit" - - -[[tool.poetry.source]] -name = "pyg-cu118" -url = "https://data.pyg.org/whl/torch-2.0.0+cu118.html" -priority = "explicit" - - [[tool.poetry.source]] name = "torch" url = "https://download.pytorch.org/whl/cpu" priority = "explicit" - -[[tool.poetry.source]] -name = "torch-cu117" -url = "https://download.pytorch.org/whl/cu117" -priority = "explicit" - - -[[tool.poetry.source]] -name = "torch-cu118" -url = "https://download.pytorch.org/whl/cu118" -priority = "explicit" - [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/LocationCreator.scala b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/LocationCreator.scala index 57028bb..81f4d44 100644 --- a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/LocationCreator.scala +++ b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/language/LocationCreator.scala @@ -17,7 +17,7 @@ object LocationCreator { location(node) } catch { case exc @ (_: NoSuchElementException | _: ClassCastException) => - logger.error(s"Cannot determine location for ${node.label} due to broken CPG", exc) + logger.debug(s"Cannot determine location for ${node.label} due to broken CPG", exc) emptyLocation(node.label, Some(node)) } } diff --git a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/utils/Torch.scala b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/utils/Torch.scala index f95d462..f09e23d 100644 --- a/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/utils/Torch.scala +++ b/semanticcpg/src/main/scala/io/shiftleft/semanticcpg/utils/Torch.scala @@ -11,377 +11,12 @@ import java.nio.file.Path object Torch { CPythonInterpreter.execManyLines(""" - |import json - |import tempfile - |from collections import Counter, defaultdict - | - |from hashlib import blake2b | |SCIENCE_PACK_AVAILABLE = True |try: - | import networkx as nx - | from networkx.readwrite import json_graph, read_graphml - | import torch - | from torch import Tensor - | from torch_geometric.data import Data + | from chenpy.graph import convert_graphml, diff_graph, to_pyg, is_similar, ged, generate_sp_model, load_sp_model |except ImportError: | SCIENCE_PACK_AVAILABLE = False - | - |def calculate_hash(content, digest_size = 16): - | h = blake2b(digest_size = digest_size) - | if content and isinstance(content, str): - | content = content.replace("\n", "").replace("\t", "").replace(" ", "") - | h.update(content.encode()) - | return h.hexdigest() - | return None - | - |def _hash_label(label, digest_size): - | return calculate_hash(label, digest_size=digest_size) - | - | - |def _init_node_labels(G, edge_attr_fn, node_attr_fn): - | if node_attr_fn: - | return {u: node_attr_fn(dd) for u, dd in G.nodes(data=True)} - | elif edge_attr_fn: - | return {u: "" for u in G} - | else: - | return {u: str(deg) for u, deg in G.degree()} - | - | - |def _neighborhood_aggregate(G, node, node_labels, edge_attr_fn=None): - | label_list = [] - | for nbr in G.neighbors(node): - | prefix = "" if edge_attr_fn is None else edge_attr_fn(G[node][nbr]) - | label_list.append(prefix + node_labels[nbr]) - | return node_labels[node] + "".join(sorted(label_list)) - | - | - |def graph_hash(G, edge_attr_fn=None, node_attr_fn=None, iterations=3, digest_size=16): - | - | def weisfeiler_lehman_step(G, labels, edge_attr_fn=None): - | new_labels = {} - | for node in G.nodes(): - | label = _neighborhood_aggregate(G, node, labels, edge_attr_fn=edge_attr_fn) - | new_labels[node] = _hash_label(label, digest_size) - | return new_labels - | - | # set initial node labels - | node_labels = _init_node_labels(G, edge_attr_fn, node_attr_fn) - | - | subgraph_hash_counts = [] - | for _ in range(iterations): - | node_labels = weisfeiler_lehman_step(G, node_labels, edge_attr_fn=edge_attr_fn) - | counter = Counter(node_labels.values()) - | # sort the counter, extend total counts - | subgraph_hash_counts.extend(sorted(counter.items(), key=lambda x: x[0])) - | - | # hash the final counter - | return _hash_label(str(tuple(subgraph_hash_counts)), digest_size) - | - | - |def subgraph_hashes( - | G, edge_attr_fn=None, node_attr_fn=None, iterations=3, digest_size=16 - |): - | - | def weisfeiler_lehman_step(G, labels, node_subgraph_hashes, edge_attr_fn=None): - | new_labels = {} - | for node in G.nodes(): - | label = _neighborhood_aggregate(G, node, labels, edge_attr_fn=edge_attr_fn) - | hashed_label = _hash_label(label, digest_size) - | new_labels[node] = hashed_label - | node_subgraph_hashes[node].append(hashed_label) - | return new_labels - | - | node_labels = _init_node_labels(G, edge_attr_fn, node_attr_fn) - | - | node_subgraph_hashes = defaultdict(list) - | for _ in range(iterations): - | node_labels = weisfeiler_lehman_step( - | G, node_labels, node_subgraph_hashes, edge_attr_fn - | ) - | - | return dict(node_subgraph_hashes) - | - | - |def diff(first_graph, second_graph, include_common=False, as_dict=False, as_dot=False): - | return diff_graph( - | first_graph, - | second_graph, - | include_common=include_common, - | as_dict=as_dict, - | as_dot=as_dot, - | ) - | - | - |def get_node_label(n): - | if not n: - | return "" - | for at in ( - | "label", - | "CODE", - | "SIGNATURE", - | "METHOD_FULL_NAME", - | "NAME", - | "VARIABLE", - | "labelE", - | ): - | if n.get(at) is not None: - | return n.get(at) - | return "" - | - | - |def diff_graph( - | first_graph, second_graph, include_common=False, as_dict=False, as_dot=False - |): - | if not first_graph and second_graph: - | return second_graph - | if first_graph and not second_graph: - | return first_graph - | graph = nx.Graph() - | if not first_graph and not second_graph: - | return graph - | first_graph_nodes = [get_node_label(r[1]) for r in first_graph.nodes(data=True)] - | second_graph_nodes = [get_node_label(r[1]) for r in second_graph.nodes(data=True)] - | removed_nodes = set(first_graph_nodes) - set(second_graph_nodes) - | added_nodes = set(second_graph_nodes) - set(first_graph_nodes) - | nodes = set(second_graph_nodes) & set(first_graph_nodes) - | first_graph_edges = [ - | (r[0], r[1], get_node_label(r[2])) for r in first_graph.edges(data=True) - | ] - | second_graph_edges = [ - | (r[0], r[1], get_node_label(r[2])) for r in second_graph.edges(data=True) - | ] - | removed_edges = set(first_graph_edges) - set(second_graph_edges) - | removed_edges_fmt = [] - | for removed_edge in removed_edges: - | src = removed_edge[0] - | dest = removed_edge[1] - | if removed_edge[0] in removed_nodes: - | src = "-" + removed_edge[0] - | if removed_edge[1] in removed_nodes: - | dest = "-" + removed_edge[1] - | removed_edges_fmt.append((src, dest, removed_edge[2])) - | added_edges = set(second_graph_edges) - set(first_graph_edges) - | added_edges_fmt = [] - | for added_edge in added_edges: - | src = added_edge[0] - | dest = added_edge[1] - | if added_edge[0] in added_nodes: - | src = "+" + added_edge[0] - | if added_edge[1] in added_nodes: - | dest = "+" + added_edge[1] - | added_edges_fmt.append((src, dest, added_edge[2])) - | edges = set(second_graph_edges) & set(first_graph_edges) - | for removed_node in removed_nodes: - | graph.add_node("-" + removed_node) - | for added_node in added_nodes: - | graph.add_node("+" + added_node) - | if include_common: - | for node in nodes: - | graph.add_node(node) - | for removed_edge in removed_edges_fmt: - | graph.add_edge(removed_edge[0], removed_edge[1], label="-" + removed_edge[2]) - | for added_edge in added_edges_fmt: - | graph.add_edge(added_edge[0], added_edge[1], label="+" + added_edge[2]) - | if include_common: - | for edge in edges: - | graph.add_edge(edge[0], edge[1], label=edge[2]) - | if as_dict: - | return nx.to_dict_of_dicts(graph) - | if as_dot: - | with tempfile.NamedTemporaryFile( - | prefix="diff_graph", suffix=".dot", delete=False - | ) as fp: - | write_dot(graph, fp.name) - | fp.flush() - | return fp.read().decode() - | return graph - | - | - |def node_match_fn(n1, n2): - | return get_node_label(n1) == get_node_label(n2) - | - | - |def gep(first_graph, second_graph, upper_bound=500): - | distance = nx.optimal_edit_paths( - | first_graph, - | second_graph, - | node_match=node_match_fn, - | edge_match=node_match_fn, - | upper_bound=upper_bound, - | ) - | if distance is None: - | distance = -1 - | return distance - | - | - |def ged(first_graph, second_graph, timeout=5, upper_bound=500): - | distance = nx.graph_edit_distance( - | first_graph, - | second_graph, - | node_match=node_match_fn, - | edge_match=node_match_fn, - | timeout=timeout, - | upper_bound=upper_bound, - | ) - | if distance is None: - | distance = -1 - | return distance - | - | - |def write_dot(G, path): - | nx.nx_agraph.write_dot(G, path) - | - | - |def hash( - | G, - | subgraph=False, - | edge_attr_fn=get_node_label, - | node_attr_fn=get_node_label, - | iterations=3, - | digest_size=16, - |): - | if subgraph: - | return subgraph_hashes( - | G, - | edge_attr_fn=edge_attr_fn, - | node_attr_fn=node_attr_fn, - | iterations=iterations, - | digest_size=digest_size, - | ) - | return graph_hash( - | G, - | edge_attr_fn=edge_attr_fn, - | node_attr_fn=node_attr_fn, - | iterations=iterations, - | digest_size=digest_size, - | ) - | - | - |def summarize(G, as_dict=False, as_dot=False): - | summary_graph = nx.snap_aggregation( - | G, node_attributes=("label", "CODE"), edge_attributes=("label", "CODE") - | ) - | if as_dict: - | return nx.to_dict_of_dicts(summary_graph) - | if as_dot: - | with tempfile.NamedTemporaryFile( - | prefix="summary_graph", suffix=".dot", delete=False - | ) as fp: - | write_dot(summary_graph, fp.name) - | fp.flush() - | return fp.read().decode() - | return summary_graph - | - | - |def is_similar(M1, M2, edit_distance=10, upper_bound=500, timeout=5): - | if not diff_graph(M1, M2, as_dict=True): - | return True - | distance = ged(M1, M2, upper_bound=upper_bound, timeout=timeout) - | if distance == -1: - | return False - | return int(distance) < edit_distance - | - | - |def convert_graphml( - | gml_file, force_multigraph=False, as_graph=True, as_adjacency_data=False - |): - | try: - | G = read_graphml(gml_file, force_multigraph=force_multigraph) - | if as_graph: - | return G - | if as_adjacency_data: - | return json.dumps(json_graph.adjacency_data(G)) - | except Exception: - | return None - | - | - |def to_pyg( - | G, - | group_node_attrs=None, - | group_edge_attrs=None, - |): - | if not SCIENCE_PACK_AVAILABLE: - | return RuntimeError( - | "Scientific dependencies missing. Please reinstall with 'pip install chen[science]'" - | ) - | G = G.to_directed() if not nx.is_directed(G) else G - | - | mapping = dict(zip(G.nodes(), range(G.number_of_nodes()))) - | edge_index = torch.empty((2, G.number_of_edges()), dtype=torch.long) - | for i, (src, dst) in enumerate(G.edges()): - | edge_index[0, i] = mapping[src] - | edge_index[1, i] = mapping[dst] - | - | data = defaultdict(list) - | - | if G.number_of_nodes() > 0: - | node_attrs = list(next(iter(G.nodes(data=True)))[-1].keys()) - | else: - | node_attrs = {} - | - | if G.number_of_edges() > 0: - | edge_attrs = list(next(iter(G.edges(data=True)))[-1].keys()) - | else: - | edge_attrs = {} - | - | for i, (_, feat_dict) in enumerate(G.nodes(data=True)): - | for key, value in feat_dict.items(): - | data[str(key)].append(value) - | - | for i, (_, _, feat_dict) in enumerate(G.edges(data=True)): - | for key, value in feat_dict.items(): - | key = f"edge_{key}" if key in node_attrs else key - | data[str(key)].append(value) - | - | for key, value in G.graph.items(): - | if key == "node_default" or key == "edge_default": - | continue # Do not load default attributes. - | key = f"graph_{key}" if key in node_attrs else key - | data[str(key)] = value - | - | for key, value in data.items(): - | if isinstance(value, (tuple, list)) and isinstance(value[0], Tensor): - | data[key] = torch.stack(value, dim=0) - | else: - | try: - | data[key] = torch.tensor(value) - | except (ValueError, TypeError): - | pass - | - | data["edge_index"] = edge_index.view(2, -1) - | data = Data.from_dict(data) - | - | if group_node_attrs is all: - | group_node_attrs = list(node_attrs) - | if group_node_attrs is not None: - | xs = [] - | for key in group_node_attrs: - | x = data.get(key, "") - | x = x.view(-1, 1) if x.dim() <= 1 else x - | xs.append(x) - | if data.get(key) is not None: - | del data[key] - | data.x = torch.cat(xs, dim=-1) - | - | if group_edge_attrs is all: - | group_edge_attrs = list(edge_attrs) - | if group_edge_attrs is not None: - | xs = [] - | for key in group_edge_attrs: - | key = f"edge_{key}" if key in node_attrs else key - | x = data.get(key, "") - | x = x.view(-1, 1) if x.dim() <= 1 else x - | xs.append(x) - | if data.get(key) is not None: - | del data[key] - | data.edge_attr = torch.cat(xs, dim=-1) - | - | if data.x is None and data.pos is None: - | data.num_nodes = G.number_of_nodes() - | - | return data - | |""".stripMargin) def convert_graphml(gml_file: Path) = py.Dynamic.global.convert_graphml(gml_file.toAbsolutePath.toString) @@ -447,4 +82,13 @@ object Torch { -1.0 } } + + def generate_sp_model( + filename: String, + vocab_size: Int = 20000, + model_type: String = "unigram", + model_prefix: String = "m_user" + ) = py.Dynamic.global.generate_sp_model(filename, vocab_size, model_type, model_prefix) + + def load_sp_model(filename: String) = py.Dynamic.global.load_sp_model(filename) }