pep518 venvs

wreck.pep518_venvs.DC_SLOTS: dict[str, bool]

Allows dataclasses.dataclass __slots__ support from py310

wreck.pep518_venvs.TOML_SECTION_VENVS: str = "wreck.venvs"

pyproject.toml section excluding tool. prefix

wreck.pep518_venvs.DICT_SEARCH_KEY: str = "venv_base_path"

In pyproject.toml section, key name. The value contains the venv relative path

class wreck.pep518_venvs.VenvMap(loader, parse_venv_relpath=None, check_suffixes=('.in', '.unlock', '.lock'))

From pyproject.toml, read [[tool.wreck.venvs]] array of tables.

Each virtual environment should have a list of requirement files which maybe can recreate it.

The venv relative path and the requirements files relative paths are both posix. The top level requirements file paths are w/o suffix.

Complete example venvs and respective list of requirement files

[[tool.wreck.venvs]]
venv_base_path = '.doc/.venv'
in_folder = 'docs'
reqs = [
    'docs/pip-tools',
    'docs/requirements',
]
[[tool.wreck.venvs]]
venv_base_path = '.venv'
in_folder = 'requirements'
reqs = [
    'requirements/pip-tools',
    'requirements/pip',
    'requirements/prod.shared',
    'requirements/kit',
    'requirements/tox',
    'requirements/mypy',
    'requirements/manage',
    'requirements/dev',
]
  • In TOML format, paths MUST be single quoted.

  • Note lack of suffix.

    There are three suffix per requirements: .in, .unlock, and .lock.

  • The venv folder should already exist.

    The focus is on the requirements files, not what’s install within the virtual environment.

  • The requirements files should already exist.

    As long as the .in files exist, to recreate .lock and .unlockreqs fix .unlockreqs unlock

Variables:
  • _loader (wreck.pep518_venvs.VenvMapLoader) – Contains some paths and loaded unparsed mappings

  • check_suffixes (tuple[str, ...]) – Default (“.in”, “.unlock”, “.lock”). Suffixes of requirements file to check exists and is file

_iter: collections.abc.Iterator[wreck.pep518_venvs.VenvReq]

Package base folder absolute path

_venvs: list[wreck.pep518_venvs.VenvReq]

key is virtual environment absolute path as_posix. Value is a list of absolute path to top level .in requirement files

To change suffix, use wreck._safe_path.replace_suffixes()

_missing

Make missing requirements available. Then at a convenient time can provide feedback on missing requirements files

__slots__ = ("_loader", "_venvs", "_iter", "_missing")

Reduce memory footprint. Enhance performance

Raises:
ensure_abspath(key)

Convenience wrapper around VenvMapLoader method of the same name.

Parameters:

key (str | pathlib.Path) – A relative or absolute path

Returns:

Absolute path

Return type:

pathlib.Path

property missing

During each iteration, check that requirement files exists is performed. The results are stored rather than raising exceptions.

Checks for existence of .in, .unlock and .lock files.

Does not check for .lnk

Returns:

venv

Return type:

list[str]

reqs(key)

For one venv, get requirements (.in).

Parameters:

key (Any) – venv relative or absolute path

Returns:

One venv, VenvReq items

Return type:

list[wreck.pep518_venvs.VenvReq]

Raises:
  • TypeError – venv relative path (as_posix) is a str key. Unsupported type

  • KeyError – No such venv found

class wreck.pep518_venvs.VenvMapLoader(pyproject_toml_base_path: dataclasses.InitVar[str])

Load the pyproject.toml [[tool.wreck.venvs]] section

Variables:

pyproject_toml_base_path – Start path for the reverse search to find pyproject.toml file

Vartype:

str

project_base: pathlib.Path

Package base folder absolute path

pyproject_toml: pathlib.Path

pyproject.toml absolute path

l_data: collections.abc.Sequence[wreck.monkey.pyproject_reading.TOML_RESULT]

TOML section [[tool.wreck.venvs]] are array of tables. Reading this produces a list of Mapping

section_parent: wreck.monkey.pyproject_reading.TOML_RESULT

venv array of tables parent section. Does not include itself. Intended to contain behavioral variables only. key/value pair validation is needed.

ensure_abspath(key)

Support key being either relative or absolute path

Parameters:

key (str | pathlib.Path) – venv path. Either relative or absolute path

Returns:

venv absolute Path

Return type:

pathlib.Path

Raises:
  • TypeError – unsupported type expecting str or pathlib.Path

static load_data(pyproject_toml_base_path)

From a path do a reverse search to find a pyproject.toml or a .pyproject_toml test file.

