Skip to content

Commit 821300d

Browse files
committed
feat: Add wildcard_imported boolean attribute to aliases, deprecate on_wildcard_expansion event
Extensions can now hook onto `on_alias` instead, and check the `wildcard_imported` property of aliases.
1 parent d3e50db commit 821300d

File tree

5 files changed

+39
-20
lines changed

5 files changed

+39
-20
lines changed

docs/guide/users/extending.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,6 @@ There are also specific **load events** for each object kind:
208208
- [`on_alias`][griffe.Extension.on_alias]: The "on alias" event is triggered on aliases (imported/inherited objects).
209209
- [`on_package`][griffe.Extension.on_package]: The "on package" event is triggered on top-level modules (packages) only.
210210

211-
And a special **load event** for wildcard expansion:
212-
213-
- [`on_wildcard_expansion`][griffe.Extension.on_wildcard_expansion]: The "on wildcard expansion" event is triggered for each alias that is created by expanding wildcard imports (`from ... import *`).
214-
215211
#### Analysis events
216212

217213
**Analysis events** are triggered while modules are being scanned (with static or dynamic analysis). Data is incomplete when these events are triggered, so we recommend only hooking onto these events if you know what you are doing. In doubt, prefer using **load events** above.

src/griffe/_internal/extensions/base.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ def __new__(cls, name: str, bases: tuple[type, ...], attrs: dict[str, Any]) -> _
5050
DeprecationWarning,
5151
stacklevel=1,
5252
)
53+
if "on_wildcard_expansion" in attrs:
54+
warnings.warn(
55+
"The `on_wildcard_expansion` event is deprecated. "
56+
"Instead, hook onto the `on_alias` event "
57+
"and check for aliases' `wildcard_imported` boolean attribute.",
58+
DeprecationWarning,
59+
stacklevel=2,
60+
)
5361
return super().__new__(cls, name, bases, attrs)
5462

5563

@@ -465,21 +473,6 @@ def on_package(self, *, pkg: Module, loader: GriffeLoader, **kwargs: Any) -> Non
465473
if hasattr(self, "on_package_loaded"):
466474
self.on_package_loaded(pkg=pkg, loader=loader, **kwargs)
467475

468-
def on_wildcard_expansion(
469-
self,
470-
*,
471-
alias: Alias,
472-
loader: GriffeLoader,
473-
**kwargs: Any,
474-
) -> None:
475-
"""Run when wildcard imports are expanded into aliases.
476-
477-
Parameters:
478-
alias: The alias instance.
479-
loader: The loader currently in use.
480-
**kwargs: For forward-compatibility.
481-
"""
482-
483476

484477
LoadableExtensionType = Union[str, dict[str, Any], Extension, type[Extension]]
485478
"""All the types that can be passed to `load_extensions`."""
@@ -506,6 +499,9 @@ def add(self, *extensions: Extension) -> None:
506499
for extension in extensions:
507500
self._extensions.append(extension)
508501

502+
def _noop(self, **kwargs: Any) -> None:
503+
"""No-op method for extension hooks."""
504+
509505
def call(self, event: str, **kwargs: Any) -> None:
510506
"""Call the extension hook for the given event.
511507
@@ -519,7 +515,7 @@ def call(self, event: str, **kwargs: Any) -> None:
519515
with suppress(TypeError):
520516
getattr(extension, event)(**kwargs)
521517
else:
522-
getattr(extension, event)(**kwargs)
518+
getattr(extension, event, self._noop)(**kwargs)
523519

524520

525521
builtin_extensions: set[str] = {

src/griffe/_internal/loader.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,7 @@ def expand_wildcards(
417417
lineno=alias_lineno,
418418
endlineno=alias_endlineno,
419419
parent=obj, # type: ignore[arg-type]
420+
wildcard_imported=True,
420421
)
421422
# Special case: we avoid overwriting a submodule with an alias.
422423
# Griffe suffers from this limitation where an object cannot store both
@@ -431,6 +432,7 @@ def expand_wildcards(
431432

432433
# Everything went right (supposedly), we add the alias as a member of the current object.
433434
obj.set_member(new_member.name, alias)
435+
# YORE: Bump 2: Remove line.
434436
self.extensions.call("on_wildcard_expansion", alias=alias, loader=self)
435437

436438
def resolve_module_aliases(

src/griffe/_internal/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,7 @@ def __init__(
12921292
runtime: bool = True,
12931293
parent: Module | Class | Alias | None = None,
12941294
inherited: bool = False,
1295+
wildcard_imported: bool = False,
12951296
) -> None:
12961297
"""Initialize the alias.
12971298
@@ -1304,6 +1305,7 @@ def __init__(
13041305
runtime: Whether this alias is present at runtime or not.
13051306
parent: The alias parent.
13061307
inherited: Whether this alias wraps an inherited member.
1308+
wildcard_imported: Whether this alias was created using a wildcard import.
13071309
"""
13081310
self.name: str = name
13091311
"""The alias name."""
@@ -1320,6 +1322,9 @@ def __init__(
13201322
self.inherited: bool = inherited
13211323
"""Whether this alias represents an inherited member."""
13221324

1325+
self.wildcard_imported: bool = wildcard_imported
1326+
"""Whether this alias was created using a wildcard import."""
1327+
13231328
self.public: bool | None = None
13241329
"""Whether this alias is public."""
13251330

tests/test_extensions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,23 @@ def on_package_loaded(self, *, pkg: Module, loader: GriffeLoader, **kwargs: Any)
252252
with temporary_visited_package("pkg", {}, extensions=load_extensions(extension)):
253253
assert extension.records == ["called as on_package"]
254254

255+
256+
# YORE: Bump 2: Remove block.
257+
def test_deprecated_on_wildcard_expansion_event() -> None:
258+
"""Hook still runs, a deprecation warning is emitted when the class is declared."""
259+
with pytest.warns(DeprecationWarning, match="`on_wildcard_expansion` event is deprecated"):
260+
261+
class Ext(Extension):
262+
def __init__(self) -> None:
263+
self.records: list[str] = []
264+
265+
def on_wildcard_expansion(self, *, alias: Alias, loader: GriffeLoader, **kwargs: Any) -> None: # noqa: ARG002
266+
self.records.append("called as on_wildcard_expansion")
267+
268+
extension = Ext()
269+
with temporary_visited_package(
270+
"pkg",
271+
{"__init__.py": "from pkg.module import *", "module.py": "def func(): ..."},
272+
extensions=load_extensions(extension),
273+
):
274+
assert extension.records == ["called as on_wildcard_expansion"]

0 commit comments

Comments
 (0)