Skip to content

Models¤

Griffe stores information extracted from Python source code into data models.

These models represent trees of objects, starting with modules, and containing classes, functions, attributes, and type aliases.

Modules can have submodules, classes, functions, attributes, and type aliases. Classes can have nested classes, methods, attributes, and type aliases. Functions and attributes do not have any members.

Indirections to objects declared in other modules are represented as "aliases". An alias therefore represents an imported object, and behaves almost exactly like the object it points to: it is a light wrapper around the object, with special methods and properties that allow to access the target's data transparently.

The 6 models:

Model kind enumeration¤

Kind ¤

Bases: str, Enum


              flowchart TD
              griffe.Kind[Kind]

              

              click griffe.Kind href "" "griffe.Kind"
            

Enumeration of the different object kinds.

Attributes:

ALIAS class-attribute instance-attribute ¤

ALIAS = 'alias'

Aliases (imported objects).

ATTRIBUTE class-attribute instance-attribute ¤

ATTRIBUTE = 'attribute'

Attributes and properties.

CLASS class-attribute instance-attribute ¤

CLASS = 'class'

FUNCTION class-attribute instance-attribute ¤

FUNCTION = 'function'

MODULE class-attribute instance-attribute ¤

MODULE = 'module'

TYPE_ALIAS class-attribute instance-attribute ¤

TYPE_ALIAS = 'type alias'

Model base classes¤

GetMembersMixin ¤

Mixin class to share methods for accessing members.

Methods:

__getitem__ ¤

__getitem__(key: str | Sequence[str]) -> Any

Get a member with its name or path.

This method is part of the consumer API: do not use when producing Griffe trees!

Members will be looked up in both declared members and inherited ones, triggering computation of the latter.

Parameters:

Examples:

>>> foo = griffe_object["foo"]
>>> bar = griffe_object["path.to.bar"]
>>> qux = griffe_object[("path", "to", "qux")]
Source code in src/griffe/_internal/mixins.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def __getitem__(self, key: str | Sequence[str]) -> Any:
    """Get a member with its name or path.

    This method is part of the consumer API:
    do not use when producing Griffe trees!

    Members will be looked up in both declared members and inherited ones,
    triggering computation of the latter.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> foo = griffe_object["foo"]
        >>> bar = griffe_object["path.to.bar"]
        >>> qux = griffe_object[("path", "to", "qux")]
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        return self.all_members[parts[0]]  # type: ignore[attr-defined]
    return self.all_members[parts[0]][parts[1:]]  # type: ignore[attr-defined]

get_member ¤

get_member(key: str | Sequence[str]) -> Any

Get a member with its name or path.

This method is part of the producer API: you can use it safely while building Griffe trees (for example in Griffe extensions).

Members will be looked up in declared members only, not inherited ones.

Parameters:

Examples:

>>> foo = griffe_object["foo"]
>>> bar = griffe_object["path.to.bar"]
>>> bar = griffe_object[("path", "to", "bar")]
Source code in src/griffe/_internal/mixins.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def get_member(self, key: str | Sequence[str]) -> Any:
    """Get a member with its name or path.

    This method is part of the producer API:
    you can use it safely while building Griffe trees
    (for example in Griffe extensions).

    Members will be looked up in declared members only, not inherited ones.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> foo = griffe_object["foo"]
        >>> bar = griffe_object["path.to.bar"]
        >>> bar = griffe_object[("path", "to", "bar")]
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        return self.members[parts[0]]  # type: ignore[attr-defined]
    return self.members[parts[0]].get_member(parts[1:])  # type: ignore[attr-defined]

SetMembersMixin ¤

Mixin class to share methods for setting members.

Methods:

__setitem__ ¤

__setitem__(
    key: str | Sequence[str], value: Object | Alias
) -> None

Set a member with its name or path.

This method is part of the consumer API: do not use when producing Griffe trees!

Parameters:

Examples:

>>> griffe_object["foo"] = foo
>>> griffe_object["path.to.bar"] = bar
>>> griffe_object[("path", "to", "qux")] = qux
Source code in src/griffe/_internal/mixins.py
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def __setitem__(self, key: str | Sequence[str], value: Object | Alias) -> None:
    """Set a member with its name or path.

    This method is part of the consumer API:
    do not use when producing Griffe trees!

    Parameters:
        key: The name or path of the member.
        value: The member.

    Examples:
        >>> griffe_object["foo"] = foo
        >>> griffe_object["path.to.bar"] = bar
        >>> griffe_object[("path", "to", "qux")] = qux
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        self.members[name] = value  # type: ignore[attr-defined]
        if self.is_collection:  # type: ignore[attr-defined]
            value._modules_collection = self  # type: ignore[union-attr]
        else:
            value.parent = self  # type: ignore[assignment]
    else:
        self.members[parts[0]][parts[1:]] = value  # type: ignore[attr-defined]

set_member ¤

set_member(
    key: str | Sequence[str], value: Object | Alias
) -> None

Set a member with its name or path.

This method is part of the producer API: you can use it safely while building Griffe trees (for example in Griffe extensions).

Parameters:

Examples:

>>> griffe_object.set_member("foo", foo)
>>> griffe_object.set_member("path.to.bar", bar)
>>> griffe_object.set_member(("path", "to", "qux"), qux)
Source code in src/griffe/_internal/mixins.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def set_member(self, key: str | Sequence[str], value: Object | Alias) -> None:
    """Set a member with its name or path.

    This method is part of the producer API:
    you can use it safely while building Griffe trees
    (for example in Griffe extensions).

    Parameters:
        key: The name or path of the member.
        value: The member.

    Examples:
        >>> griffe_object.set_member("foo", foo)
        >>> griffe_object.set_member("path.to.bar", bar)
        >>> griffe_object.set_member(("path", "to", "qux"), qux)
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        if name in self.members:  # type: ignore[attr-defined]
            member = self.members[name]  # type: ignore[attr-defined]
            if not member.is_alias:
                # When reassigning a module to an existing one,
                # try to merge them as one regular and one stubs module
                # (implicit support for .pyi modules).
                if member.is_module and not (member.is_namespace_package or member.is_namespace_subpackage):
                    # Accessing attributes of the value or member can trigger alias errors.
                    # Accessing file paths can trigger a builtin module error.
                    with suppress(AliasResolutionError, CyclicAliasError, BuiltinModuleError):
                        if value.is_module and value.filepath != member.filepath:
                            with suppress(ValueError):
                                value = merge_stubs(member, value)  # type: ignore[arg-type]
                for alias in member.aliases.values():
                    with suppress(CyclicAliasError):
                        alias.target = value
        self.members[name] = value  # type: ignore[attr-defined]
        if self.is_collection:  # type: ignore[attr-defined]
            value._modules_collection = self  # type: ignore[union-attr]
        else:
            value.parent = self  # type: ignore[assignment]
    else:
        self.members[parts[0]].set_member(parts[1:], value)  # type: ignore[attr-defined]

DelMembersMixin ¤

Mixin class to share methods for deleting members.

Methods:

  • __delitem__

    Delete a member with its name or path.

  • del_member

    Delete a member with its name or path.

__delitem__ ¤

__delitem__(key: str | Sequence[str]) -> None

Delete a member with its name or path.

This method is part of the consumer API: do not use when producing Griffe trees!

Members will be looked up in both declared members and inherited ones, triggering computation of the latter.

Parameters:

Examples:

>>> del griffe_object["foo"]
>>> del griffe_object["path.to.bar"]
>>> del griffe_object[("path", "to", "qux")]
Source code in src/griffe/_internal/mixins.py
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def __delitem__(self, key: str | Sequence[str]) -> None:
    """Delete a member with its name or path.

    This method is part of the consumer API:
    do not use when producing Griffe trees!

    Members will be looked up in both declared members and inherited ones,
    triggering computation of the latter.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> del griffe_object["foo"]
        >>> del griffe_object["path.to.bar"]
        >>> del griffe_object[("path", "to", "qux")]
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        try:
            del self.members[name]  # type: ignore[attr-defined]
        except KeyError:
            del self.inherited_members[name]  # type: ignore[attr-defined]
    else:
        del self.all_members[parts[0]][parts[1:]]  # type: ignore[attr-defined]

del_member ¤

del_member(key: str | Sequence[str]) -> None

Delete a member with its name or path.

This method is part of the producer API: you can use it safely while building Griffe trees (for example in Griffe extensions).

Members will be looked up in declared members only, not inherited ones.

Parameters:

Examples:

>>> griffe_object.del_member("foo")
>>> griffe_object.del_member("path.to.bar")
>>> griffe_object.del_member(("path", "to", "qux"))
Source code in src/griffe/_internal/mixins.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def del_member(self, key: str | Sequence[str]) -> None:
    """Delete a member with its name or path.

    This method is part of the producer API:
    you can use it safely while building Griffe trees
    (for example in Griffe extensions).

    Members will be looked up in declared members only, not inherited ones.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> griffe_object.del_member("foo")
        >>> griffe_object.del_member("path.to.bar")
        >>> griffe_object.del_member(("path", "to", "qux"))
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        del self.members[name]  # type: ignore[attr-defined]
    else:
        self.members[parts[0]].del_member(parts[1:])  # type: ignore[attr-defined]

