diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 14c7b59..a427348 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,7 +2,17 @@ Changelog for autopypath ======================== -0.9.1 (2026-01-22) +1.0.0 (2026-01-22) +------------------ +- Official release of autopypath version 1.0.0. +- Finalized documentation and public API. +- Added detailed examples and usage instructions. +- Narrowed down and stabilized the public API. +- Removed unused pydeps dependency. +- Fixed display of Apache-2.0 license badge in index.rst +- Bumped version to 1.0.0. + +0.9.1 (2026-01-21) ------------------------ - Added pre-commit Git hooks for code quality checks and formatting on commit. - Updated index.rst and README.rst documentation. diff --git a/README.rst b/README.rst index 01b33f9..7b63cfa 100644 --- a/README.rst +++ b/README.rst @@ -64,6 +64,7 @@ Documentation - `Usage `_ - `Configuration `_ +- `Public API `_ - `Contributing `_ - `Code of Conduct `_ diff --git a/docs_source/_static/custom.css b/docs_source/_static/custom.css index 886ced1..862b530 100644 --- a/docs_source/_static/custom.css +++ b/docs_source/_static/custom.css @@ -281,8 +281,6 @@ figure.caption-first figcaption { } - - .image-block-caption { font-size: var(--font-size--small); text-align: center; @@ -353,6 +351,12 @@ div.content div.article-container article section dl.py.class dd dl.field-list.s margin-top: .25rem } +/* function parameters */ +dl.py.function dt.sig.sig-object.py dl dd em.sig-param { + font-size: var(--font-size--small--2); + +} + /* 'property' fields in class documentation */ dl.py.class dd dl.py.property dt.py.sig.sig-object em.property:first-child span.pre { font-weight: bold; diff --git a/docs_source/conf.py b/docs_source/conf.py index 8ebccc4..4eaface 100644 --- a/docs_source/conf.py +++ b/docs_source/conf.py @@ -37,6 +37,9 @@ # -- General configuration --------------------------------------------------- + +python_maximum_signature_line_length = 20 + # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' @@ -47,7 +50,7 @@ extensions = [ # 'sphinx.ext.duration', 'sphinx.ext.doctest', - 'sphinx.ext.apidoc', + #'sphinx.ext.apidoc', # 'sphinx.ext.autodoc', # 'sphinx.ext.autosummary', 'sphinx.ext.intersphinx', @@ -60,11 +63,12 @@ intersphinx_mapping = { 'python': ('https://docs.python.org/3/', None), + 'typing': ('https://typing.python.org/en/latest/', None), 'sphinx': ('https://www.sphinx-doc.org/en/master/', None), 'pytest': ('https://docs.pytest.org/en/latest/', None), 'tox': ('https://tox.readthedocs.io/en/latest/', None), } -intersphinx_disabled_domains = ['std'] +#intersphinx_disabled_domains = ['std'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] diff --git a/docs_source/configuration.rst b/docs_source/configuration.rst index ef42b92..3600609 100644 --- a/docs_source/configuration.rst +++ b/docs_source/configuration.rst @@ -120,3 +120,33 @@ In either `pyproject.toml` or `autopypath.toml`, the configuration for paths loo [tool.autopypath] paths = ["src", "lib", "custom_dir"] + +Path Resolution Order +===================== + +The order in which autopypath resolves paths can be customized using the +`path_resolution_order` parameter to `configure_pypath()` or in a +`pyproject.toml` or `autopypath.toml` file. This setting determines the sequence +of configuration sources that autopypath checks for paths to add to `sys.path`. + +The available sources are: + +- `manual`: Paths provided directly via the `paths` parameter to `configure_pypath()`. +- `autopypath`: Paths specified in `autopypath.toml` configuration files. +- `pyproject`: Paths specified in `pyproject.toml` configuration files. + +The default resolution order is `['manual', 'autopypath', 'pyproject']`, meaning +that manually provided paths take precedence over those specified in `autopypath.toml`, +which in turn take precedence over those in `pyproject.toml`. ' + +This primarily affect the order in which paths are added to `sys.path` when using +the `prepend` load strategy. + +In either `pyproject.toml` or `autopypath.toml`, the configuration for path resolution +order looks like this: + +.. code-block:: toml + + [tool.autopypath] + path_resolution_order = ["manual", "autopypath", "pyproject"] + diff --git a/docs_source/index.rst b/docs_source/index.rst index 3b4fa1f..715ccb3 100644 --- a/docs_source/index.rst +++ b/docs_source/index.rst @@ -23,8 +23,8 @@ autopypath :target: https://pypi.org/project/autopypath/ :alt: Python Versions -.. image:: https://img.shields.io/pypi/l/autopypath - :target: https://pypi.org/project/autopypath/ +.. image:: https://img.shields.io/badge/License-Apache_2.0-green.svg + :target: https://opensource.org/licenses/Apache-2.0 :alt: License .. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json @@ -42,13 +42,9 @@ Table of Contents installation usage configuration - tutorials - faq + public_api contributing code_of_conduct - genindex - modindex - Source What is autopypath? ------------------- diff --git a/docs_source/public_api.rst b/docs_source/public_api.rst new file mode 100644 index 0000000..4486064 --- /dev/null +++ b/docs_source/public_api.rst @@ -0,0 +1,200 @@ +.. default-role:: py:obj + +========== +Public API +========== + +This section documents the public API of `autopypath`. These are the +classes, functions, and exceptions that users can import and use directly +in their own code. All other internal modules and functions are considered +implementation details and should not be relied upon. + +autopypath +========== + +.. module:: autopypath + +.. code-block:: python + :caption: Example usage + + import autopypath + +The main module that adjusts `sys.path` when imported. + + +autopypath.debug +================ + +.. module:: autopypath.debug + +.. code-block:: python + :caption: Example usage + + import autopypath.debug + +A module that enables debug logging for `autopypath`. Importing this +module sets the logging level to DEBUG, providing detailed information +about the path resolution process. It also upgrades logged warnings to +logged errors and raises corresponding +:class:`~autopypath.exceptions.AutopypathError` exceptions. + +It behaves the same as the main `autopypath` module but with enhanced logging +and error handling for debugging purposes. + + +autopypath.custom +================= + +.. module:: autopypath.custom + +Module for programmatic configuration of `autopypath`. + +configure_pypath +---------------- + +.. py:function:: configure_pypath(*, \ + repo_markers: Mapping[str, Literal['dir', 'file']] | None = None, \ + paths: Sequence[Path | str] | None = None, \ + load_strategy: Literal['prepend', 'prepend_highest_priority', 'replace'] | None = None, \ + path_resolution_order: Sequence[Literal['manual', 'autopypath', 'pyproject']] | None = None, \ + log_level: int | None = None, \ + strict: bool = False) + + A function that allows programmatic configuration of `autopypath` settings + such as custom paths to add to `sys.path`, repository markers, and + other options. This function can be used as an alternative to + configuration files like `pyproject.toml` or `autopypath.toml`. + + When this function is called, it performs the same path resolution + logic as the main `autopypath` module, adjusting :data:`sys.path` + according to the provided parameters and any detected configuration files. + + .. code-block:: python + :caption: Example usage + + from autopypath.custom import configure_pypath, AutopypathError + + try: + configure_pypath( + repo_markers={'src': 'dir', 'setup.py': 'file'}, + paths=['src/utils', 'lib'], + load_strategy='prepend', + path_resolution_order=['manual', 'pyproject'], + log_level=logging.INFO, + strict=True + ) + except AutopypathError as e: + print(f"Error configuring autopypath: {e}") + + :param repo_markers: + A mapping of file or directory names to their marker type used to identify the repository + root. They can only be of type 'dir' or 'file' and must be names only (no paths). If :obj:`None`, + the default repo markers are used. + :type repo_markers: `~typing.Mapping`\[`str`, `~typing.Literal`\["dir", "file"]] | :obj:`None` + + :param paths: + A sequence of paths to include in the :data:`sys.path`. + If passed as strings, they must be formatted as POSIX-style paths (e.g., 'src/utils') and + cannot be absolute paths. + If passed as :class:`pathlib.Path` objects, they can be either absolute or relative paths. + :type paths: `~typing.Sequence`\[`~pathlib.Path` | `str`] | :obj:`None` + + :param load_strategy: + The strategy for loading :data:`sys.path` entries. + + - 'prepend': (default) Adds new paths to the front of :data:`sys.path`, but after any existing entries. + - 'prepend_highest_priority': Adds new paths to the very front of :data:`sys.path`, before any existing entries. + - 'replace': Clears all existing entries in :data:`sys.path` and replaces them with the new paths. + :type load_strategy: `~typing.Literal`\['prepend', 'prepend_highest_priority', 'replace'] | :obj:`None` + + :param path_resolution_order: + The order in which to resolve :data:`sys.path` sources. It specifies which configuration + sources to check for paths to be added and in what order. + + - 'manual': The `paths` parameter passed to this function. + - 'autopypath': Configuration from `autopypath.toml` files. + - 'pyproject': Configuration from `pyproject.toml` files. + + If :obj:`None`, the default order is used: `['manual', 'autopypath', 'pyproject']` + :type path_resolution_order: `~typing.Sequence`\[`~typing.Literal`\['manual', 'autopypath', 'pyproject']] | :obj:`None` + + :param log_level: + The `logging` level to use during configuration. If :obj:`None`, the current log level is used. + The logging levels are those defined in the standard `logging` module, such as + `logging.DEBUG`, `logging.INFO`, `logging.WARNING`, etc. + :type log_level: `int` | :obj:`None` + + :param strict: + If `True`, raises an error for conditions that would normally only log a warning. + Default is `False`. It also turns logged warnings into logged errors and raised + :class:`~autopypath.custom.AutopypathError` exceptions. + + Conditions that normally trigger logged warnings include: + + - Specified paths that do not exist or cannot be resolved. + :type strict: `bool` + + :raises AutopypathError: + This is raised for various error conditions such as broken configurations; + failure to find the repository root due to missing project markers; + no paths being found and added to :data:`sys.path`; and other issues that + represent fatal errors in the path resolution process. + +.. exception:: AutopypathError + + The main exception class for `autopypath`. + + This exception is made available as an import from the :mod:`autopypath.custom` + module because that is where users are most likely to need to catch it when + using the programmatic configuration function. + + Trying to import it from the main :mod:`autopypath` module or :mod:`autopypath.debug` + module is generally not useful, as those modules automatically run the path + resolution logic on import---before the user would have a chance to wrap the + import in a `try/except` block. + + This exception is raised for fatal error conditions, including: + + - Broken configurations. + - Failure to find the repository root (missing markers). + - No valid paths found to add to :data:`sys.path`. + - Strict mode violations (when `strict=True`). + +pyproject.toml and autopypath.toml Configurations and Defaults +============================================================== + +For information on configuring `autopypath` using `pyproject.toml` or +`autopypath.toml` files, and for the defaults used when no configurations +are explicitly set, please refer to the :ref:`configuration section ` +of the documentation. + +Logging +======= + +`autopypath` uses the standard Python `logging` module to log messages +about its operations. By default, it logs info, warnings and errors to help +users identify potential issues with path resolution. + +Users can adjust the logging level by importing the :mod:`autopypath.debug` +module for debug-level logging, or by using the `log_level` parameter +of the :func:`configure_pypath` function for custom logging levels +during programmatic configuration. + +The logged messages are information but not structured or machine-readable. +They are intended to assist users in debugging path resolution issues +and understanding how `autopypath` is modifying :data:`sys.path` but not +to be parsed or processed programmatically. + +Exceptions +========== + +`autopypath` raises exceptions for fatal error conditions that prevent +it from successfully resolving and adjusting :data:`sys.path`. The only +exception class is :class:`~autopypath.custom.AutopypathError`, which +is raised for issues such as broken configurations, failure to find +the repository root, no valid paths found, and strict mode violations. + +Users can catch these exceptions when using the :func:`configure_pypath` +function for programmatic configuration. The exceptions provide +meaningful error messages to help diagnose and resolve issues with +path resolution. diff --git a/docs_source/source/autopypath.custom.rst b/docs_source/source/autopypath.custom.rst deleted file mode 100644 index 18438e3..0000000 --- a/docs_source/source/autopypath.custom.rst +++ /dev/null @@ -1,7 +0,0 @@ -autopypath.custom package -========================= - -.. automodule:: autopypath.custom - :members: - :show-inheritance: - :undoc-members: diff --git a/docs_source/source/autopypath.debug.rst b/docs_source/source/autopypath.debug.rst deleted file mode 100644 index dfa5bb0..0000000 --- a/docs_source/source/autopypath.debug.rst +++ /dev/null @@ -1,7 +0,0 @@ -autopypath.debug module -======================= - -.. automodule:: autopypath.debug - :members: - :show-inheritance: - :undoc-members: diff --git a/docs_source/source/autopypath.rst b/docs_source/source/autopypath.rst deleted file mode 100644 index 579f807..0000000 --- a/docs_source/source/autopypath.rst +++ /dev/null @@ -1,23 +0,0 @@ -autopypath package -================== - -.. automodule:: autopypath - :members: - :show-inheritance: - :undoc-members: - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - autopypath.custom - -Submodules ----------- - -.. toctree:: - :maxdepth: 4 - - autopypath.debug diff --git a/docs_source/source/modules.rst b/docs_source/source/modules.rst deleted file mode 100644 index df09d42..0000000 --- a/docs_source/source/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -src -=== - -.. toctree:: - :maxdepth: 4 - - autopypath diff --git a/pyproject.toml b/pyproject.toml index 09eb7fe..def0eae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,6 @@ dev = [ "ruff>=0.14.11", "hatch>=1.13", "hatchling>=1.27", - "pydeps>=1.23.2", "tox>=4.22.0", "tox-uv>=1.13.1", "uv>=0.9.18", @@ -105,7 +104,6 @@ docs = [ tools = [ "hatch>=1.13", "hatchling>=1.27", - "pydeps>=1.23.2", "tox>=4.22.0", "tox-uv>=1.13.1", "uv>=0.9.18", @@ -185,9 +183,8 @@ exclude = ["venv"] description = "Build the documentation" base_python = ["python3.12"] dependency_groups = ["docs", "test"] -allowlist_externals = ["sphinx-build", "sphinx-apidoc", "pydeps"] +allowlist_externals = ["sphinx-build"] commands = [ - ["sphinx-apidoc", "--separate", "--remove-old", "--module-first", "-f", "-o", "docs_source/source", "src"], ["sphinx-build", "-b", "html", "docs_source/", "documentation/"], ] diff --git a/src/autopypath/__init__.py b/src/autopypath/__init__.py index 47bd75b..f0264a0 100644 --- a/src/autopypath/__init__.py +++ b/src/autopypath/__init__.py @@ -265,9 +265,7 @@ from ._exceptions import AutopypathError from ._log import _log -__all__ = [ - 'AutopypathError', -] +__all__ = [] # Only run if directly imported by a script being executed as __main__ diff --git a/src/autopypath/_meta.py b/src/autopypath/_meta.py index 88d8424..1c96e06 100644 --- a/src/autopypath/_meta.py +++ b/src/autopypath/_meta.py @@ -7,8 +7,8 @@ __author__ = 'Jerilyn Franz' __copyright__ = '2026, Jerilyn Franz' -__version__ = '0.9.1' -__release__ = '0.9.1' +__version__ = '1.0.0' +__release__ = '1.0.0' __project__ = 'autopypath' __license__ = 'Apache-2.0' __url__ = 'https://github.com/snowhare/python-autopypath' diff --git a/src/autopypath/debug.py b/src/autopypath/debug.py index e42be0f..063ed0b 100644 --- a/src/autopypath/debug.py +++ b/src/autopypath/debug.py @@ -34,7 +34,7 @@ from ._exceptions import AutopypathError from ._log import _log -__all__ = ['AutopypathError'] +__all__ = [] _log.setLevel(logging.DEBUG)