CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
_requirestxt.py132 linesDownload Raw Back to command
1"""Helper code used to generate ``requires.txt`` files in the egg-info directory.2 3The ``requires.txt`` file has an specific format:4    - Environment markers need to be part of the section headers and5      should not be part of the requirement spec itself.6 7See https://setuptools.pypa.io/en/latest/deprecated/python_eggs.html#requires-txt8"""9 10from __future__ import annotations11 12import io13from collections import defaultdict14from collections.abc import Mapping15from itertools import filterfalse16from typing import TypeVar17 18from jaraco.text import yield_lines19from packaging.requirements import Requirement20 21from .. import _reqs22from .._reqs import _StrOrIter23 24# dict can work as an ordered set25_T = TypeVar("_T")26_Ordered = dict[_T, None]27 28 29def _prepare(30    install_requires: _StrOrIter, extras_require: Mapping[str, _StrOrIter]31) -> tuple[list[str], dict[str, list[str]]]:32    """Given values for ``install_requires`` and ``extras_require``33    create modified versions in a way that can be written in ``requires.txt``34    """35    extras = _convert_extras_requirements(extras_require)36    return _move_install_requirements_markers(install_requires, extras)37 38 39def _convert_extras_requirements(40    extras_require: Mapping[str, _StrOrIter],41) -> defaultdict[str, _Ordered[Requirement]]:42    """43    Convert requirements in `extras_require` of the form44    `"extra": ["barbazquux; {marker}"]` to45    `"extra:{marker}": ["barbazquux"]`.46    """47    output = defaultdict[str, _Ordered[Requirement]](dict)48    for section, v in extras_require.items():49        # Do not strip empty sections.50        output[section]51        for r in _reqs.parse(v):52            output[section + _suffix_for(r)].setdefault(r)53 54    return output55 56 57def _move_install_requirements_markers(58    install_requires: _StrOrIter, extras_require: Mapping[str, _Ordered[Requirement]]59) -> tuple[list[str], dict[str, list[str]]]:60    """61    The ``requires.txt`` file has an specific format:62        - Environment markers need to be part of the section headers and63          should not be part of the requirement spec itself.64 65    Move requirements in ``install_requires`` that are using environment66    markers ``extras_require``.67    """68 69    # divide the install_requires into two sets, simple ones still70    # handled by install_requires and more complex ones handled by extras_require.71 72    inst_reqs = list(_reqs.parse(install_requires))73    simple_reqs = filter(_no_marker, inst_reqs)74    complex_reqs = filterfalse(_no_marker, inst_reqs)75    simple_install_requires = list(map(str, simple_reqs))76 77    for r in complex_reqs:78        extras_require[':' + str(r.marker)].setdefault(r)79 80    expanded_extras = dict(81        # list(dict.fromkeys(...))  ensures a list of unique strings82        (k, list(dict.fromkeys(str(r) for r in map(_clean_req, v))))83        for k, v in extras_require.items()84    )85 86    return simple_install_requires, expanded_extras87 88 89def _suffix_for(req):90    """Return the 'extras_require' suffix for a given requirement."""91    return ':' + str(req.marker) if req.marker else ''92 93 94def _clean_req(req):95    """Given a Requirement, remove environment markers and return it"""96    r = Requirement(str(req))  # create a copy before modifying97    r.marker = None98    return r99 100 101def _no_marker(req):102    return not req.marker103 104 105def _write_requirements(stream, reqs):106    lines = yield_lines(reqs or ())107 108    def append_cr(line):109        return line + '\n'110 111    lines = map(append_cr, lines)112    stream.writelines(lines)113 114 115def write_requirements(cmd, basename, filename):116    dist = cmd.distribution117    data = io.StringIO()118    install_requires, extras_require = _prepare(119        dist.install_requires or (), dist.extras_require or {}120    )121    _write_requirements(data, install_requires)122    for extra in sorted(extras_require):123        data.write('\n[{extra}]\n'.format(**vars()))124        _write_requirements(data, extras_require[extra])125    cmd.write_or_delete_file("requirements", filename, data.getvalue())126 127 128def write_setup_requirements(cmd, basename, filename):129    data = io.StringIO()130    _write_requirements(data, cmd.distribution.setup_requires)131    cmd.write_or_delete_file("setup-requirements", filename, data.getvalue())132 
Aluode/PerceptionLabPortable · CoolFace