SerializationMixin ¤

Mixin class to share methods for de/serializing objects.

Methods:

  • as_json

    Return this object's data as a JSON string.

  • from_json

    Create an instance of this class from a JSON string.

as_json ¤

as_json(*, full: bool = False, **kwargs: Any) -> str

Return this object's data as a JSON string.

Parameters:

  • full ¤

    (bool, default: False ) –

    Whether to return full info, or just base info.

  • **kwargs ¤

    (Any, default: {} ) –

    Additional serialization options passed to encoder.

Returns:

  • str

    A JSON string.

Source code in src/griffe/_internal/mixins.py
215
216
217
218
219
220
221
222
223
224
225
226
227
def as_json(self, *, full: bool = False, **kwargs: Any) -> str:
    """Return this object's data as a JSON string.

    Parameters:
        full: Whether to return full info, or just base info.
        **kwargs: Additional serialization options passed to encoder.

    Returns:
        A JSON string.
    """
    from griffe._internal.encoders import JSONEncoder  # Avoid circular import.  # noqa: PLC0415

    return json.dumps(self, cls=JSONEncoder, full=full, **kwargs)

from_json classmethod ¤

from_json(json_string: str, **kwargs: Any) -> _ObjType

Create an instance of this class from a JSON string.

Parameters:

  • json_string ¤

    (str) –

    JSON to decode into Object.

  • **kwargs ¤

    (Any, default: {} ) –

    Additional options passed to decoder.

Returns:

  • _ObjType

    An Object instance.

Raises:

  • TypeError

    When the json_string does not represent and object of the class from which this classmethod has been called.

Source code in src/griffe/_internal/mixins.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
@classmethod
def from_json(cls: type[_ObjType], json_string: str, **kwargs: Any) -> _ObjType:  # noqa: PYI019
    """Create an instance of this class from a JSON string.

    Parameters:
        json_string: JSON to decode into Object.
        **kwargs: Additional options passed to decoder.

    Returns:
        An Object instance.

    Raises:
        TypeError: When the json_string does not represent and object
            of the class from which this classmethod has been called.
    """
    from griffe._internal.encoders import json_decoder  # Avoid circular import.  # noqa: PLC0415

    kwargs.setdefault("object_hook", json_decoder)
    obj = json.loads(json_string, **kwargs)
    if not isinstance(obj, cls):
        raise TypeError(f"provided JSON object is not of type {cls}")
    return obj

ObjectAliasMixin ¤

Bases: GetMembersMixin, SetMembersMixin, DelMembersMixin, SerializationMixin


              flowchart TD
              griffe.ObjectAliasMixin[ObjectAliasMixin]
              griffe._internal.mixins.GetMembersMixin[GetMembersMixin]
              griffe._internal.mixins.SetMembersMixin[SetMembersMixin]
              griffe._internal.mixins.DelMembersMixin[DelMembersMixin]
              griffe._internal.mixins.SerializationMixin[SerializationMixin]

                              griffe._internal.mixins.GetMembersMixin --> griffe.ObjectAliasMixin
                
                griffe._internal.mixins.SetMembersMixin --> griffe.ObjectAliasMixin
                
                griffe._internal.mixins.DelMembersMixin --> griffe.ObjectAliasMixin
                
                griffe._internal.mixins.SerializationMixin --> griffe.ObjectAliasMixin
                


              click griffe.ObjectAliasMixin href "" "griffe.ObjectAliasMixin"
              click griffe._internal.mixins.GetMembersMixin href "" "griffe._internal.mixins.GetMembersMixin"
              click griffe._internal.mixins.SetMembersMixin href "" "griffe._internal.mixins.SetMembersMixin"
              click griffe._internal.mixins.DelMembersMixin href "" "griffe._internal.mixins.DelMembersMixin"
              click griffe._internal.mixins.SerializationMixin href "" "griffe._internal.mixins.SerializationMixin"
            

Mixin class to share methods that appear both in objects and aliases, unchanged.

Methods:

  • __delitem__

    Delete a member with its name or path.

  • __getitem__

    Get a member with its name or path.

  • __setitem__

    Set a member with its name or path.

  • as_json

    Return this object's data as a JSON string.

  • del_member

    Delete a member with its name or path.

  • from_json

    Create an instance of this class from a JSON string.

  • get_member

    Get a member with its name or path.

  • set_member

    Set a member with its name or path.

Attributes:

all_members property ¤

all_members: dict[str, Object | Alias]

All members (declared and inherited).

This method is part of the consumer API: do not use when producing Griffe trees!

attributes property ¤

attributes: dict[str, Attribute]

The attribute members.

This method is part of the consumer API: do not use when producing Griffe trees!

classes property ¤

classes: dict[str, Class]

The class members.

This method is part of the consumer API: do not use when producing Griffe trees!

functions property ¤

functions: dict[str, Function]

The function members.

This method is part of the consumer API: do not use when producing Griffe trees!

is_class_private property ¤

is_class_private: bool

Whether this object/alias is class-private (starts with __ and is a class member).

is_deprecated property ¤

is_deprecated: bool

Whether this object is deprecated.

is_exported property ¤

is_exported: bool

Whether this object/alias is exported (listed in __all__).

is_generic property ¤

is_generic: bool

Whether this object is generic.

is_imported property ¤

is_imported: bool

Whether this object/alias was imported from another module.

is_private property ¤

is_private: bool

Whether this object/alias is private (starts with _) but not special.

is_public property ¤

is_public: bool

Whether this object is considered public.

In modules, developers can mark objects as public thanks to the __all__ variable. In classes however, there is no convention or standard to do so.

Therefore, to decide whether an object is public, we follow this algorithm:

  • If the object's public attribute is set (boolean), return its value.
  • If the object is listed in its parent's (a module) __all__ attribute, it is public.
  • If the parent (module) defines __all__ and the object is not listed in, it is private.
  • If the object has a private name, it is private.
  • If the object was imported from another module, it is private.
  • Otherwise, the object is public.

is_special property ¤

is_special: bool

Whether this object/alias is special ("dunder" attribute/method, starts and end with __).

is_wildcard_exposed property ¤

is_wildcard_exposed: bool

Whether this object/alias is exposed to wildcard imports.

To be exposed to wildcard imports, an object/alias must:

  • be available at runtime
  • have a module as parent
  • be listed in __all__ if __all__ is defined
  • or not be private (having a name starting with an underscore)

Special case for Griffe trees: a submodule is only exposed if its parent imports it.

Returns:

  • bool

    True or False.

modules property ¤

modules: dict[str, Module]

The module members.

This method is part of the consumer API: do not use when producing Griffe trees!

type_aliases property ¤

type_aliases: dict[str, TypeAlias]

The type alias members.

This method is part of the consumer API: do not use when producing Griffe trees!

__delitem__ ¤

__delitem__(key: str | Sequence[str]) -> None

Delete a member with its name or path.

This method is part of the consumer API: do not use when producing Griffe trees!

Members will be looked up in both declared members and inherited ones, triggering computation of the latter.

Parameters:

Examples:

>>> del griffe_object["foo"]
>>> del griffe_object["path.to.bar"]
>>> del griffe_object[("path", "to", "qux")]
Source code in src/griffe/_internal/mixins.py
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def __delitem__(self, key: str | Sequence[str]) -> None:
    """Delete a member with its name or path.

    This method is part of the consumer API:
    do not use when producing Griffe trees!

    Members will be looked up in both declared members and inherited ones,
    triggering computation of the latter.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> del griffe_object["foo"]
        >>> del griffe_object["path.to.bar"]
        >>> del griffe_object[("path", "to", "qux")]
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        try:
            del self.members[name]  # type: ignore[attr-defined]
        except KeyError:
            del self.inherited_members[name]  # type: ignore[attr-defined]
    else:
        del self.all_members[parts[0]][parts[1:]]  # type: ignore[attr-defined]

__getitem__ ¤

__getitem__(key: str | Sequence[str]) -> Any

Get a member with its name or path.

This method is part of the consumer API: do not use when producing Griffe trees!

Members will be looked up in both declared members and inherited ones, triggering computation of the latter.

Parameters:

Examples:

>>> foo = griffe_object["foo"]
>>> bar = griffe_object["path.to.bar"]
>>> qux = griffe_object[("path", "to", "qux")]
Source code in src/griffe/_internal/mixins.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def __getitem__(self, key: str | Sequence[str]) -> Any:
    """Get a member with its name or path.

    This method is part of the consumer API:
    do not use when producing Griffe trees!

    Members will be looked up in both declared members and inherited ones,
    triggering computation of the latter.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> foo = griffe_object["foo"]
        >>> bar = griffe_object["path.to.bar"]
        >>> qux = griffe_object[("path", "to", "qux")]
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        return self.all_members[parts[0]]  # type: ignore[attr-defined]
    return self.all_members[parts[0]][parts[1:]]  # type: ignore[attr-defined]