The venvs and venv’s requirements won’t change. Possible some files are missing. So the load process needs to only occur once.

Parameters:

pyproject_toml_base_path – Start path for the reverse search to find pyproject.toml file

Type:

str

Returns:

TOML project and one section data along with a few paths

Return type:

tuple[collections.abc.Sequence[wreck.monkey.pyproject_reading.TOML_RESULT], TOML_RESULT, pathlib.Path, pathlib.Path]

Raises:
  • FileNotFoundError – pyproject.toml file reverse search start path expecting Path or file not found

  • LookupError – no [[tools.wreck.venvs]] TOML array of tables

parse_data(parse_venv_relpath=None, check_suffixes=('.in', '.unlock', '.lock'))

Take raw TOML section array of tables and parse.

Each datum is stored along with redundant metadata project_base and in_folder. :param _sphinx_paramlinks_wreck.pep518_venvs.VenvMapLoader.parse_data.check_suffixes:

Default (“.in”, “.unlock”, “.lock”). Suffixes of requirements file to check exists and is file

Returns:

All VenvReq and missing files

Return type:

tuple[list[wreck.pep518_venvs.VenvReq], list[str]]

Raises:
  • NotADirectoryError – venv relative paths do not correspond to actual venv folders

  • ValueError – expecting [[tool.wreck.venvs]] field reqs to be a sequence

property venv_relpaths

Get venvs’ relative path.

Supplements parse_data

Returns:

venvs’ relative path

Return type:

list[pathlib.Path]

class wreck.pep518_venvs.VenvReq(project_base: Path, venv_relpath: str, req_relpath: str, req_folders: tuple[str, ...])

Can always apply project_base to get the absolute Path

project_base: pathlib.Path

Absolute path to project base folder

venv_relpath: str

As sourced from TOML file a str (single quoted) relative path to venv base folder

req_relpath: str

As sourced from TOML file a str (single quoted) relative path to requirement file w/o (end) suffix: .in, .unlock, .lock. So a shared (between venv) requirement file, would be written requirements/prod.shared w/o the final suffix e.g. .in.

req_folders: tuple[str]

req folders relative path. Requirement files should not be outside these folders. Intentionally, cannot specify additional folders.

property is_req_shared

Check if requirement file suffix is .shared. Indicating requirement file is shared with multiple venv. And thus not an ideal place for nudge pins

Returns:

True if requirements file has a .shared suffix

Return type:

bool

property req_abspath

Get abspath for requirement. If lacks a .in append it

Stored in TOML file as a relative path (str).

Returns:

venv absolute Path

Return type:

pathlib.Path

reqs_all(suffix='.in')

Yields abspath to requirements files. The suffix filters by requirements file type

Parameters:

suffix (str) – Specific requirements file type

Returns:

Generator of absolute path to requirement folders

Return type:

collections.abc.Generator[pathlib.Path, None, None]

property venv_abspath

Get abspath for venv.

Stored in TOML file as a relative path (str).

Returns:

venv absolute Path

Return type:

pathlib.Path

wreck.pep518_venvs.check_loader(loader)

Check loader valid

Parameters:

loader (Any) – Should be a VenvMapLoader

Raises:
wreck.pep518_venvs.check_venv_relpath(loader, venv_path_mixed)

Expecting relpath. If abspath convert to relpath

Relative path acts as a dict key. An absolute path is not a key. Selecting by always nonexistent key returns empty Sequence, abspath_reqs

Assume loader has been checked

Parameters:
Returns:

relative Path to venv base folder

Return type:

pathlib.Path

Raises:
  • TypeError – venv_path is either None or unsupported type

wreck.pep518_venvs.fix_check_suffixes(check_suffixes)

Passthrough a Sequence[str]. Coerce str into a non str Sequence. If unsupported type or None return None

Parameters:

check_suffixes (Any) – Should be a Sequence[str] or a str

Returns:

A non-str Sequence or None if unsupported type

Return type:

collections.abc.Sequence[str] | None

wreck.pep518_venvs.get_reqs(loader, venv_path=None, suffix_last='.in')

get absolute path to requirement files

Filtering by venv relative or absolute path is recommended

Parameters:
  • loader (wreck.pep518_venvs.VenvMapLoader) – Contains some paths and loaded unparsed mappings

  • venv_path (Any) – Filter by venv relative or absolute path

  • suffix_last (str) – Default .in. Last suffix is replaced, not all suffixes

Returns:

Sequence of absolute path to requirements files

Return type:

tuple[pathlib.Path]

Raises: