descry-codegraph 1.0.0__tar.gz → 1.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- descry_codegraph-1.0.0/CLAUDE.md → descry_codegraph-1.0.2/AGENTS.md +3 -3
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/CHANGELOG.md +32 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/PKG-INFO +2 -2
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/README.md +1 -1
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/pyproject.toml +1 -1
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/__init__.py +1 -1
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/cli.py +9 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/handlers.py +1 -1
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/mcp_server.py +2 -2
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/resolver.py +63 -11
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/rust_parser.py +5 -1
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_backtracking.py +91 -64
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_cli.py +23 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_generate.py +132 -31
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_ground_truth.py +4 -1
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_mcp.py +1 -1
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_web_server.py +4 -4
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/.github/assets/01-landing.png +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/.github/workflows/ci.yml +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/.github/workflows/release.yml +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/.gitignore +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/CONTRACT.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/LICENSE +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/SECURITY.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/THIRD-PARTY-NOTICES.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/claude-skill/README.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/claude-skill/descry/SKILL.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/claude-skill/descry/references/cli-reference.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/claude-skill/descry/references/mcp-tools.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/claude-skill/descry/references/recipes.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/docs/CERTAINTY.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/docs/TOOLS.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/docs/UPGRADING.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/justfile +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/pi-extension/README.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/pi-extension/descry-cli.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/pi-extension/descry-tools.ts +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_answers.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_comments.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_env.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_files.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_graph.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_parse_cache.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_parsing.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_reads.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_stdlib.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/_streams.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/clang_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/cross_lang.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/dart_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/dotnet_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/embeddings.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/generate.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/git_history.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/go_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/java_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/php_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/proto_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/python_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/query.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/ruby_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/__init__.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapter.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/__init__.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/_empty_environment.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/_java_compat.init.gradle +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/clang.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/dart.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/dotnet.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/go.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/java.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/php.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/python.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/ruby.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/rust.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/adapters/typescript.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/cache.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/pb2.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/scip/support.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/c.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/cpp.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/dart.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/dotnet.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/go.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/java.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/node.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/php.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/python.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/ruby.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/rust.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/stdlib/typescript.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/ts_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/web/__init__.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/web/server.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/web/web/index.html +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/src/descry/web/web/style.css +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/__init__.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/conftest.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/eval/README.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/eval/__init__.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/eval/compare.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/eval/corpus.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/eval/metrics.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/eval/registry.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/eval/results/results-descry.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/eval/results/results-ripgrep.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/fixtures/small_graph.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/c/Makefile +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/c/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/c/io.c +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/c/io.h +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/c/main.c +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/c/order.c +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/Makefile +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/main.cpp +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/models.hpp +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/reader.hpp +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/Gt.csproj +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/Io.cs +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/Models.cs +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/Program.cs +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/dart/bin/main.dart +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/dart/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/dart/lib/io.dart +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/dart/lib/models.dart +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/dart/pubspec.yaml +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/go/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/go/go.mod +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/go/io.go +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/go/main.go +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/go/models.go +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/java/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Base.java +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Io.java +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Main.java +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Order.java +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Reader.java +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/User.java +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/package.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/src/io.js +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/src/main.js +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/src/models.js +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/php/composer.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/php/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/php/src/Io.php +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/php/src/Models.php +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/php/src/main.php +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/python/app/__init__.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/python/app/io.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/python/app/main.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/python/app/models.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/python/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/python/pyproject.toml +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/Gemfile +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/lib/io.rb +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/lib/main.rb +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/lib/models.rb +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/rust/Cargo.toml +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/rust/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/rust/src/io.rs +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/rust/src/main.rs +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/rust/src/models.rs +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/expected.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/package.json +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/src/io.ts +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/src/main.ts +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/src/models.ts +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_clang_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_config.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_cross_lang.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_dart_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_docs.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_dotnet_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_embeddings.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_git_history.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_go_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_handlers.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_hardening.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_interfaces.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_java_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_non_regular_files.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_parse_cache.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_php_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_query.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_resolve_cache.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_ruby_parser.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_scip.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_scip_cache.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_scip_clang.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_scip_dart.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_scip_dotnet.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_scip_go.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_scip_java.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_scip_php.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_scip_ruby.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_stdlib.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tests/test_written_through.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/docs/gen_tools.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/README.md +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/common.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_c.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_cpp.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_dart.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_dotnet.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_go.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_java.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_node.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_php.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_python.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_ruby.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_rust.py +0 -0
- {descry_codegraph-1.0.0 → descry_codegraph-1.0.2}/tools/stdlib/gen_typescript.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AGENTS.md
|
|
2
2
|
|
|
3
|
-
This file provides guidance to
|
|
3
|
+
This file provides guidance to coding agents when working with code in this repository.
|
|
4
4
|
|
|
5
5
|
## Commands
|
|
6
6
|
|
|
@@ -23,7 +23,7 @@ just test tests/test_config.py::TestFromToml::test_from_toml_basic # one test
|
|
|
23
23
|
just test -k "cross_lang and not slow" # by expression
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Python 3.11+ required (enforced by `pyproject.toml`). Pre-commit gate: `just lint && just fmt && just test` all pass (
|
|
26
|
+
Python 3.11+ required (enforced by `pyproject.toml`). Pre-commit gate: `just lint && just fmt && just test` all pass (3343 tests pass; a handful more are skipped where the environment lacks their fixture — a drop is a regression signal).
|
|
27
27
|
|
|
28
28
|
Invoke the tool while developing:
|
|
29
29
|
|
|
@@ -4,6 +4,38 @@ All notable changes to Descry will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [semver](https://semver.org/) from 1.0.0.
|
|
6
6
|
|
|
7
|
+
## [1.0.2] — 2026-10-31
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Rust glob re-exports (`pub use m::*`) that reach a module by several
|
|
12
|
+
routes, or lead back round a cycle, no longer make indexing exponential:
|
|
13
|
+
each name a glob brings, and each type alias, is looked up once per
|
|
14
|
+
file.
|
|
15
|
+
- Rust: `<Self>::f(x)` is read as `Self::f(x)`; it, and a crate-root path
|
|
16
|
+
`::f(x)` with an argument of a project type, stopped the index.
|
|
17
|
+
- Rust: indexing a nested `vec![vec![..]; n]` twice stopped the index.
|
|
18
|
+
- Rust: a `static` or `const` in a `quote!` template, its type written
|
|
19
|
+
with `#` interpolations, stopped the index.
|
|
20
|
+
- MCP: arguments a tool cannot read are refused naming what is wrong with
|
|
21
|
+
each (`terms: Field required`), not the field alone.
|
|
22
|
+
- CLI: without a terminal on stderr, loading the embedding model prints no
|
|
23
|
+
progress bars or Hugging Face Hub notices; `HF_HUB_DISABLE_PROGRESS_BARS`,
|
|
24
|
+
`HF_HUB_VERBOSITY` and `TRANSFORMERS_VERBOSITY` set by the user are kept.
|
|
25
|
+
- README: `[timeouts] index_minutes = 0` is no time limit.
|
|
26
|
+
|
|
27
|
+
## [1.0.1] — 2026-10-30
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- On macOS, stopping `descry index` (Ctrl-C, `SIGINT`) stops the run as
|
|
32
|
+
`SIGTERM` and `SIGHUP` do; it reported "Index error: Operation not
|
|
33
|
+
permitted" and exited 2.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- `CLAUDE.md` is `AGENTS.md`.
|
|
38
|
+
|
|
7
39
|
## [1.0.0] — 2026-10-29
|
|
8
40
|
|
|
9
41
|
### Breaking
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: descry-codegraph
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
4
4
|
Summary: Codebase knowledge graph: polyglot indexer, semantic search, call-graph analysis
|
|
5
5
|
Project-URL: Homepage, https://github.com/06chaynes/descry
|
|
6
6
|
Project-URL: Repository, https://github.com/06chaynes/descry
|
|
@@ -308,7 +308,7 @@ timeout = 30
|
|
|
308
308
|
scip_minutes = 30 # per indexer; 0 = unlimited
|
|
309
309
|
embedding_seconds = 60 # MCP and web answer `loading` past it; the CLI waits
|
|
310
310
|
query_ms = 4000 # 0 = no time limit
|
|
311
|
-
index_minutes = 30 # Timeout for `descry index` subprocess
|
|
311
|
+
index_minutes = 30 # Timeout for `descry index` subprocess; 0 = unlimited
|
|
312
312
|
|
|
313
313
|
[query]
|
|
314
314
|
max_depth = 3
|
|
@@ -247,7 +247,7 @@ timeout = 30
|
|
|
247
247
|
scip_minutes = 30 # per indexer; 0 = unlimited
|
|
248
248
|
embedding_seconds = 60 # MCP and web answer `loading` past it; the CLI waits
|
|
249
249
|
query_ms = 4000 # 0 = no time limit
|
|
250
|
-
index_minutes = 30 # Timeout for `descry index` subprocess
|
|
250
|
+
index_minutes = 30 # Timeout for `descry index` subprocess; 0 = unlimited
|
|
251
251
|
|
|
252
252
|
[query]
|
|
253
253
|
max_depth = 3
|
|
@@ -11,6 +11,7 @@ Usage:
|
|
|
11
11
|
import argparse
|
|
12
12
|
import asyncio
|
|
13
13
|
import json
|
|
14
|
+
import os
|
|
14
15
|
import sys
|
|
15
16
|
|
|
16
17
|
from descry._answers import fail
|
|
@@ -516,6 +517,14 @@ def build_parser():
|
|
|
516
517
|
|
|
517
518
|
def main():
|
|
518
519
|
write_utf8()
|
|
520
|
+
if not sys.stderr.isatty():
|
|
521
|
+
# Scripted use: no model-loading progress bars or Hub notices.
|
|
522
|
+
for name, value in (
|
|
523
|
+
("HF_HUB_DISABLE_PROGRESS_BARS", "1"),
|
|
524
|
+
("HF_HUB_VERBOSITY", "error"),
|
|
525
|
+
("TRANSFORMERS_VERBOSITY", "error"),
|
|
526
|
+
):
|
|
527
|
+
os.environ.setdefault(name, value)
|
|
519
528
|
parser = build_parser()
|
|
520
529
|
args = parser.parse_args()
|
|
521
530
|
|
|
@@ -1058,7 +1058,7 @@ def _kill_process_tree(proc: asyncio.subprocess.Process) -> None:
|
|
|
1058
1058
|
)
|
|
1059
1059
|
else:
|
|
1060
1060
|
# The child may have exited without the event loop having seen it yet.
|
|
1061
|
-
with contextlib.suppress(ProcessLookupError):
|
|
1061
|
+
with contextlib.suppress(ProcessLookupError, PermissionError):
|
|
1062
1062
|
os.killpg(proc.pid, signal.SIGKILL)
|
|
1063
1063
|
|
|
1064
1064
|
|
|
@@ -115,13 +115,13 @@ class _Server(MCPServer):
|
|
|
115
115
|
if isinstance(exc.__cause__, ValidationError):
|
|
116
116
|
fields = sorted(
|
|
117
117
|
{
|
|
118
|
-
".
|
|
118
|
+
f"{'.'.join(str(part) for part in err['loc'])}: {err['msg']}"
|
|
119
119
|
for err in exc.__cause__.errors()
|
|
120
120
|
}
|
|
121
121
|
)
|
|
122
122
|
answer = fail(
|
|
123
123
|
"invalid",
|
|
124
|
-
f"Invalid arguments for {name}: {'
|
|
124
|
+
f"Invalid arguments for {name}: {'; '.join(fields)}.",
|
|
125
125
|
)
|
|
126
126
|
return _answered(json.dumps(public(answer), indent=2), answer)
|
|
127
127
|
raise
|
|
@@ -1297,7 +1297,9 @@ class CallResolver:
|
|
|
1297
1297
|
# signature a call of it is of
|
|
1298
1298
|
"overloads",
|
|
1299
1299
|
"reaches", # file ID -> the files its includes reach (C/C++)
|
|
1300
|
+
"rust_aliases", # (Rust module, name) -> see _alias_in
|
|
1300
1301
|
"rust_in_scope", # Rust scope ID -> the modules named there
|
|
1302
|
+
"rust_used", # (Rust module, name) -> see _rust_used
|
|
1301
1303
|
"rust_uses", # Rust scope ID -> what the `use`s in force bind
|
|
1302
1304
|
"shared_declaration", # candidate node IDs -> node ID or None
|
|
1303
1305
|
# Language -> the last name segments of the types and functions its
|
|
@@ -1327,6 +1329,8 @@ class CallResolver:
|
|
|
1327
1329
|
"_forwarding",
|
|
1328
1330
|
"open_aliases",
|
|
1329
1331
|
"standard",
|
|
1332
|
+
"_rust_walked",
|
|
1333
|
+
"_rust_begun",
|
|
1330
1334
|
)
|
|
1331
1335
|
|
|
1332
1336
|
def begin_file(self):
|
|
@@ -1593,6 +1597,9 @@ class CallResolver:
|
|
|
1593
1597
|
builder.rust_mods, files
|
|
1594
1598
|
)
|
|
1595
1599
|
self._importing = set() # (scope ID, name) of the Rust `use`s being read
|
|
1600
|
+
self._rust_cuts = 0 # times a Rust cycle guard stopped a walk
|
|
1601
|
+
self._rust_walked = {} # see _rust_keep
|
|
1602
|
+
self._rust_begun = [] # see _rust_recall
|
|
1596
1603
|
# A module is importable by its path below its topmost package and,
|
|
1597
1604
|
# through namespace packages, by any longer path no other module owns.
|
|
1598
1605
|
for top, parts, file_id in py_files:
|
|
@@ -2104,10 +2111,11 @@ class CallResolver:
|
|
|
2104
2111
|
elif (
|
|
2105
2112
|
verdict == (None, _EXTERNAL)
|
|
2106
2113
|
and self._path_call
|
|
2114
|
+
and (split := _split_callee(callee))[0]
|
|
2107
2115
|
and (owner := self._receiver_type())
|
|
2108
2116
|
):
|
|
2109
2117
|
# An outside trait's path: the receiver's project impl of it.
|
|
2110
|
-
path, name =
|
|
2118
|
+
path, name = split
|
|
2111
2119
|
own = [
|
|
2112
2120
|
m
|
|
2113
2121
|
for m in self._rust_trait_methods(owner, name, path[-1])
|
|
@@ -3124,7 +3132,9 @@ class CallResolver:
|
|
|
3124
3132
|
(target,),
|
|
3125
3133
|
)
|
|
3126
3134
|
found = None
|
|
3127
|
-
if (scope_id, name)
|
|
3135
|
+
if (scope_id, name) in self._importing:
|
|
3136
|
+
self._rust_cuts += 1
|
|
3137
|
+
else:
|
|
3128
3138
|
# A `use` may lead back to itself through the module tree.
|
|
3129
3139
|
self._importing.add((scope_id, name))
|
|
3130
3140
|
try:
|
|
@@ -3357,11 +3367,42 @@ class CallResolver:
|
|
|
3357
3367
|
]
|
|
3358
3368
|
return defined or found
|
|
3359
3369
|
|
|
3370
|
+
def _rust_recall(self, memo, key, seen):
|
|
3371
|
+
"""``[value]`` kept for the Rust walk through `use`s and globs for
|
|
3372
|
+
``key`` whose cycle guard holds ``seen`` (see `_rust_keep`); else
|
|
3373
|
+
None, and the walk is begun."""
|
|
3374
|
+
if key in memo:
|
|
3375
|
+
return [memo[key]]
|
|
3376
|
+
if seen and key in self._rust_walked:
|
|
3377
|
+
self._rust_cuts += 1
|
|
3378
|
+
return [self._rust_walked[key]]
|
|
3379
|
+
self._rust_begun.append((self._rust_cuts, self._rust_walked))
|
|
3380
|
+
if not seen:
|
|
3381
|
+
self._rust_walked = {}
|
|
3382
|
+
return None
|
|
3383
|
+
|
|
3384
|
+
def _rust_keep(self, memo, key, seen, found):
|
|
3385
|
+
"""``found``, what the walk `_rust_recall` began gives: kept in
|
|
3386
|
+
``memo`` for the file; where a cycle guard cut it short, only until
|
|
3387
|
+
the walk that began with no ``seen`` ends. A module that globs reach
|
|
3388
|
+
by several routes is then walked once."""
|
|
3389
|
+
cuts, outer = self._rust_begun.pop()
|
|
3390
|
+
if not seen:
|
|
3391
|
+
self._rust_walked = outer
|
|
3392
|
+
if self._rust_cuts == cuts:
|
|
3393
|
+
memo[key] = found
|
|
3394
|
+
elif seen:
|
|
3395
|
+
self._rust_walked[key] = found
|
|
3396
|
+
return found
|
|
3397
|
+
|
|
3360
3398
|
def _rust_used(self, module, segment, seen):
|
|
3361
3399
|
"""What a `use` of the Rust module ``module`` binds ``segment`` to,
|
|
3362
3400
|
a path from the module or from a crate, else what each glob `use`
|
|
3363
3401
|
of the module's own does: IDs, ``"external"`` where one leads
|
|
3364
3402
|
outside the project. ``seen`` as `_rust_path`'s."""
|
|
3403
|
+
key = (module, segment)
|
|
3404
|
+
if kept := self._rust_recall(self.rust_used, key, seen):
|
|
3405
|
+
return kept[0]
|
|
3365
3406
|
uses = self._uses(module)
|
|
3366
3407
|
alternatives = self.builder.rust_use_alternatives.get((module, segment))
|
|
3367
3408
|
written = [uses[segment]] if segment in uses else []
|
|
@@ -3376,16 +3417,18 @@ class CallResolver:
|
|
|
3376
3417
|
if segment in uses and not self._rust_rooted(target, module):
|
|
3377
3418
|
held = self._imported(segment, module)
|
|
3378
3419
|
elif self._rust_rooted(target, module):
|
|
3379
|
-
if
|
|
3380
|
-
|
|
3381
|
-
|
|
3420
|
+
if key in seen:
|
|
3421
|
+
self._rust_cuts += 1
|
|
3422
|
+
else:
|
|
3423
|
+
held = self._rust_path(target.split("::"), module, seen | {key})
|
|
3382
3424
|
else:
|
|
3383
3425
|
# A glob of another crate's module may bring the name.
|
|
3384
3426
|
held = _EXTERNAL
|
|
3385
3427
|
if held == _EXTERNAL:
|
|
3386
|
-
|
|
3428
|
+
hits = _EXTERNAL
|
|
3429
|
+
break
|
|
3387
3430
|
hits += held or []
|
|
3388
|
-
return hits
|
|
3431
|
+
return self._rust_keep(self.rust_used, key, seen, hits)
|
|
3389
3432
|
|
|
3390
3433
|
def _rust_library(self, name, scope_id):
|
|
3391
3434
|
"""The root of the library of the project crate ``name`` written in
|
|
@@ -4820,7 +4863,7 @@ class CallResolver:
|
|
|
4820
4863
|
value = self._called(member, value if len(value) > 2 else value[1])
|
|
4821
4864
|
value = value[1] if value and value[0] == "pointer" else value
|
|
4822
4865
|
continue
|
|
4823
|
-
if step == "[]" and isinstance(value, tuple):
|
|
4866
|
+
if step == "[]" and isinstance(value, tuple) and value[0] != "literal":
|
|
4824
4867
|
# A subscript gives what the type's `operator[]` returns, in
|
|
4825
4868
|
# Rust its `Index` impl's `Output`, the element an iterator
|
|
4826
4869
|
# gives where the index decides it: by the data for a
|
|
@@ -8152,17 +8195,24 @@ class CallResolver:
|
|
|
8152
8195
|
found = self.builder.rust_alias_types.get((module, name))
|
|
8153
8196
|
if found:
|
|
8154
8197
|
return module, name, _rust_declared(found)
|
|
8198
|
+
key = (module, name)
|
|
8199
|
+
if kept := self._rust_recall(self.rust_aliases, key, seen):
|
|
8200
|
+
return kept[0]
|
|
8155
8201
|
uses = self._uses(module)
|
|
8156
8202
|
written = [uses[name]] if name in uses else []
|
|
8157
8203
|
written = written or [
|
|
8158
8204
|
f"{path[:-1]}{name}" for path in uses.values() if path[-3:] == "::*"
|
|
8159
8205
|
]
|
|
8206
|
+
hit = None
|
|
8160
8207
|
for target in written:
|
|
8161
8208
|
*qualifier, leaf = target.split("::")
|
|
8162
8209
|
if qualifier and self._rust_child(module, qualifier[0]):
|
|
8163
8210
|
qualifier = ["self", *qualifier]
|
|
8164
8211
|
path = "::".join([*qualifier, leaf])
|
|
8165
|
-
if not qualifier
|
|
8212
|
+
if not qualifier:
|
|
8213
|
+
continue
|
|
8214
|
+
if (module, path) in seen:
|
|
8215
|
+
self._rust_cuts += 1
|
|
8166
8216
|
continue
|
|
8167
8217
|
if not self._rust_rooted(path, module):
|
|
8168
8218
|
continue
|
|
@@ -8170,8 +8220,10 @@ class CallResolver:
|
|
|
8170
8220
|
for scope in held if isinstance(held, list) else ():
|
|
8171
8221
|
hit = self._alias_in(scope, leaf, seen | {(module, path)})
|
|
8172
8222
|
if hit:
|
|
8173
|
-
|
|
8174
|
-
|
|
8223
|
+
break
|
|
8224
|
+
if hit:
|
|
8225
|
+
break
|
|
8226
|
+
return self._rust_keep(self.rust_aliases, key, seen, hit)
|
|
8175
8227
|
|
|
8176
8228
|
def _alias_value(self, alias, written, scope_id, receiver):
|
|
8177
8229
|
"""Value of the type ``written`` in ``scope_id`` that names the Rust
|
|
@@ -50,7 +50,7 @@ _RUST_STRING_LET_RE = re.compile(
|
|
|
50
50
|
|
|
51
51
|
_RUST_CONST_RE = re.compile(
|
|
52
52
|
r"\b(?:const|static)\s+(?:mut\s+)?(?P<name>[A-Z][A-Z0-9_]*)\s*:\s*"
|
|
53
|
-
r"(?P<type>[^=;()
|
|
53
|
+
r"(?P<type>[^=;().#]+?)\s*="
|
|
54
54
|
)
|
|
55
55
|
|
|
56
56
|
|
|
@@ -1960,6 +1960,10 @@ class RustParser(BaseParser):
|
|
|
1960
1960
|
# with its arguments.
|
|
1961
1961
|
typed = re.fullmatch(r"(\w+)::<(.+)>::(\w+)", callee)
|
|
1962
1962
|
typed = typed and f"{typed[1]}<{typed[2]}>.{typed[3]}"
|
|
1963
|
+
# `<Self>::f` is `Self::f`.
|
|
1964
|
+
closed = callee[:1] == "<" and _angle_end(callee, 0)
|
|
1965
|
+
if closed and callee[closed + 1 : closed + 3] == "::":
|
|
1966
|
+
callee = callee[1:closed] + callee[closed + 1 :]
|
|
1963
1967
|
# `parse::<T>` calls `parse`; the type arguments are the
|
|
1964
1968
|
# call site's, not part of the callee's name.
|
|
1965
1969
|
callee = _strip_generics(callee)
|
|
@@ -21,45 +21,80 @@ from descry.generate import CodeGraphBuilder
|
|
|
21
21
|
|
|
22
22
|
_GO_FIELD = next(r for r in go_parser._DECLARATIONS if "(?!(?:return" in r.pattern)
|
|
23
23
|
|
|
24
|
-
# 3,000 characters took seconds to minutes where the time was cubic, and
|
|
25
|
-
# 20,000 seconds where it was quadratic; each now takes milliseconds.
|
|
26
|
-
_RUN = " " * 3000
|
|
27
|
-
_LONG_RUN = " " * 20000
|
|
28
24
|
|
|
25
|
+
def _seconds(run):
|
|
26
|
+
"""The least CPU time of three calls of `run`."""
|
|
27
|
+
|
|
28
|
+
def once():
|
|
29
|
+
start = time.process_time()
|
|
30
|
+
run()
|
|
31
|
+
return time.process_time() - start
|
|
32
|
+
|
|
33
|
+
return min(once() for _ in range(3))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def assert_linear(run, n):
|
|
37
|
+
"""`run(n)` takes under ten times the CPU time of `run(n // 4)`: time
|
|
38
|
+
linear in `n` gives four times, quadratic sixteen."""
|
|
39
|
+
quarter = _seconds(lambda: run(n // 4))
|
|
40
|
+
assert _seconds(lambda: run(n)) < 10 * max(quarter, 0.05)
|
|
29
41
|
|
|
42
|
+
|
|
43
|
+
# 3,000 characters took seconds to minutes where the time was cubic, and
|
|
44
|
+
# 20,000 seconds where it was quadratic.
|
|
30
45
|
@pytest.mark.parametrize(
|
|
31
|
-
("find", "text"),
|
|
46
|
+
("find", "text", "length"),
|
|
32
47
|
[
|
|
33
|
-
(_RE_LOCAL_FUNCTION.match,
|
|
34
|
-
(DartParser.binding_re.search, "const" +
|
|
35
|
-
(java_parser._RE_METHOD.match, "final" +
|
|
36
|
-
(java_parser._RE_FIELD.match, "final" +
|
|
37
|
-
(ts_parser._TS_IMPORT_RE.findall, "import" +
|
|
38
|
-
(rust_parser._RUST_ARM_RE.search,
|
|
39
|
-
(java_parser._RE_METHOD.match, "public <T>" +
|
|
40
|
-
(java_parser._RE_METHOD.match, "public @A" +
|
|
41
|
-
(java_parser._RE_ENUM_CONSTANT.match, "A" +
|
|
42
|
-
(rust_parser._RUST_BINDER_RES[1].findall, "for" +
|
|
43
|
-
(rust_parser._RUST_FOR_RE.search, " for" +
|
|
44
|
-
(rust_parser._RUST_IF_LET_RE.search, "while let" +
|
|
45
|
-
(rust_parser._RUST_MATCH_RE.search, "match" +
|
|
46
|
-
(ruby_parser._RE_INLINE_BODY.match, "x" + "\r\n" *
|
|
47
|
-
(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
(
|
|
58
|
-
(
|
|
59
|
-
(
|
|
60
|
-
(
|
|
61
|
-
(
|
|
62
|
-
|
|
48
|
+
(_RE_LOCAL_FUNCTION.match, lambda n: " " * n + "!", 3000),
|
|
49
|
+
(DartParser.binding_re.search, lambda n: "const" + " " * n, 3000),
|
|
50
|
+
(java_parser._RE_METHOD.match, lambda n: "final" + " " * n, 3000),
|
|
51
|
+
(java_parser._RE_FIELD.match, lambda n: "final" + " " * n, 3000),
|
|
52
|
+
(ts_parser._TS_IMPORT_RE.findall, lambda n: "import" + " " * n + "x;\n", 3000),
|
|
53
|
+
(rust_parser._RUST_ARM_RE.search, lambda n: " " * n + "!", 3000),
|
|
54
|
+
(java_parser._RE_METHOD.match, lambda n: "public <T>" + " " * n, 3000),
|
|
55
|
+
(java_parser._RE_METHOD.match, lambda n: "public @A" + " " * n, 3000),
|
|
56
|
+
(java_parser._RE_ENUM_CONSTANT.match, lambda n: "A" + " " * n + ")", 3000),
|
|
57
|
+
(rust_parser._RUST_BINDER_RES[1].findall, lambda n: "for" + " " * n, 3000),
|
|
58
|
+
(rust_parser._RUST_FOR_RE.search, lambda n: " for" + " " * n + "x", 3000),
|
|
59
|
+
(rust_parser._RUST_IF_LET_RE.search, lambda n: "while let" + " " * n, 3000),
|
|
60
|
+
(rust_parser._RUST_MATCH_RE.search, lambda n: "match" + " " * n + "a b", 3000),
|
|
61
|
+
(ruby_parser._RE_INLINE_BODY.match, lambda n: "x" + "\r\n" * n + ")", 1500),
|
|
62
|
+
(
|
|
63
|
+
dotnet_parser._RE_MEMBER.match,
|
|
64
|
+
lambda n: "partial unsafe" + " " * n + ")",
|
|
65
|
+
20000,
|
|
66
|
+
),
|
|
67
|
+
(
|
|
68
|
+
dotnet_parser._RE_PARAMETER.search,
|
|
69
|
+
lambda n: "scoped readonly" + " " * n + "x;",
|
|
70
|
+
20000,
|
|
71
|
+
),
|
|
72
|
+
(_GO_FIELD.search, lambda n: " chan a" + " " * n + "x(", 20000),
|
|
73
|
+
(ruby_parser._RE_ALIAS.search, lambda n: "alias" + " " * n + ")", 20000),
|
|
74
|
+
(ruby_parser._RE_MIXIN.match, lambda n: " prepend" + " " * n + "=", 20000),
|
|
75
|
+
(_RE_TYPE.fullmatch, lambda n: " " * n + ")", 20000),
|
|
76
|
+
(
|
|
77
|
+
java_parser._RE_METHOD.match,
|
|
78
|
+
lambda n: "private final a" + " " * n + "b",
|
|
79
|
+
20000,
|
|
80
|
+
),
|
|
81
|
+
(
|
|
82
|
+
java_parser._RE_FIELD.match,
|
|
83
|
+
lambda n: "public static a" + " " * n + "b(",
|
|
84
|
+
20000,
|
|
85
|
+
),
|
|
86
|
+
(ruby_parser._RE_ENDLESS.match, lambda n: " " * n + "x", 60000),
|
|
87
|
+
(ruby_parser._RE_INLINE_BODY.match, lambda n: "end" + "\n" * n + "x", 60000),
|
|
88
|
+
(dotnet_parser._RE_PRIMARY_CONSTRUCTOR.match, lambda n: " " * n + "x", 60000),
|
|
89
|
+
(
|
|
90
|
+
dotnet_parser._RE_PARAMETER.findall,
|
|
91
|
+
lambda n: "readonly" + "\t\n " * n + ")",
|
|
92
|
+
20000,
|
|
93
|
+
),
|
|
94
|
+
(_RE_CLOSURE.findall, lambda n: "\n" * n, 60000),
|
|
95
|
+
(ts_parser._TS_IMPORT_RE.findall, lambda n: "\n" * n, 60000),
|
|
96
|
+
(ts_parser._TS_DEFAULT_EXPORT_RE.findall, lambda n: "\u2028" * n, 60000),
|
|
97
|
+
(rust_parser._RUST_USE_RE.findall, lambda n: "\n" * n, 60000),
|
|
63
98
|
],
|
|
64
99
|
ids=[
|
|
65
100
|
"dart-local-function",
|
|
@@ -94,34 +129,30 @@ _LONG_RUN = " " * 20000
|
|
|
94
129
|
"rust-use-blank-lines",
|
|
95
130
|
],
|
|
96
131
|
)
|
|
97
|
-
def test_a_whitespace_run_is_taken_once(find, text):
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
find(text)
|
|
101
|
-
|
|
102
|
-
assert time.process_time() - start < 1
|
|
132
|
+
def test_a_whitespace_run_is_taken_once(find, text, length):
|
|
133
|
+
assert_linear(lambda n: find(text(n)), length)
|
|
103
134
|
|
|
104
135
|
|
|
105
136
|
@pytest.mark.parametrize(
|
|
106
137
|
("name", "source", "count"),
|
|
107
138
|
[
|
|
108
|
-
("m.js", lambda n: "const b = { a: g() };\n" * n,
|
|
109
|
-
("m.js", lambda n: "let b = 1;\n" + "b = g();\nb.x();\n" * n,
|
|
139
|
+
("m.js", lambda n: "const b = { a: g() };\n" * n, 10000),
|
|
140
|
+
("m.js", lambda n: "let b = 1;\n" + "b = g();\nb.x();\n" * n, 5000),
|
|
110
141
|
(
|
|
111
142
|
"m.js",
|
|
112
143
|
lambda n: (
|
|
113
144
|
"function f(xs) {\n" + " for (const x of xs) { x.a(); }\n" * n + "}\n"
|
|
114
145
|
),
|
|
115
|
-
|
|
146
|
+
7500,
|
|
116
147
|
),
|
|
117
|
-
("m.rb", lambda n: "b = 2\n" * n,
|
|
118
|
-
("m.rb", lambda n: "a = []\n" + "a <<-b\n" * n,
|
|
119
|
-
("m.dart", lambda n: "void main() {\n" + " var b = 2;\n" * n + "}\n",
|
|
120
|
-
("m.py", lambda n: "def f():\n" + " b = B()\n b.x()\n" * n,
|
|
148
|
+
("m.rb", lambda n: "b = 2\n" * n, 10000),
|
|
149
|
+
("m.rb", lambda n: "a = []\n" + "a <<-b\n" * n, 30000),
|
|
150
|
+
("m.dart", lambda n: "void main() {\n" + " var b = 2;\n" * n + "}\n", 10000),
|
|
151
|
+
("m.py", lambda n: "def f():\n" + " b = B()\n b.x()\n" * n, 10000),
|
|
121
152
|
(
|
|
122
153
|
"m.py",
|
|
123
154
|
lambda n: "def f(xs):\n" + " for x in xs:\n x.a()\n" * n,
|
|
124
|
-
|
|
155
|
+
5000,
|
|
125
156
|
),
|
|
126
157
|
(
|
|
127
158
|
"M.java",
|
|
@@ -130,7 +161,7 @@ def test_a_whitespace_run_is_taken_once(find, text):
|
|
|
130
161
|
+ " B b = new B();\n b.x();\n" * n
|
|
131
162
|
+ " }\n}\n"
|
|
132
163
|
),
|
|
133
|
-
|
|
164
|
+
5000,
|
|
134
165
|
),
|
|
135
166
|
(
|
|
136
167
|
"M.cs",
|
|
@@ -139,14 +170,14 @@ def test_a_whitespace_run_is_taken_once(find, text):
|
|
|
139
170
|
+ " var b = new B();\n b.X();\n" * n
|
|
140
171
|
+ " }\n}\n"
|
|
141
172
|
),
|
|
142
|
-
|
|
173
|
+
4000,
|
|
143
174
|
),
|
|
144
175
|
(
|
|
145
176
|
"M.cs",
|
|
146
177
|
lambda n: "".join(
|
|
147
178
|
f"class C{i} {{ int M() {{ return {i}; }} }}\n" for i in range(n)
|
|
148
179
|
),
|
|
149
|
-
|
|
180
|
+
1500,
|
|
150
181
|
),
|
|
151
182
|
(
|
|
152
183
|
"m.go",
|
|
@@ -156,7 +187,7 @@ def test_a_whitespace_run_is_taken_once(find, text):
|
|
|
156
187
|
* n
|
|
157
188
|
+ "\treturn nil\n}\n"
|
|
158
189
|
),
|
|
159
|
-
|
|
190
|
+
5000,
|
|
160
191
|
),
|
|
161
192
|
(
|
|
162
193
|
"m.php",
|
|
@@ -165,14 +196,14 @@ def test_a_whitespace_run_is_taken_once(find, text):
|
|
|
165
196
|
+ " foreach ($xs as $x) { $x->a(); }\n" * n
|
|
166
197
|
+ "}\n"
|
|
167
198
|
),
|
|
168
|
-
|
|
199
|
+
4000,
|
|
169
200
|
),
|
|
170
201
|
(
|
|
171
202
|
"src/lib.rs",
|
|
172
203
|
lambda n: "".join(
|
|
173
204
|
f"fn f{i}<T: Clone>(a: T) -> T {{ a.clone() }}\n" for i in range(n)
|
|
174
205
|
),
|
|
175
|
-
|
|
206
|
+
6000,
|
|
176
207
|
),
|
|
177
208
|
(
|
|
178
209
|
"m.js",
|
|
@@ -182,7 +213,7 @@ def test_a_whitespace_run_is_taken_once(find, text):
|
|
|
182
213
|
* n
|
|
183
214
|
+ "}\n"
|
|
184
215
|
),
|
|
185
|
-
|
|
216
|
+
2500,
|
|
186
217
|
),
|
|
187
218
|
(
|
|
188
219
|
"src/lib.rs",
|
|
@@ -191,7 +222,7 @@ def test_a_whitespace_run_is_taken_once(find, text):
|
|
|
191
222
|
+ " match v { Some(b) => b.a(), None => () }\n" * n
|
|
192
223
|
+ "}\n"
|
|
193
224
|
),
|
|
194
|
-
|
|
225
|
+
5000,
|
|
195
226
|
),
|
|
196
227
|
],
|
|
197
228
|
ids=[
|
|
@@ -216,22 +247,18 @@ def test_a_whitespace_run_is_taken_once(find, text):
|
|
|
216
247
|
def test_a_repeated_line_is_read_in_linear_time(name, source, count, tmp_path):
|
|
217
248
|
"""A line that binds a name again, loops over it, matches it, or
|
|
218
249
|
declares a type or a generic function costs the same time however many
|
|
219
|
-
came before it
|
|
220
|
-
|
|
221
|
-
is checked, so a slow machine does not fail it."""
|
|
250
|
+
came before it, where four times the lines took sixteen times as long,
|
|
251
|
+
minutes in all."""
|
|
222
252
|
|
|
223
253
|
def reading(lines):
|
|
224
254
|
root = tmp_path / str(lines)
|
|
225
255
|
(root / name).parent.mkdir(parents=True, exist_ok=True)
|
|
226
256
|
(root / name).write_text(source(lines))
|
|
227
|
-
start = time.process_time()
|
|
228
257
|
builder = CodeGraphBuilder(root)
|
|
229
258
|
builder.process_directory()
|
|
230
259
|
builder.resolve_references()
|
|
231
|
-
return time.process_time() - start
|
|
232
260
|
|
|
233
|
-
|
|
234
|
-
assert reading(count) < 8 * max(quarter, 0.05)
|
|
261
|
+
assert_linear(reading, count)
|
|
235
262
|
|
|
236
263
|
|
|
237
264
|
def test_the_patterns_still_match_source():
|
|
@@ -65,6 +65,29 @@ class TestCliNoCommand:
|
|
|
65
65
|
assert result.returncode == 1
|
|
66
66
|
|
|
67
67
|
|
|
68
|
+
class TestCliHubOutput:
|
|
69
|
+
_NAMES = (
|
|
70
|
+
"HF_HUB_DISABLE_PROGRESS_BARS",
|
|
71
|
+
"HF_HUB_VERBOSITY",
|
|
72
|
+
"TRANSFORMERS_VERBOSITY",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
@pytest.mark.parametrize("terminal", [False, True])
|
|
76
|
+
def test_scripted_use_quiets_model_loading(self, monkeypatch, terminal):
|
|
77
|
+
"""Without a terminal on stderr, model loading shows no progress bars
|
|
78
|
+
or Hub notices; a value the user set is kept."""
|
|
79
|
+
for name in self._NAMES:
|
|
80
|
+
monkeypatch.delenv(name, raising=False)
|
|
81
|
+
monkeypatch.setenv("HF_HUB_VERBOSITY", "info")
|
|
82
|
+
monkeypatch.setattr(sys.stderr, "isatty", lambda: terminal)
|
|
83
|
+
monkeypatch.setattr(sys, "argv", ["descry"])
|
|
84
|
+
with pytest.raises(SystemExit):
|
|
85
|
+
cli.main()
|
|
86
|
+
assert [os.environ.get(name) for name in self._NAMES] == (
|
|
87
|
+
[None, "info", None] if terminal else ["1", "info", "error"]
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
68
91
|
class TestCliArguments:
|
|
69
92
|
@pytest.mark.parametrize(
|
|
70
93
|
"args", [["callers", "x", "--limit", "ten"], ["search", "x", "--frob", "1"]]
|