Skip to content

Commit b823639

Browse files
committed
feat: Add an is_public helper method to guess if an object is public
A `public` attribute is also added to Object and Alias, allowing extension writers to force an object to be public.
1 parent d400cb1 commit b823639

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

src/griffe/dataclasses.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ def __init__(
334334
self.aliases: dict[str, Alias] = {}
335335
self.runtime: bool = runtime
336336
self.extra: dict[str, dict[str, Any]] = defaultdict(dict)
337+
self.public: bool | None = None
337338
self._lines_collection: LinesCollection | None = lines_collection
338339
self._modules_collection: ModulesCollection | None = modules_collection
339340

@@ -761,6 +762,7 @@ def __init__(
761762
self.alias_endlineno: int | None = endlineno
762763
self.runtime: bool = runtime
763764
self.inherited: bool = inherited
765+
self.public: bool | None = None
764766
self._parent: Module | Class | Alias | None = parent
765767
self._passed_through: bool = False
766768
if isinstance(target, str):

src/griffe/mixins.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,39 @@ def is_implicitely_exported(self) -> bool:
293293
"""
294294
return self.parent.exports is None # type: ignore[attr-defined]
295295

296+
def is_public(
297+
self,
298+
*,
299+
strict: bool = False,
300+
check_name: bool = True,
301+
) -> bool:
302+
"""Whether this object is considered public.
303+
304+
In modules, developers can mark objects as public thanks to the `__all__` variable.
305+
In classes however, there is no convention or standard to do so.
306+
307+
Therefore, to decide whether an object is public, we follow this algorithm:
308+
309+
- If the object's `public` attribute is set (boolean), return its value.
310+
- In strict mode, the object is public only if it is explicitely exported (listed in `__all__`).
311+
Strict mode should only be used for module members.
312+
- Otherwise, if name checks are enabled, the object is private if its name starts with an underscore.
313+
- Otherwise, if the object is an alias, and is neither inherited from a base class,
314+
nor a member of a parent alias, it is not public.
315+
- Otherwise, the object is public.
316+
"""
317+
if self.public is not None: # type: ignore[attr-defined]
318+
return self.public # type: ignore[attr-defined]
319+
if self.is_explicitely_exported:
320+
return True
321+
if strict:
322+
return False
323+
if check_name and self.name.startswith("_"): # type: ignore[attr-defined]
324+
return False
325+
if self.is_alias and not (self.inherited or self.parent.is_alias): # type: ignore[attr-defined]
326+
return False
327+
return True
328+
296329

297330
class SerializationMixin:
298331
"""A mixin that adds de/serialization conveniences."""

0 commit comments

Comments
 (0)