Skip to content

Commit 72b1bbd

Browse files
Copilotjohnslavik
andcommitted
Fix griffelib/griffecli separation and add proper exports
Co-authored-by: johnslavik <64036239+johnslavik@users.noreply.github.com>
1 parent b2dad08 commit 72b1bbd

9 files changed

Lines changed: 137 additions & 90 deletions

File tree

packages/griffecli/pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,15 @@ classifiers = [
4141
"Typing :: Typed",
4242
]
4343

44+
[project.scripts]
45+
griffecli = "griffecli:main"
46+
4447
[tool.hatch.metadata.hooks.uv-dynamic-versioning]
48+
dependencies = ["griffelib=={version}", "colorama>=0.4"]
4549

4650
[tool.hatch.metadata.hooks.uv-dynamic-versioning.optional-dependencies]
4751

4852
[tool.hatch.build.targets.sdist]
53+
54+
[tool.hatch.build.targets.wheel]
55+
sources = ["src/"]
Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,27 @@
1-
# TODO: Cut proper imports from griffelib `__init__.py` module
1+
# This top-level module imports all public names from the CLI package,
2+
# and exposes them as public objects.
3+
4+
"""Griffe CLI package.
5+
6+
The CLI (Command Line Interface) for the griffe library.
7+
This package provides command-line tools for interacting with griffe.
8+
9+
## CLI entrypoints
10+
11+
- [`griffecli.main`][]: Run the main program.
12+
- [`griffecli.check`][]: Check for API breaking changes in two versions of the same package.
13+
- [`griffecli.dump`][]: Load packages data and dump it as JSON.
14+
- [`griffecli.get_parser`][]: Get the argument parser for the CLI.
15+
"""
16+
17+
from __future__ import annotations
18+
19+
from griffecli._internal.cli import DEFAULT_LOG_LEVEL, check, dump, get_parser, main
20+
21+
__all__ = [
22+
"DEFAULT_LOG_LEVEL",
23+
"check",
24+
"dump",
25+
"get_parser",
26+
"main",
27+
]

packages/griffecli/src/griffecli/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Entry-point module, in case you use `python -m griffelib`.
1+
# Entry-point module, in case you use `python -m griffecli`.
22
#
33
# Why does this file exist, and why `__main__`? For more info, read:
44
#

packages/griffecli/src/griffecli/_internal/cli.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
# We might be tempted to import things from `__main__` later,
55
# but that will cause problems; the code will get executed twice:
66
#
7-
# - When we run `python -m griffelib`, Python will execute
7+
# - When we run `python -m griffecli`, Python will execute
88
# `__main__.py` as a script. That means there won't be any
9-
# `griffelib.__main__` in `sys.modules`.
9+
# `griffecli.__main__` in `sys.modules`.
1010
# - When you import `__main__` it will get executed again (as a module) because
11-
# there's no `griffelib.__main__` in `sys.modules`.
11+
# there's no `griffecli.__main__` in `sys.modules`.
1212

1313
from __future__ import annotations
1414