__setitem__ ¤

__setitem__(
    key: str | Sequence[str], value: Object | Alias
) -> None

Set a member with its name or path.

This method is part of the consumer API: do not use when producing Griffe trees!

Parameters:

Examples:

>>> griffe_object["foo"] = foo
>>> griffe_object["path.to.bar"] = bar
>>> griffe_object[("path", "to", "qux")] = qux
Source code in src/griffe/_internal/mixins.py
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def __setitem__(self, key: str | Sequence[str], value: Object | Alias) -> None:
    """Set a member with its name or path.

    This method is part of the consumer API:
    do not use when producing Griffe trees!

    Parameters:
        key: The name or path of the member.
        value: The member.

    Examples:
        >>> griffe_object["foo"] = foo
        >>> griffe_object["path.to.bar"] = bar
        >>> griffe_object[("path", "to", "qux")] = qux
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        self.members[name] = value  # type: ignore[attr-defined]
        if self.is_collection:  # type: ignore[attr-defined]
            value._modules_collection = self  # type: ignore[union-attr]
        else:
            value.parent = self  # type: ignore[assignment]
    else:
        self.members[parts[0]][parts[1:]] = value  # type: ignore[attr-defined]

as_json ¤

as_json(*, full: bool = False, **kwargs: Any) -> str

Return this object's data as a JSON string.

Parameters:

  • full ¤

    (bool, default: False ) –

    Whether to return full info, or just base info.

  • **kwargs ¤

    (Any, default: {} ) –

    Additional serialization options passed to encoder.

Returns:

  • str

    A JSON string.

Source code in src/griffe/_internal/mixins.py
215
216
217
218
219
220
221
222
223
224
225
226
227
def as_json(self, *, full: bool = False, **kwargs: Any) -> str:
    """Return this object's data as a JSON string.

    Parameters:
        full: Whether to return full info, or just base info.
        **kwargs: Additional serialization options passed to encoder.

    Returns:
        A JSON string.
    """
    from griffe._internal.encoders import JSONEncoder  # Avoid circular import.  # noqa: PLC0415

    return json.dumps(self, cls=JSONEncoder, full=full, **kwargs)

del_member ¤

del_member(key: str | Sequence[str]) -> None

Delete a member with its name or path.

This method is part of the producer API: you can use it safely while building Griffe trees (for example in Griffe extensions).

Members will be looked up in declared members only, not inherited ones.

Parameters:

Examples:

>>> griffe_object.del_member("foo")
>>> griffe_object.del_member("path.to.bar")
>>> griffe_object.del_member(("path", "to", "qux"))
Source code in src/griffe/_internal/mixins.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def del_member(self, key: str | Sequence[str]) -> None:
    """Delete a member with its name or path.

    This method is part of the producer API:
    you can use it safely while building Griffe trees
    (for example in Griffe extensions).

    Members will be looked up in declared members only, not inherited ones.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> griffe_object.del_member("foo")
        >>> griffe_object.del_member("path.to.bar")
        >>> griffe_object.del_member(("path", "to", "qux"))
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        del self.members[name]  # type: ignore[attr-defined]
    else:
        self.members[parts[0]].del_member(parts[1:])  # type: ignore[attr-defined]

from_json classmethod ¤

from_json(json_string: str, **kwargs: Any) -> _ObjType

Create an instance of this class from a JSON string.

Parameters:

  • json_string ¤

    (str) –

    JSON to decode into Object.

  • **kwargs ¤

    (Any, default: {} ) –

    Additional options passed to decoder.

Returns:

  • _ObjType

    An Object instance.

Raises:

  • TypeError

    When the json_string does not represent and object of the class from which this classmethod has been called.

Source code in src/griffe/_internal/mixins.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
@classmethod
def from_json(cls: type[_ObjType], json_string: str, **kwargs: Any) -> _ObjType:  # noqa: PYI019
    """Create an instance of this class from a JSON string.

    Parameters:
        json_string: JSON to decode into Object.
        **kwargs: Additional options passed to decoder.

    Returns:
        An Object instance.

    Raises:
        TypeError: When the json_string does not represent and object
            of the class from which this classmethod has been called.
    """
    from griffe._internal.encoders import json_decoder  # Avoid circular import.  # noqa: PLC0415

    kwargs.setdefault("object_hook", json_decoder)
    obj = json.loads(json_string, **kwargs)
    if not isinstance(obj, cls):
        raise TypeError(f"provided JSON object is not of type {cls}")
    return obj

get_member ¤

get_member(key: str | Sequence[str]) -> Any

Get a member with its name or path.

This method is part of the producer API: you can use it safely while building Griffe trees (for example in Griffe extensions).

Members will be looked up in declared members only, not inherited ones.

Parameters:

Examples:

>>> foo = griffe_object["foo"]
>>> bar = griffe_object["path.to.bar"]
>>> bar = griffe_object[("path", "to", "bar")]
Source code in src/griffe/_internal/mixins.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def get_member(self, key: str | Sequence[str]) -> Any:
    """Get a member with its name or path.

    This method is part of the producer API:
    you can use it safely while building Griffe trees
    (for example in Griffe extensions).

    Members will be looked up in declared members only, not inherited ones.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> foo = griffe_object["foo"]
        >>> bar = griffe_object["path.to.bar"]
        >>> bar = griffe_object[("path", "to", "bar")]
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        return self.members[parts[0]]  # type: ignore[attr-defined]
    return self.members[parts[0]].get_member(parts[1:])  # type: ignore[attr-defined]

set_member ¤

set_member(
    key: str | Sequence[str], value: Object | Alias
) -> None

Set a member with its name or path.

This method is part of the producer API: you can use it safely while building Griffe trees (for example in Griffe extensions).

Parameters:

Examples:

>>> griffe_object.set_member("foo", foo)
>>> griffe_object.set_member("path.to.bar", bar)
>>> griffe_object.set_member(("path", "to", "qux"), qux)
Source code in src/griffe/_internal/mixins.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def set_member(self, key: str | Sequence[str], value: Object | Alias) -> None:
    """Set a member with its name or path.

    This method is part of the producer API:
    you can use it safely while building Griffe trees
    (for example in Griffe extensions).

    Parameters:
        key: The name or path of the member.
        value: The member.

    Examples:
        >>> griffe_object.set_member("foo", foo)
        >>> griffe_object.set_member("path.to.bar", bar)
        >>> griffe_object.set_member(("path", "to", "qux"), qux)
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        if name in self.members:  # type: ignore[attr-defined]
            member = self.members[name]  # type: ignore[attr-defined]
            if not member.is_alias:
                # When reassigning a module to an existing one,
                # try to merge them as one regular and one stubs module
                # (implicit support for .pyi modules).
                if member.is_module and not (member.is_namespace_package or member.is_namespace_subpackage):
                    # Accessing attributes of the value or member can trigger alias errors.
                    # Accessing file paths can trigger a builtin module error.
                    with suppress(AliasResolutionError, CyclicAliasError, BuiltinModuleError):
                        if value.is_module and value.filepath != member.filepath:
                            with suppress(ValueError):
                                value = merge_stubs(member, value)  # type: ignore[arg-type]
                for alias in member.aliases.values():
                    with suppress(CyclicAliasError):
                        alias.target = value
        self.members[name] = value  # type: ignore[attr-defined]
        if self.is_collection:  # type: ignore[attr-defined]
            value._modules_collection = self  # type: ignore[union-attr]
        else:
            value.parent = self  # type: ignore[assignment]
    else:
        self.members[parts[0]].set_member(parts[1:], value)  # type: ignore[attr-defined]

Object ¤

Object(
    name: str,
    *,
    lineno: int | None = None,
    endlineno: int | None = None,
    runtime: bool = True,
    docstring: Docstring | None = None,
    type_parameters: TypeParameters | None = None,
    parent: Module | Class | None = None,
    lines_collection: LinesCollection | None = None,
    modules_collection: ModulesCollection | None = None,
    git_info: GitInfo | None = None,
    analysis: Literal["static", "dynamic"] | None = None,
)

