From e0dda88874e73cd484b9e8464c5921a903db3cf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez=20Mondrag=C3=B3n?= <16805946+edgarrmondragon@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:54:41 -0600 Subject: [PATCH] Document `markers.default_environment()` (#753) Co-authored-by: Brett Cannon --- .readthedocs.yml | 2 +- docs/conf.py | 1 + docs/markers.rst | 14 ++++++++ docs/requirements.txt | 2 ++ pyproject.toml | 1 + src/packaging/markers.py | 78 ++++++++++++++++++++++++++++++++++++++-- 6 files changed, 94 insertions(+), 4 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index a5f0ba47..a779538e 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -3,7 +3,7 @@ version: 2 build: os: ubuntu-22.04 tools: - python: "3.8" + python: "3.9" formats: [pdf] sphinx: diff --git a/docs/conf.py b/docs/conf.py index d89b26aa..b4da79ee 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,6 +21,7 @@ "sphinx.ext.doctest", "sphinx.ext.extlinks", "sphinx.ext.intersphinx", + "sphinx_toolbox.more_autodoc.autotypeddict", ] # General information about the project. diff --git a/docs/markers.rst b/docs/markers.rst index d3b7676d..e802dac0 100644 --- a/docs/markers.rst +++ b/docs/markers.rst @@ -71,6 +71,20 @@ Reference :raises: UndefinedEnvironmentName: If the marker accesses a value that isn't present inside of the environment dictionary. + :rtype: bool + +.. autotypeddict:: packaging.markers.Environment + + A dictionary that represents a Python environment as captured by + :func:`default_environment`. + +.. function:: default_environment() + + Returns a dictionary representing the current Python process. This is the + base environment that is used when evaluating markers in + :meth:`Marker.evaluate`. + + :rtype: Environment .. exception:: InvalidMarker diff --git a/docs/requirements.txt b/docs/requirements.txt index a95ae18b..299a951c 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,3 @@ furo +sphinx-toolbox +typing-extensions>=4.1.0; python_version < "3.9" diff --git a/pyproject.toml b/pyproject.toml index d2bc3f9d..4f6aca04 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,6 +51,7 @@ exclude_lines = ["pragma: no cover", "@abc.abstractmethod", "@abc.abstractproper strict = true show_error_codes = true enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] +warn_unused_ignores = true [[tool.mypy.overrides]] module = ["_manylinux"] diff --git a/src/packaging/markers.py b/src/packaging/markers.py index 6eb08dcf..2d60bdf2 100644 --- a/src/packaging/markers.py +++ b/src/packaging/markers.py @@ -8,7 +8,7 @@ import os import platform import sys -from typing import Any, Callable +from typing import Any, Callable, TypedDict, cast from ._parser import MarkerAtom, MarkerList, Op, Value, Variable from ._parser import parse_marker as _parse_marker @@ -46,6 +46,78 @@ class UndefinedEnvironmentName(ValueError): """ +class Environment(TypedDict): + implementation_name: str + """The implementation's identifier, e.g. ``'cpython'``.""" + + implementation_version: str + """ + The implementation's version, e.g. ``'3.13.0a2'`` for CPython 3.13.0a2, or + ``'7.3.13'`` for PyPy3.10 v7.3.13. + """ + + os_name: str + """ + The value of :py:data:`os.name`. The name of the operating system dependent module + imported, e.g. ``'posix'``. + """ + + platform_machine: str + """ + Returns the machine type, e.g. ``'i386'``. + + An empty string if the value cannot be determined. + """ + + platform_release: str + """ + The system's release, e.g. ``'2.2.0'`` or ``'NT'``. + + An empty string if the value cannot be determined. + """ + + platform_system: str + """ + The system/OS name, e.g. ``'Linux'``, ``'Windows'`` or ``'Java'``. + + An empty string if the value cannot be determined. + """ + + platform_version: str + """ + The system's release version, e.g. ``'#3 on degas'``. + + An empty string if the value cannot be determined. + """ + + python_full_version: str + """ + The Python version as string ``'major.minor.patchlevel'``. + + Note that unlike the Python :py:data:`sys.version`, this value will always include + the patchlevel (it defaults to 0). + """ + + platform_python_implementation: str + """ + A string identifying the Python implementation, e.g. ``'CPython'``. + """ + + python_version: str + """The Python version as string ``'major.minor'``.""" + + sys_platform: str + """ + This string contains a platform identifier that can be used to append + platform-specific components to :py:data:`sys.path`, for instance. + + For Unix systems, except on Linux and AIX, this is the lowercased OS name as + returned by ``uname -s`` with the first part of the version as returned by + ``uname -r`` appended, e.g. ``'sunos5'`` or ``'freebsd8'``, at the time when Python + was built. + """ + + def _normalize_extra_values(results: Any) -> Any: """ Normalize extra values. @@ -167,7 +239,7 @@ def format_full_version(info: sys._version_info) -> str: return version -def default_environment() -> dict[str, str]: +def default_environment() -> Environment: iver = format_full_version(sys.implementation.version) implementation_name = sys.implementation.name return { @@ -235,7 +307,7 @@ def evaluate(self, environment: dict[str, str] | None = None) -> bool: The environment is determined from the current Python process. """ - current_environment = default_environment() + current_environment = cast("dict[str, str]", default_environment()) current_environment["extra"] = "" if environment is not None: current_environment.update(environment)