diff --git a/docs/extensions/built-in/dataclasses.md b/docs/extensions/built-in/dataclasses.md index 554a88f79..24e72b70b 100644 --- a/docs/extensions/built-in/dataclasses.md +++ b/docs/extensions/built-in/dataclasses.md @@ -29,14 +29,14 @@ Additional metadata like `ClassVar`, the `init` and `kw_only` parameters, or the === "CLI" ```console - $ griffecli dump -e dataclasses,other my_package + $ griffe dump -e dataclasses,other my_package ``` === "Python" ```python import griffe - my_package = griffelib.load("my_package", extensions=griffelib.load_extensions("dataclasses", "other")) + my_package = griffe.load("my_package", extensions=griffe.load_extensions("dataclasses", "other")) ``` === "mkdocstrings" diff --git a/docs/extensions/built-in/unpack-typeddict.md b/docs/extensions/built-in/unpack-typeddict.md index b7968a72f..d3dbca7ab 100644 --- a/docs/extensions/built-in/unpack-typeddict.md +++ b/docs/extensions/built-in/unpack-typeddict.md @@ -65,14 +65,14 @@ To enable the extension: === "CLI" ```console - $ griffecli dump -e unpack_typeddict my_package + $ griffe dump -e unpack_typeddict my_package ``` === "Python" ```python import griffe - my_package = griffelib.load("my_package", extensions=griffelib.load_extensions("unpack_typeddict")) + my_package = griffe.load("my_package", extensions=griffe.load_extensions("unpack_typeddict")) ``` === "mkdocstrings" diff --git a/docs/extensions/official/runtime-objects.md b/docs/extensions/official/runtime-objects.md index c8c1d730e..27b391e8a 100644 --- a/docs/extensions/official/runtime-objects.md +++ b/docs/extensions/official/runtime-objects.md @@ -11,7 +11,7 @@ This extension stores runtime objects corresponding to each loaded Griffe object ```pycon >>> import griffe ->>> griffe_data = griffelib.load("griffe", extensions=griffelib.load_extensions("griffe_runtime_objects"), resolve_aliases=True) +>>> griffe_data = griffe.load("griffe", extensions=griffe.load_extensions("griffe_runtime_objects"), resolve_aliases=True) >>> griffe_data["parse"].extra defaultdict(, {'runtime-objects': {'object': }}) >>> griffe_data["Module"].extra diff --git a/docs/extensions/official/warnings-deprecated.md b/docs/extensions/official/warnings-deprecated.md index 10ea7f78b..61ff9ddb2 100644 --- a/docs/extensions/official/warnings-deprecated.md +++ b/docs/extensions/official/warnings-deprecated.md @@ -7,7 +7,7 @@ --- -This extension adds support for functions and classes decorated with [`@warnings.deprecated(...)`][warnings.deprecated], as implemented thanks to [PEP 702](https://peps.python.org/pep-0702/). The message provided in the decorator call will be stored in the corresponding Griffe object's [`deprecated`][griffelib.Object.deprecated] attribute (usable by downstream rendering templates), and will also add an admonition to the object's docstring with the provided message as text. +This extension adds support for functions and classes decorated with [`@warnings.deprecated(...)`][warnings.deprecated], as implemented thanks to [PEP 702](https://peps.python.org/pep-0702/). The message provided in the decorator call will be stored in the corresponding Griffe object's [`deprecated`][griffe.Object.deprecated] attribute (usable by downstream rendering templates), and will also add an admonition to the object's docstring with the provided message as text. ```python from warnings import deprecated diff --git a/docs/guide/contributors/architecture.md b/docs/guide/contributors/architecture.md index f360069c1..3d936e9a5 100644 --- a/docs/guide/contributors/architecture.md +++ b/docs/guide/contributors/architecture.md @@ -22,8 +22,8 @@ descriptions = { "scripts": "Our different scripts. See [Scripts, configuration](#scripts-configuration).", "site": "Documentation site, built with `make run mkdocs build` (git-ignored).", "src": "The source of our Python package(s). See [Sources](#sources) and [Program structure](#program-structure).", - "packages/griffe/src/griffe": "Our public API, exposed to users. See [Program structure](#program-structure).", - "packages/griffe/src/griffe/_internal": "Our internal API, hidden from users. See [Program structure](#program-structure).", + "src/griffe": "Our public API, exposed to users. See [Program structure](#program-structure).", + "packages/griffelib/src/griffelib/_internal": "Our internal API, hidden from users. See [Program structure](#program-structure).", "tests": "Our test suite. See [Tests](#tests).", ".copier-answers.yml": "The answers file generated by [Copier](https://copier.readthedocs.io/en/stable/). See [Boilerplate](#boilerplate).", "devdeps.txt": "Our development dependencies specification. See [`make setup`][command-setup] command.", @@ -108,7 +108,7 @@ The test suite is based on [pytest](https://docs.pytest.org/en/8.2.x/). Test mod ## Program structure -The internal API is contained within the `packages/griffe/src/griffe/_internal` folder. The top-level `griffe/__init__.py` module exposes all the public API, by importing the internal objects from various submodules of `griffelib._internal`. +The internal API is contained within the `packages/griffelib/src/griffelib/_internal` folder. The top-level `griffe/__init__.py` module exposes all the public API, by importing the internal objects from `griffelib`, which itself imports from various submodules of `griffelib._internal`. Users then import `griffe` directly, or import objects from it. @@ -122,7 +122,7 @@ if os.getenv("DEPLOY") == "true": from pydeps.target import Target cli.verbose = cli._not_verbose - options = cli.parse_args(["packages/griffe/src/griffe", "--noshow", "--reverse"]) + options = cli.parse_args(["packages/griffelib/src/griffelib", "--noshow", "--reverse"]) colors.START_COLOR = 128 target = Target(options["fname"]) with target.chdir_work(): diff --git a/docs/guide/contributors/workflow.md b/docs/guide/contributors/workflow.md index 62d2ff5f4..0e6064a49 100644 --- a/docs/guide/contributors/workflow.md +++ b/docs/guide/contributors/workflow.md @@ -57,6 +57,10 @@ Deprecated code should also be marked as legacy code. We use [Yore](https://pawa Examples: ```python title="Remove function when we bump to 2.0" +# YORE: Bump 2: Remove block. +def deprecated_function(): + ... +``` ```python title="Simplify imports when Python 3.15 is EOL" # YORE: EOL 3.15: Replace block with line 4. diff --git a/docs/guide/users/checking.md b/docs/guide/users/checking.md index 85c9d9800..9594fafd5 100644 --- a/docs/guide/users/checking.md +++ b/docs/guide/users/checking.md @@ -9,13 +9,13 @@ Griffe is able to compare two snapshots of your project to detect API breakages By default, Griffe will compare the current code to the latest tag: ```console -$ griffecli check mypackage +$ griffe check mypackage ``` To specify another Git reference to check against, use the `--against` or `-a` option: ```console -$ griffecli check mypackage -a 0.2.0 +$ griffe check mypackage -a 0.2.0 ``` You can specify a Git tag, commit (hash), or even a branch: Griffe will create a worktree at this reference in a temporary directory, and clean it up after finishing. @@ -23,24 +23,24 @@ You can specify a Git tag, commit (hash), or even a branch: Griffe will create a If you want to also specify the *base* reference to use (instead of the current code), use the `--base` or `-b` option. Some examples: ```console -$ griffecli check mypackage -b HEAD -a 2.0.0 -$ griffecli check mypackage -b 2.0.0 -a 1.0.0 -$ griffecli check mypackage -b fix-issue-90 -a 1.2.3 -$ griffecli check mypackage -b 8afcfd6e +$ griffe check mypackage -b HEAD -a 2.0.0 +$ griffe check mypackage -b 2.0.0 -a 1.0.0 +$ griffe check mypackage -b fix-issue-90 -a 1.2.3 +$ griffe check mypackage -b 8afcfd6e ``` TIP: **Important:** Remember that the base is the most recent reference, and the one we compare it against is the oldest one. -The package name you pass to `griffecli check` must be found relative to the repository root. For Griffe to find packages in subfolders, pass the parent subfolder to the `--search` or `-s` option. Example for `src`-layouts: +The package name you pass to `griffe check` must be found relative to the repository root. For Griffe to find packages in subfolders, pass the parent subfolder to the `--search` or `-s` option. Example for `src`-layouts: ```console -$ griffecli check -s src griffe +$ griffe check -s src griffe ``` Example in a monorepo, within a deeper file tree: ```console -$ griffecli check -s back/services/identity-provider/src identity_provider +$ griffe check -s back/services/identity-provider/src identity_provider ``` ### Using PyPI @@ -54,39 +54,39 @@ $ pip install griffe[pypi] The command syntax is: ```console -$ griffecli check package_name -b project-name==2.0 -a project-name==1.0 +$ griffe check package_name -b project-name==2.0 -a project-name==1.0 ``` You can let Griffe guess the package name by passing an empty string: ```console -$ griffecli check "" -b project-name==2.0 -a project-name==1.0 +$ griffe check "" -b project-name==2.0 -a project-name==1.0 ``` [PEP 508 version specifiers](https://peps.python.org/pep-0508/) are supported (`<`, `<=`, `!=`, `==`, `>=`, `>`, `~=`). For example, to compare v2 against the version just before it: ```console -$ griffecli check "" -b project-name==2.0 -a project-name<2.0 +$ griffe check "" -b project-name==2.0 -a project-name<2.0 ``` Without a version specifier on the base reference, or without a base reference at all, Griffe will use the latest available version. The two following commands compare the latest version against v1: ```console -$ griffecli check "" -b project-name -a project-name==1.0 -$ griffecli check "" -a project-name==1.0 +$ griffe check "" -b project-name -a project-name==1.0 +$ griffe check "" -a project-name==1.0 ``` Griffe will actually install packages in a cache directory. It means a few things: source distributions are supported, and only packages that are compatible with your current environment can be checked. ## Python API -To programmatically check for API breaking changes, you have to load two snapshots of your code base, for example using our [`load_git()`][griffelib.load_git] utility, and then passing them both to the [`find_breaking_changes()`][griffelib.find_breaking_changes] function. This function will yield instances of [`Breakage`][griffelib.Breakage]. It's up to you how you want to use these breakage instances. +To programmatically check for API breaking changes, you have to load two snapshots of your code base, for example using our [`load_git()`][griffe.load_git] utility, and then passing them both to the [`find_breaking_changes()`][griffe.find_breaking_changes] function. This function will yield instances of [`Breakage`][griffe.Breakage]. It's up to you how you want to use these breakage instances. ```python import griffe -my_pkg_v1 = griffelib.load_git("my_pkg", ref="v1") -my_pkg_v2 = griffelib.load_git("my_pkg", ref="v2") +my_pkg_v1 = griffe.load_git("my_pkg", ref="v1") +my_pkg_v2 = griffe.load_git("my_pkg", ref="v2") for breaking_change in find_breaking_changes(my_pkg_v1, my_pkg_v2): print(breaking_change.explain()) @@ -110,7 +110,7 @@ jobs: fetch-depth: 0 # We the need the full Git history. - uses: astral-sh/setup-uv@v6 # The following command will compare current changes to latest tag. - - run: uvx griffecli check --search src --format github your_package_name + - run: uvx griffe check --search src --format github your_package_name ``` The last step will fail the workflow if any breaking change is found. @@ -643,9 +643,9 @@ Griffe supports writing detected breakages in multiple formats, or styles. This is the default format. Griffe will print each detected breakage on a single line: -```console exec="1" source="console" result="ansi" returncode="1" id="griffecli-check-oneline" +```console exec="1" source="console" result="ansi" returncode="1" id="griffe-check-oneline" $ export FORCE_COLOR=1 # markdown-exec: hide -$ griffecli check griffe -ssrc -b0.46.0 -a0.45.0 +$ griffe check griffe -ssrc -b0.46.0 -a0.45.0 ``` [](){#format-verbose} @@ -655,11 +655,11 @@ $ griffecli check griffe -ssrc -b0.46.0 -a0.45.0 - **CLI**: `-f verbose` / `-v` - **API**: `check(..., style="verbose")` / `check(..., style=ExplanationStyle.VERBOSE)` / `check(..., verbose=True)` -Depending on the detected breakages, the lines might be hard to read (being too compact), so `griffecli check` also accepts a `--verbose` or `-v` option to add some space to the output: +Depending on the detected breakages, the lines might be hard to read (being too compact), so `griffe check` also accepts a `--verbose` or `-v` option to add some space to the output: -```console exec="1" source="console" result="ansi" returncode="1" id="griffecli-check-verbose" +```console exec="1" source="console" result="ansi" returncode="1" id="griffe-check-verbose" $ export FORCE_COLOR=1 # markdown-exec: hide -$ griffecli check griffe -ssrc -b0.46.0 -a0.45.0 --verbose +$ griffe check griffe -ssrc -b0.46.0 -a0.45.0 --verbose ``` [](){#format-markdown} @@ -672,26 +672,26 @@ $ griffecli check griffe -ssrc -b0.46.0 -a0.45.0 --verbose The Markdown format is adapted for changelogs. It doesn't show the file and line number, and instead prints out the complete path of your API objects. With a bit of automation, you will be able to automatically insert a summary of breaking changes in your changelog entries. ```md exec="1" source="tabbed-left" tabs="Output|Result" -- `griffelib.loader.GriffeLoader.resolve_aliases(only_exported)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.loader.GriffeLoader.resolve_aliases(only_exported)`: *Parameter default was changed*: `True` -> `None` -- `griffelib.loader.GriffeLoader.resolve_aliases(only_known_modules)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.loader.GriffeLoader.resolve_aliases(only_known_modules)`: *Parameter default was changed*: `True` -> `None` -- `griffelib.loader.GriffeLoader.resolve_aliases(max_iterations)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.loader.GriffeLoader.resolve_module_aliases(only_exported)`: *Parameter was removed* -- `griffelib.loader.GriffeLoader.resolve_module_aliases(only_known_modules)`: *Parameter was removed* -- `griffelib.git.tmp_worktree(commit)`: *Parameter was removed* -- `griffelib.git.tmp_worktree(repo)`: *Positional parameter was moved*: position: from 2 to 1 (-1) -- `griffelib.git.load_git(commit)`: *Parameter was removed* -- `griffelib.git.load_git(repo)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.git.load_git(submodules)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.git.load_git(try_relative_path)`: *Parameter was removed* -- `griffelib.git.load_git(extensions)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.git.load_git(search_paths)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.git.load_git(docstring_parser)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.git.load_git(docstring_options)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.git.load_git(lines_collection)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.git.load_git(modules_collection)`: *Parameter kind was changed*: positional or keyword -> keyword-only -- `griffelib.git.load_git(allow_inspection)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.loader.GriffeLoader.resolve_aliases(only_exported)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.loader.GriffeLoader.resolve_aliases(only_exported)`: *Parameter default was changed*: `True` -> `None` +- `griffe.loader.GriffeLoader.resolve_aliases(only_known_modules)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.loader.GriffeLoader.resolve_aliases(only_known_modules)`: *Parameter default was changed*: `True` -> `None` +- `griffe.loader.GriffeLoader.resolve_aliases(max_iterations)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.loader.GriffeLoader.resolve_module_aliases(only_exported)`: *Parameter was removed* +- `griffe.loader.GriffeLoader.resolve_module_aliases(only_known_modules)`: *Parameter was removed* +- `griffe.git.tmp_worktree(commit)`: *Parameter was removed* +- `griffe.git.tmp_worktree(repo)`: *Positional parameter was moved*: position: from 2 to 1 (-1) +- `griffe.git.load_git(commit)`: *Parameter was removed* +- `griffe.git.load_git(repo)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.git.load_git(submodules)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.git.load_git(try_relative_path)`: *Parameter was removed* +- `griffe.git.load_git(extensions)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.git.load_git(search_paths)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.git.load_git(docstring_parser)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.git.load_git(docstring_options)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.git.load_git(lines_collection)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.git.load_git(modules_collection)`: *Parameter kind was changed*: positional or keyword -> keyword-only +- `griffe.git.load_git(allow_inspection)`: *Parameter kind was changed*: positional or keyword -> keyword-only ``` [](){#format-github} @@ -701,7 +701,7 @@ The Markdown format is adapted for changelogs. It doesn't show the file and line - **CLI**: `-f github` - **API**: `check(..., style="github")` / `check(..., style=ExplanationStyle.GITHUB)` -When running `griffecli check` in CI, you can enable GitHub's annotations thanks to the GitHub output style. Annotations are displayed on specific lines of code. They are visible in the Checks tab. When you create an annotation for a file that is part of the pull request, the annotations are also shown in the Files changed tab. +When running `griffe check` in CI, you can enable GitHub's annotations thanks to the GitHub output style. Annotations are displayed on specific lines of code. They are visible in the Checks tab. When you create an annotation for a file that is part of the pull request, the annotations are also shown in the Files changed tab. /// tab | Files changed tab ![gha_annotations_2](../../img/gha_annotations_2.png) @@ -712,12 +712,12 @@ When running `griffecli check` in CI, you can enable GitHub's annotations thanks /// ```console -% python -m griffecli check -fgithub -ssrc griffe -::warning file=packages/griffe/src/griffe/finder.py,line=58,title=Package.name::Attribute value was changed: `name` -> unset -::warning file=packages/griffe/src/griffe/finder.py,line=60,title=Package.path::Attribute value was changed: `path` -> unset -::warning file=packages/griffe/src/griffe/finder.py,line=62,title=Package.stubs::Attribute value was changed: `stubs` -> `None` -::warning file=packages/griffe/src/griffe/finder.py,line=75,title=NamespacePackage.name::Attribute value was changed: `name` -> unset -::warning file=packages/griffe/src/griffe/finder.py,line=77,title=NamespacePackage.path::Attribute value was changed: `path` -> unset +% python -m griffe check -fgithub -ssrc griffe +::warning file=src/griffe/finder.py,line=58,title=Package.name::Attribute value was changed: `name` -> unset +::warning file=src/griffe/finder.py,line=60,title=Package.path::Attribute value was changed: `path` -> unset +::warning file=src/griffe/finder.py,line=62,title=Package.stubs::Attribute value was changed: `stubs` -> `None` +::warning file=src/griffe/finder.py,line=75,title=NamespacePackage.name::Attribute value was changed: `name` -> unset +::warning file=src/griffe/finder.py,line=77,title=NamespacePackage.path::Attribute value was changed: `path` -> unset ``` ## Next steps diff --git a/docs/guide/users/extending.md b/docs/guide/users/extending.md index 1f9dd1917..9aa408731 100644 --- a/docs/guide/users/extending.md +++ b/docs/guide/users/extending.md @@ -28,11 +28,11 @@ To specify options in the JSON form, use a dictionary instead of a string: the d Some examples: ```bash -griffecli dump griffe -e pydantic,scripts/exts.py:DynamicDocstrings,griffe_attrs +griffe dump griffe -e pydantic,scripts/exts.py:DynamicDocstrings,griffe_attrs ``` ```bash -griffecli check --search src griffe -e '[ +griffe check --search src griffe -e '[ {"pydantic": {"schema": true}}, { "scripts/exts.py:DynamicDocstrings": { @@ -47,9 +47,9 @@ In the above two examples, `pydantic` would be a built-in extension, `scripts/ex ### Programmatically -Within Python code, extensions can be specified with the `extensions` parameter of the [`GriffeLoader` class][griffelib.GriffeLoader] or [`load` function][griffelib.load]. +Within Python code, extensions can be specified with the `extensions` parameter of the [`GriffeLoader` class][griffe.GriffeLoader] or [`load` function][griffe.load]. -The parameter accepts an instance of the [`Extensions` class][griffelib.Extensions]. Such an instance is created with the help of the [`load_extensions` function][griffelib.load_extensions], which itself accepts a list of strings, dictionaries, extension classes and extension instances. +The parameter accepts an instance of the [`Extensions` class][griffe.Extensions]. Such an instance is created with the help of the [`load_extensions` function][griffe.load_extensions], which itself accepts a list of strings, dictionaries, extension classes and extension instances. Strings and dictionaries are used the same way as [on the command-line](#on-the-command-line). Extension instances are used as such, and extension classes are instantiated without any options. @@ -60,7 +60,7 @@ import griffe from mypackage.extensions import ThisExtension, ThisOtherExtension -extensions = griffelib.load_extensions( +extensions = griffe.load_extensions( {"pydantic": {"schema": true}}, {"scripts/exts.py:DynamicDocstrings": {"paths": ["mypkg.mymod.myobj"]}}, "griffe_attrs", @@ -68,7 +68,7 @@ extensions = griffelib.load_extensions( ThisOtherExtension, ) -data = griffelib.load("mypackage", extensions=extensions) +data = griffe.load("mypackage", extensions=extensions) ``` ### In MkDocs @@ -88,7 +88,7 @@ plugins: - griffe_attrs ``` -The `extensions` key accepts a list that is passed to the [`load_extensions` function][griffelib.load_extensions]. See [how to use extensions programmatically](#programmatically) to learn more. +The `extensions` key accepts a list that is passed to the [`load_extensions` function][griffe.load_extensions]. See [how to use extensions programmatically](#programmatically) to learn more. ## Writing extensions @@ -100,9 +100,9 @@ To extract information from your Python sources, Griffe tries to build Abstract If the source code is not available (the modules are built-in or compiled), Griffe imports the modules and builds object trees instead. -Griffe then follows the [Visitor pattern](https://www.wikiwand.com/en/Visitor_pattern) to walk the tree and extract information. For ASTs, Griffe uses its [Visitor agent][griffelib.Visitor] and for object trees, it uses its [Inspector agent][griffelib.Inspector]. +Griffe then follows the [Visitor pattern](https://www.wikiwand.com/en/Visitor_pattern) to walk the tree and extract information. For ASTs, Griffe uses its [Visitor agent][griffe.Visitor] and for object trees, it uses its [Inspector agent][griffe.Inspector]. -Sometimes during the walk through the source or runtime objects, both the visitor and inspector agents will trigger events, called **analysis events**. These events can be hooked on by extensions to alter or enhance Griffe's behavior. Some hooks will be passed just the current node being visited, others will be passed both the node and an instance of an [Object][griffelib.Object] subclass, such as a [Module][griffelib.Module], a [Class][griffelib.Class], a [Function][griffelib.Function], an [Attribute][griffelib.Attribute], or a [Type Alias][griffelib.TypeAlias]. Extensions will therefore be able to modify these instances. +Sometimes during the walk through the source or runtime objects, both the visitor and inspector agents will trigger events, called **analysis events**. These events can be hooked on by extensions to alter or enhance Griffe's behavior. Some hooks will be passed just the current node being visited, others will be passed both the node and an instance of an [Object][griffe.Object] subclass, such as a [Module][griffe.Module], a [Class][griffe.Class], a [Function][griffe.Function], an [Attribute][griffe.Attribute], or a [Type Alias][griffe.TypeAlias]. Extensions will therefore be able to modify these instances. Once the Griffe tree for a given package has been fully constructed, Griffe will trigger a second set of events, called **load events**, by walking the tree again. **It is safer to use load events as they are triggered only once data is complete for a given package**, contrary to the analysis events which are triggered *while the Griffe tree is still being built*. @@ -114,7 +114,7 @@ M(Module definition) --- C(Class definition) & F(Function definition) C --- m(Function definition) & A(Variable assignment) ``` -The following flow chart shows an example of an object tree inspection. The tree is simplified as well: [many more types of objects are handled][griffelib.ObjectKind]. +The following flow chart shows an example of an object tree inspection. The tree is simplified as well: [many more types of objects are handled][griffe.ObjectKind]. ```mermaid flowchart TB @@ -125,9 +125,9 @@ C --- m(Method) & A(Attribute) For a more concrete example, let say that we visit (or inspect) an AST (or object tree) for a given module, and that this module contains a single class, which itself contains a single method: - the agent (visitor or inspector) will walk through the tree by starting with the module node -- it will instantiate a [Module][griffelib.Module], then walk through its members, continuing with the class node -- it will instantiate a [Class][griffelib.Class], then walk through its members, continuing with the function node -- it will instantiate a [Function][griffelib.Function] +- it will instantiate a [Module][griffe.Module], then walk through its members, continuing with the class node +- it will instantiate a [Class][griffe.Class], then walk through its members, continuing with the function node +- it will instantiate a [Function][griffe.Function] - then it will go back up and finish walking since there are no more nodes to walk through Every time the agent enters a node, creates an object instance, or finishes handling members of an object, it will trigger an event. @@ -137,21 +137,21 @@ The flow of events is drawn in the following flowchart: ```mermaid flowchart TB visit_mod{{enter module node}} -event_mod_node{{"on_node event
on_module_node event"}} +event_mod_node{{"on_node event
on_module_node event"}} create_mod{{create module instance}} -event_mod_instance{{"on_instance event
on_module_instance event"}} +event_mod_instance{{"on_instance event
on_module_instance event"}} visit_mod_members{{visit module members}} visit_cls{{enter class node}} -event_cls_node{{"on_node event
on_class_node event"}} +event_cls_node{{"on_node event
on_class_node event"}} create_cls{{create class instance}} -event_cls_instance{{"on_instance event
on_class_instance event"}} +event_cls_instance{{"on_instance event
on_class_instance event"}} visit_cls_members{{visit class members}} visit_func{{enter func node}} -event_func_node{{"on_node event
on_function_node event"}} +event_func_node{{"on_node event
on_function_node event"}} create_func{{create function instance}} -event_func_instance{{"on_instance event
on_function_instance event"}} -event_cls_members{{"on_members event
on_class_members event"}} -event_mod_members{{"on_members event
on_module_members event"}} +event_func_instance{{"on_instance event
on_function_instance event"}} +event_cls_members{{"on_members event
on_class_members event"}} +event_mod_members{{"on_members event
on_module_members event"}} start{start} --> visit_mod visit_mod --> event_mod_node @@ -198,17 +198,17 @@ There are two kinds of events in Griffe: [**load events**](#load-events) and [** There is 1 generic **load event**: -- [`on_object`][griffelib.Extension.on_object]: The "on object" event is triggered on any kind of object (except for aliases and packages, so modules, classes, functions, attributes and type aliases), once the tree for the object's package has been fully constructed. +- [`on_object`][griffe.Extension.on_object]: The "on object" event is triggered on any kind of object (except for aliases and packages, so modules, classes, functions, attributes and type aliases), once the tree for the object's package has been fully constructed. There are also specific **load events** for each object kind: -- [`on_module`][griffelib.Extension.on_module]: The "on module" event is triggered on modules. -- [`on_class`][griffelib.Extension.on_class]: The "on class" event is triggered on classes. -- [`on_function`][griffelib.Extension.on_function]: The "on function" event is triggered on functions. -- [`on_attribute`][griffelib.Extension.on_attribute]: The "on attribute" event is triggered on attributes. -- [`on_type_alias`][griffelib.Extension.on_type_alias]: The "on type alias" event is triggered on type aliases. -- [`on_alias`][griffelib.Extension.on_alias]: The "on alias" event is triggered on aliases (imported/inherited objects). -- [`on_package`][griffelib.Extension.on_package]: The "on package" event is triggered on top-level modules (packages) only. +- [`on_module`][griffe.Extension.on_module]: The "on module" event is triggered on modules. +- [`on_class`][griffe.Extension.on_class]: The "on class" event is triggered on classes. +- [`on_function`][griffe.Extension.on_function]: The "on function" event is triggered on functions. +- [`on_attribute`][griffe.Extension.on_attribute]: The "on attribute" event is triggered on attributes. +- [`on_type_alias`][griffe.Extension.on_type_alias]: The "on type alias" event is triggered on type aliases. +- [`on_alias`][griffe.Extension.on_alias]: The "on alias" event is triggered on aliases (imported/inherited objects). +- [`on_package`][griffe.Extension.on_package]: The "on package" event is triggered on top-level modules (packages) only. #### Analysis events @@ -216,46 +216,46 @@ There are also specific **load events** for each object kind: There are 3 generic **analysis events**: -- [`on_node`][griffelib.Extension.on_node]: The "on node" events are triggered when the agent (visitor or inspector) starts handling a node in the tree (AST or object tree). -- [`on_instance`][griffelib.Extension.on_instance]: The "on instance" events are triggered when the agent just created an instance of [Module][griffelib.Module], [Class][griffelib.Class], [Function][griffelib.Function], [Attribute][griffelib.Attribute], or [Type Alias][griffelib.TypeAlias], and added it as a member of its parent. The "on instance" event is **not** triggered when an [Alias][griffelib.Alias] is created. -- [`on_members`][griffelib.Extension.on_members]: The "on members" events are triggered when the agent just finished handling all the members of an object. Functions, attributes and type aliases do not have members, so there are no "on members" events for these kinds. +- [`on_node`][griffe.Extension.on_node]: The "on node" events are triggered when the agent (visitor or inspector) starts handling a node in the tree (AST or object tree). +- [`on_instance`][griffe.Extension.on_instance]: The "on instance" events are triggered when the agent just created an instance of [Module][griffe.Module], [Class][griffe.Class], [Function][griffe.Function], [Attribute][griffe.Attribute], or [Type Alias][griffe.TypeAlias], and added it as a member of its parent. The "on instance" event is **not** triggered when an [Alias][griffe.Alias] is created. +- [`on_members`][griffe.Extension.on_members]: The "on members" events are triggered when the agent just finished handling all the members of an object. Functions, attributes and type aliases do not have members, so there are no "on members" events for these kinds. There are also specific **analysis events** for each object kind: -- [`on_module_node`][griffelib.Extension.on_module_node] -- [`on_module_instance`][griffelib.Extension.on_module_instance] -- [`on_module_members`][griffelib.Extension.on_module_members] -- [`on_class_node`][griffelib.Extension.on_class_node] -- [`on_class_instance`][griffelib.Extension.on_class_instance] -- [`on_class_members`][griffelib.Extension.on_class_members] -- [`on_function_node`][griffelib.Extension.on_function_node] -- [`on_function_instance`][griffelib.Extension.on_function_instance] -- [`on_attribute_node`][griffelib.Extension.on_attribute_node] -- [`on_attribute_instance`][griffelib.Extension.on_attribute_instance] -- [`on_type_alias_node`][griffelib.Extension.on_type_alias_node] -- [`on_type_alias_instance`][griffelib.Extension.on_type_alias_instance] -- [`on_alias_instance`][griffelib.Extension.on_alias_instance] +- [`on_module_node`][griffe.Extension.on_module_node] +- [`on_module_instance`][griffe.Extension.on_module_instance] +- [`on_module_members`][griffe.Extension.on_module_members] +- [`on_class_node`][griffe.Extension.on_class_node] +- [`on_class_instance`][griffe.Extension.on_class_instance] +- [`on_class_members`][griffe.Extension.on_class_members] +- [`on_function_node`][griffe.Extension.on_function_node] +- [`on_function_instance`][griffe.Extension.on_function_instance] +- [`on_attribute_node`][griffe.Extension.on_attribute_node] +- [`on_attribute_instance`][griffe.Extension.on_attribute_instance] +- [`on_type_alias_node`][griffe.Extension.on_type_alias_node] +- [`on_type_alias_instance`][griffe.Extension.on_type_alias_instance] +- [`on_alias_instance`][griffe.Extension.on_alias_instance] #### Extensions and hooks -**Extensions** are classes that inherit from [Griffe's Extension base class][griffelib.Extension] and define some hooks as methods: +**Extensions** are classes that inherit from [Griffe's Extension base class][griffe.Extension] and define some hooks as methods: ```python import griffe -class MyExtension(griffelib.Extension): +class MyExtension(griffe.Extension): def on_object( self, *, - obj: griffelib.Object, - loader: griffelib.GriffeLoader, + obj: griffe.Object, + loader: griffe.GriffeLoader, **kwargs, ) -> None: """Do something with `obj`.""" ``` -Hooks are always defined as methods of a class inheriting from [Extension][griffelib.Extension], never as standalone functions. IDEs should autocomplete the signature when you start typing `def` followed by a hook name. +Hooks are always defined as methods of a class inheriting from [Extension][griffe.Extension], never as standalone functions. IDEs should autocomplete the signature when you start typing `def` followed by a hook name. Since hooks are declared in a class, feel free to also declare state variables (or any other variable) in the `__init__` method: @@ -273,8 +273,8 @@ class MyExtension(Extension): def on_object( self, *, - obj: griffelib.Object, - loader: griffelib.GriffeLoader, + obj: griffe.Object, + loader: griffe.GriffeLoader, **kwargs, ) -> None: """Do something with `obj`.""" @@ -292,8 +292,8 @@ To support static analysis, dynamic analysis, or both in your load events, you c import griffe -class MyExtension(griffelib.Extension): - def on_object(self, *, obj: griffelib.Object, **kwargs) -> None: +class MyExtension(griffe.Extension): + def on_object(self, *, obj: griffe.Object, **kwargs) -> None: """Do something with `obj`.""" if obj.analysis == "static": ... # Apply logic for static analysis. @@ -307,10 +307,10 @@ class MyExtension(griffelib.Extension): Extensions provide basic functionality to help you visit trees during analysis of the code: -- [`visit`][griffelib.Extension.visit]: call `self.visit(node)` to start visiting an abstract syntax tree. -- [`generic_visit`][griffelib.Extension.generic_visit]: call `self.generic_visit(node)` to visit each subnode of a given node. -- [`inspect`][griffelib.Extension.inspect]: call `self.inspect(node)` to start visiting an object tree. Nodes contain references to the runtime objects, see [`ObjectNode`][griffelib.ObjectNode]. -- [`generic_inspect`][griffelib.Extension.generic_inspect]: call `self.generic_inspect(node)` to visit each subnode of a given node. +- [`visit`][griffe.Extension.visit]: call `self.visit(node)` to start visiting an abstract syntax tree. +- [`generic_visit`][griffe.Extension.generic_visit]: call `self.generic_visit(node)` to visit each subnode of a given node. +- [`inspect`][griffe.Extension.inspect]: call `self.inspect(node)` to start visiting an object tree. Nodes contain references to the runtime objects, see [`ObjectNode`][griffe.ObjectNode]. +- [`generic_inspect`][griffe.Extension.generic_inspect]: call `self.generic_inspect(node)` to visit each subnode of a given node. Calling `self.visit(node)` or `self.inspect(node)` will do nothing unless you actually implement methods that handle specific types of nodes: @@ -333,7 +333,7 @@ Calling `self.visit(node)` or `self.inspect(node)` will do nothing unless you ac See the [list of existing AST classes](#ast-nodes) to learn what method you can implement. -- for object trees, methods must be named `inspect_`, where `` is replaced with the string value of the node's kind. The different kinds are listed in the [`ObjectKind`][griffelib.ObjectKind] enumeration. For example, to allow inspecting coroutine nodes, you must implement the `inspect_coroutine` method: +- for object trees, methods must be named `inspect_`, where `` is replaced with the string value of the node's kind. The different kinds are listed in the [`ObjectKind`][griffe.ObjectKind] enumeration. For example, to allow inspecting coroutine nodes, you must implement the `inspect_coroutine` method: ```python from griffe import Extension, ObjectNode @@ -349,26 +349,26 @@ Calling `self.visit(node)` or `self.inspect(node)` will do nothing unless you ac ### Triggering other extensions -If your extension creates new objects, you might want to trigger the other enabled extensions on these object instances. To do this you can use [`agent.extensions.call`][griffelib.Extensions.call]: +If your extension creates new objects, you might want to trigger the other enabled extensions on these object instances. To do this you can use [`agent.extensions.call`][griffe.Extensions.call]: ```python import ast import griffe -class MyExtension(griffelib.Extension): +class MyExtension(griffe.Extension): # Example from within a load event: - def on_package(self, *, pkg: griffelib.Module, loader: griffelib.GriffeLoader, **kwargs) -> None: + def on_package(self, *, pkg: griffe.Module, loader: griffe.GriffeLoader, **kwargs) -> None: # New object created for whatever reason. - function = griffelib.Function(...) + function = griffe.Function(...) # Trigger other extensions. loader.extensions.call("on_function", func=function, loader=loader) # Example from within an analysis event: - def on_node(self, *, node: ast.AST | griffelib.ObjectNode, agent: griffelib.Visitor | griffelib.Inspector, **kwargs) -> None: + def on_node(self, *, node: ast.AST | griffe.ObjectNode, agent: griffe.Visitor | griffe.Inspector, **kwargs) -> None: # New object created for whatever reason. - function = griffelib.Function(...) + function = griffe.Function(...) # Trigger other extensions. agent.extensions.call("on_function_instance", node=node, agent=agent, func=function, **kwargs) @@ -384,8 +384,8 @@ import griffe self_namespace = "my_extension" -class MyExtension(griffelib.Extension): - def on_object(self, obj: griffelib.Object, **kwargs) -> None: +class MyExtension(griffe.Extension): + def on_object(self, obj: griffe.Object, **kwargs) -> None: obj.extra[self_namespace]["some_key"] = "some_value" ``` @@ -398,8 +398,8 @@ self_namespace = "my_extension" mkdocstrings_namespace = "mkdocstrings" -class MyExtension(griffelib.Extension): - def on_class(self, cls: griffelib.Class, **kwargs) -> None: +class MyExtension(griffe.Extension): + def on_class(self, cls: griffe.Class, **kwargs) -> None: cls.extra[mkdocstrings_namespace]["template"] = "my_custom_template" ``` @@ -413,13 +413,13 @@ Extensions can be made to support options. These options can then be passed from import griffe -class MyExtension(griffelib.Extension): +class MyExtension(griffe.Extension): def __init__(self, option1: str, option2: bool = False) -> None: super().__init__() self.option1 = option1 self.option2 = option2 - def on_attribute(self, attr: griffelib.Attribute, **kwargs) -> None: + def on_attribute(self, attr: griffe.Attribute, **kwargs) -> None: if self.option2: ... # Do something. ``` @@ -431,11 +431,11 @@ To better integrate with Griffe and other tools in the ecosystem (notably MkDocs ```python import griffe -logger = griffelib.get_logger(__name__) +logger = griffe.get_logger(__name__) -class MyExtension(griffelib.Extension): - def on_module(self, mod: griffelib.Module, **kwargs) -> None: +class MyExtension(griffe.Extension): + def on_module(self, mod: griffe.Module, **kwargs) -> None: logger.info("Doing some work on module %s", mod.path) ``` @@ -459,17 +459,17 @@ import ast import inspect import griffe -logger = griffelib.get_logger(__name__) +logger = griffe.get_logger(__name__) -class DynamicDocstrings(griffelib.Extension): +class DynamicDocstrings(griffe.Extension): def __init__(self, object_paths: list[str] | None = None) -> None: self.object_paths = object_paths def on_object( self, - obj: griffelib.Object, - loader: griffelib.GriffeLoader, + obj: griffe.Object, + loader: griffe.GriffeLoader, **kwargs, ) -> None: if obj.analysis == "dynamic": @@ -480,7 +480,7 @@ class DynamicDocstrings(griffelib.Extension): # Import object to get its evaluated docstring. try: - runtime_obj = griffelib.dynamic_import(obj.path) + runtime_obj = griffe.dynamic_import(obj.path) docstring = runtime_obj.__doc__ except ImportError: logger.debug(f"Could not get dynamic docstring for {obj.path}") @@ -494,7 +494,7 @@ class DynamicDocstrings(griffelib.Extension): if obj.docstring: obj.docstring.value = docstring else: - obj.docstring = griffelib.Docstring( + obj.docstring = griffe.Docstring( docstring, parent=obj, docstring_parser=loader.docstring_parser, diff --git a/docs/guide/users/how-to/parse-docstrings.md b/docs/guide/users/how-to/parse-docstrings.md index 70ebb6c05..fef3d12ee 100644 --- a/docs/guide/users/how-to/parse-docstrings.md +++ b/docs/guide/users/how-to/parse-docstrings.md @@ -1,6 +1,6 @@ # Using Griffe as a docstring-parsing library -You can use Griffe to parse arbitrary docstrings. You don't have to load anything through the Griffe loader. You just need to import the [`Docstring`][griffelib.Docstring] class. Then you can build a `Docstring` instance and call its `parse` method, choosing the parsing-style to use: +You can use Griffe to parse arbitrary docstrings. You don't have to load anything through the Griffe loader. You just need to import the [`Docstring`][griffe.Docstring] class. Then you can build a `Docstring` instance and call its `parse` method, choosing the parsing-style to use: ```python from griffe import Docstring diff --git a/docs/guide/users/how-to/selectively-inspect.md b/docs/guide/users/how-to/selectively-inspect.md index cfb0bf594..87be96210 100644 --- a/docs/guide/users/how-to/selectively-inspect.md +++ b/docs/guide/users/how-to/selectively-inspect.md @@ -26,7 +26,7 @@ Start by creating an extensions module (a simple Python file) somewhere in your import griffe -class InspectSpecificObjects(griffelib.Extension): +class InspectSpecificObjects(griffe.Extension): """An extension to inspect just a few specific objects.""" ``` @@ -36,7 +36,7 @@ Make it accept configuration options by declaring an `__init__` method: import griffe -class InspectSpecificObjects(griffelib.Extension): +class InspectSpecificObjects(griffe.Extension): """An extension to inspect just a few specific objects.""" def __init__(self, objects: list[str]) -> None: @@ -53,17 +53,17 @@ Now that our extension accepts options, we implement its core functionality. We import griffe -class InspectSpecificObjects(griffelib.Extension): +class InspectSpecificObjects(griffe.Extension): """An extension to inspect just a few specific objects.""" def __init__(self, objects: list[str]) -> None: self.objects = objects - def on_instance(self, *, obj: griffelib.Object, **kwargs) -> None: + def on_instance(self, *, obj: griffe.Object, **kwargs) -> None: ... ``` -Check out the [available hooks][griffelib.Extension] to see if there more appropriate hooks for your needs. +Check out the [available hooks][griffe.Extension] to see if there more appropriate hooks for your needs. Lets now use our configuration option to decide whether to do something or skip: @@ -71,13 +71,13 @@ Lets now use our configuration option to decide whether to do something or skip: import griffe -class InspectSpecificObjects(griffelib.Extension): +class InspectSpecificObjects(griffe.Extension): """An extension to inspect just a few specific objects.""" def __init__(self, objects: list[str]) -> None: self.objects = objects - def on_instance(self, *, obj: griffelib.Object, **kwargs) -> None: + def on_instance(self, *, obj: griffe.Object, **kwargs) -> None: if obj.path not in self.objects: return ``` @@ -87,21 +87,21 @@ Now we know that only the objects we're interested in will be handled, so lets h ```python hl_lines="3 16-20" import griffe -logger = griffelib.get_logger("griffe_inspect_specific_objects") # (1)! +logger = griffe.get_logger("griffe_inspect_specific_objects") # (1)! -class InspectSpecificObjects(griffelib.Extension): +class InspectSpecificObjects(griffe.Extension): """An extension to inspect just a few specific objects.""" def __init__(self, objects: list[str]) -> None: self.objects = objects - def on_instance(self, *, obj: griffelib.Object, **kwargs) -> None: + def on_instance(self, *, obj: griffe.Object, **kwargs) -> None: if obj.path not in self.objects: return try: - runtime_obj = griffelib.dynamic_import(obj.path) + runtime_obj = griffe.dynamic_import(obj.path) except ImportError as error: logger.warning(f"Could not import {obj.path}: {error}") # (2)! return @@ -117,21 +117,21 @@ For example, we could use the runtime object's `__doc__` attribute, which could ```python hl_lines="22-25" import griffe -logger = griffelib.get_logger("griffe_inspect_specific_objects") +logger = griffe.get_logger("griffe_inspect_specific_objects") -class InspectSpecificObjects(griffelib.Extension): +class InspectSpecificObjects(griffe.Extension): """An extension to inspect just a few specific objects.""" def __init__(self, objects: list[str]) -> None: self.objects = objects - def on_instance(self, *, obj: griffelib.Object, **kwargs) -> None: + def on_instance(self, *, obj: griffe.Object, **kwargs) -> None: if obj.path not in self.objects: return try: - runtime_obj = griffelib.dynamic_import(obj.path) + runtime_obj = griffe.dynamic_import(obj.path) except ImportError as error: logger.warning(f"Could not import {obj.path}: {error}") return @@ -139,7 +139,7 @@ class InspectSpecificObjects(griffelib.Extension): if obj.docstring: obj.docstring.value = runtime_obj.__doc__ else: - obj.docstring = griffelib.Docstring(runtime_obj.__doc__) + obj.docstring = griffe.Docstring(runtime_obj.__doc__) ``` Or we could alter the Griffe object parameters in case of functions, which could have been modified by a signature-changing decorator: @@ -148,21 +148,21 @@ Or we could alter the Griffe object parameters in case of functions, which could import inspect import griffe -logger = griffelib.get_logger("griffe_inspect_specific_objects") +logger = griffe.get_logger("griffe_inspect_specific_objects") -class InspectSpecificObjects(griffelib.Extension): +class InspectSpecificObjects(griffe.Extension): """An extension to inspect just a few specific objects.""" def __init__(self, objects: list[str]) -> None: self.objects = objects - def on_instance(self, *, obj: griffelib.Object, **kwargs) -> None: + def on_instance(self, *, obj: griffe.Object, **kwargs) -> None: if obj.path not in self.objects: return try: - runtime_obj = griffelib.dynamic_import(obj.path) + runtime_obj = griffe.dynamic_import(obj.path) except ImportError as error: logger.warning(f"Could not import {obj.path}: {error}") return @@ -181,17 +181,17 @@ We could also entirely replace the Griffe object obtained from static analysis b import griffe -class InspectSpecificObjects(griffelib.Extension): +class InspectSpecificObjects(griffe.Extension): """An extension to inspect just a few specific objects.""" def __init__(self, objects: list[str]) -> None: self.objects = objects - def on_instance(self, *, obj: griffelib.Object, **kwargs) -> None: + def on_instance(self, *, obj: griffe.Object, **kwargs) -> None: if obj.path not in self.objects: return - inspected_module = griffelib.inspect(obj.module.path, filepath=obj.filepath) + inspected_module = griffe.inspect(obj.module.path, filepath=obj.filepath) obj.parent.set_member(obj.name, inspected_module[obj.name]) # (1)! ``` diff --git a/docs/guide/users/how-to/set-docstring-styles.md b/docs/guide/users/how-to/set-docstring-styles.md index ddfb4794d..5c03e5cfd 100644 --- a/docs/guide/users/how-to/set-docstring-styles.md +++ b/docs/guide/users/how-to/set-docstring-styles.md @@ -44,11 +44,11 @@ import re import griffe -class ApplyDocstringStyle(griffelib.Extension): +class ApplyDocstringStyle(griffe.Extension): def __init__(self, regex: str = "") -> None: self.regex = re.compile(regex) - def on_instance(self, *, obj: griffelib.Object, **kwargs) -> None: + def on_instance(self, *, obj: griffe.Object, **kwargs) -> None: if obj.docstring: if match := self.regex.search(obj.docstring.value): obj.docstring.parser = match.group(1) @@ -73,11 +73,11 @@ import re import griffe -class ApplyDocstringStyle(griffelib.Extension): +class ApplyDocstringStyle(griffe.Extension): def __init__(self, regex: str = ".*# style: (google|numpy|sphinx)$") -> None: self.regex = re.compile(regex) - def on_instance(self, *, obj: griffelib.Object, **kwargs) -> None: + def on_instance(self, *, obj: griffe.Object, **kwargs) -> None: if obj.docstring: if match := self.regex.search(obj.docstring.source): obj.docstring.parser = match.group(1) @@ -91,7 +91,7 @@ Finally, you could decide to map a list of objects to the docstring style they s import griffe from fnmatch import fnmatch -class ApplyDocstringStyle(griffelib.Extension): +class ApplyDocstringStyle(griffe.Extension): def __init__(self, config: dict[str, str]): self.instances = {} self.globs = {} @@ -101,7 +101,7 @@ class ApplyDocstringStyle(griffelib.Extension): else: self.instances[key] = value - def on_instance(self, *, obj: griffelib.Object, **kwargs) -> None: + def on_instance(self, *, obj: griffe.Object, **kwargs) -> None: if obj.path in self.instances: if obj.docstring: obj.docsring.parser = self.instances[obj.path] diff --git a/docs/guide/users/how-to/set-git-info.md b/docs/guide/users/how-to/set-git-info.md index 9c827940f..5fde20b4a 100644 --- a/docs/guide/users/how-to/set-git-info.md +++ b/docs/guide/users/how-to/set-git-info.md @@ -12,7 +12,7 @@ Start by creating an extensions module (a simple Python file) somewhere in your import griffe -class GitInfo(griffelib.Extension): +class GitInfo(griffe.Extension): """An extension to set the right Git information.""" ``` @@ -25,12 +25,12 @@ from typing import Any import griffe -class GitInfo(griffelib.Extension): +class GitInfo(griffe.Extension): """An extension to set the right Git information.""" - def on_package(self, *, pkg: griffelib.Module, **kwargs: Any) -> None: + def on_package(self, *, pkg: griffe.Module, **kwargs: Any) -> None: if pkg.name == "my_package_name": - pkg.git_info = griffelib.GitInfo( + pkg.git_info = griffe.GitInfo( repository=Path("/path/to/this/package/local/repository"), service="forgejo", remote_url="https://myhostedforge.mydomain.com/myaccount/myproject", @@ -51,7 +51,7 @@ We could also reuse properties that Griffe found: ```python # Here we reuse `repository` and `commit_hash` while overriding only `service` and `remote_url`. -pkg.git_info = griffelib.GitInfo( +pkg.git_info = griffe.GitInfo( repository=pkg.git_info.repository, service="forgejo", remote_url="https://myhostedforge.mydomain.com/myaccount/myproject", @@ -74,7 +74,7 @@ Start by creating an extensions module (a simple Python file) somewhere in your import griffe -class SourceLinks(griffelib.Extension): +class SourceLinks(griffe.Extension): """An extension to set the right source links.""" ``` @@ -87,10 +87,10 @@ from typing import Any import griffe -class SourceLinks(griffelib.Extension): +class SourceLinks(griffe.Extension): """An extension to set the right source links.""" - def on_object(self, *, obj: griffelib.Object, **kwargs: Any) -> None: + def on_object(self, *, obj: griffe.Object, **kwargs: Any) -> None: if obj.path == "my_package_name.my_function": obj.source_link = "https://myhostedforge.mydomain.com/myaccount/myproject/src/commit/77f928aeab857cb45564462a4f849c2df2cca99a/src/lib.rs#L35-L48" # Handle any other object you want. @@ -107,10 +107,10 @@ from typing import Any import griffe -class SourceLinks(griffelib.Extension): +class SourceLinks(griffe.Extension): """An extension to set the right source links.""" - def on_object(self, *, obj: griffelib.Object, **kwargs: Any) -> None: + def on_object(self, *, obj: griffe.Object, **kwargs: Any) -> None: if obj.path == "my_package_name.my_function": obj.source_link = obj.git_info.get_source_link( filepath="src/lib.rs", diff --git a/docs/guide/users/how-to/support-decorators.md b/docs/guide/users/how-to/support-decorators.md index ffde3455e..b0fe8da5c 100644 --- a/docs/guide/users/how-to/support-decorators.md +++ b/docs/guide/users/how-to/support-decorators.md @@ -24,11 +24,11 @@ Start by creating an extensions module (a simple Python file) somewhere in your import griffe -class MyDecorator(griffelib.Extension): +class MyDecorator(griffe.Extension): """An extension to suport my decorator.""" ``` -Now we can declare the [`on_instance`][griffelib.Extension.on_instance] hook, which receives any kind of Griffe object ([`Module`][griffelib.Module], [`Class`][griffelib.Class], [`Function`][griffelib.Function], [`Attribute`][griffelib.Attribute], [`TypeAlias`][griffelib.TypeAlias]), or we could use a kind-specific hook such as [`on_module_instance`][griffelib.Extension.on_module_instance], [`on_class_instance`][griffelib.Extension.on_class_instance], [`on_function_instance`][griffelib.Extension.on_function_instance], [`on_attribute_instance`][griffelib.Extension.on_attribute_instance] and [`on_type_alias_instance`][griffelib.Extension.on_type_alias_instance]. For example, if you know your decorator is only ever used on class declarations, it would make sense to use `on_class_instance`. +Now we can declare the [`on_instance`][griffe.Extension.on_instance] hook, which receives any kind of Griffe object ([`Module`][griffe.Module], [`Class`][griffe.Class], [`Function`][griffe.Function], [`Attribute`][griffe.Attribute], [`TypeAlias`][griffe.TypeAlias]), or we could use a kind-specific hook such as [`on_module_instance`][griffe.Extension.on_module_instance], [`on_class_instance`][griffe.Extension.on_class_instance], [`on_function_instance`][griffe.Extension.on_function_instance], [`on_attribute_instance`][griffe.Extension.on_attribute_instance] and [`on_type_alias_instance`][griffe.Extension.on_type_alias_instance]. For example, if you know your decorator is only ever used on class declarations, it would make sense to use `on_class_instance`. For the example, lets use the `on_function_instance` hook, which receives `Function` instances. @@ -36,10 +36,10 @@ For the example, lets use the `on_function_instance` hook, which receives `Funct import griffe -class MyDecorator(griffelib.Extension): +class MyDecorator(griffe.Extension): """An extension to suport my decorator.""" - def on_function_instance(self, *, func: griffelib.Function, **kwargs) -> None: + def on_function_instance(self, *, func: griffe.Function, **kwargs) -> None: ... ``` @@ -49,13 +49,13 @@ In this hook, we check if our function is decorated with our custom decorator: import griffe -class MyDecorator(griffelib.Extension): +class MyDecorator(griffe.Extension): """An extension to suport my decorator.""" - def on_function_instance(self, *, func: griffelib.Function, **kwargs) -> None: + def on_function_instance(self, *, func: griffe.Function, **kwargs) -> None: for decorator in func.decorators: if decorator.callable_path == "my_package.utils.enhance": ... # Update the function attributes. ``` -Now all that is left to do is to actually write the code that updates the function according to what the decorator is doing. We could update the function's docstring, or its return type, or its parameters: it all depends on your decorator and what it does to the objects it decorates. Check out the [API reference for function objects][griffelib.Function] to see what data this object stores. +Now all that is left to do is to actually write the code that updates the function according to what the decorator is doing. We could update the function's docstring, or its return type, or its parameters: it all depends on your decorator and what it does to the objects it decorates. Check out the [API reference for function objects][griffe.Function] to see what data this object stores. diff --git a/docs/guide/users/loading.md b/docs/guide/users/loading.md index 06a98a040..4bbd1c12a 100644 --- a/docs/guide/users/loading.md +++ b/docs/guide/users/loading.md @@ -4,12 +4,12 @@ Griffe can load API data from both source code (static analysis) and objects at ## The `load` function -The main interface to load API data is Griffe's [`load`][griffelib.load] function: +The main interface to load API data is Griffe's [`load`][griffe.load] function: ```python import griffe -my_package = griffelib.load("my_package") +my_package = griffe.load("my_package") ``` You can ask to load a specific object rather than a package: @@ -17,7 +17,7 @@ You can ask to load a specific object rather than a package: ```python import griffe -my_method = griffelib.load("my_package.MyClass.my_method") +my_method = griffe.load("my_package.MyClass.my_method") ``` Griffe will load the whole package anyway, but return the specified object directly, so that you don't have to access it manually. To manually access the object representing the method called `my_method`, you would have used the `my_package` variable instantiated before, like this: @@ -33,8 +33,8 @@ Finally, you can even load packages or modules by passing absolute or relative f ```python import griffe -griffelib.load("src/my_package") -griffelib.load("some_script.py") +griffe.load("src/my_package") +griffe.load("some_script.py") ``` In case of ambiguity, you can instruct Griffe to ignore existing relative file paths with `try_relative_paths=False`. For example, when using [the flat layout (in contrast to the src-layout)](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/), your Python package is in the root of the repository. @@ -51,12 +51,12 @@ Here if you ask Griffe to load `my_package`, it will find it as a relative path, ```python import griffe -my_installed_package = griffelib.load("my_package", try_relative_path=False) +my_installed_package = griffe.load("my_package", try_relative_path=False) ``` ## The `GriffeLoader` class -The [`load`][griffelib.load] function is a shortcut for instantiating the [`GriffeLoader`][griffelib.GriffeLoader] class and calling its [`load`][griffelib.GriffeLoader.load] method. Calling the [`load`][griffelib.load] function multiple times will instantiate a new Griffe loader each time. If you care about efficiency, it is better to instantiate the loader yourself and use its `load` method: +The [`load`][griffe.load] function is a shortcut for instantiating the [`GriffeLoader`][griffe.GriffeLoader] class and calling its [`load`][griffe.GriffeLoader.load] method. Calling the [`load`][griffe.load] function multiple times will instantiate a new Griffe loader each time. If you care about efficiency, it is better to instantiate the loader yourself and use its `load` method: ```python import griffe @@ -72,13 +72,13 @@ Reusing the same loader will also help resolving aliases across different packag ## Search paths -To specify in which directories Griffe should search for packages and modules, you can use the `search_paths` parameter on both the [`load` function][griffelib.load] and the [`GriffeLoader` class][griffelib.GriffeLoader]. +To specify in which directories Griffe should search for packages and modules, you can use the `search_paths` parameter on both the [`load` function][griffe.load] and the [`GriffeLoader` class][griffe.GriffeLoader]. === "`load`" ```python import griffe - my_package = griffelib.load("my_package", search_paths=["src"]) + my_package = griffe.load("my_package", search_paths=["src"]) ``` === "`GriffeLoader`" @@ -100,7 +100,7 @@ Griffe always tries first to find sources for the specified object. Then, unless ```python import griffe -my_package = griffelib.load("my_package", force_inspection=True) +my_package = griffe.load("my_package", force_inspection=True) ``` [](){#forcing-dynamic-analysis-not-recommended} @@ -125,10 +125,10 @@ If you want to be careful about what gets executed in the current Python process import griffe # Here Griffe will fall back on dynamic analysis and import `itertools`. -griffelib.load("itertools") +griffe.load("itertools") # While here it will raise `ModuleNotFoundError`. -griffelib.load("itertools", allow_inspection=False) +griffe.load("itertools", allow_inspection=False) ``` ## Alias resolution @@ -138,7 +138,7 @@ griffelib.load("itertools", allow_inspection=False) > > The name "alias" comes from the fact that imported objects can be aliased under a different name: `from X import A as B`. In the case of inherited members, this doesn't really apply, but we reuse the concept for conciseness. > -> An [`Alias`][griffelib.Alias] instance is therefore a pointer to another object. It has its own name, parent, line numbers, and stores the path to the target object. Thanks to this path, we can access the actual target object and all its metadata, such as name, parent, line numbers, docstring, etc.. Obtaining a reference to the target object is what we call "alias resolution". +> An [`Alias`][griffe.Alias] instance is therefore a pointer to another object. It has its own name, parent, line numbers, and stores the path to the target object. Thanks to this path, we can access the actual target object and all its metadata, such as name, parent, line numbers, docstring, etc.. Obtaining a reference to the target object is what we call "alias resolution". > > **To summarize, alias resolution is a post-process task that resolves imports after loading everything.** @@ -171,14 +171,14 @@ When loading this package, `my_package.my_function` will be an alias pointing at ```python import griffe -my_package = griffelib.load("my_package") +my_package = griffe.load("my_package") my_package["my_function"].resolved # False ``` ```python import griffe -my_package = griffelib.load("my_package", resolve_aliases=True) +my_package = griffe.load("my_package", resolve_aliases=True) my_package["my_function"].resolved # True my_package["my_function"].target is my_package["my_module.my_function"] # True ``` @@ -207,17 +207,17 @@ from package1 import X ```pycon >>> import griffe ->>> package2 = griffelib.load("package2", resolve_aliases=True) +>>> package2 = griffe.load("package2", resolve_aliases=True) >>> package2["X"].target_path 'package1.X' >>> package2["X"].resolved False >>> package2["X"].target Traceback (most recent call last): - File "griffe/_internal/models.py", line 1375, in _resolve_target + File "griffelib/_internal/models.py", line 1375, in _resolve_target resolved = self.modules_collection.get_member(self.target_path) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - File "griffe/_internal/mixins.py", line 84, in get_member + File "griffelib/_internal/mixins.py", line 84, in get_member return self.members[parts[0]].get_member(parts[1:]) # type: ignore[attr-defined] ~~~~~~~~~~~~^^^^^^^^^^ KeyError: 'package1' @@ -226,23 +226,23 @@ The above exception was the direct cause of the following exception: Traceback (most recent call last): File "", line 1, in - File "griffe/_internal/dataclasses.py", line 1310, in target + File "griffelib/_internal/dataclasses.py", line 1310, in target self.resolve_target() - File "griffe/_internal/dataclasses.py", line 1369, in resolve_target + File "griffelib/_internal/dataclasses.py", line 1369, in resolve_target self._resolve_target() - File "griffe/_internal/dataclasses.py", line 1377, in _resolve_target + File "griffelib/_internal/dataclasses.py", line 1377, in _resolve_target raise AliasResolutionError(self) from error griffelib._internal.exceptions.AliasResolutionError: Could not resolve alias package2.X pointing at package1.X (in package2/__init__.py:1) ``` -As you can see in the interpreter session above, Griffe did not resolve the `X` alias. When we tried to access its target object anyway, it failed with a `KeyError`, which was raised again as an [`AliasResolutionError`][griffelib.AliasResolutionError]. +As you can see in the interpreter session above, Griffe did not resolve the `X` alias. When we tried to access its target object anyway, it failed with a `KeyError`, which was raised again as an [`AliasResolutionError`][griffe.AliasResolutionError]. Lets try again, but this time by loading both packages. ```pycon >>> import griffe ->>> package1 = griffelib.load("package1") # nothing to resolve ->>> package2 = griffelib.load("package2", resolve_aliases=True) +>>> package1 = griffe.load("package1") # nothing to resolve +>>> package2 = griffe.load("package2", resolve_aliases=True) >>> package2["X"].target_path 'package1.X' >>> package2["X"].resolved @@ -257,20 +257,20 @@ The same exception again? What happened here? We loaded both packages, but Griff If you look closely at the first exception traceback, you will see that Griffe searched the target path in `self.modules_collection`. So what is this modules collection? -Each instance of [`GriffeLoader`][griffelib.GriffeLoader] holds a reference to an instance of [`ModulesCollection`][griffelib.ModulesCollection]. If you don't create such a collection manually to pass it to the loader, it will instantiate one itself. All objects loaded with this loader are added to this very modules collection, and gain a reference to it. +Each instance of [`GriffeLoader`][griffe.GriffeLoader] holds a reference to an instance of [`ModulesCollection`][griffe.ModulesCollection]. If you don't create such a collection manually to pass it to the loader, it will instantiate one itself. All objects loaded with this loader are added to this very modules collection, and gain a reference to it. -Since the [`load` function][griffelib.load] is just a shortcut for creating a loader and calling its [`load` method][griffelib.GriffeLoader.load], when we called `griffelib.load(...)` twice, it actually created two distinct collections of modules. When Griffe tried to resolve aliases of `package2`, it looked for `package1` in `package2`'s collection, and couldn't find it. Indeed, `package1` was in another modules collection. +Since the [`load` function][griffe.load] is just a shortcut for creating a loader and calling its [`load` method][griffe.GriffeLoader.load], when we called `griffe.load(...)` twice, it actually created two distinct collections of modules. When Griffe tried to resolve aliases of `package2`, it looked for `package1` in `package2`'s collection, and couldn't find it. Indeed, `package1` was in another modules collection. Therefore, to resolve aliases *across different packages*, these packages must be loaded within the same modules collection. In order to do that, you have a few options: - instantiate a single loader, and use it to load both packages -- create your own modules collection, and pass it to the [`load` function][griffelib.load] each time you call it -- create your own modules collection, and pass it to the different instances of [`GriffeLoader`][griffelib.GriffeLoader] you create +- create your own modules collection, and pass it to the [`load` function][griffe.load] each time you call it +- create your own modules collection, and pass it to the different instances of [`GriffeLoader`][griffe.GriffeLoader] you create === "Same loader" ```pycon >>> import griffe - >>> loader = griffelib.GriffeLoader() + >>> loader = griffe.GriffeLoader() >>> package1 = loader.load("package1") >>> package2 = loader.load("package2") >>> loader.resolve_aliases() @@ -283,9 +283,9 @@ Therefore, to resolve aliases *across different packages*, these packages must b === "Same collection with `load`" ```pycon >>> import griffe - >>> collection = griffelib.ModulesCollection() - >>> package1 = griffelib.load("package1", modules_collection=collection) - >>> package2 = griffelib.load("package2", modules_collection=collection, resolve_aliases=True) + >>> collection = griffe.ModulesCollection() + >>> package1 = griffe.load("package1", modules_collection=collection) + >>> package2 = griffe.load("package2", modules_collection=collection, resolve_aliases=True) >>> package2["X"].resolved True >>> package2["X"].target @@ -295,10 +295,10 @@ Therefore, to resolve aliases *across different packages*, these packages must b === "Same collection, different loaders" ```pycon >>> import griffe - >>> collection = griffelib.ModulesCollection() - >>> loader1 = griffelib.GriffeLoader(modules_collection=collection, ...) + >>> collection = griffe.ModulesCollection() + >>> loader1 = griffe.GriffeLoader(modules_collection=collection, ...) >>> package1 = loader1.load("package1") - >>> loader2 = griffelib.GriffeLoader(modules_collection=collection, ...) # different parameters + >>> loader2 = griffe.GriffeLoader(modules_collection=collection, ...) # different parameters >>> package2 = loader2.load("package2") >>> package2["X"].resolved True @@ -315,7 +315,7 @@ By default, when resolving aliases, Griffe loaders will not be able to resolve a ```python import griffe -package2 = griffelib.load("package2", resolve_aliases=True, resolve_external=True) +package2 = griffe.load("package2", resolve_aliases=True, resolve_external=True) print(package2["X"].target.name) # X ``` @@ -334,7 +334,7 @@ By default, Griffe runs some Git commands to find the following information abou - what service it corresponds to (GitHub, etc.) - the current commit hash -It then assigns this information to each package it loads, in the [`git_info`][griffelib.Object.git_info] attribute. This attribute can be reassigned on any object, if necessary. Each object who has it set to `None` will look into its parents. +It then assigns this information to each package it loads, in the [`git_info`][griffe.Object.git_info] attribute. This attribute can be reassigned on any object, if necessary. Each object who has it set to `None` will look into its parents. In the following cases, the information will not be set: @@ -343,15 +343,15 @@ In the following cases, the information will not be set: - Griffe cannot identify a known, supported service from the remote URL - any Git command failed -Griffe supports the services listed in the [`KnownGitService`][griffelib.KnownGitService] symbol. Please open a feature request if you would like to add support for other services. +Griffe supports the services listed in the [`KnownGitService`][griffe.KnownGitService] symbol. Please open a feature request if you would like to add support for other services. -Thanks to this source information, Griffe can then compute [source links][griffelib.Object.source_link] for each objects, by combining the information with the object's filepath and line numbers. +Thanks to this source information, Griffe can then compute [source links][griffe.Object.source_link] for each objects, by combining the information with the object's filepath and line numbers. You can globally change how Griffe obtains the source information with the following environment variables: - `GRIFFE_GIT_REMOTE_URL`: It is the repository remote URL, as an HTTPS link that readers of your documentation can access to see the repository online, on the service it is hosted on. Example: `GRIFFE_GIT_REMOTE_URL=https://app.radicle.at/nodes/seed.radicle.at/rad:z4M5XTPDD4Wh1sm8iPCenF85J3z8Z`. - `GRIFFE_GIT_REMOTE`: You can also let Griffe obtain the remote URL by getting it from the Git local configuration. The Git remote defaults to `origin`. This environment variable lets you change it to something else. Example: `GRIFFE_GIT_REMOTE=upstream`. -- `GRIFFE_GIT_SERVICE`: Griffe infers the service by looking at the remote URL. If the remote URL contains a [known service name][griffelib.KnownGitService], Griffe will use it as service. You can otherwise explicitly set the service using this environment variable. Example: `GRIFFE_GIT_SERVICE=codeberg`. +- `GRIFFE_GIT_SERVICE`: Griffe infers the service by looking at the remote URL. If the remote URL contains a [known service name][griffe.KnownGitService], Griffe will use it as service. You can otherwise explicitly set the service using this environment variable. Example: `GRIFFE_GIT_SERVICE=codeberg`. - `GRIFFE_GIT_COMMIT_HASH`: Griffe gets the commit hash by running a Git command. If you prefer using another commit hash, you can set it using this environment variable. Example: `GRIFFE_GIT_COMMIT_HASH=77f928aeab857cb45564462a4f849c2df2cca99a`. For more complex cases, see [How to programmatically set the correct Git information or source link on objects](how-to/set-git-info.md). diff --git a/docs/guide/users/navigating.md b/docs/guide/users/navigating.md index a0cb2559e..1d1c169fe 100644 --- a/docs/guide/users/navigating.md +++ b/docs/guide/users/navigating.md @@ -2,28 +2,28 @@ Griffe loads API data into data models. These models provide various attributes and methods to access or update specific fields. The different models are: -- [`Module`][griffelib.Module], representing Python modules; -- [`Class`][griffelib.Class], representing Python classes; -- [`Function`][griffelib.Function], representing Python functions and class methods; -- [`Attribute`][griffelib.Attribute], representing object attributes that weren't identified as modules, classes or functions; -- [`Type Alias`][griffelib.TypeAlias], representing Python type aliases; -- [`Alias`][griffelib.Alias], representing indirections such as imported objects or class members inherited from parent classes. +- [`Module`][griffe.Module], representing Python modules; +- [`Class`][griffe.Class], representing Python classes; +- [`Function`][griffe.Function], representing Python functions and class methods; +- [`Attribute`][griffe.Attribute], representing object attributes that weren't identified as modules, classes or functions; +- [`Type Alias`][griffe.TypeAlias], representing Python type aliases; +- [`Alias`][griffe.Alias], representing indirections such as imported objects or class members inherited from parent classes. When [loading an object](loading.md), Griffe will give you back an instance of one of these models. A few examples: ```python >>> import griffe ->>> type(griffelib.load("markdown")) +>>> type(griffe.load("markdown")) ->>> type(griffelib.load("markdown.core.Markdown")) +>>> type(griffe.load("markdown.core.Markdown")) ->>> type(griffelib.load("markdown.Markdown")) +>>> type(griffe.load("markdown.Markdown")) ->>> type(griffelib.load("markdown.core.markdown")) +>>> type(griffe.load("markdown.core.markdown")) ->>> type(griffelib.load("markdown.markdown")) +>>> type(griffe.load("markdown.markdown")) ->>> type(griffelib.load("markdown.Markdown.references")) +>>> type(griffe.load("markdown.Markdown.references")) ``` @@ -31,30 +31,30 @@ However deep the object is, Griffe loads the entire package. It means that in al ## Moving up: parents -Each object holds a reference to its [`parent`][griffelib.Object.parent] (except for the top-level module, for which the parent is `None`). Shortcuts are provided to climb up directly to the parent [`module`][griffelib.Object.module], or the top-level [`package`][griffelib.Object.package]. As we have seen in the [Loading chapter](loading.md), Griffe stores all loaded modules in a modules collection; this collection can be accessed too, through the [`modules_collection`][griffelib.Object.modules_collection] attribute. +Each object holds a reference to its [`parent`][griffe.Object.parent] (except for the top-level module, for which the parent is `None`). Shortcuts are provided to climb up directly to the parent [`module`][griffe.Object.module], or the top-level [`package`][griffe.Object.package]. As we have seen in the [Loading chapter](loading.md), Griffe stores all loaded modules in a modules collection; this collection can be accessed too, through the [`modules_collection`][griffe.Object.modules_collection] attribute. ## Moving down: members To access an object's members, there are a few options: -- Access to regular members through the [`members`][griffelib.Object.members] attribute, which is a dictionary. The keys are member names, the values are Griffe models. +- Access to regular members through the [`members`][griffe.Object.members] attribute, which is a dictionary. The keys are member names, the values are Griffe models. ```pycon >>> import griffe - >>> markdown = griffelib.load("markdown") + >>> markdown = griffe.load("markdown") >>> markdown.members["Markdown"] Alias('Markdown', 'markdown.core.Markdown') >>> markdown.members["core"].members["Markdown"] Class('Markdown', 46, 451) ``` -- Access to both regular and inherited members through the [`all_members`][griffelib.Object.all_members] attribute, which is a dictionary again. See [Inherited members](#inherited-members). +- Access to both regular and inherited members through the [`all_members`][griffe.Object.all_members] attribute, which is a dictionary again. See [Inherited members](#inherited-members). - Convenient dictionary-like item access, thanks to the subscript syntax `[]`. With this syntax, you will not only be able to chain accesses, but also merge them into a single access by using dot-separated paths to objects: ```pycon >>> import griffe - >>> markdown = griffelib.load("markdown") + >>> markdown = griffe.load("markdown") >>> markdown["core"]["Markdown"] # chained access Class('Markdown', 46, 451) >>> markdown["core.Markdown"] # merged access @@ -65,7 +65,7 @@ To access an object's members, there are a few options: ```pycon >>> import griffe - >>> markdown = griffelib.load("markdown") + >>> markdown = griffe.load("markdown") >>> markdown[("core", "Markdown")] # tuple access Class('Markdown', 46, 451) >>> # Due to the nature of the subscript syntax, @@ -74,18 +74,18 @@ To access an object's members, there are a few options: Class('Markdown', 46, 451) ``` -- Less convenient, but safer access to members while the object tree is being built (while a package is still being loaded), using the [`get_member()`][griffelib.GetMembersMixin.get_member] method. +- Less convenient, but safer access to members while the object tree is being built (while a package is still being loaded), using the [`get_member()`][griffe.GetMembersMixin.get_member] method. ```pycon >>> import griffe - >>> markdown = griffelib.load("markdown") + >>> markdown = griffe.load("markdown") >>> markdown.get_member("core.Markdown") Class('Markdown', 46, 451) ``` In particular, Griffe extensions should always use `get_member` instead of the subscript syntax `[]`. The `get_member` method only looks into regular members, while the subscript syntax looks into inherited members too (for classes), which cannot be correctly computed until a package is fully loaded (which is generally not the case when an extension is running). -- In addition to this, models provide the [`attributes`][griffelib.Object.attributes], [`functions`][griffelib.Object.functions], [`classes`][griffelib.Object.classes], [`type_aliases`][griffelib.Object.type_aliases] or [`modules`][griffelib.Object.modules] attributes, which return only members of the corresponding kind. These attributes are computed dynamically each time (they are Python properties). +- In addition to this, models provide the [`attributes`][griffe.Object.attributes], [`functions`][griffe.Object.functions], [`classes`][griffe.Object.classes], [`type_aliases`][griffe.Object.type_aliases] or [`modules`][griffe.Object.modules] attributes, which return only members of the corresponding kind. These attributes are computed dynamically each time (they are Python properties). The same way members are accessed, they can also be set: @@ -97,22 +97,22 @@ The same way members are accessed, they can also be set: - Dictionary-like item deletion: `del markdown["thing"]`, also supporting dotted-paths and string tuples. This will delete only regular members: inherited members (classes only) are re-computed everytime they are accessed. - Safer method for extensions: `markdown.del_member("thing")`, also supporting dotted-paths and string tuples. -- Regular member deletion: `del markdown.members["thing"]`. **This is not recommended, as the [`aliases`][griffelib.Object.aliases] attribute of other objects in the tree will not be automatically updated.** +- Regular member deletion: `del markdown.members["thing"]`. **This is not recommended, as the [`aliases`][griffe.Object.aliases] attribute of other objects in the tree will not be automatically updated.** ### Inherited members Griffe supports class inheritance, both when visiting and inspecting modules. -To access members of a class that are inherited from base classes, use the [`inherited_members`][griffelib.Object.inherited_members] attribute. Everytime you access inherited members, the base classes of the given class will be resolved, then the MRO (Method Resolution Order) will be computed for these base classes, and a dictionary of inherited members will be built. Make sure to store the result in a variable to avoid re-computing it everytime (you are responsible for the caching part). Also make sure to only access `inherited_members` once everything is loaded by Griffe, to avoid computing things too early. Don't try to access inherited members in extensions, while visiting or inspecting modules. +To access members of a class that are inherited from base classes, use the [`inherited_members`][griffe.Object.inherited_members] attribute. Everytime you access inherited members, the base classes of the given class will be resolved, then the MRO (Method Resolution Order) will be computed for these base classes, and a dictionary of inherited members will be built. Make sure to store the result in a variable to avoid re-computing it everytime (you are responsible for the caching part). Also make sure to only access `inherited_members` once everything is loaded by Griffe, to avoid computing things too early. Don't try to access inherited members in extensions, while visiting or inspecting modules. -Inherited members are aliases that point at the corresponding members in parent classes. These aliases will have their [`inherited`][griffelib.Alias.inherited] attribute set to true. +Inherited members are aliases that point at the corresponding members in parent classes. These aliases will have their [`inherited`][griffe.Alias.inherited] attribute set to true. **Important:** only classes from already loaded packages will be used when computing inherited members. This gives users control over how deep into inheritance to go, by pre-loading packages from which you want to inherit members. For example, if `package_c.ClassC` inherits from `package_b.ClassB`, itself inheriting from `package_a.ClassA`, and you want to load `ClassB` members only: ```python import griffe -loader = griffelib.GriffeLoader() +loader = griffe.GriffeLoader() # note that we don't load package_a loader.load("package_b") loader.load("package_c") @@ -120,9 +120,9 @@ loader.load("package_c") If a base class cannot be resolved during computation of inherited members, Griffe logs a DEBUG message. -If you want to access all members at once (both declared and inherited), use the [`all_members`][griffelib.Object.all_members] attribute. If you want to access only declared members, use the [`members`][griffelib.Object] attribute. +If you want to access all members at once (both declared and inherited), use the [`all_members`][griffe.Object.all_members] attribute. If you want to access only declared members, use the [`members`][griffe.Object] attribute. -Accessing the [`attributes`][griffelib.Object.attributes], [`functions`][griffelib.Object.functions], [`classes`][griffelib.Object.classes], [`type_aliases`][griffelib.Object.type_aliases] or [`modules`][griffelib.Object.modules] attributes will trigger inheritance computation, so make sure to only access them once everything is loaded by Griffe. Don't try to access inherited members in extensions, while visiting or inspecting modules. +Accessing the [`attributes`][griffe.Object.attributes], [`functions`][griffe.Object.functions], [`classes`][griffe.Object.classes], [`type_aliases`][griffe.Object.type_aliases] or [`modules`][griffe.Object.modules] attributes will trigger inheritance computation, so make sure to only access them once everything is loaded by Griffe. Don't try to access inherited members in extensions, while visiting or inspecting modules. #### Limitations @@ -174,46 +174,46 @@ We will try to lift these limitations in the future. ## Aliases -Aliases represent indirections, such as objects imported from elsewhere, attributes, or methods inherited from parent classes. They are pointers to the object they represent. The path of the object they represent is stored in their [`target_path`][griffelib.Alias.target_path] attribute. Once they are resolved, the target object can be accessed through their [`target`][griffelib.Alias.target] attribute. +Aliases represent indirections, such as objects imported from elsewhere, attributes, or methods inherited from parent classes. They are pointers to the object they represent. The path of the object they represent is stored in their [`target_path`][griffe.Alias.target_path] attribute. Once they are resolved, the target object can be accessed through their [`target`][griffe.Alias.target] attribute. -Aliases can be found in objects' members. Each object can also access its own aliases (the aliases pointing at it) through its [`aliases`][griffelib.Object.aliases] attribute. This attribute is a dictionary whose keys are the aliases paths and values are the aliases themselves. +Aliases can be found in objects' members. Each object can also access its own aliases (the aliases pointing at it) through its [`aliases`][griffe.Object.aliases] attribute. This attribute is a dictionary whose keys are the aliases paths and values are the aliases themselves. Most of the time, aliases simply act as proxies to their target objects. For example, accessing the `docstring` of an alias will simply return the docstring of the object it targets. -Accessing fields on aliases will trigger their resolution. If they are already resolved (their `target` attribute is set to the target object), the field is returned. If they are not resolved, their target path will be looked up in the modules collection, and if it is found, the object at this location will be assigned to the alias' `target` attribute. If it isn't found, an [`AliasResolutionError`][griffelib.AliasResolutionError] exception will be raised. +Accessing fields on aliases will trigger their resolution. If they are already resolved (their `target` attribute is set to the target object), the field is returned. If they are not resolved, their target path will be looked up in the modules collection, and if it is found, the object at this location will be assigned to the alias' `target` attribute. If it isn't found, an [`AliasResolutionError`][griffe.AliasResolutionError] exception will be raised. Since merely accessing an alias field can raise an exception, it is often useful to check if an object is an alias before accessing its fields. There are multiple ways to check if an object is an alias: -- using the `is_alias` boolean ([`Object.is_alias`][griffelib.Object.is_alias], [`Alias.is_alias`][griffelib.Alias.is_alias]), which won't trigger resolution -- using `isinstance` to check if the object is an instance of [`Alias`][griffelib.Alias] +- using the `is_alias` boolean ([`Object.is_alias`][griffe.Object.is_alias], [`Alias.is_alias`][griffe.Alias.is_alias]), which won't trigger resolution +- using `isinstance` to check if the object is an instance of [`Alias`][griffe.Alias] ```pycon >>> import griffe ->>> load = griffelib.load("griffelib.load") +>>> load = griffe.load("griffe.load") >>> load.is_alias True ->>> isinstance(load, griffelib.Alias) +>>> isinstance(load, griffe.Alias) True ``` -The [`kind`][griffelib.Alias.kind] of an alias will only return [`ALIAS`][griffelib.Kind.ALIAS] if the alias is not resolved and cannot be resolved within the current modules collection. +The [`kind`][griffe.Alias.kind] of an alias will only return [`ALIAS`][griffe.Kind.ALIAS] if the alias is not resolved and cannot be resolved within the current modules collection. You can of course also catch any raised exception with a regular try/except block: ```python try: print(obj.source) -except griffelib.AliasResolutionError: +except griffe.AliasResolutionError: pass ``` -To check if an alias is already resolved, you can use its [`resolved`][griffelib.Alias.resolved] attribute. +To check if an alias is already resolved, you can use its [`resolved`][griffe.Alias.resolved] attribute. ### Alias chains -Aliases can be chained. For example, if module `a` imports `X` from module `b`, which itself imports `X` from module `c`, then `a.X` is an alias to `b.X` which is an alias to `c.X`: `a.X` -> `b.X` -> `c.X`. To access the final target directly, you can use the [`final_target`][griffelib.Alias.final_target] attribute. Most alias properties that act like proxies actually fetch the final target rather than the next one to return the final field. +Aliases can be chained. For example, if module `a` imports `X` from module `b`, which itself imports `X` from module `c`, then `a.X` is an alias to `b.X` which is an alias to `c.X`: `a.X` -> `b.X` -> `c.X`. To access the final target directly, you can use the [`final_target`][griffe.Alias.final_target] attribute. Most alias properties that act like proxies actually fetch the final target rather than the next one to return the final field. -Sometimes, when a package makes use of complicated imports (wildcard imports from parents and submodules), or when runtime objects are hard to inspect, it is possible to end up with a cyclic chain of aliases. You could for example end up with a chain like `a.X` -> `b.X` -> `c.X` -> `a.X`. In this case, the alias *cannot* be resolved, since the chain goes in a loop. Griffe will raise a [`CyclicAliasError`][griffelib.CyclicAliasError] when trying to resolve such cyclic chains. +Sometimes, when a package makes use of complicated imports (wildcard imports from parents and submodules), or when runtime objects are hard to inspect, it is possible to end up with a cyclic chain of aliases. You could for example end up with a chain like `a.X` -> `b.X` -> `c.X` -> `a.X`. In this case, the alias *cannot* be resolved, since the chain goes in a loop. Griffe will raise a [`CyclicAliasError`][griffe.CyclicAliasError] when trying to resolve such cyclic chains. Aliases chains are never partially resolved: either they are resolved down to their final target, or none of their links are resolved. @@ -221,9 +221,9 @@ Aliases chains are never partially resolved: either they are resolved down to th The kind of an object (module, class, function, attribute, type alias or alias) can be obtained in several ways. -- With the [`kind`][griffelib.Object.kind] attribute and the [`Kind`][griffelib.Kind] enumeration: `obj.kind is Kind.MODULE`. +- With the [`kind`][griffe.Object.kind] attribute and the [`Kind`][griffe.Kind] enumeration: `obj.kind is Kind.MODULE`. -- With the [`is_kind()`][griffelib.Object.is_kind] method: +- With the [`is_kind()`][griffe.Object.is_kind] method: - `obj.is_kind(Kind.MODULE)` - `obj.is_kind("class")` @@ -231,21 +231,21 @@ The kind of an object (module, class, function, attribute, type alias or alias) When given a set of kinds, the method returns true if the object is of one of the given kinds. -- With the [`is_module`][griffelib.Object.is_module], [`is_class`][griffelib.Object.is_class], [`is_function`][griffelib.Object.is_function], [`is_attribute`][griffelib.Object.is_attribute], [`is_type_alias`][griffelib.Object.is_type_alias], and [`is_alias`][griffelib.Object.is_alias] attributes. +- With the [`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], and [`is_alias`][griffe.Object.is_alias] attributes. Additionally, it is possible to check if an object is a sub-kind of module, with the following attributes: -- [`is_init_module`][griffelib.Object.is_init_module], for `__init__.py` modules -- [`is_package`][griffelib.Object.is_package], for top-level packages -- [`is_subpackage`][griffelib.Object.is_subpackage], for non-top-level packages -- [`is_namespace_package`][griffelib.Object.is_namespace_package], for top-level [namespace packages](https://packaging.python.org/en/latest/guides/packaging-namespace-packages/) -- [`is_namespace_subpackage`][griffelib.Object.is_namespace_subpackage], for non-top-level namespace packages +- [`is_init_module`][griffe.Object.is_init_module], for `__init__.py` modules +- [`is_package`][griffe.Object.is_package], for top-level packages +- [`is_subpackage`][griffe.Object.is_subpackage], for non-top-level packages +- [`is_namespace_package`][griffe.Object.is_namespace_package], for top-level [namespace packages](https://packaging.python.org/en/latest/guides/packaging-namespace-packages/) +- [`is_namespace_subpackage`][griffe.Object.is_namespace_subpackage], for non-top-level namespace packages -Finally, additional [`labels`][griffelib.Object.labels] are attached to objects to further specify their kind. The [`has_labels()`][griffelib.Object.has_labels] method can be used to check if an object has several specific labels. +Finally, additional [`labels`][griffe.Object.labels] are attached to objects to further specify their kind. The [`has_labels()`][griffe.Object.has_labels] method can be used to check if an object has several specific labels. ## Object location -An object is identified by its [`path`][griffelib.Object.path], which is its location in the object tree. The path is composed of all the parent names and the object name, separated by dots, for example `mod.Class.meth`. This `path` is the [`canonical_path`][griffelib.Object.canonical_path] on regular objects. For aliases however, the `path` is *where they are imported* while the canonical path is *where they come from*. Example: +An object is identified by its [`path`][griffe.Object.path], which is its location in the object tree. The path is composed of all the parent names and the object name, separated by dots, for example `mod.Class.meth`. This `path` is the [`canonical_path`][griffe.Object.canonical_path] on regular objects. For aliases however, the `path` is *where they are imported* while the canonical path is *where they come from*. Example: ```python # pkg1.py @@ -254,7 +254,7 @@ from pkg2 import A as B ```pycon >>> import griffe ->>> B = griffelib.load("pkg1.B") +>>> B = griffe.load("pkg1.B") >>> B.path 'pkg1.B' >>> B.canonical_path @@ -265,20 +265,20 @@ from pkg2 import A as B Information on the actual source code of objects is available through the following attributes: -- [`filepath`][griffelib.Object.filepath], the absolute path to the module the object appears in, for example `~/project/src/pkg/mod.py` -- [`relative_filepath`][griffelib.Object.relative_filepath], the relative path to the module, compared to the current working directory, for example `src/pkg/mod.py` -- [`relative_package_filepath`][griffelib.Object.relative_package_filepath], the relative path to the module, compared to the parent of the top-level package, for example `pkg/mod.py` -- [`lineno`][griffelib.Object.lineno] and [`endlineno`][griffelib.Object.endlineno], the starting and ending line numbers of the object in the source -- [`lines`][griffelib.Object.lines], the lines of code defining the object (or importing the alias) -- [`source`][griffelib.Object.source], the source lines concatenated as a single multiline string +- [`filepath`][griffe.Object.filepath], the absolute path to the module the object appears in, for example `~/project/src/pkg/mod.py` +- [`relative_filepath`][griffe.Object.relative_filepath], the relative path to the module, compared to the current working directory, for example `src/pkg/mod.py` +- [`relative_package_filepath`][griffe.Object.relative_package_filepath], the relative path to the module, compared to the parent of the top-level package, for example `pkg/mod.py` +- [`lineno`][griffe.Object.lineno] and [`endlineno`][griffe.Object.endlineno], the starting and ending line numbers of the object in the source +- [`lines`][griffe.Object.lines], the lines of code defining the object (or importing the alias) +- [`source`][griffe.Object.source], the source lines concatenated as a single multiline string -Each object holds a reference to a [`lines_collection`][griffelib.Object.lines_collection]. Similar to the modules collection, this lines collection is a dictionary whose keys are module file-paths and values are their contents as list of lines. The lines collection is populated by the loader. +Each object holds a reference to a [`lines_collection`][griffe.Object.lines_collection]. Similar to the modules collection, this lines collection is a dictionary whose keys are module file-paths and values are their contents as list of lines. The lines collection is populated by the loader. ## Object visibility Each object has fields that are related to their visibility within the API. -- [`is_public`][griffelib.Object.is_public]: whether this object is public (destined to be consumed by your users). For module-level objects, Griffe considers that the object is public if: +- [`is_public`][griffe.Object.is_public]: whether this object is public (destined to be consumed by your users). For module-level objects, Griffe considers that the object is public if: - it is listed in its parent module's `__all__` attribute - or if its parent module does not declare `__all__`, and the object doesn't have a private name, and the object is not imported from elsewhere @@ -312,47 +312,47 @@ Each object has fields that are related to their visibility within the API. ... ``` -- [`is_deprecated`][griffelib.Object.is_deprecated]: whether this object is deprecated and shouldn't be used. +- [`is_deprecated`][griffe.Object.is_deprecated]: whether this object is deprecated and shouldn't be used. -- [`is_special`][griffelib.Object.is_special]: whether this object has a special name like `__special__` +- [`is_special`][griffe.Object.is_special]: whether this object has a special name like `__special__` -- [`is_private`][griffelib.Object.is_private]: whether this object has a private name like `_private` or `__private`, but not `__special__` +- [`is_private`][griffe.Object.is_private]: whether this object has a private name like `_private` or `__private`, but not `__special__` -- [`is_class_private`][griffelib.Object.is_class_private]: whether this object has a class-private name like `__private` and is a member of a class +- [`is_class_private`][griffe.Object.is_class_private]: whether this object has a class-private name like `__private` and is a member of a class Since `is_private` only checks the name of the object, it is not mutually exclusive with `is_public`. It means an object can return true for both `is_public` and `is_private`. We invite Griffe users to mostly rely on `is_public` and `not is_public`. -It is possible to force `is_public` and `is_deprecated` to return true or false by setting the [`public`][griffelib.Object.public] and [`deprecated`][griffelib.Object.deprecated] fields respectively. These fields are typically set by extensions that support new ways of marking objects as public or deprecated. +It is possible to force `is_public` and `is_deprecated` to return true or false by setting the [`public`][griffe.Object.public] and [`deprecated`][griffe.Object.deprecated] fields respectively. These fields are typically set by extensions that support new ways of marking objects as public or deprecated. ## Imports/exports -Modules and classes populate their [`imports`][griffelib.Object.imports] field with names that were imported from other modules. Similarly, modules populate their [`exports`][griffelib.Object.exports] field with names that were exported by being listed into the module's `__all__` attribute. Each object then provides then [`is_imported`][griffelib.Object.is_imported] and [`is_exported`][griffelib.Object.is_exported] fields, which tell if an object was imported or exported respectively. Additionally, objects also provide an [`is_wildcard_exposed`][griffelib.Object.is_wildcard_exposed] field that tells if an object is exposed to wildcard imports, i.e. will be imported when another module does `from this_module import *`. +Modules and classes populate their [`imports`][griffe.Object.imports] field with names that were imported from other modules. Similarly, modules populate their [`exports`][griffe.Object.exports] field with names that were exported by being listed into the module's `__all__` attribute. Each object then provides then [`is_imported`][griffe.Object.is_imported] and [`is_exported`][griffe.Object.is_exported] fields, which tell if an object was imported or exported respectively. Additionally, objects also provide an [`is_wildcard_exposed`][griffe.Object.is_wildcard_exposed] field that tells if an object is exposed to wildcard imports, i.e. will be imported when another module does `from this_module import *`. ## Docstrings -Each object has an optional [`docstring`][griffelib.Object.docstring] attached to it. To check whether it has one without comparing against `None`, the two following fields can be used: +Each object has an optional [`docstring`][griffe.Object.docstring] attached to it. To check whether it has one without comparing against `None`, the two following fields can be used: -- [`has_docstring`][griffelib.Object.has_docstring]: whether this object has a docstring (even empty) -- [`has_docstrings`][griffelib.Object.has_docstrings]: same thing, but recursive; whether this object or any of its members has a docstring (even empty) +- [`has_docstring`][griffe.Object.has_docstring]: whether this object has a docstring (even empty) +- [`has_docstrings`][griffe.Object.has_docstrings]: same thing, but recursive; whether this object or any of its members has a docstring (even empty) -[Docstrings][griffelib.Docstring] provide their cleaned-up [`value`][griffelib.Docstring.value] (de-indented string, stripped from leading and trailing newlines), as well as their starting and ending line numbers with [`lineno`][griffelib.Docstring.lineno] and [`endlineno`][griffelib.Docstring.endlineno]. +[Docstrings][griffe.Docstring] provide their cleaned-up [`value`][griffe.Docstring.value] (de-indented string, stripped from leading and trailing newlines), as well as their starting and ending line numbers with [`lineno`][griffe.Docstring.lineno] and [`endlineno`][griffe.Docstring.endlineno]. Docstrings can be parsed against several [docstring-styles](../../reference/docstrings.md), which are micro-formats that allow documenting things such as parameters, returned values, raised exceptions, etc.. -When loading a package, it is possible to specify the docstring style to attach to every docstring (see the `docstring_parser` parameter of [`griffelib.load`][griffelib.load]). Accessing the [`parsed`][griffelib.Docstring.parsed] field of a docstring will use this style to parse the docstring and return a list of [docstring sections][advanced-api-sections]. Each section has a `value` whose shape depends on the section kind. For example, parameter sections have a list of parameter representations as value, while a text section only has a string as value. +When loading a package, it is possible to specify the docstring style to attach to every docstring (see the `docstring_parser` parameter of [`griffe.load`][griffe.load]). Accessing the [`parsed`][griffe.Docstring.parsed] field of a docstring will use this style to parse the docstring and return a list of [docstring sections][advanced-api-sections]. Each section has a `value` whose shape depends on the section kind. For example, parameter sections have a list of parameter representations as value, while a text section only has a string as value. -After a package is loaded, it is still possible to change the style used for specific docstrings by either overriding their [`parser`][griffelib.Docstring.parser] and [`parser_options`][griffelib.Docstring.parser_options] attributes, or by calling their [`parse()`][griffelib.Docstring.parse] method with a different style: +After a package is loaded, it is still possible to change the style used for specific docstrings by either overriding their [`parser`][griffe.Docstring.parser] and [`parser_options`][griffe.Docstring.parser_options] attributes, or by calling their [`parse()`][griffe.Docstring.parse] method with a different style: ```pycon >>> import griffe ->>> markdown = griffelib.load("markdown", docstring_parser="google") +>>> markdown = griffe.load("markdown", docstring_parser="google") >>> markdown["Markdown"].docstring.parse("numpy") [...] ``` Do note, however, that the `parsed` attribute is cached, and won't be reset when overriding the `parser` or `parser_options` values. -Docstrings have a [`parent`][griffelib.Docstring.parent] field too, that is a reference to their respective module, class, function, attribute or type alias. +Docstrings have a [`parent`][griffe.Docstring.parent] field too, that is a reference to their respective module, class, function, attribute or type alias. ## Model-specific fields @@ -360,46 +360,46 @@ Models have most fields in common, but also have specific fields. ### Modules -- [`imports_future_annotations`][griffelib.Module.imports_future_annotations]: Whether the module imports [future annotations](https://peps.python.org/pep-0563/), which changes the way we parse type annotations. -- [`overloads`][griffelib.Module.overloads]: A dictionary to store overloads for module-level functions. +- [`imports_future_annotations`][griffe.Module.imports_future_annotations]: Whether the module imports [future annotations](https://peps.python.org/pep-0563/), which changes the way we parse type annotations. +- [`overloads`][griffe.Module.overloads]: A dictionary to store overloads for module-level functions. ### Classes -- [`bases`][griffelib.Class.bases]: A list of class bases in the form of [expressions][griffelib.Expr]. -- [`resolved_bases`][griffelib.Class.resolved_bases]: A list of class bases, in the form of [Class][griffelib.Class] objects. Only the bases that were loaded are returned, the others are discarded. -- [`mro()`][griffelib.Class.mro]: A method to compute the Method Resolution Order in the form of a list of [Class][griffelib.Class] objects. -- [`overloads`][griffelib.Class.overloads]: A dictionary to store overloads for class-level methods. -- [`decorators`][griffelib.Class.decorators]: The [decorators][griffelib.Decorator] applied to the class. -- [`parameters`][griffelib.Class.parameters]: The [parameters][griffelib.Parameters] of the class' `__init__` method, if any. -- [`type_parameters`][griffelib.Class.type_parameters]: The [type parameters][griffelib.TypeParameters] of the class. +- [`bases`][griffe.Class.bases]: A list of class bases in the form of [expressions][griffe.Expr]. +- [`resolved_bases`][griffe.Class.resolved_bases]: A list of class bases, in the form of [Class][griffe.Class] objects. Only the bases that were loaded are returned, the others are discarded. +- [`mro()`][griffe.Class.mro]: A method to compute the Method Resolution Order in the form of a list of [Class][griffe.Class] objects. +- [`overloads`][griffe.Class.overloads]: A dictionary to store overloads for class-level methods. +- [`decorators`][griffe.Class.decorators]: The [decorators][griffe.Decorator] applied to the class. +- [`parameters`][griffe.Class.parameters]: The [parameters][griffe.Parameters] of the class' `__init__` method, if any. +- [`type_parameters`][griffe.Class.type_parameters]: The [type parameters][griffe.TypeParameters] of the class. ### Functions -- [`decorators`][griffelib.Function.decorators]: The [decorators][griffelib.Decorator] applied to the function. -- [`overloads`][griffelib.Function.overloads]: The overloaded signatures of the function. -- [`parameters`][griffelib.Function.parameters]: The [parameters][griffelib.Parameters] of the function. -- [`returns`][griffelib.Function.returns]: The type annotation of the returned value, in the form of an [expression][griffelib.Expr]. The `annotation` field can also be used, for compatibility with attributes. -- [`type_parameters`][griffelib.Function.type_parameters]: The [type parameters][griffelib.TypeParameters] of the function. +- [`decorators`][griffe.Function.decorators]: The [decorators][griffe.Decorator] applied to the function. +- [`overloads`][griffe.Function.overloads]: The overloaded signatures of the function. +- [`parameters`][griffe.Function.parameters]: The [parameters][griffe.Parameters] of the function. +- [`returns`][griffe.Function.returns]: The type annotation of the returned value, in the form of an [expression][griffe.Expr]. The `annotation` field can also be used, for compatibility with attributes. +- [`type_parameters`][griffe.Function.type_parameters]: The [type parameters][griffe.TypeParameters] of the function. ### Attributes -- [`annotation`][griffelib.Attribute.annotation]: The type annotation of the attribute, in the form of an [expression][griffelib.Expr]. -- [`value`][griffelib.Attribute.value]: The value of the attribute, in the form of an [expression][griffelib.Expr]. -- [`deleter`][griffelib.Attribute.deleter]: The property deleter. -- [`setter`][griffelib.Attribute.setter]: The property setter. +- [`annotation`][griffe.Attribute.annotation]: The type annotation of the attribute, in the form of an [expression][griffe.Expr]. +- [`value`][griffe.Attribute.value]: The value of the attribute, in the form of an [expression][griffe.Expr]. +- [`deleter`][griffe.Attribute.deleter]: The property deleter. +- [`setter`][griffe.Attribute.setter]: The property setter. ### Type aliases -- [`value`][griffelib.TypeAlias.value]: The value of the type alias, in the form of an [expression][griffelib.Expr]. -- [`type_parameters`][griffelib.TypeAlias.type_parameters]: The [type parameters][griffelib.TypeParameters] of the type alias. +- [`value`][griffe.TypeAlias.value]: The value of the type alias, in the form of an [expression][griffe.Expr]. +- [`type_parameters`][griffe.TypeAlias.type_parameters]: The [type parameters][griffe.TypeParameters] of the type alias. ### Alias -- [`alias_lineno`][griffelib.Alias.alias_lineno]: The alias line number (where the object is imported). -- [`alias_endlineno`][griffelib.Alias.alias_endlineno]: The alias ending line number (where the object is imported). -- [`target`][griffelib.Alias.target]: The alias target (a module, class, function or attribute). -- [`target_path`][griffelib.Alias.target_path]: The path of the alias target, as a string. -- [`wildcard`][griffelib.Alias.wildcard]: Whether this alias represents a wildcard import, and if so from which module. -- [`resolve_target()`][griffelib.Alias.resolve_target]: A method that resolves the target when called. +- [`alias_lineno`][griffe.Alias.alias_lineno]: The alias line number (where the object is imported). +- [`alias_endlineno`][griffe.Alias.alias_endlineno]: The alias ending line number (where the object is imported). +- [`target`][griffe.Alias.target]: The alias target (a module, class, function or attribute). +- [`target_path`][griffe.Alias.target_path]: The path of the alias target, as a string. +- [`wildcard`][griffe.Alias.wildcard]: Whether this alias represents a wildcard import, and if so from which module. +- [`resolve_target()`][griffe.Alias.resolve_target]: A method that resolves the target when called. ## Expressions @@ -444,7 +444,7 @@ The Python language keeps evolving, and often library developers must continue s Yet this doesn't mean they can't enjoy latest features in their own docs: Griffe allows to "modernize" expressions, for example by replacing `typing.Union` with PEP 604 type unions `|`. Thanks to this, downstream tools like [mkdocstrings][mkdocstrings-python] can automatically transform type annotations into their modern equivalent. This improves consistency in your docs, and shows users how to use your code with the latest features of the language. -To modernize an expression, simply call its [`modernize()`][griffelib.Expr.modernize] method. It returns a new, modernized expression. Some parts of the expression might be left unchanged, so be careful if you decide to mutate them. +To modernize an expression, simply call its [`modernize()`][griffe.Expr.modernize] method. It returns a new, modernized expression. Some parts of the expression might be left unchanged, so be careful if you decide to mutate them. Modernizations applied: diff --git a/docs/guide/users/recommendations/public-apis.md b/docs/guide/users/recommendations/public-apis.md index c7b525c95..9a0d1cbbd 100644 --- a/docs/guide/users/recommendations/public-apis.md +++ b/docs/guide/users/recommendations/public-apis.md @@ -287,7 +287,7 @@ Start hiding your module layout early! It is much easier to (partially) expose t ## Unique names and public locations -Whether or not you are planning to hide your module layout, as recommended in the previous section, one thing that will help both you and your users is making sure your object names are unique across your code base. Having unique names ensures that you can expose everything at the top-level module of your package without having to alias objects (using `from ... import x as y`). It will also ensure that your users don't end up importing multiple different objects with the same name, again having to alias them. Finally, it forces you to use meaningful names for your objects, names that don't need the context of the above namespaces (generally modules) to understand what they mean. For example, in Griffe we previously exposed `griffelib.docstrings.utils.warning`. Exposing `warning` at the top-level made it very vague: what does it do? So we renamed it `docstring_warning`, which is much clearer. +Whether or not you are planning to hide your module layout, as recommended in the previous section, one thing that will help both you and your users is making sure your object names are unique across your code base. Having unique names ensures that you can expose everything at the top-level module of your package without having to alias objects (using `from ... import x as y`). It will also ensure that your users don't end up importing multiple different objects with the same name, again having to alias them. Finally, it forces you to use meaningful names for your objects, names that don't need the context of the above namespaces (generally modules) to understand what they mean. For example, in Griffe we previously exposed `griffe.docstrings.utils.warning`. Exposing `warning` at the top-level made it very vague: what does it do? So we renamed it `docstring_warning`, which is much clearer. Ensuring unique names across a code base is sometimes not feasible, or not desirable; in this case, try to use namespacing while still hiding the module layout the best you can. @@ -422,7 +422,7 @@ The first user of your CLI as API is... you. When you declare your project's CLI ```toml [project.scripts] -griffe = "griffecli:main" +griffe = "griffe:main" ``` ...this entrypoint ends up as a Python script in the `bin` directory of your virtual environment: @@ -438,7 +438,7 @@ if __name__ == "__main__": sys.exit(main()) ``` -In this script, we find our entrypoint, `griffecli.main`, used programmatically. +In this script, we find our entrypoint, `griffe.main`, used programmatically. --- @@ -450,21 +450,21 @@ import griffe def test_main() -> None: - assert griffecli.main(["dump", "griffe", "-s", "src", "-o/dev/null"]) == 0 + assert griffe.main(["dump", "griffe", "-s", "src", "-o/dev/null"]) == 0 def test_show_help(capsys: pytest.CaptureFixture) -> None: with pytest.raises(SystemExit): - griffecli.main(["-h"]) + griffe.main(["-h"]) captured = capsys.readouterr() assert "griffe" in captured.out def test_show_version(capsys: pytest.CaptureFixture) -> None: with pytest.raises(SystemExit): - griffecli.main(["-V"]) + griffe.main(["-V"]) captured = capsys.readouterr() - assert griffelib.get_version() in captured.out + assert griffe.get_version() in captured.out ``` Now, when you start testing the logic of your CLI subcommands, such as our `dump` subcommand above, you might feel like passing again and again through the command-line arguments parser (here `argparse`) is wasteful and redundant. It is important to test that your arguments are parsed correctly (as you expect them to be parsed), but they shouldn't *have* to be parsed when you are testing the underlying logic. diff --git a/docs/guide/users/serializing.md b/docs/guide/users/serializing.md index ddc9e840b..6adcfb4e6 100644 --- a/docs/guide/users/serializing.md +++ b/docs/guide/users/serializing.md @@ -7,7 +7,7 @@ Griffe can be used to load API data and output it as JSON on standard output or The easiest way to load and serialize API data is to use the command-line tool: ```console -$ griffecli dump httpx fastapi +$ griffe dump httpx fastapi { "httpx": { "name": "httpx", @@ -25,7 +25,7 @@ It will output a JSON-serialized version of the package's API data. Try it out on Griffe itself: ```console -$ griffecli dump griffe +$ griffe dump griffe { "griffe": { "name": "griffe", @@ -37,13 +37,13 @@ $ griffecli dump griffe To output in a file instead of standard output, use the `-o`, `--output` option: ```console -$ griffecli dump griffe -o griffelib.json +$ griffe dump griffe -o griffe.json ``` If you load multiple packages' signatures, you can dump each in its own file with a templated filepath: ```console -$ griffecli dump griffe -o './dumps/{package}.json' +$ griffe dump griffe -o './dumps/{package}.json' ``` By default, Griffe will search in `sys.path`, so if you installed it through *pipx*, there are few chances it will find your packages. To explicitly specify search paths, use the `-s, --search ` option. You can use it multiple times. You can also add the search paths to the `PYTHONPATH` environment variable. If Griffe can't find the packages, it will fail with a `ModuleNotFoundError`. @@ -54,14 +54,14 @@ See all the options for the `dump` command in the [CLI reference](../../referenc If you have read through the [Navigating](navigating.md) chapter, you know about our six data models for modules, classes, functions, attributes, type aliases and aliases. Each one of these model provide the two following methods: -- [`as_json`][griffelib.Object.as_json], which allows to serialize an object into JSON, -- [`from_json`][griffelib.Object.from_json], which allows loading JSON back into a model instance. +- [`as_json`][griffe.Object.as_json], which allows to serialize an object into JSON, +- [`from_json`][griffe.Object.from_json], which allows loading JSON back into a model instance. -These two methods are convenient wrappers around our [JSON encoder][griffelib.JSONEncoder] and [JSON decoder][griffelib.json_decoder]. The JSON encoder and decoder will give you finer-grain control over what you serialize or load, as the methods above are only available on data models, and not on sub-structures like decorators or parameters. +These two methods are convenient wrappers around our [JSON encoder][griffe.JSONEncoder] and [JSON decoder][griffe.json_decoder]. The JSON encoder and decoder will give you finer-grain control over what you serialize or load, as the methods above are only available on data models, and not on sub-structures like decorators or parameters. -Under the hood, `as_json` just calls [`as_dict`][griffelib.Object.as_dict], which converts the model instance into a dictionary, and then serializes this dictionary to JSON. +Under the hood, `as_json` just calls [`as_dict`][griffe.Object.as_dict], which converts the model instance into a dictionary, and then serializes this dictionary to JSON. -When serializing an object, by default the JSON will only contain the fields required to load it back to a Griffe model instance. If you are not planning on loading back the data into our data models, or if you want to load them in a different implementation which is not able to infer back all the other fields, you can choose to serialize every possible field. We call this a full dump, and it is enabled with the `full` option of the [encoder][griffelib.JSONEncoder] or the [`as_json`][griffelib.Object.as_json] method. +When serializing an object, by default the JSON will only contain the fields required to load it back to a Griffe model instance. If you are not planning on loading back the data into our data models, or if you want to load them in a different implementation which is not able to infer back all the other fields, you can choose to serialize every possible field. We call this a full dump, and it is enabled with the `full` option of the [encoder][griffe.JSONEncoder] or the [`as_json`][griffe.Object.as_json] method. ## Schema diff --git a/docs/index.md b/docs/index.md index 79b1851ae..efb9818a1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,7 +10,7 @@ hide: Griffe logo, created by François Rozet <francois.rozet@outlook.com> -> Griffe, pronounced "grif" (`/ɡʁif/`), is a french word that means "claw", but also "signature" in a familiar way. "On reconnaît bien là sa griffelib." +> Griffe, pronounced "grif" (`/ɡʁif/`), is a french word that means "claw", but also "signature" in a familiar way. "On reconnaît bien là sa griffe."
@@ -41,17 +41,17 @@ Griffe can be used as a Python library. For example, the [Python handler](https:
-```console exec="1" source="console" result="json" title="Serializing as JSON" id="griffecli-dump" +```console exec="1" source="console" result="json" title="Serializing as JSON" id="griffe-dump" $ export FORCE_COLOR=1 # markdown-exec: hide -$ griffecli dump griffe -ssrc -r 2>/dev/null | head -n29 +$ griffe dump griffe -ssrc -r 2>/dev/null | head -n29 ```
-```console exec="1" source="console" result="ansi" returncode="1" title="Checking for API breaking changes" id="griffecli-check" +```console exec="1" source="console" result="ansi" returncode="1" title="Checking for API breaking changes" id="griffe-check" $ export FORCE_COLOR=1 # markdown-exec: hide -$ griffecli check griffe -ssrc -b0.46.0 -a0.45.0 --verbose +$ griffe check griffe -ssrc -b0.46.0 -a0.45.0 --verbose ```
diff --git a/docs/installation.md b/docs/installation.md index 531dcab22..e0c69a8df 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -104,3 +104,20 @@ Griffe is a Python package, so you can install it with your favorite Python pack [uv](https://docs.astral.sh/uv/) is an extremely fast Python package and project manager, written in Rust.
+ +## Running Griffe + +Once installed, you can run Griffe using the `griffe` command: + +```console +$ griffe check mypackage +``` + +Or as a Python module: + +```console +$ python -m griffe check mypackage +``` + +TIP: **Alternative CLI Package** +If you need to run Griffe without the full library, you can also use `python -m griffecli` instead of `python -m griffe`. This runs the CLI directly from the `griffecli` package. diff --git a/docs/introduction.md b/docs/introduction.md index bf16b1fc5..a7226fa6e 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -9,13 +9,13 @@ Griffe is both a command line tool and a Python library. The command line tool o ```bash # Load API of `my_package`, serialize it to JSON, # print it to standard output. -griffecli dump my_package +griffe dump my_package ``` ```bash # Check for API breaking changes # between current version and version 1.0 (Git reference). -griffecli check my_package --against 1.0 +griffe check my_package --against 1.0 ``` Both commands accept a `-h`, `--help` argument to show all the available options. For a complete reference of the command line interface, see [Reference / Command line interface](reference/cli.md). @@ -27,31 +27,31 @@ As a library, Griffe exposes all its public API directly in the top-level module ```python import griffe -griffelib.load(...) -griffelib.find_breaking_changes(...) -griffecli.main(...) -griffelib.visit(...) -griffelib.inspect(...) +griffe.load(...) +griffe.find_breaking_changes(...) +griffe.main(...) +griffe.visit(...) +griffe.inspect(...) ``` -To start exploring your API within Griffe data models, use the [`load`][griffelib.load] function to load your package and access its various objects: +To start exploring your API within Griffe data models, use the [`load`][griffe.load] function to load your package and access its various objects: ```python import griffe -my_package = griffelib.load("my_package") +my_package = griffe.load("my_package") some_method = my_package["some_module.SomeClass.some_method"] print(some_method.docstring.value) print(f"Is `some_method` public? {'yes' if some_method.is_public else 'no'}") ``` -Use the [`load_git`][griffelib.load_git] function to load your API at a particular moment in time, specified with a Git reference (commit hash, branch name, tag name): +Use the [`load_git`][griffe.load_git] function to load your API at a particular moment in time, specified with a Git reference (commit hash, branch name, tag name): ```python import griffe -my_package_v2_1 = griffelib.load_git("my_package", ref="2.1") +my_package_v2_1 = griffe.load_git("my_package", ref="2.1") ``` For more advanced usage, see our guide on [loading and navigating data](guide/users/loading.md). diff --git a/docs/playground.md b/docs/playground.md index 4039ad3ce..55869f3c0 100644 --- a/docs/playground.md +++ b/docs/playground.md @@ -16,6 +16,6 @@ import griffe, micropip await micropip.install("cowsay") # And load it with Griffe! -cowsay = griffelib.load("cowsay") +cowsay = griffe.load("cowsay") cowsay.as_json(indent=2)[:1000] ``` diff --git a/docs/reference/api/agents.md b/docs/reference/api/agents.md index c4b78f9c9..224426697 100644 --- a/docs/reference/api/agents.md +++ b/docs/reference/api/agents.md @@ -4,70 +4,74 @@ Griffe is able to analyze code both statically and dynamically. ## **Main API** -::: griffelib.visit +::: griffe.visit -::: griffelib.inspect +::: griffe.inspect ## **Advanced API** -::: griffelib.Visitor +::: griffe.Visitor -::: griffelib.Inspector +::: griffe.Inspector ## **Dynamic analysis helpers** -::: griffelib.sys_path +::: griffe.sys_path -::: griffelib.dynamic_import +::: griffe.dynamic_import -::: griffelib.ObjectNode +::: griffe.ObjectNode -::: griffelib.ObjectKind +::: griffe.ObjectKind ## **Static analysis helpers** -::: griffelib.builtin_decorators +::: griffe.builtin_decorators -::: griffelib.stdlib_decorators +::: griffe.stdlib_decorators -::: griffelib.typing_overload +::: griffe.typing_overload -::: griffelib.ast_kind +::: griffe.ast_kind -::: griffelib.ast_children +::: griffe.ast_children -::: griffelib.ast_previous_siblings +::: griffe.ast_previous_siblings -::: griffelib.ast_next_siblings +::: griffe.ast_next_siblings -::: griffelib.ast_siblings +::: griffe.ast_siblings -::: griffelib.ast_previous +::: griffe.ast_previous -::: griffelib.ast_next +::: griffe.ast_next -::: griffelib.ast_first_child +::: griffe.ast_first_child -::: griffelib.ast_last_child +::: griffe.ast_last_child -::: griffelib.get_docstring +::: griffe.get_docstring -::: griffelib.get_name +::: griffe.get_name -::: griffelib.get_names +::: griffe.get_names -::: griffelib.get_instance_names +::: griffe.get_instance_names -::: griffelib.get__all__ +::: griffe.get__all__ -::: griffelib.safe_get__all__ +::: griffe.safe_get__all__ -::: griffelib.relative_to_absolute +::: griffe.relative_to_absolute -::: griffelib.get_parameters +::: griffe.get_parameters -::: griffelib.get_value +::: griffe.get_value -::: griffelib.safe_get_value +::: griffe.safe_get_value + +## **Deprecated API** + +::: griffe.ExportedName diff --git a/docs/reference/api/checks.md b/docs/reference/api/checks.md index a30110d55..9caa656e5 100644 --- a/docs/reference/api/checks.md +++ b/docs/reference/api/checks.md @@ -1,33 +1,33 @@ # API checks -::: griffelib.find_breaking_changes +::: griffe.find_breaking_changes -::: griffelib.ExplanationStyle +::: griffe.ExplanationStyle -::: griffelib.Breakage +::: griffe.Breakage -::: griffelib.BreakageKind +::: griffe.BreakageKind -::: griffelib.AttributeChangedTypeBreakage +::: griffe.AttributeChangedTypeBreakage -::: griffelib.AttributeChangedValueBreakage +::: griffe.AttributeChangedValueBreakage -::: griffelib.ClassRemovedBaseBreakage +::: griffe.ClassRemovedBaseBreakage -::: griffelib.ObjectChangedKindBreakage +::: griffe.ObjectChangedKindBreakage -::: griffelib.ObjectRemovedBreakage +::: griffe.ObjectRemovedBreakage -::: griffelib.ParameterAddedRequiredBreakage +::: griffe.ParameterAddedRequiredBreakage -::: griffelib.ParameterChangedDefaultBreakage +::: griffe.ParameterChangedDefaultBreakage -::: griffelib.ParameterChangedKindBreakage +::: griffe.ParameterChangedKindBreakage -::: griffelib.ParameterChangedRequiredBreakage +::: griffe.ParameterChangedRequiredBreakage -::: griffelib.ParameterMovedBreakage +::: griffe.ParameterMovedBreakage -::: griffelib.ParameterRemovedBreakage +::: griffe.ParameterRemovedBreakage -::: griffelib.ReturnChangedTypeBreakage +::: griffe.ReturnChangedTypeBreakage diff --git a/docs/reference/api/cli.md b/docs/reference/api/cli.md index c806e83cf..08e83a31a 100644 --- a/docs/reference/api/cli.md +++ b/docs/reference/api/cli.md @@ -2,12 +2,12 @@ ## **Main API** -::: griffecli.main +::: griffe.main -::: griffecli.check +::: griffe.check -::: griffecli.dump +::: griffe.dump ## **Advanced API** -::: griffecli.get_parser +::: griffe.get_parser diff --git a/docs/reference/api/docstrings/models.md b/docs/reference/api/docstrings/models.md index ff4b97a25..17f3bdfd9 100644 --- a/docs/reference/api/docstrings/models.md +++ b/docs/reference/api/docstrings/models.md @@ -2,80 +2,80 @@ ## **Main API** -::: griffelib.Docstring +::: griffe.Docstring ## **Advanced API: Sections** -::: griffelib.DocstringSectionKind +::: griffe.DocstringSectionKind -::: griffelib.DocstringSectionText +::: griffe.DocstringSectionText -::: griffelib.DocstringSectionParameters +::: griffe.DocstringSectionParameters -::: griffelib.DocstringSectionOtherParameters +::: griffe.DocstringSectionOtherParameters -::: griffelib.DocstringSectionTypeParameters +::: griffe.DocstringSectionTypeParameters -::: griffelib.DocstringSectionRaises +::: griffe.DocstringSectionRaises -::: griffelib.DocstringSectionWarns +::: griffe.DocstringSectionWarns -::: griffelib.DocstringSectionReturns +::: griffe.DocstringSectionReturns -::: griffelib.DocstringSectionYields +::: griffe.DocstringSectionYields -::: griffelib.DocstringSectionReceives +::: griffe.DocstringSectionReceives -::: griffelib.DocstringSectionExamples +::: griffe.DocstringSectionExamples -::: griffelib.DocstringSectionAttributes +::: griffe.DocstringSectionAttributes -::: griffelib.DocstringSectionFunctions +::: griffe.DocstringSectionFunctions -::: griffelib.DocstringSectionClasses +::: griffe.DocstringSectionClasses -::: griffelib.DocstringSectionTypeAliases +::: griffe.DocstringSectionTypeAliases -::: griffelib.DocstringSectionModules +::: griffe.DocstringSectionModules -::: griffelib.DocstringSectionDeprecated +::: griffe.DocstringSectionDeprecated -::: griffelib.DocstringSectionAdmonition +::: griffe.DocstringSectionAdmonition ## **Advanced API: Section items** -::: griffelib.DocstringAdmonition +::: griffe.DocstringAdmonition -::: griffelib.DocstringDeprecated +::: griffe.DocstringDeprecated -::: griffelib.DocstringRaise +::: griffe.DocstringRaise -::: griffelib.DocstringWarn +::: griffe.DocstringWarn -::: griffelib.DocstringReturn +::: griffe.DocstringReturn -::: griffelib.DocstringYield +::: griffe.DocstringYield -::: griffelib.DocstringReceive +::: griffe.DocstringReceive -::: griffelib.DocstringParameter +::: griffe.DocstringParameter -::: griffelib.DocstringTypeParameter +::: griffe.DocstringTypeParameter -::: griffelib.DocstringAttribute +::: griffe.DocstringAttribute -::: griffelib.DocstringFunction +::: griffe.DocstringFunction -::: griffelib.DocstringClass +::: griffe.DocstringClass -::: griffelib.DocstringTypeAlias +::: griffe.DocstringTypeAlias -::: griffelib.DocstringModule +::: griffe.DocstringModule ## **Models base classes** -::: griffelib.DocstringElement +::: griffe.DocstringElement -::: griffelib.DocstringNamedElement +::: griffe.DocstringNamedElement -::: griffelib.DocstringSection +::: griffe.DocstringSection diff --git a/docs/reference/api/docstrings/parsers.md b/docs/reference/api/docstrings/parsers.md index e4345ba77..625d1dbb0 100644 --- a/docs/reference/api/docstrings/parsers.md +++ b/docs/reference/api/docstrings/parsers.md @@ -2,42 +2,42 @@ ## **Main API** -::: griffelib.parse +::: griffe.parse -::: griffelib.parse_auto +::: griffe.parse_auto -::: griffelib.parse_google +::: griffe.parse_google -::: griffelib.parse_numpy +::: griffe.parse_numpy -::: griffelib.parse_sphinx +::: griffe.parse_sphinx -::: griffelib.DocstringStyle +::: griffe.DocstringStyle ## **Parser options** -::: griffelib.DocstringOptions +::: griffe.DocstringOptions -::: griffelib.GoogleOptions +::: griffe.GoogleOptions -::: griffelib.NumpyOptions +::: griffe.NumpyOptions -::: griffelib.SphinxOptions +::: griffe.SphinxOptions -::: griffelib.AutoOptions +::: griffe.AutoOptions -::: griffelib.PerStyleOptions +::: griffe.PerStyleOptions ## **Advanced API** -::: griffelib.Parser +::: griffe.Parser -::: griffelib.parsers +::: griffe.parsers -::: griffelib.parse_docstring_annotation +::: griffe.parse_docstring_annotation -::: griffelib.docstring_warning +::: griffe.docstring_warning -::: griffelib.DocstringDetectionMethod +::: griffe.DocstringDetectionMethod -::: griffelib.infer_docstring_style +::: griffe.infer_docstring_style diff --git a/docs/reference/api/exceptions.md b/docs/reference/api/exceptions.md index 8630c15ec..e33a10071 100644 --- a/docs/reference/api/exceptions.md +++ b/docs/reference/api/exceptions.md @@ -1,27 +1,27 @@ # Exceptions -::: griffelib.GriffeError +::: griffe.GriffeError -::: griffelib.LoadingError +::: griffe.LoadingError -::: griffelib.NameResolutionError +::: griffe.NameResolutionError -::: griffelib.UnhandledEditableModuleError +::: griffe.UnhandledEditableModuleError -::: griffelib.UnimportableModuleError +::: griffe.UnimportableModuleError -::: griffelib.AliasResolutionError +::: griffe.AliasResolutionError -::: griffelib.CyclicAliasError +::: griffe.CyclicAliasError -::: griffelib.LastNodeError +::: griffe.LastNodeError -::: griffelib.RootNodeError +::: griffe.RootNodeError -::: griffelib.BuiltinModuleError +::: griffe.BuiltinModuleError -::: griffelib.ExtensionError +::: griffe.ExtensionError -::: griffelib.ExtensionNotLoadedError +::: griffe.ExtensionNotLoadedError -::: griffelib.GitError +::: griffe.GitError diff --git a/docs/reference/api/expressions.md b/docs/reference/api/expressions.md index 4b3395c39..d91795c79 100644 --- a/docs/reference/api/expressions.md +++ b/docs/reference/api/expressions.md @@ -10,88 +10,88 @@ ## **Helpers** -::: griffelib.get_annotation +::: griffe.get_annotation -::: griffelib.get_base_class +::: griffe.get_base_class -::: griffelib.get_class_keyword +::: griffe.get_class_keyword -::: griffelib.get_condition +::: griffe.get_condition -::: griffelib.get_expression +::: griffe.get_expression -::: griffelib.safe_get_annotation +::: griffe.safe_get_annotation -::: griffelib.safe_get_base_class +::: griffe.safe_get_base_class -::: griffelib.safe_get_class_keyword +::: griffe.safe_get_class_keyword -::: griffelib.safe_get_condition +::: griffe.safe_get_condition -::: griffelib.safe_get_expression +::: griffe.safe_get_expression ## **Expression nodes** -::: griffelib.Expr +::: griffe.Expr -::: griffelib.ExprAttribute +::: griffe.ExprAttribute -::: griffelib.ExprBinOp +::: griffe.ExprBinOp -::: griffelib.ExprBoolOp +::: griffe.ExprBoolOp -::: griffelib.ExprCall +::: griffe.ExprCall -::: griffelib.ExprCompare +::: griffe.ExprCompare -::: griffelib.ExprComprehension +::: griffe.ExprComprehension -::: griffelib.ExprConstant +::: griffe.ExprConstant -::: griffelib.ExprDict +::: griffe.ExprDict -::: griffelib.ExprDictComp +::: griffe.ExprDictComp -::: griffelib.ExprExtSlice +::: griffe.ExprExtSlice -::: griffelib.ExprFormatted +::: griffe.ExprFormatted -::: griffelib.ExprGeneratorExp +::: griffe.ExprGeneratorExp -::: griffelib.ExprIfExp +::: griffe.ExprIfExp -::: griffelib.ExprJoinedStr +::: griffe.ExprJoinedStr -::: griffelib.ExprKeyword +::: griffe.ExprKeyword -::: griffelib.ExprVarPositional +::: griffe.ExprVarPositional -::: griffelib.ExprVarKeyword +::: griffe.ExprVarKeyword -::: griffelib.ExprLambda +::: griffe.ExprLambda -::: griffelib.ExprList +::: griffe.ExprList -::: griffelib.ExprListComp +::: griffe.ExprListComp -::: griffelib.ExprName +::: griffe.ExprName -::: griffelib.ExprNamedExpr +::: griffe.ExprNamedExpr -::: griffelib.ExprParameter +::: griffe.ExprParameter -::: griffelib.ExprSet +::: griffe.ExprSet -::: griffelib.ExprSetComp +::: griffe.ExprSetComp -::: griffelib.ExprSlice +::: griffe.ExprSlice -::: griffelib.ExprSubscript +::: griffe.ExprSubscript -::: griffelib.ExprTuple +::: griffe.ExprTuple -::: griffelib.ExprUnaryOp +::: griffe.ExprUnaryOp -::: griffelib.ExprYield +::: griffe.ExprYield -::: griffelib.ExprYieldFrom +::: griffe.ExprYieldFrom diff --git a/docs/reference/api/extensions.md b/docs/reference/api/extensions.md index 8ae746205..42ee96a80 100644 --- a/docs/reference/api/extensions.md +++ b/docs/reference/api/extensions.md @@ -2,26 +2,26 @@ ## **Main API** -::: griffelib.load_extensions +::: griffe.load_extensions -::: griffelib.Extension +::: griffe.Extension ## **Advanced API** -::: griffelib.Extensions +::: griffe.Extensions ## **Types** -::: griffelib.LoadableExtensionType +::: griffe.LoadableExtensionType ## **Builtin extensions** -::: griffelib.builtin_extensions +::: griffe.builtin_extensions -::: griffelib.DataclassesExtension +::: griffe.DataclassesExtension options: inherited_members: false -::: griffelib.UnpackTypedDictExtension +::: griffe.UnpackTypedDictExtension options: inherited_members: false diff --git a/docs/reference/api/finder.md b/docs/reference/api/finder.md index f79f92565..54c452e31 100644 --- a/docs/reference/api/finder.md +++ b/docs/reference/api/finder.md @@ -2,14 +2,14 @@ ## **Advanced API** -::: griffelib.ModuleFinder +::: griffe.ModuleFinder -::: griffelib.Package +::: griffe.Package -::: griffelib.NamespacePackage +::: griffe.NamespacePackage ## **Types** -::: griffelib.NamePartsType +::: griffe.NamePartsType -::: griffelib.NamePartsAndPathType +::: griffe.NamePartsAndPathType diff --git a/docs/reference/api/git.md b/docs/reference/api/git.md new file mode 100644 index 000000000..7abc81fcf --- /dev/null +++ b/docs/reference/api/git.md @@ -0,0 +1,13 @@ +# Git utilities + + + +DANGER: **Deprecated utilities.** We have decided to stop exposing Git-related utilities as it's not a core part of the library's functionality. The functions documented on this page will become unavailable in the next major version. + +::: griffe.assert_git_repo + +::: griffe.get_latest_tag + +::: griffe.get_repo_root + +::: griffe.tmp_worktree diff --git a/docs/reference/api/helpers.md b/docs/reference/api/helpers.md index 4267786da..74e44d05a 100644 --- a/docs/reference/api/helpers.md +++ b/docs/reference/api/helpers.md @@ -1,21 +1,21 @@ # Helpers -::: griffelib.TmpPackage +::: griffe.TmpPackage -::: griffelib.temporary_pyfile +::: griffe.temporary_pyfile -::: griffelib.temporary_pypackage +::: griffe.temporary_pypackage -::: griffelib.temporary_visited_module +::: griffe.temporary_visited_module -::: griffelib.temporary_visited_package +::: griffe.temporary_visited_package -::: griffelib.temporary_inspected_module +::: griffe.temporary_inspected_module -::: griffelib.temporary_inspected_package +::: griffe.temporary_inspected_package -::: griffelib.vtree +::: griffe.vtree -::: griffelib.htree +::: griffe.htree -::: griffelib.module_vtree +::: griffe.module_vtree diff --git a/docs/reference/api/loaders.md b/docs/reference/api/loaders.md index 10dccf38c..b3eb060c9 100644 --- a/docs/reference/api/loaders.md +++ b/docs/reference/api/loaders.md @@ -2,22 +2,22 @@ ## **Main API** -::: griffelib.load +::: griffe.load -::: griffelib.load_git +::: griffe.load_git -::: griffelib.load_pypi +::: griffe.load_pypi ## **Advanced API** -::: griffelib.GriffeLoader +::: griffe.GriffeLoader -::: griffelib.ModulesCollection +::: griffe.ModulesCollection -::: griffelib.LinesCollection +::: griffe.LinesCollection ## **Additional API** -::: griffelib.Stats +::: griffe.Stats -::: griffelib.merge_stubs +::: griffe.merge_stubs diff --git a/docs/reference/api/loggers.md b/docs/reference/api/loggers.md index 2611b9c2e..0ba1d0dbd 100644 --- a/docs/reference/api/loggers.md +++ b/docs/reference/api/loggers.md @@ -2,18 +2,18 @@ ## **Main API** -::: griffelib.logger +::: griffe.logger -::: griffelib.get_logger +::: griffe.get_logger -::: griffelib.Logger +::: griffe.Logger -::: griffelib.LogLevel +::: griffe.LogLevel -::: griffecli.DEFAULT_LOG_LEVEL +::: griffe.DEFAULT_LOG_LEVEL options: annotations_path: full ## **Advanced API** -::: griffelib.patch_loggers +::: griffe.patch_loggers diff --git a/docs/reference/api/models.md b/docs/reference/api/models.md index 76732f917..3b7f35316 100644 --- a/docs/reference/api/models.md +++ b/docs/reference/api/models.md @@ -10,41 +10,41 @@ Indirections to objects declared in other modules are represented as "aliases". The 6 models: -- [`Module`][griffelib.Module] -- [`Class`][griffelib.Class] -- [`Function`][griffelib.Function] -- [`Attribute`][griffelib.Attribute] -- [`Alias`][griffelib.Alias] -- [`TypeAlias`][griffelib.TypeAlias] +- [`Module`][griffe.Module] +- [`Class`][griffe.Class] +- [`Function`][griffe.Function] +- [`Attribute`][griffe.Attribute] +- [`Alias`][griffe.Alias] +- [`TypeAlias`][griffe.TypeAlias] ## **Model kind enumeration** -::: griffelib.Kind +::: griffe.Kind ## **Model base classes** -::: griffelib.GetMembersMixin +::: griffe.GetMembersMixin -::: griffelib.SetMembersMixin +::: griffe.SetMembersMixin -::: griffelib.DelMembersMixin +::: griffe.DelMembersMixin -::: griffelib.SerializationMixin +::: griffe.SerializationMixin -::: griffelib.ObjectAliasMixin +::: griffe.ObjectAliasMixin -::: griffelib.Object +::: griffe.Object ## **Type parameters** -::: griffelib.TypeParameters +::: griffe.TypeParameters -::: griffelib.TypeParameter +::: griffe.TypeParameter -::: griffelib.TypeParameterKind +::: griffe.TypeParameterKind ## **Git information** -::: griffelib.KnownGitService +::: griffe.KnownGitService -::: griffelib.GitInfo +::: griffe.GitInfo diff --git a/docs/reference/api/models/alias.md b/docs/reference/api/models/alias.md index ae146795d..df1419cc3 100644 --- a/docs/reference/api/models/alias.md +++ b/docs/reference/api/models/alias.md @@ -1 +1 @@ -# ::: griffelib.Alias +# ::: griffe.Alias diff --git a/docs/reference/api/models/attribute.md b/docs/reference/api/models/attribute.md index 2ca25220b..89abf00d6 100644 --- a/docs/reference/api/models/attribute.md +++ b/docs/reference/api/models/attribute.md @@ -1 +1 @@ -# ::: griffelib.Attribute +# ::: griffe.Attribute diff --git a/docs/reference/api/models/class.md b/docs/reference/api/models/class.md index 2bcc01425..f6720d4b8 100644 --- a/docs/reference/api/models/class.md +++ b/docs/reference/api/models/class.md @@ -1,5 +1,5 @@ -# ::: griffelib.Class +# ::: griffe.Class ## **Utilities** -::: griffelib.c3linear_merge +::: griffe.c3linear_merge diff --git a/docs/reference/api/models/function.md b/docs/reference/api/models/function.md index ffe172ddc..20003780b 100644 --- a/docs/reference/api/models/function.md +++ b/docs/reference/api/models/function.md @@ -1,11 +1,11 @@ -# ::: griffelib.Function +# ::: griffe.Function -::: griffelib.Parameters +::: griffe.Parameters -::: griffelib.Parameter +::: griffe.Parameter -::: griffelib.ParameterKind +::: griffe.ParameterKind -::: griffelib.ParametersType +::: griffe.ParametersType -::: griffelib.Decorator +::: griffe.Decorator diff --git a/docs/reference/api/models/module.md b/docs/reference/api/models/module.md index 39a74357f..ea42941f9 100644 --- a/docs/reference/api/models/module.md +++ b/docs/reference/api/models/module.md @@ -1 +1 @@ -# ::: griffelib.Module +# ::: griffe.Module diff --git a/docs/reference/api/models/type_alias.md b/docs/reference/api/models/type_alias.md index 8033a7f5b..367d906d5 100644 --- a/docs/reference/api/models/type_alias.md +++ b/docs/reference/api/models/type_alias.md @@ -1,3 +1,3 @@ # Type Alias -::: griffelib.TypeAlias +::: griffe.TypeAlias diff --git a/docs/reference/api/serializers.md b/docs/reference/api/serializers.md index 2ac8a7b76..c9fff7b4e 100644 --- a/docs/reference/api/serializers.md +++ b/docs/reference/api/serializers.md @@ -2,10 +2,10 @@ ## **Main API** -See the [`as_json()`][griffelib.Object.as_json] and [`from_json()`][griffelib.Object.from_json] methods of objects. +See the [`as_json()`][griffe.Object.as_json] and [`from_json()`][griffe.Object.from_json] methods of objects. ## **Advanced API** -::: griffelib.JSONEncoder +::: griffe.JSONEncoder -::: griffelib.json_decoder +::: griffe.json_decoder diff --git a/docs/reference/docstrings.md b/docs/reference/docstrings.md index e6b342212..dd26177b0 100644 --- a/docs/reference/docstrings.md +++ b/docs/reference/docstrings.md @@ -68,7 +68,7 @@ Note: Find out possibly invalid section syntax by grepping for "reasons" in Griffe debug logs: ```bash -griffecli dump -Ldebug -o/dev/null -fdgoogle your_package 2>&1 | grep reasons +griffe dump -Ldebug -o/dev/null -fdgoogle your_package 2>&1 | grep reasons ``` Some sections support documenting multiple items (attributes, parameters, etc.). When multiple items are supported, each item description can use multiple lines, and continuation lines must be indented once more so that the parser is able to differentiate items. diff --git a/docs/schema-docstrings-options.json b/docs/schema-docstrings-options.json index dfdb081fe..516d86eb7 100644 --- a/docs/schema-docstrings-options.json +++ b/docs/schema-docstrings-options.json @@ -5,19 +5,19 @@ "properties": { "ignore_init_summary": { "title": "Whether to discard the summary line in `__init__` methods' docstrings.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/docstrings/google/#griffelib.docstrings.google.parse", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/docstrings/google/#griffe.docstrings.google.parse", "type": "boolean", "default": false }, "trim_doctest_flags": { "title": "Whether to remove doctest flags from Python example blocks.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/docstrings/google/#griffelib.docstrings.google.parse", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/docstrings/google/#griffe.docstrings.google.parse", "type": "boolean", "default": true }, "returns_multiple_items": { "title": "Whether the `Returns` section has multiple items.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/docstrings/google/#griffelib.docstrings.google.parse", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/griffe/docstrings/google/#griffe.docstrings.google.parse", "type": "boolean", "default": true } diff --git a/docs/schema.json b/docs/schema.json index 7b76c4412..2af3ca516 100644 --- a/docs/schema.json +++ b/docs/schema.json @@ -7,32 +7,32 @@ "properties": { "name": { "title": "The name of the alias.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.name", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.name", "type": "string" }, "kind": { "title": "The 'alias' kind.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.kind", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.kind", "const": "alias" }, "path": { "title": "The alias path.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.path", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.path", "type": "string" }, "target_path": { "title": "For aliases, the Python path of their target.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.target_path", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.target_path", "type": "string" }, "lineno": { "title": "For aliases, the import starting line number in their own module.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.lineno", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.lineno", "type": "integer" }, "endlineno": { "title": "For aliases, the import ending line number in their own module.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.endlineno", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.endlineno", "type": [ "integer", "null" @@ -40,17 +40,17 @@ }, "inherited": { "title": "Whether the alias is the member of another alias.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.inherited", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.inherited", "type": "boolean" }, "runtime": { "title": "Whether the alias exists at runtime.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.runtime", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.runtime", "type": "boolean" }, "public": { "title": "Whether the alias is public.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.public", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.public", "type": [ "null", "boolean" @@ -58,7 +58,7 @@ }, "deprecated": { "title": "Whether the alias is explicitly marked as deprecated.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.deprecated", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.deprecated", "type": [ "null", "boolean", @@ -67,7 +67,7 @@ }, "analysis": { "title": "The type of analysis used to load this alias.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.analysis", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.analysis", "type": [ "null", "string" @@ -80,42 +80,42 @@ }, "is_public": { "title": "Whether the alias is public.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.is_public", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.is_public", "type": "boolean" }, "is_deprecated": { "title": "Whether the alias is deprecated.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.is_deprecated", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.is_deprecated", "type": "boolean" }, "is_private": { "title": "Whether the alias is private.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.is_private", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.is_private", "type": "boolean" }, "is_class_private": { "title": "Whether the alias is class-private.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.is_class_private", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.is_class_private", "type": "boolean" }, "is_special": { "title": "Whether the alias is special.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.is_special", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.is_special", "type": "boolean" }, "is_imported": { "title": "Whether the alias is imported.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.is_imported", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.is_imported", "type": "boolean" }, "is_exported": { "title": "Whether the alias is exported.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.is_exported", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.is_exported", "type": "boolean" }, "is_wildcard_exposed": { "title": "Whether the alias is wildcard-exposed.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Alias.is_wildcard_exposed", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Alias.is_wildcard_exposed", "type": "boolean" } }, @@ -133,12 +133,12 @@ "properties": { "name": { "title": "The name of the object.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.name", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.name", "type": "string" }, "kind": { "title": "The kind of object.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.kind", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.kind", "enum": [ "module", "class", @@ -149,32 +149,32 @@ }, "path": { "title": "The path of the object (dot-separated Python path).", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.path", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.path", "type": "string" }, "filepath": { "title": "The file path of the object's parent module.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.filepath", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.filepath", "type": "string" }, "relative_filepath": { "title": "The file path of the object's parent module, relative to the (at the time) current working directory.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.relative_filepath", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.relative_filepath", "type": "string" }, "relative_package_filepath": { "title": "The file path of the object's package, as found in the explored directories of the Python paths.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.relative_package_filepath", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.relative_package_filepath", "type": "string" }, "git_info": { "title": "The Git information associated to this object's package.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Object.git_info", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Object.git_info", "$ref": "#/$defs/GitInfo" }, "source_link": { "title": "The source link of the object.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.source_link", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.source_link", "type": [ "string", "null" @@ -182,7 +182,7 @@ }, "public": { "title": "Whether the object was explicitly marked as public.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.public", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.public", "type": [ "null", "boolean" @@ -190,7 +190,7 @@ }, "exports": { "title": "The exports of the object.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.exports", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.exports", "type": [ "null", "array" @@ -201,17 +201,17 @@ }, "imports": { "title": "The imports of the object.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.imports", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.imports", "type": "object" }, "runtime": { "title": "Whether this object exists at runtime.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.runtime", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.runtime", "type": "boolean" }, "deprecated": { "title": "Whether the object was explicitly marked as deprecated.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.deprecated", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.deprecated", "type": [ "null", "string", @@ -220,7 +220,7 @@ }, "analysis": { "title": "The type of analysis used to load this object.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffelib.Object.analysis", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/alias/#griffe.Object.analysis", "type": [ "null", "string" @@ -233,27 +233,27 @@ }, "labels": { "title": "The labels of the object.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.labels", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.labels", "type": "array" }, "docstring": { "title": "The docstring of the object.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffelib.Docstring", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffe.Docstring", "type": "object", "properties": { "value": { "title": "The actual string.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffelib.Docstring.value", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffe.Docstring.value", "type": "string" }, "lineno": { "title": "The docstring starting line number.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffelib.Docstring.lineno", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffe.Docstring.lineno", "type": "integer" }, "endlineno": { "title": "The docstring ending line number.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffelib.Docstring.endlineno", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffe.Docstring.endlineno", "type": [ "integer", "null" @@ -261,7 +261,7 @@ }, "parsed": { "title": "The parsed docstring (list of docstring sections).", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffelib.Docstring.parsed", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffe.Docstring.parsed", "type": "array", "items": { "type": "object", @@ -312,12 +312,12 @@ }, "lineno": { "title": "The docstring starting line number.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffelib.Docstring.lineno", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffe.Docstring.lineno", "type": "integer" }, "endlineno": { "title": "The docstring ending line number.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffelib.Docstring.endlineno", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/docstrings/models/#griffe.Docstring.endlineno", "type": [ "integer", "null" @@ -325,42 +325,42 @@ }, "is_public": { "title": "Whether the object is public.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.is_public", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_public", "type": "boolean" }, "is_deprecated": { "title": "Whether the object is deprecated.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.is_deprecated", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_deprecated", "type": "boolean" }, "is_private": { "title": "Whether the object is private.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.is_private", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_private", "type": "boolean" }, "is_class_private": { "title": "Whether the object is class-private.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.is_class_private", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_class_private", "type": "boolean" }, "is_special": { "title": "Whether the object is special.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.is_special", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_special", "type": "boolean" }, "is_imported": { "title": "Whether the object is imported.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.is_imported", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_imported", "type": "boolean" }, "is_exported": { "title": "Whether the object is exported.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.is_exported", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_exported", "type": "boolean" }, "is_wildcard_exposed": { "title": "Whether the object is wildcard-exposed.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.Object.is_wildcard_exposed", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.Object.is_wildcard_exposed", "type": "boolean" }, "bases": true, @@ -390,7 +390,7 @@ "properties": { "bases": { "title": "For classes, their bases classes.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/class/#griffelib.Class.bases", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/class/#griffe.Class.bases", "type": "array", "items": { "$ref": "#/$defs/annotation" @@ -398,24 +398,24 @@ }, "decorators": { "title": "For classes, their decorators.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/class/#griffelib.Class.decorators", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/class/#griffe.Class.decorators", "type": "array", "items": { "type": "object", "properties": { "value": { "title": "The decorator value (string, name or expression).", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Decorator.value", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Decorator.value", "$ref": "#/$defs/annotation" }, "lineno": { "title": "The decorator starting line number.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Decorator.lineno", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Decorator.lineno", "type": "integer" }, "endlineno": { "title": "The decorator ending line number.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Decorator.endlineno", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Decorator.endlineno", "type": [ "integer", "null" @@ -432,7 +432,7 @@ }, "type_parameters": { "title": "For classes, their type parameters.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/class/#griffelib.Class.type_parameters", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/class/#griffe.Class.type_parameters", "type": "array", "items": { "$ref": "#/$defs/type_parameter" @@ -457,29 +457,29 @@ "properties": { "parameters": { "title": "For functions, their parameters.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Function.parameters", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Function.parameters", "type": "array", "items": { "type": "object", "properties": { "name": { "title": "The name of the parameter.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Parameter.name", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Parameter.name", "type": "string" }, "annotation": { "title": "The annotation of the parameter.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Parameter.annotation", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Parameter.annotation", "$ref": "#/$defs/annotation" }, "kind": { "title": "The kind of parameter.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Parameter.kind", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Parameter.kind", "type": "string" }, "default": { "title": "The default value of the parameter.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Parameter.default", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Parameter.default", "$ref": "#/$defs/annotation" } }, @@ -491,12 +491,12 @@ }, "returns": { "title": "For functions, their return annotation.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Function.returns", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Function.returns", "$ref": "#/$defs/annotation" }, "type_parameters": { "title": "For functions, their type parameters.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffelib.Function.type_parameters", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/function/#griffe.Function.type_parameters", "type": "array", "items": { "$ref": "#/$defs/type_parameter" @@ -521,12 +521,12 @@ "properties": { "value": { "title": "For attributes, their value.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/attribute/#griffelib.Attribute.value", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/attribute/#griffe.Attribute.value", "$ref": "#/$defs/annotation" }, "annotation": { "title": "For attributes, their type annotation.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/attribute/#griffelib.Attribute.annotation", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/attribute/#griffe.Attribute.annotation", "$ref": "#/$defs/annotation" } } @@ -544,12 +544,12 @@ "properties": { "value": { "title": "For type aliases, their value.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/type_alias/#griffelib.TypeAlias.value", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/type_alias/#griffe.TypeAlias.value", "$ref": "#/$defs/annotation" }, "type_parameters": { "title": "For type aliases, their type parameters.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/type_alias/#griffelib.TypeAlias.type_parameters", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/type_alias/#griffe.TypeAlias.type_parameters", "type": "array", "items": { "$ref": "#/$defs/type_parameter" @@ -584,17 +584,17 @@ }, "type_parameter": { "title": "Type Parameter.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.TypeParameter", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.TypeParameter", "type": "object", "properties": { "name": { "title": "The type parameter name.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.TypeParameter.name", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.TypeParameter.name", "type": "string" }, "kind": { "title": "The type parameter kind.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.TypeParameter.kind", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.TypeParameter.kind", "enum": [ "type-var", "type-var-tuple", @@ -603,12 +603,12 @@ }, "annotation": { "title": "The type parameter bound or constraints.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.TypeParameter.annotation", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.TypeParameter.annotation", "$ref": "#/$defs/annotation" }, "default": { "title": "The type parameter default.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.TypeParameter.default", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.TypeParameter.default", "$ref": "#/$defs/annotation" } }, @@ -622,19 +622,19 @@ }, "GitInfo": { "title": "Git information.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.GitInfo", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.GitInfo", "type": "object", "properties": { "repository": { "title": "The repository local path.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.GitInfo.repository", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.GitInfo.repository", "type": [ "string" ] }, "service": { "title": "The Git service (e.g., 'github', 'gitlab', 'bitbucket').", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.GitInfo.service", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.GitInfo.service", "type": [ "string" ], @@ -651,14 +651,14 @@ }, "remote_url": { "title": "The remote URL.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.GitInfo.remote_url", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.GitInfo.remote_url", "type": [ "string" ] }, "commit_hash": { "title": "The commit hash.", - "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffelib.GitInfo.commit_hash", + "markdownDescription": "https://mkdocstrings.github.io/griffe/reference/api/models/#griffe.GitInfo.commit_hash", "type": [ "string" ] diff --git a/packages/griffecli/src/griffecli/_internal/cli.py b/packages/griffecli/src/griffecli/_internal/cli.py index b13154dc9..a78a52fbe 100644 --- a/packages/griffecli/src/griffecli/_internal/cli.py +++ b/packages/griffecli/src/griffecli/_internal/cli.py @@ -138,7 +138,7 @@ def get_parser() -> argparse.ArgumentParser: description = "Signatures for entire Python programs. " "Extract the structure, the frame, the skeleton of your project, " "to generate API documentation or find breaking changes in your API." - parser = argparse.ArgumentParser(add_help=False, usage=usage, description=description, prog="griffelib") + parser = argparse.ArgumentParser(add_help=False, usage=usage, description=description, prog="griffe") main_help = "Show this help message and exit. Commands also accept the -h/--help option." subcommand_help = "Show this help message and exit." @@ -215,7 +215,7 @@ def add_common_options(subparser: argparse.ArgumentParser) -> None: dest="subcommand", title="Commands", metavar="COMMAND", - prog="griffelib", + prog="griffe", required=True, ) @@ -511,7 +511,7 @@ def check( against = against or _get_latest_tag(package) repository = _get_repo_root(against_path) except GitError as error: - print(f"griffelib: error: {error}", file=sys.stderr) + print(f"griffe: error: {error}", file=sys.stderr) return 2 # Load old and new version of the package. @@ -577,7 +577,7 @@ def check( def main(args: list[str] | None = None) -> int: """Run the main program. - This function is executed when you type `griffelib` or `python -m griffelib`. + This function is executed when you type `griffe` or `python -m griffe`. Parameters: args: Arguments passed from the command line. @@ -599,7 +599,7 @@ def main(args: list[str] | None = None) -> int: except AttributeError: choices = "', '".join(_level_choices) print( - f"griffelib: error: invalid log level '{log_level}' (choose from '{choices}')", + f"griffe: error: invalid log level '{log_level}' (choose from '{choices}')", file=sys.stderr, ) return 1 diff --git a/pyproject.toml b/pyproject.toml index 3bddfc0db..77f2bc30a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -136,3 +136,7 @@ ci = [ [tool.uv] default-groups = ["maintain", "ci", "docs"] workspace = { members = ["packages/*"] } + +[tool.uv.sources] +griffelib = { workspace = true } +griffecli = { workspace = true }