Bases: ObjectAliasMixin


              flowchart TD
              griffe.Object[Object]
              griffe._internal.mixins.ObjectAliasMixin[ObjectAliasMixin]
              griffe._internal.mixins.GetMembersMixin[GetMembersMixin]
              griffe._internal.mixins.SetMembersMixin[SetMembersMixin]
              griffe._internal.mixins.DelMembersMixin[DelMembersMixin]
              griffe._internal.mixins.SerializationMixin[SerializationMixin]

                              griffe._internal.mixins.ObjectAliasMixin --> griffe.Object
                                griffe._internal.mixins.GetMembersMixin --> griffe._internal.mixins.ObjectAliasMixin
                
                griffe._internal.mixins.SetMembersMixin --> griffe._internal.mixins.ObjectAliasMixin
                
                griffe._internal.mixins.DelMembersMixin --> griffe._internal.mixins.ObjectAliasMixin
                
                griffe._internal.mixins.SerializationMixin --> griffe._internal.mixins.ObjectAliasMixin
                



              click griffe.Object href "" "griffe.Object"
              click griffe._internal.mixins.ObjectAliasMixin href "" "griffe._internal.mixins.ObjectAliasMixin"
              click griffe._internal.mixins.GetMembersMixin href "" "griffe._internal.mixins.GetMembersMixin"
              click griffe._internal.mixins.SetMembersMixin href "" "griffe._internal.mixins.SetMembersMixin"
              click griffe._internal.mixins.DelMembersMixin href "" "griffe._internal.mixins.DelMembersMixin"
              click griffe._internal.mixins.SerializationMixin href "" "griffe._internal.mixins.SerializationMixin"
            

An abstract class representing a Python object.

Parameters:

  • name ¤

    (str) –

    The object name, as declared in the code.

  • lineno ¤

    (int | None, default: None ) –

    The object starting line, or None for modules. Lines start at 1.

  • endlineno ¤

    (int | None, default: None ) –

    The object ending line (inclusive), or None for modules.

  • runtime ¤

    (bool, default: True ) –

    Whether this object is present at runtime or not.

  • docstring ¤

    (Docstring | None, default: None ) –

    The object docstring.

  • type_parameters ¤

    (TypeParameters | None, default: None ) –

    The object type parameters, if any.

  • parent ¤

    (Module | Class | None, default: None ) –

    The object parent.

  • lines_collection ¤

    (LinesCollection | None, default: None ) –

    A collection of source code lines.

  • modules_collection ¤

    (ModulesCollection | None, default: None ) –

    A collection of modules.

  • git_info ¤

    (GitInfo | None, default: None ) –

    Git information.

  • analysis ¤

    (Literal['static', 'dynamic'] | None, default: None ) –

    The type of analysis used to load this object. None means the object was created manually.

Methods:

  • __bool__

    An object is always true-ish.

  • __delitem__

    Delete a member with its name or path.

  • __getitem__

    Get a member with its name or path.

  • __len__

    The number of members in this object, recursively.

  • __setitem__

    Set a member with its name or path.

  • as_dict

    Return this object's data as a dictionary.

  • as_json

    Return this object's data as a JSON string.

  • del_member

    Delete a member with its name or path.

  • filter_members

    Filter and return members based on predicates.

  • from_json

    Create an instance of this class from a JSON string.

  • get_member

    Get a member with its name or path.

  • has_labels

    Tell if this object has all the given labels.

  • is_kind

    Tell if this object is of the given kind.

  • resolve

    Resolve a name within this object's and parents' scope.

  • set_member

    Set a member with its name or path.

Attributes:

Source code in src/griffe/_internal/models.py
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
def __init__(
    self,
    name: str,
    *,
    lineno: int | None = None,
    endlineno: int | None = None,
    runtime: bool = True,
    docstring: Docstring | None = None,
    type_parameters: TypeParameters | None = None,
    parent: Module | Class | None = None,
    lines_collection: LinesCollection | None = None,
    modules_collection: ModulesCollection | None = None,
    git_info: GitInfo | None = None,
    analysis: Literal["static", "dynamic"] | None = None,
) -> None:
    """Initialize the object.

    Parameters:
        name: The object name, as declared in the code.
        lineno: The object starting line, or None for modules. Lines start at 1.
        endlineno: The object ending line (inclusive), or None for modules.
        runtime: Whether this object is present at runtime or not.
        docstring: The object docstring.
        type_parameters: The object type parameters, if any.
        parent: The object parent.
        lines_collection: A collection of source code lines.
        modules_collection: A collection of modules.
        git_info: Git information.
        analysis: The type of analysis used to load this object.
            None means the object was created manually.
    """
    self.name: str = name
    """The object name."""

    self.lineno: int | None = lineno
    """The starting line number of the object.

    See also: [`endlineno`][griffe.Object.endlineno].
    """

    self.endlineno: int | None = endlineno
    """The ending line number of the object.

    See also: [`lineno`][griffe.Object.lineno].
    """

    self.docstring: Docstring | None = docstring
    """The object docstring.

    See also: [`has_docstring`][griffe.Object.has_docstring],
    [`has_docstrings`][griffe.Object.has_docstrings].
    """

    # TODO: Maybe move these into `Class` and `Function`.
    # Then always return them in `Class` and `Function`'s `as_dict` methods,
    # and remove the conditional in the `_load_class` and `_load_function` decoders.
    self.type_parameters: TypeParameters = type_parameters or TypeParameters()
    """The object type parameters."""

    self.parent: Module | Class | None = parent
    """The parent of the object (none if top module)."""

    self.members: dict[str, Object | Alias] = {}
    """The object members (modules, classes, functions, attributes, type aliases).

    See also: [`inherited_members`][griffe.Object.inherited_members],
    [`get_member`][griffe.Object.get_member],
    [`set_member`][griffe.Object.set_member],
    [`filter_members`][griffe.Object.filter_members].
    """

    self.labels: set[str] = set()
    """The object labels (`property`, `dataclass`, etc.).

    See also: [`has_labels`][griffe.Object.has_labels]."""

    self.imports: dict[str, str] = {}
    """The other objects imported by this object.

    Keys are the names within the object (`from ... import ... as AS_NAME`),
    while the values are the actual names of the objects (`from ... import REAL_NAME as ...`).
    """

    self.exports: list[str | ExprName] | None = None
    """The names of the objects exported by this (module) object through the `__all__` variable.

    Exports can contain string (object names) or resolvable names,
    like other lists of exports coming from submodules:

    ```python
    from .submodule import __all__ as submodule_all

    __all__ = ["hello", *submodule_all]
    ```

    Exports get expanded by the loader before it expands wildcards and resolves aliases.

    See also: [`GriffeLoader.expand_exports`][griffe.GriffeLoader.expand_exports].
    """

    self.aliases: dict[str, Alias] = {}
    """The aliases pointing to this object."""

    self.runtime: bool = runtime
    """Whether this object is available at runtime.

    Typically, type-guarded objects (under an `if TYPE_CHECKING` condition)
    are not available at runtime.
    """

    self.extra: dict[str, dict[str, Any]] = defaultdict(dict)
    """Namespaced dictionaries storing extra metadata for this object, used by extensions."""

    self.public: bool | None = None
    """Whether this object is public."""

    self.deprecated: bool | str | None = None
    """Whether this object is deprecated (boolean or deprecation message)."""

    self.analysis: Literal["static", "dynamic"] | None = analysis
    """The type of analysis used to load this object.

    None means the object was created manually.
    """

    self._lines_collection: LinesCollection | None = lines_collection
    self._modules_collection: ModulesCollection | None = modules_collection
    self._git_info: GitInfo | None = git_info
    self._source_link: str | None = None

    # Attach the docstring to this object.
    if docstring:
        docstring.parent = self

aliases instance-attribute ¤

aliases: dict[str, Alias] = {}

The aliases pointing to this object.

all_members property ¤

all_members: dict[str, Object | Alias]

All members (declared and inherited).

This method is part of the consumer API: do not use when producing Griffe trees!

analysis instance-attribute ¤

analysis: Literal['static', 'dynamic'] | None = analysis

The type of analysis used to load this object.

None means the object was created manually.

attributes property ¤

attributes: dict[str, Attribute]

The attribute members.

This method is part of the consumer API: do not use when producing Griffe trees!

canonical_path property ¤

canonical_path: str

The full dotted path of this object.

The canonical path is the path where the object was defined (not imported).

See also: path.

classes property ¤

classes: dict[str, Class]

The class members.

This method is part of the consumer API: do not use when producing Griffe trees!

deprecated instance-attribute ¤

deprecated: bool | str | None = None

Whether this object is deprecated (boolean or deprecation message).

endlineno instance-attribute ¤

endlineno: int | None = endlineno

exports instance-attribute ¤

exports: list[str | ExprName] | None = None

The names of the objects exported by this (module) object through the __all__ variable.

Exports can contain string (object names) or resolvable names, like other lists of exports coming from submodules:

from .submodule import __all__ as submodule_all

__all__ = ["hello", *submodule_all]

Exports get expanded by the loader before it expands wildcards and resolves aliases.

