Repository navigation
feat: type what an object gives by attribute or item with a Members model - #159
Merged
Merged
Conversation
A module-level name denotes what its value denotes in a function body: an alias, an attribute, an item or a call of an import or of an earlier module-level name, resolved in statement order.
…odel Symbol resolution reads the Members models the engine provides as the semantic.members input, so SymbolAnalysis now depends on MembersAnalysis besides scopes and imports.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A
Members(symbol, dynamic=None, defined=(), typed=())model says what the attributes and items of a class's instances give. With it, every path to a pymongo collection denotesCollection, so one sink onCollection.findcovers all of these:client.shop.users.find;client["shop"]["users"].find;client.get_database("shop").get_collection("users").find;db = client.shop;Collection;Closes #157. The pymongo models of CoreTrace-Entreprise/coretrace-python-analyzer-plugins#3 will use it.
Stacked on #156. Merge #156 first; this PR then shows only its own two commits.
Design
Membersis insemantic/symbols.py, next to the symbol resolution it drives. It is exported with the other models fromcoretrace_python.taint.typedwins;definedkeeps the class's own attributes on their path;dynamic;dynamic, an item keeps its container's symbol, as before.SymbolTable.attribute(symbol, name)andSymbolTable.item(symbol)are the only place where attributes and items derive symbols. That covers function bodies (derive_symbols), module-level names (_denoted), attribute chains lowered to oneSymbol(ir/lowering.py), attributes inherited from an external base, and names resolved throughresolve_expression.semantic.membersinput (MembersAnalysis). On its own it is empty, likeinterprocedural.clearing. The engine provides it wherever it provides the security models: single-file checks, project analyses and parallel workers.definedis normalised to a sorted tuple.repr(models)is part of the cache key, and a set's order changes between processes.Changed expectation
test_transitive_dependencies_are_exposednow listsMembersAnalysisamong the dependencies ofSymbolAnalysis, because symbol resolution reads the models. The test still checks the transitive closure.Tests
tests/test_members.pyuses a fakedocstorelibrary, so the engine stays free of pymongo knowledge. It covers:definedattribute, and a method called on what a member method returns;NOSQLsink onCollection.find, reached through every path;defined;jobs=2. A mutation check confirms that each of these two provisioning paths is needed.Local results:
ruff checkandmypyreport nothing.