packages/griffelib/pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,5 +44,9 @@ classifiers = [
4444
[tool.hatch.metadata.hooks.uv-dynamic-versioning]
4545

4646
[tool.hatch.metadata.hooks.uv-dynamic-versioning.optional-dependencies]
47+
pypi = ["pip>=24.0", "platformdirs>=4.2", "wheel>=0.42"]
4748

4849
[tool.hatch.build.targets.sdist]
50+
51+
[tool.hatch.build.targets.wheel]
52+
sources = ["src/"]

packages/griffelib/src/griffelib/__init__.py

Lines changed: 65 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,143 +2,136 @@
22
# and exposes them as public objects. We have tests to make sure
33
# no object is forgotten in this list.
44

5-
"""Griffe package.
5+
"""Griffe library package.
66
77
Signatures for entire Python programs.
88
Extract the structure, the frame, the skeleton of your project,
99
to generate API documentation or find breaking changes in your API.
1010
11-
The entirety of the public API is exposed here, in the top-level `griffelib` module.
11+
The entirety of the library API is exposed here, in the top-level `griffelib` module.
12+
For backward compatibility, you can also import from `griffe` which re-exports everything.
1213
1314
All messages written to standard output or error are logged using the `logging` module.
14-
Our logger's name is set to `"griffelib"` and is public (you can rely on it).
15-
You can obtain the logger from the standard `logging` module: `logging.getLogger("griffelib")`.
15+
Our logger's name is set to `"griffe"` and is public (you can rely on it).
16+
You can obtain the logger from the standard `logging` module: `logging.getLogger("griffe")`.
1617
Actual logging messages are not part of the public API (they might change without notice).
1718
1819
Raised exceptions throughout the package are part of the public API (you can rely on them).
1920
Their actual messages are not part of the public API (they might change without notice).
2021
2122
The following paragraphs will help you discover the package's content.
2223
23-
## CLI entrypoints
24-
25-
Griffe provides a command-line interface (CLI) to interact with the package. The CLI entrypoints can be called from Python code.
26-
27-
- [`griffecli.main`][]: Run the main program.
28-
- [`griffecli.check`][]: Check for API breaking changes in two versions of the same package.
29-
- [`griffecli.dump`][]: Load packages data and dump it as JSON.
30-
3124
## Loaders
3225
3326
To load API data, Griffe provides several high-level functions.
3427
35-
- [`griffelib.load`][]: Load and return a Griffe object.
36-
- [`griffelib.load_git`][]: Load and return a module from a specific Git reference.
37-
- [`griffelib.load_pypi`][]: Load and return a module from a specific package version downloaded using pip.
28+
- [`griffe.load`][]: Load and return a Griffe object.
29+
- [`griffe.load_git`][]: Load and return a module from a specific Git reference.
30+
- [`griffe.load_pypi`][]: Load and return a module from a specific package version downloaded using pip.
3831
3932
## Models
4033
4134
The data loaded by Griffe is represented by several classes.
4235
43-
- [`griffelib.Module`][]: The class representing a Python module.
44-
- [`griffelib.Class`][]: The class representing a Python class.
45-
- [`griffelib.Function`][]: The class representing a Python function or method.
46-
- [`griffelib.Attribute`][]: The class representing a Python attribute.
47-
- [`griffelib.Alias`][]: This class represents an alias, or indirection, to an object declared in another module.
36+
- [`griffe.Module`][]: The class representing a Python module.
37+
- [`griffe.Class`][]: The class representing a Python class.
38+
- [`griffe.Function`][]: The class representing a Python function or method.
39+
- [`griffe.Attribute`][]: The class representing a Python attribute.
40+
- [`griffe.Alias`][]: This class represents an alias, or indirection, to an object declared in another module.
4841
4942
Additional classes are available to represent other concepts.
5043
51-
- [`griffelib.Decorator`][]: This class represents a decorator.
52-
- [`griffelib.Parameters`][]: This class is a container for parameters.
53-
- [`griffelib.Parameter`][]: This class represent a function parameter.
44+
- [`griffe.Decorator`][]: This class represents a decorator.
45+
- [`griffe.Parameters`][]: This class is a container for parameters.
46+
- [`griffe.Parameter`][]: This class represent a function parameter.
5447
5548
## Agents
5649
5750
Griffe is able to analyze code both statically and dynamically, using the following "agents".
5851
However most of the time you will only need to use the loaders above.
5952
60-
- [`griffelib.visit`][]: Parse and visit a module file.
61-
- [`griffelib.inspect`][]: Inspect a module.
53+
- [`griffe.visit`][]: Parse and visit a module file.
54+
- [`griffe.inspect`][]: Inspect a module.
6255
6356
## Serializers
6457
6558
Griffe can serizalize data to dictionary and JSON.
6659
67-
- [`griffelib.Object.as_json`][griffelib.Object.as_json]
68-
- [`griffelib.Object.from_json`][griffelib.Object.from_json]
69-
- [`griffelib.JSONEncoder`][]: JSON encoder for Griffe objects.
70-
- [`griffelib.json_decoder`][]: JSON decoder for Griffe objects.
60+
- [`griffe.Object.as_json`][griffe.Object.as_json]
61+
- [`griffe.Object.from_json`][griffe.Object.from_json]
62+
- [`griffe.JSONEncoder`][]: JSON encoder for Griffe objects.
63+
- [`griffe.json_decoder`][]: JSON decoder for Griffe objects.
7164
7265
## API checks
7366
7467
Griffe can compare two versions of the same package to find breaking changes.
7568
76-
- [`griffelib.find_breaking_changes`][]: Find breaking changes between two versions of the same API.
77-
- [`griffelib.Breakage`][]: Breakage classes can explain what broke from a version to another.
69+
- [`griffe.find_breaking_changes`][]: Find breaking changes between two versions of the same API.
70+
- [`griffe.Breakage`][]: Breakage classes can explain what broke from a version to another.
7871
7972
## Extensions
8073
81-
Griffe supports extensions. You can create your own extension by subclassing the `griffelib.Extension` class.
74+
Griffe supports extensions. You can create your own extension by subclassing the `griffe.Extension` class.
8275
83-
- [`griffelib.load_extensions`][]: Load configured extensions.
84-
- [`griffelib.Extension`][]: Base class for Griffe extensions.
76+
- [`griffe.load_extensions`][]: Load configured extensions.
77+
- [`griffe.Extension`][]: Base class for Griffe extensions.
8578
8679
## Docstrings
8780
8881
Griffe can parse docstrings into structured data.
8982
9083
Main class:
9184
92-
- [`griffelib.Docstring`][]: This class represents docstrings.
85+
- [`griffe.Docstring`][]: This class represents docstrings.
9386
9487
Docstring section and element classes all start with `Docstring`.
9588
9689
Docstring parsers:
9790
98-
- [`griffelib.parse`][]: Parse the docstring.
99-
- [`griffelib.parse_auto`][]: Parse a docstring by automatically detecting the style it uses.
100-
- [`griffelib.parse_google`][]: Parse a Google-style docstring.
101-
- [`griffelib.parse_numpy`][]: Parse a Numpydoc-style docstring.
102-
- [`griffelib.parse_sphinx`][]: Parse a Sphinx-style docstring.
91+
- [`griffe.parse`][]: Parse the docstring.
92+
- [`griffe.parse_auto`][]: Parse a docstring by automatically detecting the style it uses.
93+
- [`griffe.parse_google`][]: Parse a Google-style docstring.
94+
- [`griffe.parse_numpy`][]: Parse a Numpydoc-style docstring.
95+
- [`griffe.parse_sphinx`][]: Parse a Sphinx-style docstring.
10396
10497
## Exceptions
10598
10699
Griffe uses several exceptions to signal errors.
107100
108-
- [`griffelib.GriffeError`][]: The base exception for all Griffe errors.
109-
- [`griffelib.LoadingError`][]: Exception for loading errors.
110-
- [`griffelib.NameResolutionError`][]: Exception for names that cannot be resolved in a object scope.
111-
- [`griffelib.UnhandledEditableModuleError`][]: Exception for unhandled editables modules, when searching modules.
112-
- [`griffelib.UnimportableModuleError`][]: Exception for modules that cannot be imported.
113-
- [`griffelib.AliasResolutionError`][]: Exception for aliases that cannot be resolved.
114-
- [`griffelib.CyclicAliasError`][]: Exception raised when a cycle is detected in aliases.
115-
- [`griffelib.LastNodeError`][]: Exception raised when trying to access a next or previous node.
116-
- [`griffelib.RootNodeError`][]: Exception raised when trying to use siblings properties on a root node.
117-
- [`griffelib.BuiltinModuleError`][]: Exception raised when trying to access the filepath of a builtin module.
118-
- [`griffelib.ExtensionError`][]: Base class for errors raised by extensions.
119-
- [`griffelib.ExtensionNotLoadedError`][]: Exception raised when an extension could not be loaded.
120-
- [`griffelib.GitError`][]: Exception raised for errors related to Git.
101+
- [`griffe.GriffeError`][]: The base exception for all Griffe errors.
102+
- [`griffe.LoadingError`][]: Exception for loading errors.
103+
- [`griffe.NameResolutionError`][]: Exception for names that cannot be resolved in a object scope.
104+
- [`griffe.UnhandledEditableModuleError`][]: Exception for unhandled editables modules, when searching modules.
105+
- [`griffe.UnimportableModuleError`][]: Exception for modules that cannot be imported.
106+
- [`griffe.AliasResolutionError`][]: Exception for aliases that cannot be resolved.
107+
- [`griffe.CyclicAliasError`][]: Exception raised when a cycle is detected in aliases.
108+
- [`griffe.LastNodeError`][]: Exception raised when trying to access a next or previous node.
109+
- [`griffe.RootNodeError`][]: Exception raised when trying to use siblings properties on a root node.
110+
- [`griffe.BuiltinModuleError`][]: Exception raised when trying to access the filepath of a builtin module.
111+
- [`griffe.ExtensionError`][]: Base class for errors raised by extensions.
112+
- [`griffe.ExtensionNotLoadedError`][]: Exception raised when an extension could not be loaded.
113+
- [`griffe.GitError`][]: Exception raised for errors related to Git.
121114
122115
# Expressions
123116
124117
Griffe stores snippets of code (attribute values, decorators, base class, type annotations) as expressions.
125118
Expressions are basically abstract syntax trees (AST) with a few differences compared to the nodes returned by [`ast`][].
126119
Griffe provides a few helpers to extract expressions from regular AST nodes.
127120
128-
- [`griffelib.get_annotation`][]: Get a type annotation as expression.
129-
- [`griffelib.get_base_class`][]: Get a base class as expression.
130-
- [`griffelib.get_class_keyword`][]: Get a class keyword as expression.
131-
- [`griffelib.get_condition`][]: Get a condition as expression.
132-
- [`griffelib.get_expression`][]: Get an expression from an AST node.
133-
- [`griffelib.safe_get_annotation`][]: Get a type annotation as expression, safely (returns `None` on error).
134-
- [`griffelib.safe_get_base_class`][]: Get a base class as expression, safely (returns `None` on error).
135-
- [`griffelib.safe_get_class_keyword`][]: Get a class keyword as expression, safely (returns `None` on error).
136-
- [`griffelib.safe_get_condition`][]: Get a condition as expression, safely (returns `None` on error).
137-
- [`griffelib.safe_get_expression`][]: Get an expression from an AST node, safely (returns `None` on error).
121+
- [`griffe.get_annotation`][]: Get a type annotation as expression.
122+
- [`griffe.get_base_class`][]: Get a base class as expression.
123+
- [`griffe.get_class_keyword`][]: Get a class keyword as expression.
124+
- [`griffe.get_condition`][]: Get a condition as expression.
125+
- [`griffe.get_expression`][]: Get an expression from an AST node.
126+
- [`griffe.safe_get_annotation`][]: Get a type annotation as expression, safely (returns `None` on error).
127+
- [`griffe.safe_get_base_class`][]: Get a base class as expression, safely (returns `None` on error).
128+
- [`griffe.safe_get_class_keyword`][]: Get a class keyword as expression, safely (returns `None` on error).
129+
- [`griffe.safe_get_condition`][]: Get a condition as expression, safely (returns `None` on error).
130+
- [`griffe.safe_get_expression`][]: Get an expression from an AST node, safely (returns `None` on error).
138131
139132
The base class for expressions.
140133
141-
- [`griffelib.Expr`][]
134+
- [`griffe.Expr`][]
142135
143136
Expression classes all start with `Expr`.
144137
@@ -147,19 +140,19 @@
147140
If you want to log messages from extensions, get a logger with `get_logger`.
148141
The `logger` attribute is used by Griffe itself. You can use it to temporarily disable Griffe logging.
149142
150-
- [`griffelib.logger`][]: Our global logger, used throughout the library.
151-
- [`griffelib.get_logger`][]: Create and return a new logger instance.
143+
- [`griffe.logger`][]: Our global logger, used throughout the library.
144+
- [`griffe.get_logger`][]: Create and return a new logger instance.
152145
153146
# Helpers
154147
155148
To test your Griffe extensions, or to load API data from code in memory, Griffe provides the following helpers.
156149
157-
- [`griffelib.temporary_pyfile`][]: Create a Python file containing the given code in a temporary directory.
158-
- [`griffelib.temporary_pypackage`][]: Create a package containing the given modules in a temporary directory.
159-
- [`griffelib.temporary_visited_module`][]: Create and visit a temporary module with the given code.
160-
- [`griffelib.temporary_visited_package`][]: Create and visit a temporary package.
161-
- [`griffelib.temporary_inspected_module`][]: Create and inspect a temporary module with the given code.
162-
- [`griffelib.temporary_inspected_package`][]: Create and inspect a temporary package.
150+
- [`griffe.temporary_pyfile`][]: Create a Python file containing the given code in a temporary directory.
151+
- [`griffe.temporary_pypackage`][]: Create a package containing the given modules in a temporary directory.
152+
- [`griffe.temporary_visited_module`][]: Create and visit a temporary module with the given code.
153+
- [`griffe.temporary_visited_package`][]: Create and visit a temporary package.
154+
- [`griffe.temporary_inspected_module`][]: Create and inspect a temporary module with the given code.
155+
- [`griffe.temporary_inspected_package`][]: Create and inspect a temporary package.
163156
"""
164157

165158
from __future__ import annotations
@@ -185,7 +178,6 @@
185178
from griffelib._internal.agents.nodes.values import get_value, safe_get_value
186179
from griffelib._internal.agents.visitor import Visitor, builtin_decorators, stdlib_decorators, typing_overload, visit
187180
from griffelib._internal.c3linear import c3linear_merge
188-
from griffecli._internal.cli import DEFAULT_LOG_LEVEL, check, dump, get_parser, main
189181
from griffelib._internal.collections import LinesCollection, ModulesCollection
190182
from griffelib._internal.diff import (
191183
AttributeChangedTypeBreakage,
@@ -383,7 +375,6 @@
383375
# names = sorted(n for n in dir(griffelib) if not n.startswith("_") and n not in ("annotations",))
384376
# print('__all__ = [\n "' + '",\n "'.join(names) + '",\n]')
385377
__all__ = [
386-
"DEFAULT_LOG_LEVEL",
387378
"Alias",
388379
"AliasResolutionError",
389380
"Attribute",
@@ -546,9 +537,7 @@
546537
"builtin_decorators",
547538
"builtin_extensions",
548539
"c3linear_merge",
549-
"check",
550540
"docstring_warning",
551-
"dump",
552541
"dynamic_import",
553542
"find_breaking_changes",
554543
"get__all__",
@@ -563,7 +552,6 @@
563552
"get_name",
564553
"get_names",
565554
"get_parameters",
566-
"get_parser",
567555
"get_value",
568556
"htree",
569557
"infer_docstring_style",
@@ -574,7 +562,6 @@
574562
"load_git",
575563
"load_pypi",
576564
"logger",
577-
"main",
578565
"merge_stubs",
579566
"module_vtree",
580567
"parse",

packages/griffelib/src/griffelib/_internal/logger.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
# For example, mkdocstrings-python patches the logger to relocate it as a child
55
# of `mkdocs.plugins` so that it fits in the MkDocs logging configuration.
66
#
7-
# We use a single, global logger because our public API is exposed in a single module, `griffelib`.
7+
# We use a single, global logger because our public API is exposed in a single module.
8+
# The logger name is "griffe" for backward compatibility.
89
# Extensions however should use their own logger, which is why we provide the `get_logger` function.
910

1011
from __future__ import annotations
@@ -40,7 +41,7 @@ def disable(self) -> Iterator[None]:
4041
self._logger.setLevel(old_level)
4142

4243
@classmethod
43-
def _get(cls, name: str = "griffelib") -> Logger:
44+
def _get(cls, name: str = "griffe") -> Logger:
4445
if name not in cls._instances:
4546
cls._instances[name] = cls(name)
4647
return cls._instances[name]
@@ -60,15 +61,15 @@ def _patch_loggers(cls, get_logger_func: Callable) -> None:
6061
6162
Griffe's output and error messages are logging messages.
6263
63-
Griffe provides the [`patch_loggers`][griffelib.patch_loggers]
64+
Griffe provides the [`patch_loggers`][griffe.patch_loggers]
6465
function so dependent libraries can patch Griffe loggers as they see fit.
6566
6667
For example, to fit in the MkDocs logging configuration
6768
and prefix each log message with the module name:
6869
6970
```python
7071
import logging
71-
from griffelib import patch_loggers
72+
from griffe import patch_loggers
7273
7374
7475
class LoggerAdapter(logging.LoggerAdapter):
@@ -90,7 +91,7 @@ def get_logger(name):
9091
"""
9192

9293

93-
def get_logger(name: str = "griffelib") -> Logger:
94+
def get_logger(name: str = "griffe") -> Logger:
9495
"""Create and return a new logger instance.
9596
9697
Parameters:

0 commit comments

Comments
 (0)