See also: GriffeLoader.expand_exports.

extra instance-attribute ¤

Namespaced dictionaries storing extra metadata for this object, used by extensions.

filepath property ¤

filepath: Path | list[Path]

The file path (or directory list for namespace packages) where this object was defined.

See also: relative_filepath, relative_package_filepath.

Examples:

>>> import griffe
>>> markdown = griffe.load("markdown")
>>> markdown.filepath
PosixPath('~/project/.venv/lib/python3.11/site-packages/markdown/__init__.py')

functions property ¤

functions: dict[str, Function]

The function members.

This method is part of the consumer API: do not use when producing Griffe trees!

git_info property writable ¤

git_info: GitInfo | None

Git information for this object, if available.

has_docstrings property ¤

has_docstrings: bool

Whether this object or any of its members has a docstring (empty or not).

Inherited members are not considered. Imported members are not considered, unless they are also public.

See also: docstring, has_docstring.

imports instance-attribute ¤

imports: dict[str, str] = {}

The other objects imported by this object.

Keys are the names within the object (from ... import ... as AS_NAME), while the values are the actual names of the objects (from ... import REAL_NAME as ...).

inherited class-attribute instance-attribute ¤

inherited: bool = False

Always false for objects.

Only aliases can be marked as inherited.

inherited_members property ¤

inherited_members: dict[str, Alias]

Members that are inherited from base classes.

This method is part of the consumer API: do not use when producing Griffe trees!

See also: members.

is_class_private property ¤

is_class_private: bool

Whether this object/alias is class-private (starts with __ and is a class member).

is_collection class-attribute instance-attribute ¤

is_collection: bool = False

Always false for objects.

is_deprecated property ¤

is_deprecated: bool

Whether this object is deprecated.

is_exported property ¤

is_exported: bool

Whether this object/alias is exported (listed in __all__).

is_generic property ¤

is_generic: bool

Whether this object is generic.

is_imported property ¤

is_imported: bool

Whether this object/alias was imported from another module.

is_init_method property ¤

is_init_method: bool

Whether this function is an __init__ method.

is_init_module property ¤

is_init_module: bool

is_namespace_package property ¤

is_namespace_package: bool

is_private property ¤

is_private: bool

Whether this object/alias is private (starts with _) but not special.

is_public property ¤

is_public: bool

Whether this object is considered public.

In modules, developers can mark objects as public thanks to the __all__ variable. In classes however, there is no convention or standard to do so.

Therefore, to decide whether an object is public, we follow this algorithm:

  • If the object's public attribute is set (boolean), return its value.
  • If the object is listed in its parent's (a module) __all__ attribute, it is public.
  • If the parent (module) defines __all__ and the object is not listed in, it is private.
  • If the object has a private name, it is private.
  • If the object was imported from another module, it is private.
  • Otherwise, the object is public.

is_special property ¤

is_special: bool

Whether this object/alias is special ("dunder" attribute/method, starts and end with __).

is_subpackage property ¤

is_subpackage: bool

is_wildcard_exposed property ¤

is_wildcard_exposed: bool

Whether this object/alias is exposed to wildcard imports.

To be exposed to wildcard imports, an object/alias must:

  • be available at runtime
  • have a module as parent
  • be listed in __all__ if __all__ is defined
  • or not be private (having a name starting with an underscore)

Special case for Griffe trees: a submodule is only exposed if its parent imports it.

Returns:

  • bool

    True or False.

kind instance-attribute ¤

kind: Kind

The object kind.

labels instance-attribute ¤

labels: set[str] = set()

lines_collection property ¤

lines_collection: LinesCollection

The lines collection attached to this object or its parents.

See also: lines, source.

Raises:

  • ValueError

    When no modules collection can be found in the object or its parents.

module property ¤

module: Module

The parent module of this object.

See also: package.

Examples:

>>> import griffe
>>> markdown = griffe.load("markdown")
>>> markdown["core.Markdown.references"].module
Module(PosixPath('~/project/.venv/lib/python3.11/site-packages/markdown/core.py'))
>>> # The `module` of a module is itself.
>>> markdown["core"].module
Module(PosixPath('~/project/.venv/lib/python3.11/site-packages/markdown/core.py'))

Raises:

  • ValueError

    When the object is not a module and does not have a parent.

modules property ¤

modules: dict[str, Module]

The module members.

This method is part of the consumer API: do not use when producing Griffe trees!

modules_collection property ¤

modules_collection: ModulesCollection

The modules collection attached to this object or its parents.

Raises:

  • ValueError

    When no modules collection can be found in the object or its parents.

name instance-attribute ¤

name: str = name

The object name.

package property ¤

package: Module

The absolute top module (the package) of this object.

See also: module.

Examples:

>>> import griffe
>>> markdown = griffe.load("markdown")
>>> markdown["core.Markdown.references"].package
Module(PosixPath('~/project/.venv/lib/python3.11/site-packages/markdown/__init__.py'))

parent instance-attribute ¤

parent: Module | Class | None = parent

The parent of the object (none if top module).

path property ¤

path: str

The dotted path of this object.

On regular objects (not aliases), the path is the canonical path.

See also: canonical_path.

Examples:

>>> import griffe
>>> markdown = griffe.load("markdown")
>>> markdown["core.Markdown.references"].path
'markdown.core.Markdown.references'

public instance-attribute ¤

public: bool | None = None

Whether this object is public.

relative_filepath property ¤

relative_filepath: Path

The file path where this object was defined, relative to the current working directory.

If this object's file path is not relative to the current working directory, return its absolute path.

See also: filepath, relative_package_filepath.

Raises:

  • ValueError

    When the relative path could not be computed.

relative_package_filepath property ¤

relative_package_filepath: Path

runtime instance-attribute ¤

runtime: bool = runtime

Whether this object is available at runtime.

Typically, type-guarded objects (under an if TYPE_CHECKING condition) are not available at runtime.

source_link: str | None

Source link for this object, if available.

type_aliases property ¤

type_aliases: dict[str, TypeAlias]

The type alias members.

This method is part of the consumer API: do not use when producing Griffe trees!

type_parameters instance-attribute ¤

type_parameters: TypeParameters = (
    type_parameters or TypeParameters()
)

The object type parameters.

__bool__ ¤

__bool__() -> bool

An object is always true-ish.

Source code in src/griffe/_internal/models.py
717
718
719
def __bool__(self) -> bool:
    """An object is always true-ish."""
    return True

__delitem__ ¤

__delitem__(key: str | Sequence[str]) -> None

Delete a member with its name or path.

This method is part of the consumer API: do not use when producing Griffe trees!

Members will be looked up in both declared members and inherited ones, triggering computation of the latter.

Parameters:

Examples:

>>> del griffe_object["foo"]
>>> del griffe_object["path.to.bar"]
>>> del griffe_object[("path", "to", "qux")]
Source code in src/griffe/_internal/mixins.py
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
def __delitem__(self, key: str | Sequence[str]) -> None:
    """Delete a member with its name or path.

    This method is part of the consumer API:
    do not use when producing Griffe trees!

    Members will be looked up in both declared members and inherited ones,
    triggering computation of the latter.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> del griffe_object["foo"]
        >>> del griffe_object["path.to.bar"]
        >>> del griffe_object[("path", "to", "qux")]
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        try:
            del self.members[name]  # type: ignore[attr-defined]
        except KeyError:
            del self.inherited_members[name]  # type: ignore[attr-defined]
    else:
        del self.all_members[parts[0]][parts[1:]]  # type: ignore[attr-defined]

__getitem__ ¤

__getitem__(key: str | Sequence[str]) -> Any

Get a member with its name or path.

This method is part of the consumer API: do not use when producing Griffe trees!

Members will be looked up in both declared members and inherited ones, triggering computation of the latter.

Parameters:

Examples:

>>> foo = griffe_object["foo"]
>>> bar = griffe_object["path.to.bar"]
>>> qux = griffe_object[("path", "to", "qux")]
Source code in src/griffe/_internal/mixins.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def __getitem__(self, key: str | Sequence[str]) -> Any:
    """Get a member with its name or path.

    This method is part of the consumer API:
    do not use when producing Griffe trees!

    Members will be looked up in both declared members and inherited ones,
    triggering computation of the latter.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> foo = griffe_object["foo"]
        >>> bar = griffe_object["path.to.bar"]
        >>> qux = griffe_object[("path", "to", "qux")]
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        return self.all_members[parts[0]]  # type: ignore[attr-defined]
    return self.all_members[parts[0]][parts[1:]]  # type: ignore[attr-defined]

__len__ ¤

__len__() -> int

The number of members in this object, recursively.

Source code in src/griffe/_internal/models.py
721
722
723
def __len__(self) -> int:
    """The number of members in this object, recursively."""
    return len(self.members) + sum(len(member) for member in self.members.values())

