Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document markers.default_environment() #753

Merged
merged 12 commits into from
Mar 11, 2024
Merged
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: 2
build:
os: ubuntu-22.04
tools:
python: "3.8"
python: "3.9"

formats: [pdf]
sphinx:
Expand Down
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"sphinx.ext.doctest",
"sphinx.ext.extlinks",
"sphinx.ext.intersphinx",
"sphinx_toolbox.more_autodoc.autotypeddict",
]

# General information about the project.
Expand Down
14 changes: 14 additions & 0 deletions docs/markers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 2 additions & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
furo
sphinx-toolbox
typing-extensions>=4.1.0; python_version < "3.9"
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
78 changes: 75 additions & 3 deletions src/packaging/markers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down