mapFolding 0.9.5__py3-none-any.whl → 0.11.0__py3-none-any.whl

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.
@@ -1,188 +0,0 @@
1
- """
2
- Core AST Traversal and Transformation Utilities for Python Code Manipulation
3
-
4
- This module provides the foundation for traversing and modifying Python Abstract Syntax Trees (ASTs). It contains two
5
- primary classes:
6
-
7
- 1. NodeTourist: Implements the visitor pattern to traverse an AST and extract information from nodes that match specific
8
- predicates without modifying the AST.
9
-
10
- 2. NodeChanger: Extends ast.NodeTransformer to selectively transform AST nodes that match specific predicates, enabling
11
- targeted code modifications.
12
-
13
- The module also provides utilities for importing modules, loading callables from files, and parsing Python code into AST
14
- structures, creating a complete workflow for code analysis and transformation.
15
- """
16
-
17
- from collections.abc import Callable
18
- from inspect import getsource as inspect_getsource
19
- from mapFolding.someAssemblyRequired import ast_Identifier, str_nameDOTname
20
- from os import PathLike
21
- from pathlib import Path, PurePath
22
- from types import ModuleType
23
- from typing import Any, Literal
24
- import ast
25
- import importlib
26
- import importlib.util
27
-
28
- # TODO Identify the logic that narrows the type and can help the user during static type checking.
29
-
30
- class NodeTourist(ast.NodeVisitor):
31
- """
32
- Visit and extract information from AST nodes that match a predicate.
33
-
34
- NodeTourist implements the visitor pattern to traverse an AST, applying a predicate function to each node and
35
- capturing nodes or their attributes when they match. Unlike NodeChanger, it doesn't modify the AST but collects
36
- information during traversal.
37
-
38
- This class is particularly useful for analyzing AST structures, extracting specific nodes or node properties, and
39
- gathering information about code patterns.
40
- """
41
- def __init__(self, findThis: Callable[..., Any], doThat: Callable[..., Any]) -> None:
42
- self.findThis = findThis
43
- self.doThat = doThat
44
- self.nodeCaptured: Any | None = None
45
-
46
- def visit(self, node: ast.AST) -> None:
47
- if self.findThis(node):
48
- nodeActionReturn = self.doThat(node)
49
- if nodeActionReturn is not None:
50
- self.nodeCaptured = nodeActionReturn
51
- self.generic_visit(node)
52
-
53
- def captureLastMatch(self, node: ast.AST) -> Any | None:
54
- self.nodeCaptured = None
55
- self.visit(node)
56
- return self.nodeCaptured
57
-
58
- class NodeChanger(ast.NodeTransformer):
59
- """
60
- Transform AST nodes that match a predicate by applying a transformation function.
61
-
62
- NodeChanger is an AST node transformer that applies a targeted transformation to nodes matching a specific
63
- predicate. It traverses the AST and only modifies nodes that satisfy the predicate condition, leaving other nodes
64
- unchanged.
65
-
66
- This class extends ast.NodeTransformer and implements the visitor pattern to systematically process and transform an
67
- AST tree.
68
- """
69
- def __init__(self, findThis: Callable[..., Any], doThat: Callable[..., Any]) -> None:
70
- self.findThis = findThis
71
- self.doThat = doThat
72
-
73
- def visit(self, node: ast.AST) -> ast.AST:
74
- if self.findThis(node):
75
- return self.doThat(node)
76
- return super().visit(node)
77
-
78
- def importLogicalPath2Callable(logicalPathModule: str_nameDOTname, identifier: ast_Identifier, packageIdentifierIfRelative: ast_Identifier | None = None) -> Callable[..., Any]:
79
- """
80
- Import a callable object (function or class) from a module based on its logical path.
81
-
82
- This function imports a module using `importlib.import_module()` and then retrieves a specific attribute (function,
83
- class, or other object) from that module.
84
-
85
- Parameters
86
- ----------
87
- logicalPathModule
88
- The logical path to the module, using dot notation (e.g., 'package.subpackage.module').
89
- identifier
90
- The name of the callable object to retrieve from the module.
91
- packageIdentifierIfRelative : None
92
- The package name to use as the anchor point if `logicalPathModule` is a relative import. If None, absolute
93
- import is assumed.
94
-
95
- Returns
96
- -------
97
- Callable[..., Any]
98
- The callable object (function, class, etc.) retrieved from the module.
99
- """
100
- moduleImported: ModuleType = importlib.import_module(logicalPathModule, packageIdentifierIfRelative)
101
- return getattr(moduleImported, identifier)
102
-
103
- def importPathFilename2Callable(pathFilename: PathLike[Any] | PurePath, identifier: ast_Identifier, moduleIdentifier: ast_Identifier | None = None) -> Callable[..., Any]:
104
- """
105
- Load a callable (function, class, etc.) from a Python file.
106
-
107
- This function imports a specified Python file as a module, extracts a callable object from it by name, and returns
108
- that callable.
109
-
110
- Parameters
111
- ----------
112
- pathFilename
113
- Path to the Python file to import.
114
- identifier
115
- Name of the callable to extract from the imported module.
116
- moduleIdentifier
117
- Name to use for the imported module. If None, the filename stem is used.
118
-
119
- Returns
120
- -------
121
- Callable[..., Any]
122
- The callable object extracted from the imported module.
123
-
124
- Raises
125
- ------
126
- ImportError
127
- If the file cannot be imported or the importlib specification is invalid.
128
- AttributeError
129
- If the identifier does not exist in the imported module.
130
- """
131
- pathFilename = Path(pathFilename)
132
-
133
- importlibSpecification = importlib.util.spec_from_file_location(moduleIdentifier or pathFilename.stem, pathFilename)
134
- if importlibSpecification is None or importlibSpecification.loader is None: raise ImportError(f"I received\n\t`{pathFilename = }`,\n\t`{identifier = }`, and\n\t`{moduleIdentifier = }`.\n\tAfter loading, \n\t`importlibSpecification` {'is `None`' if importlibSpecification is None else 'has a value'} and\n\t`importlibSpecification.loader` is unknown.")
135
-
136
- moduleImported_jk_hahaha: ModuleType = importlib.util.module_from_spec(importlibSpecification)
137
- importlibSpecification.loader.exec_module(moduleImported_jk_hahaha)
138
- return getattr(moduleImported_jk_hahaha, identifier)
139
-
140
- def parseLogicalPath2astModule(logicalPathModule: str_nameDOTname, packageIdentifierIfRelative: ast_Identifier | None = None, mode: Literal['exec'] = 'exec') -> ast.Module:
141
- """
142
- Parse a logical Python module path into an `ast.Module`.
143
-
144
- This function imports a module using its logical path (e.g., 'package.subpackage.module') and converts its source
145
- code into an Abstract Syntax Tree (AST) Module object.
146
-
147
- Parameters
148
- ----------
149
- logicalPathModule
150
- The logical path to the module using dot notation (e.g., 'package.module').
151
- packageIdentifierIfRelative : None
152
- The package identifier to use if the module path is relative, defaults to None.
153
- mode : Literal['exec']
154
- The mode parameter for `ast.parse`. Default is `Literal['exec']`. Options are `Literal['exec']`, `"exec"` (which
155
- is _not_ the same as `Literal['exec']`), `Literal['eval']`, `Literal['func_type']`, `Literal['single']`. See
156
- `ast.parse` documentation for some details and much confusion.
157
-
158
- Returns
159
- -------
160
- astModule
161
- An AST Module object representing the parsed source code of the imported module.
162
- """
163
- moduleImported: ModuleType = importlib.import_module(logicalPathModule, packageIdentifierIfRelative)
164
- sourcePython: str = inspect_getsource(moduleImported)
165
- return ast.parse(sourcePython, mode)
166
-
167
- def parsePathFilename2astModule(pathFilename: PathLike[Any] | PurePath, mode: Literal['exec'] = 'exec') -> ast.Module:
168
- """
169
- Parse a file from a given path into an `ast.Module`.
170
-
171
- This function reads the content of a file specified by `pathFilename` and parses it into an Abstract Syntax Tree
172
- (AST) Module using Python's ast module.
173
-
174
- Parameters
175
- ----------
176
- pathFilename
177
- The path to the file to be parsed. Can be a string path, PathLike object, or PurePath object.
178
- mode : Literal['exec']
179
- The mode parameter for `ast.parse`. Default is `Literal['exec']`. Options are `Literal['exec']`, `"exec"` (which
180
- is _not_ the same as `Literal['exec']`), `Literal['eval']`, `Literal['func_type']`, `Literal['single']`. See
181
- `ast.parse` documentation for some details and much confusion.
182
-
183
- Returns
184
- -------
185
- astModule
186
- The parsed abstract syntax tree module.
187
- """
188
- return ast.parse(Path(pathFilename).read_text(), mode)