__setitem__ ¤

__setitem__(
    key: str | Sequence[str], value: Object | Alias
) -> None

Set a member with its name or path.

This method is part of the consumer API: do not use when producing Griffe trees!

Parameters:

Examples:

>>> griffe_object["foo"] = foo
>>> griffe_object["path.to.bar"] = bar
>>> griffe_object[("path", "to", "qux")] = qux
Source code in src/griffe/_internal/mixins.py
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
def __setitem__(self, key: str | Sequence[str], value: Object | Alias) -> None:
    """Set a member with its name or path.

    This method is part of the consumer API:
    do not use when producing Griffe trees!

    Parameters:
        key: The name or path of the member.
        value: The member.

    Examples:
        >>> griffe_object["foo"] = foo
        >>> griffe_object["path.to.bar"] = bar
        >>> griffe_object[("path", "to", "qux")] = qux
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        self.members[name] = value  # type: ignore[attr-defined]
        if self.is_collection:  # type: ignore[attr-defined]
            value._modules_collection = self  # type: ignore[union-attr]
        else:
            value.parent = self  # type: ignore[assignment]
    else:
        self.members[parts[0]][parts[1:]] = value  # type: ignore[attr-defined]

as_dict ¤

as_dict(
    *, full: bool = False, **kwargs: Any
) -> dict[str, Any]

Return this object's data as a dictionary.

See also: as_json.

Parameters:

  • full ¤

    (bool, default: False ) –

    Whether to return full info, or just base info.

  • **kwargs ¤

    (Any, default: {} ) –

    Additional serialization options.

Returns:

Source code in src/griffe/_internal/models.py
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
def as_dict(self, *, full: bool = False, **kwargs: Any) -> dict[str, Any]:
    """Return this object's data as a dictionary.

    See also: [`as_json`][griffe.Object.as_json].

    Parameters:
        full: Whether to return full info, or just base info.
        **kwargs: Additional serialization options.

    Returns:
        A dictionary.
    """
    base: dict[str, Any] = {
        "kind": self.kind,
        "name": self.name,
        "runtime": self.runtime,
    }

    if self.public is not None:
        base["public"] = self.public
    if self.exports is not None:
        base["exports"] = [str(export) for export in self.exports]
    if self.imports:
        base["imports"] = self.imports
    if self.deprecated is not None:
        base["deprecated"] = self.deprecated
    if self.lineno is not None:
        base["lineno"] = self.lineno
    if self.endlineno is not None:
        base["endlineno"] = self.endlineno
    if self.docstring:
        base["docstring"] = self.docstring
    if self.type_parameters:
        base["type_parameters"] = [type_param.as_dict(**kwargs) for type_param in self.type_parameters]
    if self.labels:
        base["labels"] = self.labels
    if self.members:
        base["members"] = {name: member.as_dict(full=full, **kwargs) for name, member in self.members.items()}
    if self.analysis:
        base["analysis"] = self.analysis
    if self._git_info is not None:
        base["git_info"] = asdict(self._git_info)
    if self._source_link is not None:
        base["source_link"] = self._source_link
    # TODO: Include `self.extra`?

    if full:
        base.update(
            {
                "path": self.path,
                "filepath": self.filepath,
                "relative_package_filepath": self.relative_package_filepath,
                "is_public": self.is_public,
                "is_deprecated": self.is_deprecated,
                "is_private": self.is_private,
                "is_class_private": self.is_class_private,
                "is_special": self.is_special,
                "is_imported": self.is_imported,
                "is_exported": self.is_exported,
                "is_wildcard_exposed": self.is_wildcard_exposed,
                # TODO: Add these properties?
                # "is_alias": self.is_alias,
                # "is_collection": self.is_collection,
                # "is_module": self.is_module,
                # "is_class": self.is_class,
                # "is_function": self.is_function,
                # "is_attribute": self.is_attribute,
                # "is_type_alias": self.is_type_alias,
                # "is_init_module": self.is_init_module,
                # "is_package": self.is_package,
                # "is_subpackage": self.is_subpackage,
                # "is_namespace_package": self.is_namespace_package,
                # "is_namespace_subpackage": self.is_namespace_subpackage,
                # "has_docstring": self.has_docstring,
                # "has_docstrings": self.has_docstrings,
            },
        )

        with suppress(ValueError):
            base["relative_filepath"] = self.relative_filepath

        if "source_link" not in base and (source_link := self.source_link) is not None:
            base["source_link"] = source_link

    return base

as_json ¤

as_json(*, full: bool = False, **kwargs: Any) -> str

Return this object's data as a JSON string.

Parameters:

  • full ¤

    (bool, default: False ) –

    Whether to return full info, or just base info.

  • **kwargs ¤

    (Any, default: {} ) –

    Additional serialization options passed to encoder.

Returns:

  • str

    A JSON string.

Source code in src/griffe/_internal/mixins.py
215
216
217
218
219
220
221
222
223
224
225
226
227
def as_json(self, *, full: bool = False, **kwargs: Any) -> str:
    """Return this object's data as a JSON string.

    Parameters:
        full: Whether to return full info, or just base info.
        **kwargs: Additional serialization options passed to encoder.

    Returns:
        A JSON string.
    """
    from griffe._internal.encoders import JSONEncoder  # Avoid circular import.  # noqa: PLC0415

    return json.dumps(self, cls=JSONEncoder, full=full, **kwargs)

del_member ¤

del_member(key: str | Sequence[str]) -> None

Delete a member with its name or path.

This method is part of the producer API: you can use it safely while building Griffe trees (for example in Griffe extensions).

Members will be looked up in declared members only, not inherited ones.

Parameters:

Examples:

>>> griffe_object.del_member("foo")
>>> griffe_object.del_member("path.to.bar")
>>> griffe_object.del_member(("path", "to", "qux"))
Source code in src/griffe/_internal/mixins.py
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def del_member(self, key: str | Sequence[str]) -> None:
    """Delete a member with its name or path.

    This method is part of the producer API:
    you can use it safely while building Griffe trees
    (for example in Griffe extensions).

    Members will be looked up in declared members only, not inherited ones.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> griffe_object.del_member("foo")
        >>> griffe_object.del_member("path.to.bar")
        >>> griffe_object.del_member(("path", "to", "qux"))
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        del self.members[name]  # type: ignore[attr-defined]
    else:
        self.members[parts[0]].del_member(parts[1:])  # type: ignore[attr-defined]

filter_members ¤

filter_members(
    *predicates: Callable[[Object | Alias], bool],
) -> dict[str, Object | Alias]

Filter and return members based on predicates.

See also: members.

Parameters:

  • *predicates ¤

    (Callable[[Object | Alias], bool], default: () ) –

    A list of predicates, i.e. callables accepting a member as argument and returning a boolean.

Returns:

Source code in src/griffe/_internal/models.py
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
def filter_members(self, *predicates: Callable[[Object | Alias], bool]) -> dict[str, Object | Alias]:
    """Filter and return members based on predicates.

    See also: [`members`][griffe.Object.members].

    Parameters:
        *predicates: A list of predicates, i.e. callables accepting a member as argument and returning a boolean.

    Returns:
        A dictionary of members.
    """
    if not predicates:
        return self.members
    members: dict[str, Object | Alias] = {
        name: member for name, member in self.members.items() if all(predicate(member) for predicate in predicates)
    }
    return members

from_json classmethod ¤

from_json(json_string: str, **kwargs: Any) -> _ObjType

Create an instance of this class from a JSON string.

Parameters:

  • json_string ¤

    (str) –

    JSON to decode into Object.

  • **kwargs ¤

    (Any, default: {} ) –

    Additional options passed to decoder.

Returns:

  • _ObjType

    An Object instance.

Raises:

  • TypeError

    When the json_string does not represent and object of the class from which this classmethod has been called.

Source code in src/griffe/_internal/mixins.py
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
@classmethod
def from_json(cls: type[_ObjType], json_string: str, **kwargs: Any) -> _ObjType:  # noqa: PYI019
    """Create an instance of this class from a JSON string.

    Parameters:
        json_string: JSON to decode into Object.
        **kwargs: Additional options passed to decoder.

    Returns:
        An Object instance.

    Raises:
        TypeError: When the json_string does not represent and object
            of the class from which this classmethod has been called.
    """
    from griffe._internal.encoders import json_decoder  # Avoid circular import.  # noqa: PLC0415

    kwargs.setdefault("object_hook", json_decoder)
    obj = json.loads(json_string, **kwargs)
    if not isinstance(obj, cls):
        raise TypeError(f"provided JSON object is not of type {cls}")
    return obj

get_member ¤

get_member(key: str | Sequence[str]) -> Any

Get a member with its name or path.

This method is part of the producer API: you can use it safely while building Griffe trees (for example in Griffe extensions).

