Python Analyzers
The PythonAstAnalyzer
can be used to analyze Python source code
files. An lxml.etree.Element
representation of each file's abstract
syntax tree (AST) is passed to its FeatureFinders
for analysis:
codesurvey.analyzers.python.PythonAstAnalyzer
Bases: FileAnalyzer[Element]
Analyzer that finds .py files and parses them into lxml documents representing Python abstract syntax trees for feature analysis.
Source code in codesurvey/analyzers/python/core.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
|
default_file_glob = '**/*.py'
class-attribute
instance-attribute
default_file_filters = [py_site_packages_filter]
class-attribute
instance-attribute
Excludes files under a site-packages
directory that are unlikely
to belong to the Repo under analysis.
__init__(feature_finders: Sequence[FeatureFinder], *, file_glob: Optional[str] = None, file_filters: Optional[Sequence[Callable[[FileInfo], bool]]] = None, name: Optional[str] = None)
Parameters:
-
feature_finders
(
Sequence[FeatureFinder]
) –The FeatureFinders for analyzing each source-code file.
-
file_glob
(
Optional[str]
, default:None
) –Glob pattern for finding source-code files within the Repo.
-
file_filters
(
Optional[Sequence[Callable[[FileInfo], bool]]]
, default:None
) –Filters to identify files to exclude from analysis. Each filter is a function that takes a
FileInfo
and returnsTrue
if the file should be excluded. file_filters cannot be lambdas, as they need to be pickled when passed to sub-processes. -
name
(
Optional[str]
, default:None
) –Name to identify the Analyzer. If
None
, defaults to the Analyzer type's default_name.
Source code in codesurvey/analyzers/core.py
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
|
test(code_snippet: str, *, test_filename: str = 'test_file.txt') -> Dict[str, Feature]
Utility for directly analyzing a string of source-code.
A Repo will be created in a temporary directory to perform
analysis of a file created with the given code_snippet
.
Parameters:
-
code_snippet
(
str
) –String of source-code to analyze.
-
test_filename
(
str
, default:'test_file.txt'
) –Optional custom filename used for the test file.
Returns:
Source code in codesurvey/analyzers/core.py
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 |
|
Built-In Feature Finders
CodeSurvey comes equipped with the following FeatureFinders
that can
be used with PythonAstAnalyzer
:
has_for_else
FeatureFinder for else clauses in for loops.
Source code in codesurvey/analyzers/python/features.py
129 130 131 132 133 134 |
|
has_try_finally
FeatureFinder for finally clauses in try statements.
Source code in codesurvey/analyzers/python/features.py
138 139 140 141 142 143 |
|
has_type_hint
FeatureFinder for type hints.
Source code in codesurvey/analyzers/python/features.py
147 148 149 150 151 152 |
|
has_set_function
FeatureFinder for the set function.
Source code in codesurvey/analyzers/python/features.py
156 157 158 159 160 161 |
|
has_set_value = py_ast_feature_finder('set_value', xpath='Set')
module-attribute
FeatureFinder for set literals.
has_set = union_feature_finder('set', [has_set_function, has_set_value])
module-attribute
FeatureFinder for sets.
has_fstring = py_ast_feature_finder('fstring', xpath='FormattedValue')
module-attribute
FeatureFinder for f-strings.
has_ternary = py_ast_feature_finder('ternary', xpath='IfExp')
module-attribute
FeatureFinder for ternary expressions.
has_pattern_matching = py_ast_feature_finder('pattern_matching', xpath='Match')
module-attribute
FeatureFinder for pattern matching.
has_walrus = py_ast_feature_finder('walrus', xpath='NamedExpr')
module-attribute
FeatureFinder for the walrus operator.
Custom Python Feature Finders
The following utilities can be used to define simple FeatureFinders
that can be used with PythonAstAnalyzer
to analyze Python abstract
syntax trees:
codesurvey.analyzers.python.py_ast_feature_finder(name: str, *, xpath: str) -> FeatureFinder[lxml.etree.Element]
Defines a FeatureFinder that looks for elements in a Python AST matching the given xpath query.
To explore the AST structure of the code constructs you are interested in identifying, consider using a tool like: https://python-ast-explorer.com/
Source code in codesurvey/analyzers/python/features.py
36 37 38 39 40 41 42 43 44 45 |
|
codesurvey.analyzers.python.py_ast_feature_finder_with_transform(name: str, *, xpath: str) -> Callable[[ElementTransform], FeatureFinder[lxml.etree.Element]]
Decorator for defining a FeatureFinder that looks for elements in a Python AST matching the given xpath query, transforming found elements with decorated function.
The function should receive and return an lxml.etree.Element
, or
return None
if the element should not be considered an
occurrence of the feature.
Example usage to look for function calls where the function name is 'set':
@py_ast_feature_finder_with_transform('set_function', xpath='Call/func/Name')
def has_set_function(func_name_el):
if func_name_el.get('id') == 'set':
return func_name_el
return None
To explore the AST structure of the code constructs you are interested in identifying, consider using a tool like: https://python-ast-explorer.com/
Source code in codesurvey/analyzers/python/features.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
|
codesurvey.analyzers.python.py_module_feature_finder(name: str, *, modules: Sequence[str]) -> FeatureFinder
Defines a FeatureFinder that looks for import statements of one or
more target Python modules
.
Example usage:
has_dataclasses = py_module_feature_finder('dataclasses_module', modules=['dataclasses'])
Source code in codesurvey/analyzers/python/features.py
112 113 114 115 116 117 118 119 120 121 122 123 |
|