tristanlatr / astuce

AST inference utilities
GNU Lesser General Public License v2.1
1 stars 0 forks source link

Terminology #5

Open tristanlatr opened 2 years ago

tristanlatr commented 2 years ago

This is some notes that I've taken while trying to understand everything that happens in astroid. These definitions should not be taken for cash, it's only my current understanding of the different practices/concepts related to AST semantical analysis. It can discussed here such that we have a common understanding and better communication.

Frame nodes: (ast.Module, ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef, ast.Lambda) Scoped nodes: All frame nodes are scoped nodes, with the following addition: (ast.GeneratorExp, ast.DictComp, ast.SetComp, ast.ListComp). The scope nodes have the particularity that that may contain assignments, they are therefore given a 'locals' dictionary. This dictionary keys are strings and values are nodes of types: ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef, alias, arg, Name (with Store context) that represents a assignment to the name in the given scope.

Looking-up: Looking up is the action of determining where a given name is being assigned, excluding ignorable statements. Lookups happens at the module scope (starting by the first scoped node enclosing the context in which we are doing the lookup), it does not return nodes outside of the current ast.Module and does not use the inference logic. Nonetheless it uses complex navigational features to reason about brach reachability for the specific node context, (filter_statements.py).

Inference: Inference is the action to statically evaluate an AST node into another object (in our case also represented by AST node subclasses) that express the runtime behaviour of the original node. It uses the lookup logic as well as bunch of additional complex reasoning. To infer stuff like:

i = (3,4)
a,b, (c,d) = (1,2,i)
e = b + c
assert e==5

We might also also include higher level methods to infer the value of a given name in the context of a scoped node. Would be used to infer __all__ variable on ast.Module instances. It should not use the name resolving logic.

Name resolving: Resolving a name is the action of looking it up in the current scope and expand this name to it's full dotted name. Name resolving is is charge to follow aliases, look for the definition node of an imported name in the parsed modules, etc. The name resolving logic uses the inference logic, namely for aliases. Name resolving is a very high level API and should probably not be used internally in the package. It would be useful to make the bridge in between the word of AST and the word of the objects of the client library.

Tell me what you think @pawamoy