Members will be looked up in declared members only, not inherited ones.

Parameters:

Examples:

>>> foo = griffe_object["foo"]
>>> bar = griffe_object["path.to.bar"]
>>> bar = griffe_object[("path", "to", "bar")]
Source code in src/griffe/_internal/mixins.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def get_member(self, key: str | Sequence[str]) -> Any:
    """Get a member with its name or path.

    This method is part of the producer API:
    you can use it safely while building Griffe trees
    (for example in Griffe extensions).

    Members will be looked up in declared members only, not inherited ones.

    Parameters:
        key: The name or path of the member.

    Examples:
        >>> foo = griffe_object["foo"]
        >>> bar = griffe_object["path.to.bar"]
        >>> bar = griffe_object[("path", "to", "bar")]
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        return self.members[parts[0]]  # type: ignore[attr-defined]
    return self.members[parts[0]].get_member(parts[1:])  # type: ignore[attr-defined]

has_labels ¤

has_labels(*labels: str) -> bool

Tell if this object has all the given labels.

See also: labels.

Parameters:

  • *labels ¤

    (str, default: () ) –

    Labels that must be present.

Returns:

  • bool

    True or False.

Source code in src/griffe/_internal/models.py
954
955
956
957
958
959
960
961
962
963
964
965
def has_labels(self, *labels: str) -> bool:
    """Tell if this object has all the given labels.

    See also: [`labels`][griffe.Object.labels].

    Parameters:
        *labels: Labels that must be present.

    Returns:
        True or False.
    """
    return set(labels).issubset(self.labels)

is_kind ¤

is_kind(kind: str | Kind | set[str | Kind]) -> bool

Tell if this object is of the given kind.

See also: is_module, is_class, is_function, is_attribute, is_type_alias, is_alias.

Parameters:

  • kind ¤

    (str | Kind | set[str | Kind]) –

    An instance or set of kinds (strings or enumerations).

Raises:

  • ValueError

    When an empty set is given as argument.

Returns:

  • bool

    True or False.

Source code in src/griffe/_internal/models.py
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
def is_kind(self, kind: str | Kind | set[str | Kind]) -> bool:
    """Tell if this object is of the given kind.

    See also: [`is_module`][griffe.Object.is_module],
    [`is_class`][griffe.Object.is_class],
    [`is_function`][griffe.Object.is_function],
    [`is_attribute`][griffe.Object.is_attribute],
    [`is_type_alias`][griffe.Object.is_type_alias],
    [`is_alias`][griffe.Object.is_alias].

    Parameters:
        kind: An instance or set of kinds (strings or enumerations).

    Raises:
        ValueError: When an empty set is given as argument.

    Returns:
        True or False.
    """
    if isinstance(kind, set):
        if not kind:
            raise ValueError("kind must not be an empty set")
        return self.kind in (knd if isinstance(knd, Kind) else Kind(knd) for knd in kind)
    if isinstance(kind, str):
        kind = Kind(kind)
    return self.kind is kind

resolve ¤

resolve(name: str) -> str

Resolve a name within this object's and parents' scope.

Parameters:

  • name ¤

    (str) –

    The name to resolve.

Raises:

Returns:

  • str

    The resolved name.

Source code in src/griffe/_internal/models.py
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
def resolve(self, name: str) -> str:
    """Resolve a name within this object's and parents' scope.

    Parameters:
        name: The name to resolve.

    Raises:
        NameResolutionError: When the name could not be resolved.

    Returns:
        The resolved name.
    """
    # TODO: Better match Python's own scoping rules?
    # Also, maybe return regular paths instead of canonical ones?

    # Name is a type parameter.
    if name in self.type_parameters:
        type_parameter = self.type_parameters[name]
        if type_parameter.kind is TypeParameterKind.type_var_tuple:
            prefix = "*"
        elif type_parameter.kind is TypeParameterKind.param_spec:
            prefix = "**"
        else:
            prefix = ""
        return f"{self.path}[{prefix}{name}]"

    # Name is a member of this object.
    if name in self.members:
        if self.members[name].is_alias:
            return self.members[name].target_path  # type: ignore[union-attr]
        return self.members[name].path

    # Name unknown and no more parent scope, could be a built-in.
    if self.parent is None:
        raise NameResolutionError(f"{name} could not be resolved in the scope of {self.path}")

    # Name is parent, non-module object.
    if name == self.parent.name and not self.parent.is_module:
        return self.parent.path

    # Recurse in parent.
    return self.parent.resolve(name)

set_member ¤

set_member(
    key: str | Sequence[str], value: Object | Alias
) -> None

Set a member with its name or path.

This method is part of the producer API: you can use it safely while building Griffe trees (for example in Griffe extensions).

Parameters:

Examples:

>>> griffe_object.set_member("foo", foo)
>>> griffe_object.set_member("path.to.bar", bar)
>>> griffe_object.set_member(("path", "to", "qux"), qux)
Source code in src/griffe/_internal/mixins.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def set_member(self, key: str | Sequence[str], value: Object | Alias) -> None:
    """Set a member with its name or path.

    This method is part of the producer API:
    you can use it safely while building Griffe trees
    (for example in Griffe extensions).

    Parameters:
        key: The name or path of the member.
        value: The member.

    Examples:
        >>> griffe_object.set_member("foo", foo)
        >>> griffe_object.set_member("path.to.bar", bar)
        >>> griffe_object.set_member(("path", "to", "qux"), qux)
    """
    parts = _get_parts(key)
    if len(parts) == 1:
        name = parts[0]
        if name in self.members:  # type: ignore[attr-defined]
            member = self.members[name]  # type: ignore[attr-defined]
            if not member.is_alias:
                # When reassigning a module to an existing one,
                # try to merge them as one regular and one stubs module
                # (implicit support for .pyi modules).
                if member.is_module and not (member.is_namespace_package or member.is_namespace_subpackage):
                    # Accessing attributes of the value or member can trigger alias errors.
                    # Accessing file paths can trigger a builtin module error.
                    with suppress(AliasResolutionError, CyclicAliasError, BuiltinModuleError):
                        if value.is_module and value.filepath != member.filepath:
                            with suppress(ValueError):
                                value = merge_stubs(member, value)  # type: ignore[arg-type]
                for alias in member.aliases.values():
                    with suppress(CyclicAliasError):
                        alias.target = value
        self.members[name] = value  # type: ignore[attr-defined]
        if self.is_collection:  # type: ignore[attr-defined]
            value._modules_collection = self  # type: ignore[union-attr]
        else:
            value.parent = self  # type: ignore[assignment]
    else:
        self.members[parts[0]].set_member(parts[1:], value)  # type: ignore[attr-defined]

Type parameters¤

TypeParameters ¤

TypeParameters(*type_parameters: TypeParameter)

This class is a container for type parameters.

It allows to get type parameters using their position (index) or their name:

>>> type_parameters = TypeParameters(TypeParameter("hello"), kind=TypeParameterKind.type_var)
>>> type_parameters[0] is type_parameters["hello"]
True

Parameters:

  • *type_parameters ¤

    (TypeParameter, default: () ) –

    The initial type parameters to add to the container.

Methods:

  • __contains__

    Whether a type parameter with the given name is present.

  • __delitem__

    Delete a type parameter by index or name.

  • __getitem__

    Get a type parameter by index or name.

  • __iter__

    Iterate over the type parameters, in order.

  • __len__

    The number of type parameters.

  • __setitem__

    Set a type parameter by index or name.

  • add

    Add a type parameter to the container.

Source code in src/griffe/_internal/models.py
488
489
490
491
492
493
494
def __init__(self, *type_parameters: TypeParameter) -> None:
    """Initialize the type parameters container.

    Parameters:
        *type_parameters: The initial type parameters to add to the container.
    """
    self._type_params: list[TypeParameter] = list(type_parameters)

__contains__ ¤

__contains__(type_param_name: str)

Whether a type parameter with the given name is present.

Source code in src/griffe/_internal/models.py
542
543
544
545
546
547
548
def __contains__(self, type_param_name: str):
    """Whether a type parameter with the given name is present."""
    try:
        next(param for param in self._type_params if param.name == type_param_name.lstrip("*"))
    except StopIteration:
        return False
    return True

__delitem__ ¤

__delitem__(name_or_index: int | str) -> None

Delete a type parameter by index or name.

Source code in src/griffe/_internal/models.py
522
523
524
525
526
527
528
529
530
531
532
def __delitem__(self, name_or_index: int | str) -> None:
    """Delete a type parameter by index or name."""
    if isinstance(name_or_index, int):
        del self._type_params[name_or_index]
    else:
        name = name_or_index.lstrip("*")
        try:
            index = next(idx for idx, param in enumerate(self._type_params) if param.name == name)
        except StopIteration as error:
            raise KeyError(f"type parameter {name_or_index} not found") from error
        del self._type_params[index]

__getitem__ ¤

__getitem__(name_or_index: int | str) -> TypeParameter

Get a type parameter by index or name.

Source code in src/griffe/_internal/models.py
499
500
501
502
503
504
505
506
507
def __getitem__(self, name_or_index: int | str) -> TypeParameter:
    """Get a type parameter by index or name."""
    if isinstance(name_or_index, int):
        return self._type_params[name_or_index]
    name = name_or_index.lstrip("*")
    try:
        return next(param for param in self._type_params if param.name == name)
    except StopIteration as error:
        raise KeyError(f"type parameter {name_or_index} not found") from error

__iter__ ¤

__iter__()

Iterate over the type parameters, in order.

Source code in src/griffe/_internal/models.py
538
539
540
def __iter__(self):
    """Iterate over the type parameters, in order."""
    return iter(self._type_params)

__len__ ¤

__len__()

The number of type parameters.

Source code in src/griffe/_internal/models.py
534
535
536
def __len__(self):
    """The number of type parameters."""
    return len(self._type_params)

__setitem__ ¤

__setitem__(
    name_or_index: int | str, type_parameter: TypeParameter
) -> None

Set a type parameter by index or name.

Source code in src/griffe/_internal/models.py
509
510
511
512
513
514
515
516
517
518
519
520
def __setitem__(self, name_or_index: int | str, type_parameter: TypeParameter) -> None:
    """Set a type parameter by index or name."""
    if isinstance(name_or_index, int):
        self._type_params[name_or_index] = type_parameter
    else:
        name = name_or_index.lstrip("*")
        try:
            index = next(idx for idx, param in enumerate(self._type_params) if param.name == name)
        except StopIteration:
            self._type_params.append(type_parameter)
        else:
            self._type_params[index] = type_parameter

add ¤

Add a type parameter to the container.

Parameters:

Raises:

  • ValueError

    When a type parameter with the same name is already present.

Source code in src/griffe/_internal/models.py
550
551
552
553
554
555
556
557
558
559
560
561
def add(self, type_parameter: TypeParameter) -> None:
    """Add a type parameter to the container.

    Parameters:
        type_parameter: The function parameter to add.

    Raises:
        ValueError: When a type parameter with the same name is already present.
    """
    if type_parameter.name in self:
        raise ValueError(f"type parameter {type_parameter.name} already present")
    self._type_params.append(type_parameter)

TypeParameter ¤

TypeParameter(
    name: str,
    *,
    kind: TypeParameterKind,
    bound: str | Expr | None = None,
    constraints: Sequence[str | Expr] | None = None,
    default: str | Expr | None = None,
)

This class represents a type parameter.

Parameters:

  • name ¤

    (str) –

    The type parameter name, without leading stars (* or **).

  • kind ¤

    (TypeParameterKind) –

    The type parameter kind.

  • bound ¤

    (str | Expr | None, default: None ) –

    The type parameter bound, if any. Mutually exclusive with constraints.

  • constraints ¤

    (Sequence[str | Expr] | None, default: None ) –

    The type parameter constraints, if any. Mutually exclusive with bound.

  • default ¤

    (str | Expr | None, default: None ) –

    The type parameter default, if any.

Raises:

  • ValueError

    When more than one of bound and constraints is set.

Methods:

  • as_dict

    Return this type parameter's data as a dictionary.

Attributes:

Source code in src/griffe/_internal/models.py
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
def __init__(
    self,
    name: str,
    *,
    kind: TypeParameterKind,
    bound: str | Expr | None = None,
    constraints: Sequence[str | Expr] | None = None,
    default: str | Expr | None = None,
) -> None:
    """Initialize the type parameter.

    Parameters:
        name: The type parameter name, without leading stars (`*` or `**`).
        kind: The type parameter kind.
        bound: The type parameter bound, if any.
            Mutually exclusive with `constraints`.
        constraints: The type parameter constraints, if any.
            Mutually exclusive with `bound`.
        default: The type parameter default, if any.

    Raises:
        ValueError: When more than one of `bound` and `constraints` is set.
    """
    if bound is not None and constraints:
        raise ValueError("bound and constraints are mutually exclusive")

    self.name: str = name
    """The type parameter name."""

    self.kind: TypeParameterKind = kind
    """The type parameter kind."""

    self.annotation: str | Expr | None
    """The type parameter bound or constraints."""

    if constraints:
        self.constraints = constraints
    else:
        self.bound = bound

    self.default: str | Expr | None = default
    """The type parameter default value."""

annotation instance-attribute ¤

annotation: str | Expr | None

The type parameter bound or constraints.

bound property writable ¤

bound: str | Expr | None

The type parameter bound.

constraints property writable ¤

constraints: tuple[str | Expr, ...] | None

The type parameter constraints.

default instance-attribute ¤

default: str | Expr | None = default

The type parameter default value.

kind instance-attribute ¤

The type parameter kind.

name instance-attribute ¤

name: str = name

The type parameter name.

as_dict ¤

as_dict(**kwargs: Any) -> dict[str, Any]

Return this type parameter's data as a dictionary.

Parameters:

  • **kwargs ¤

    (Any, default: {} ) –

    Additional serialization options.

Returns:

Source code in src/griffe/_internal/models.py
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
def as_dict(self, **kwargs: Any) -> dict[str, Any]:  # noqa: ARG002
    """Return this type parameter's data as a dictionary.

    Parameters:
        **kwargs: Additional serialization options.

    Returns:
        A dictionary.
    """
    base: dict[str, Any] = {
        "name": self.name,
        "kind": self.kind,
        "annotation": self.annotation,
        "default": self.default,
    }
    return base

TypeParameterKind ¤

Bases: str, Enum


              flowchart TD
              griffe.TypeParameterKind[TypeParameterKind]

              

              click griffe.TypeParameterKind href "" "griffe.TypeParameterKind"
            

Enumeration of the different type parameter kinds.

Attributes:

param_spec class-attribute instance-attribute ¤

param_spec = 'param-spec'

Parameter specification variable.

type_var class-attribute instance-attribute ¤

type_var = 'type-var'

Type variable.

type_var_tuple class-attribute instance-attribute ¤

type_var_tuple = 'type-var-tuple'

Type variable tuple.

Git information¤

KnownGitService module-attribute ¤

KnownGitService = Literal[
    "github",
    "gitlab",
    "sourcehut",
    "gitea",
    "gogs",
    "forgejo",
    "codeberg",
    "radicle",
]

Known Git hosting services.

GitInfo dataclass ¤

GitInfo(
    repository: Path,
    service: KnownGitService,
    remote_url: str,
    commit_hash: str,
)

Information about a Git repository.

Methods:

  • from_package

    Create a GitInfo instance from a Griffe package.

  • get_source_link

    Get the source link for the file at the given line numbers.

Attributes:

commit_hash instance-attribute ¤

commit_hash: str

A commit hash (usually the current checked-out one).

remote_url instance-attribute ¤

remote_url: str

The remote URL of the Git repository.

repository instance-attribute ¤

repository: Path

The path to the Git repository.

service instance-attribute ¤

service: KnownGitService

The Git hosting service (used to build the right URLs).

from_package classmethod ¤

from_package(package: Module) -> GitInfo | None

Create a GitInfo instance from a Griffe package.

Returns:

  • GitInfo | None

    The GitInfo instance, or None if unknown.

Source code in src/griffe/_internal/git.py
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
@classmethod
def from_package(cls, package: Module) -> GitInfo | None:
    """Create a GitInfo instance from a Griffe package.

    Returns:
        The GitInfo instance, or None if unknown.
    """
    try:
        path = package.filepath[0] if isinstance(package.filepath, list) else package.filepath
    except BuiltinModuleError:
        return None
    try:
        repo = _get_repo_root(path)
        if not _is_tracked(path.relative_to(repo), repo):
            return None
        remote_url = _get_git_remote_url(repo)
        if not (service := _get_git_known_service(remote_url)):
            return None
        commit_hash = _get_git_commit_hash(repo)
    except (GitError, ValueError, OSError):
        # `ValueError` can happen if `path` is not relative to `repo`.
        # `OSError` is caught just to be safe.
        return None
    return cls(repository=repo, service=service, remote_url=remote_url, commit_hash=commit_hash)
get_source_link(
    filepath: str | Path, lineno: int, endlineno: int
) -> str | None

Get the source link for the file at the given line numbers.

Returns:

  • str | None

    The source link, or None if unknown.

Source code in src/griffe/_internal/git.py
265
266
267
268
269
270
271
def get_source_link(self, filepath: str | Path, lineno: int, endlineno: int) -> str | None:
    """Get the source link for the file at the given line numbers.

    Returns:
        The source link, or None if unknown.
    """
    return _get_source_link(self.service, self.remote_url, self.commit_hash, filepath, lineno, endlineno)