Skip to content

Commit 1aa3f01

Browse files
committed
Add early transforms before handling delayed assattr nodes
When importing Gtk, it looks like this: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk It is vital that gi.require_version() is made before related 'from gi.repository import ...'. The brain_gi tries to do that using transforms. And it works unless Gtk is imported as part of delayed assattr handling. Fix this by adding early transforms that are called before delayed assattr. Fixes #2190 Fixes pylint-dev/pylint#6352
1 parent 453d307 commit 1aa3f01

File tree

4 files changed

+24
-1
lines changed

4 files changed

+24
-1
lines changed

astroid/brain/brain_gi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,6 @@ def _register_require_version(node):
245245

246246
def register(manager: AstroidManager) -> None:
247247
manager.register_failed_import_hook(_import_gi_module)
248-
manager.register_transform(
248+
manager.register_early_transform(
249249
nodes.Call, _register_require_version, _looks_like_require_version
250250
)

astroid/builder.py

+4
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ def _post_build(
164164
for symbol, _ in from_node.names:
165165
module.future_imports.add(symbol)
166166
self.add_from_names_to_locals(from_node)
167+
# Visit the transforms
168+
if self._apply_transforms:
169+
module = self._manager.visit_early_transforms(module)
170+
167171
# handle delayed assattr nodes
168172
for delayed in builder._delayed_assattr:
169173
self.delayed_assattr(delayed)

astroid/manager.py

+18
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class AstroidManager:
6262
"extension_package_whitelist": set(),
6363
"module_denylist": set(),
6464
"_transform": TransformVisitor(),
65+
"_early_transform": TransformVisitor(),
6566
"prefer_stubs": False,
6667
}
6768

@@ -75,6 +76,7 @@ def __init__(self) -> None:
7576
]
7677
self.module_denylist = AstroidManager.brain["module_denylist"]
7778
self._transform = AstroidManager.brain["_transform"]
79+
self._early_transform = AstroidManager.brain["_early_transform"]
7880
self.prefer_stubs = AstroidManager.brain["prefer_stubs"]
7981

8082
@property
@@ -110,6 +112,15 @@ def register_transform(self):
110112
def unregister_transform(self):
111113
return self._transform.unregister_transform
112114

115+
@property
116+
def register_early_transform(self):
117+
# This and unregister_early_transform below are exported for convenience
118+
return self._early_transform.register_transform
119+
120+
@property
121+
def unregister_early_transform(self):
122+
return self._early_transform.unregister_transform
123+
113124
@property
114125
def builtins_module(self) -> nodes.Module:
115126
return self.astroid_cache["builtins"]
@@ -126,6 +137,10 @@ def visit_transforms(self, node: nodes.NodeNG) -> InferenceResult:
126137
"""Visit the transforms and apply them to the given *node*."""
127138
return self._transform.visit(node)
128139

140+
def visit_early_transforms(self, node: nodes.NodeNG) -> InferenceResult:
141+
"""Visit the early transforms and apply them to the given *node*."""
142+
return self._early_transform.visit(node)
143+
129144
def ast_from_file(
130145
self,
131146
filepath: str,
@@ -466,6 +481,9 @@ def clear_cache(self) -> None:
466481
self.astroid_cache.clear()
467482
# NB: not a new TransformVisitor()
468483
AstroidManager.brain["_transform"].transforms = collections.defaultdict(list)
484+
AstroidManager.brain["_early_transform"].transforms = collections.defaultdict(
485+
list
486+
)
469487

470488
for lru_cache in (
471489
LookupMixIn.lookup,

astroid/test_utils.py

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def brainless_manager():
7373
m.astroid_cache = {}
7474
m._mod_file_cache = {}
7575
m._transform = transforms.TransformVisitor()
76+
m._early_transform = transforms.TransformVisitor()
7677
m.extension_package_whitelist = set()
7778
m.module_denylist = set()
7879
return m

0 commit comments

Comments
 (0)