Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .venv/lib/python3.11/site-packages/multidict/__init__.py +48 -0
- .venv/lib/python3.11/site-packages/multidict/__init__.pyi +152 -0
- .venv/lib/python3.11/site-packages/multidict/__pycache__/_abc.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/multidict/__pycache__/_compat.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/multidict/__pycache__/_multidict_py.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/multidict/_abc.py +48 -0
- .venv/lib/python3.11/site-packages/multidict/_compat.py +14 -0
- .venv/lib/python3.11/site-packages/multidict/_multidict_base.py +152 -0
- .venv/lib/python3.11/site-packages/multidict/_multidict_py.py +527 -0
- .venv/lib/python3.11/site-packages/multidict/py.typed +1 -0
- .venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/INSTALLER +1 -0
- .venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/LICENSE +25 -0
- .venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/METADATA +87 -0
- .venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/RECORD +8 -0
- .venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/WHEEL +5 -0
- .venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/top_level.txt +1 -0
- .venv/lib/python3.11/site-packages/packaging/__init__.py +15 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/_elffile.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/_manylinux.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/_musllinux.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/_parser.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/_structures.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/_tokenizer.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/markers.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/metadata.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/requirements.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/specifiers.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/tags.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/utils.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/__pycache__/version.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/_elffile.py +110 -0
- .venv/lib/python3.11/site-packages/packaging/_manylinux.py +263 -0
- .venv/lib/python3.11/site-packages/packaging/_musllinux.py +85 -0
- .venv/lib/python3.11/site-packages/packaging/_parser.py +354 -0
- .venv/lib/python3.11/site-packages/packaging/_structures.py +61 -0
- .venv/lib/python3.11/site-packages/packaging/_tokenizer.py +194 -0
- .venv/lib/python3.11/site-packages/packaging/licenses/__init__.py +145 -0
- .venv/lib/python3.11/site-packages/packaging/licenses/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/licenses/__pycache__/_spdx.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/packaging/licenses/_spdx.py +759 -0
- .venv/lib/python3.11/site-packages/packaging/py.typed +0 -0
- .venv/lib/python3.11/site-packages/packaging/requirements.py +91 -0
- .venv/lib/python3.11/site-packages/packaging/specifiers.py +1020 -0
- .venv/lib/python3.11/site-packages/packaging/utils.py +163 -0
- .venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/__init__.py +0 -0
- .venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__init__.py +566 -0
- .venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__main__.py +53 -0
- .venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-311.pyc +0 -0
.venv/lib/python3.11/site-packages/multidict/__init__.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Multidict implementation.
|
| 2 |
+
|
| 3 |
+
HTTP Headers and URL query string require specific data structure:
|
| 4 |
+
multidict. It behaves mostly like a dict but it can have
|
| 5 |
+
several values for the same key.
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
from ._abc import MultiMapping, MutableMultiMapping
|
| 9 |
+
from ._compat import USE_EXTENSIONS
|
| 10 |
+
|
| 11 |
+
__all__ = (
|
| 12 |
+
"MultiMapping",
|
| 13 |
+
"MutableMultiMapping",
|
| 14 |
+
"MultiDictProxy",
|
| 15 |
+
"CIMultiDictProxy",
|
| 16 |
+
"MultiDict",
|
| 17 |
+
"CIMultiDict",
|
| 18 |
+
"upstr",
|
| 19 |
+
"istr",
|
| 20 |
+
"getversion",
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
__version__ = "6.1.0"
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
try:
|
| 27 |
+
if not USE_EXTENSIONS:
|
| 28 |
+
raise ImportError
|
| 29 |
+
from ._multidict import (
|
| 30 |
+
CIMultiDict,
|
| 31 |
+
CIMultiDictProxy,
|
| 32 |
+
MultiDict,
|
| 33 |
+
MultiDictProxy,
|
| 34 |
+
getversion,
|
| 35 |
+
istr,
|
| 36 |
+
)
|
| 37 |
+
except ImportError: # pragma: no cover
|
| 38 |
+
from ._multidict_py import (
|
| 39 |
+
CIMultiDict,
|
| 40 |
+
CIMultiDictProxy,
|
| 41 |
+
MultiDict,
|
| 42 |
+
MultiDictProxy,
|
| 43 |
+
getversion,
|
| 44 |
+
istr,
|
| 45 |
+
)
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
upstr = istr
|
.venv/lib/python3.11/site-packages/multidict/__init__.pyi
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import abc
|
| 2 |
+
from typing import (
|
| 3 |
+
Generic,
|
| 4 |
+
Iterable,
|
| 5 |
+
Iterator,
|
| 6 |
+
Mapping,
|
| 7 |
+
MutableMapping,
|
| 8 |
+
TypeVar,
|
| 9 |
+
overload,
|
| 10 |
+
)
|
| 11 |
+
|
| 12 |
+
class istr(str): ...
|
| 13 |
+
|
| 14 |
+
upstr = istr
|
| 15 |
+
|
| 16 |
+
_S = str | istr
|
| 17 |
+
|
| 18 |
+
_T = TypeVar("_T")
|
| 19 |
+
|
| 20 |
+
_T_co = TypeVar("_T_co", covariant=True)
|
| 21 |
+
|
| 22 |
+
_D = TypeVar("_D")
|
| 23 |
+
|
| 24 |
+
class MultiMapping(Mapping[_S, _T_co]):
|
| 25 |
+
@overload
|
| 26 |
+
@abc.abstractmethod
|
| 27 |
+
def getall(self, key: _S) -> list[_T_co]: ...
|
| 28 |
+
@overload
|
| 29 |
+
@abc.abstractmethod
|
| 30 |
+
def getall(self, key: _S, default: _D) -> list[_T_co] | _D: ...
|
| 31 |
+
@overload
|
| 32 |
+
@abc.abstractmethod
|
| 33 |
+
def getone(self, key: _S) -> _T_co: ...
|
| 34 |
+
@overload
|
| 35 |
+
@abc.abstractmethod
|
| 36 |
+
def getone(self, key: _S, default: _D) -> _T_co | _D: ...
|
| 37 |
+
|
| 38 |
+
_Arg = (
|
| 39 |
+
Mapping[str, _T]
|
| 40 |
+
| Mapping[istr, _T]
|
| 41 |
+
| dict[str, _T]
|
| 42 |
+
| dict[istr, _T]
|
| 43 |
+
| MultiMapping[_T]
|
| 44 |
+
| Iterable[tuple[str, _T]]
|
| 45 |
+
| Iterable[tuple[istr, _T]]
|
| 46 |
+
)
|
| 47 |
+
|
| 48 |
+
class MutableMultiMapping(MultiMapping[_T], MutableMapping[_S, _T], Generic[_T]):
|
| 49 |
+
@abc.abstractmethod
|
| 50 |
+
def add(self, key: _S, value: _T) -> None: ...
|
| 51 |
+
@abc.abstractmethod
|
| 52 |
+
def extend(self, arg: _Arg[_T] = ..., **kwargs: _T) -> None: ...
|
| 53 |
+
@overload
|
| 54 |
+
@abc.abstractmethod
|
| 55 |
+
def popone(self, key: _S) -> _T: ...
|
| 56 |
+
@overload
|
| 57 |
+
@abc.abstractmethod
|
| 58 |
+
def popone(self, key: _S, default: _D) -> _T | _D: ...
|
| 59 |
+
@overload
|
| 60 |
+
@abc.abstractmethod
|
| 61 |
+
def popall(self, key: _S) -> list[_T]: ...
|
| 62 |
+
@overload
|
| 63 |
+
@abc.abstractmethod
|
| 64 |
+
def popall(self, key: _S, default: _D) -> list[_T] | _D: ...
|
| 65 |
+
|
| 66 |
+
class MultiDict(MutableMultiMapping[_T], Generic[_T]):
|
| 67 |
+
def __init__(self, arg: _Arg[_T] = ..., **kwargs: _T) -> None: ...
|
| 68 |
+
def copy(self) -> MultiDict[_T]: ...
|
| 69 |
+
def __getitem__(self, k: _S) -> _T: ...
|
| 70 |
+
def __setitem__(self, k: _S, v: _T) -> None: ...
|
| 71 |
+
def __delitem__(self, v: _S) -> None: ...
|
| 72 |
+
def __iter__(self) -> Iterator[_S]: ...
|
| 73 |
+
def __len__(self) -> int: ...
|
| 74 |
+
@overload
|
| 75 |
+
def getall(self, key: _S) -> list[_T]: ...
|
| 76 |
+
@overload
|
| 77 |
+
def getall(self, key: _S, default: _D) -> list[_T] | _D: ...
|
| 78 |
+
@overload
|
| 79 |
+
def getone(self, key: _S) -> _T: ...
|
| 80 |
+
@overload
|
| 81 |
+
def getone(self, key: _S, default: _D) -> _T | _D: ...
|
| 82 |
+
def add(self, key: _S, value: _T) -> None: ...
|
| 83 |
+
def extend(self, arg: _Arg[_T] = ..., **kwargs: _T) -> None: ...
|
| 84 |
+
@overload
|
| 85 |
+
def popone(self, key: _S) -> _T: ...
|
| 86 |
+
@overload
|
| 87 |
+
def popone(self, key: _S, default: _D) -> _T | _D: ...
|
| 88 |
+
@overload
|
| 89 |
+
def popall(self, key: _S) -> list[_T]: ...
|
| 90 |
+
@overload
|
| 91 |
+
def popall(self, key: _S, default: _D) -> list[_T] | _D: ...
|
| 92 |
+
|
| 93 |
+
class CIMultiDict(MutableMultiMapping[_T], Generic[_T]):
|
| 94 |
+
def __init__(self, arg: _Arg[_T] = ..., **kwargs: _T) -> None: ...
|
| 95 |
+
def copy(self) -> CIMultiDict[_T]: ...
|
| 96 |
+
def __getitem__(self, k: _S) -> _T: ...
|
| 97 |
+
def __setitem__(self, k: _S, v: _T) -> None: ...
|
| 98 |
+
def __delitem__(self, v: _S) -> None: ...
|
| 99 |
+
def __iter__(self) -> Iterator[_S]: ...
|
| 100 |
+
def __len__(self) -> int: ...
|
| 101 |
+
@overload
|
| 102 |
+
def getall(self, key: _S) -> list[_T]: ...
|
| 103 |
+
@overload
|
| 104 |
+
def getall(self, key: _S, default: _D) -> list[_T] | _D: ...
|
| 105 |
+
@overload
|
| 106 |
+
def getone(self, key: _S) -> _T: ...
|
| 107 |
+
@overload
|
| 108 |
+
def getone(self, key: _S, default: _D) -> _T | _D: ...
|
| 109 |
+
def add(self, key: _S, value: _T) -> None: ...
|
| 110 |
+
def extend(self, arg: _Arg[_T] = ..., **kwargs: _T) -> None: ...
|
| 111 |
+
@overload
|
| 112 |
+
def popone(self, key: _S) -> _T: ...
|
| 113 |
+
@overload
|
| 114 |
+
def popone(self, key: _S, default: _D) -> _T | _D: ...
|
| 115 |
+
@overload
|
| 116 |
+
def popall(self, key: _S) -> list[_T]: ...
|
| 117 |
+
@overload
|
| 118 |
+
def popall(self, key: _S, default: _D) -> list[_T] | _D: ...
|
| 119 |
+
|
| 120 |
+
class MultiDictProxy(MultiMapping[_T], Generic[_T]):
|
| 121 |
+
def __init__(self, arg: MultiMapping[_T] | MutableMultiMapping[_T]) -> None: ...
|
| 122 |
+
def copy(self) -> MultiDict[_T]: ...
|
| 123 |
+
def __getitem__(self, k: _S) -> _T: ...
|
| 124 |
+
def __iter__(self) -> Iterator[_S]: ...
|
| 125 |
+
def __len__(self) -> int: ...
|
| 126 |
+
@overload
|
| 127 |
+
def getall(self, key: _S) -> list[_T]: ...
|
| 128 |
+
@overload
|
| 129 |
+
def getall(self, key: _S, default: _D) -> list[_T] | _D: ...
|
| 130 |
+
@overload
|
| 131 |
+
def getone(self, key: _S) -> _T: ...
|
| 132 |
+
@overload
|
| 133 |
+
def getone(self, key: _S, default: _D) -> _T | _D: ...
|
| 134 |
+
|
| 135 |
+
class CIMultiDictProxy(MultiMapping[_T], Generic[_T]):
|
| 136 |
+
def __init__(self, arg: MultiMapping[_T] | MutableMultiMapping[_T]) -> None: ...
|
| 137 |
+
def __getitem__(self, k: _S) -> _T: ...
|
| 138 |
+
def __iter__(self) -> Iterator[_S]: ...
|
| 139 |
+
def __len__(self) -> int: ...
|
| 140 |
+
@overload
|
| 141 |
+
def getall(self, key: _S) -> list[_T]: ...
|
| 142 |
+
@overload
|
| 143 |
+
def getall(self, key: _S, default: _D) -> list[_T] | _D: ...
|
| 144 |
+
@overload
|
| 145 |
+
def getone(self, key: _S) -> _T: ...
|
| 146 |
+
@overload
|
| 147 |
+
def getone(self, key: _S, default: _D) -> _T | _D: ...
|
| 148 |
+
def copy(self) -> CIMultiDict[_T]: ...
|
| 149 |
+
|
| 150 |
+
def getversion(
|
| 151 |
+
md: MultiDict[_T] | CIMultiDict[_T] | MultiDictProxy[_T] | CIMultiDictProxy[_T],
|
| 152 |
+
) -> int: ...
|
.venv/lib/python3.11/site-packages/multidict/__pycache__/_abc.cpython-311.pyc
ADDED
|
Binary file (2.75 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/multidict/__pycache__/_compat.cpython-311.pyc
ADDED
|
Binary file (711 Bytes). View file
|
|
|
.venv/lib/python3.11/site-packages/multidict/__pycache__/_multidict_py.cpython-311.pyc
ADDED
|
Binary file (29 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/multidict/_abc.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import abc
|
| 2 |
+
import sys
|
| 3 |
+
import types
|
| 4 |
+
from collections.abc import Mapping, MutableMapping
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
class _TypingMeta(abc.ABCMeta):
|
| 8 |
+
# A fake metaclass to satisfy typing deps in runtime
|
| 9 |
+
# basically MultiMapping[str] and other generic-like type instantiations
|
| 10 |
+
# are emulated.
|
| 11 |
+
# Note: real type hints are provided by __init__.pyi stub file
|
| 12 |
+
if sys.version_info >= (3, 9):
|
| 13 |
+
|
| 14 |
+
def __getitem__(self, key):
|
| 15 |
+
return types.GenericAlias(self, key)
|
| 16 |
+
|
| 17 |
+
else:
|
| 18 |
+
|
| 19 |
+
def __getitem__(self, key):
|
| 20 |
+
return self
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class MultiMapping(Mapping, metaclass=_TypingMeta):
|
| 24 |
+
@abc.abstractmethod
|
| 25 |
+
def getall(self, key, default=None):
|
| 26 |
+
raise KeyError
|
| 27 |
+
|
| 28 |
+
@abc.abstractmethod
|
| 29 |
+
def getone(self, key, default=None):
|
| 30 |
+
raise KeyError
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
class MutableMultiMapping(MultiMapping, MutableMapping):
|
| 34 |
+
@abc.abstractmethod
|
| 35 |
+
def add(self, key, value):
|
| 36 |
+
raise NotImplementedError
|
| 37 |
+
|
| 38 |
+
@abc.abstractmethod
|
| 39 |
+
def extend(self, *args, **kwargs):
|
| 40 |
+
raise NotImplementedError
|
| 41 |
+
|
| 42 |
+
@abc.abstractmethod
|
| 43 |
+
def popone(self, key, default=None):
|
| 44 |
+
raise KeyError
|
| 45 |
+
|
| 46 |
+
@abc.abstractmethod
|
| 47 |
+
def popall(self, key, default=None):
|
| 48 |
+
raise KeyError
|
.venv/lib/python3.11/site-packages/multidict/_compat.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import platform
|
| 3 |
+
|
| 4 |
+
NO_EXTENSIONS = bool(os.environ.get("MULTIDICT_NO_EXTENSIONS"))
|
| 5 |
+
|
| 6 |
+
PYPY = platform.python_implementation() == "PyPy"
|
| 7 |
+
|
| 8 |
+
USE_EXTENSIONS = not NO_EXTENSIONS and not PYPY
|
| 9 |
+
|
| 10 |
+
if USE_EXTENSIONS:
|
| 11 |
+
try:
|
| 12 |
+
from . import _multidict # type: ignore[attr-defined] # noqa: F401
|
| 13 |
+
except ImportError:
|
| 14 |
+
USE_EXTENSIONS = False
|
.venv/lib/python3.11/site-packages/multidict/_multidict_base.py
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
from collections.abc import ItemsView, Iterable, KeysView, Set, ValuesView
|
| 3 |
+
|
| 4 |
+
if sys.version_info >= (3, 11):
|
| 5 |
+
from typing import assert_never
|
| 6 |
+
else:
|
| 7 |
+
from typing_extensions import assert_never
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
def _abc_itemsview_register(view_cls):
|
| 11 |
+
ItemsView.register(view_cls)
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def _abc_keysview_register(view_cls):
|
| 15 |
+
KeysView.register(view_cls)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
def _abc_valuesview_register(view_cls):
|
| 19 |
+
ValuesView.register(view_cls)
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def _viewbaseset_richcmp(view, other, op):
|
| 23 |
+
if op == 0: # <
|
| 24 |
+
if not isinstance(other, Set):
|
| 25 |
+
return NotImplemented
|
| 26 |
+
return len(view) < len(other) and view <= other
|
| 27 |
+
elif op == 1: # <=
|
| 28 |
+
if not isinstance(other, Set):
|
| 29 |
+
return NotImplemented
|
| 30 |
+
if len(view) > len(other):
|
| 31 |
+
return False
|
| 32 |
+
for elem in view:
|
| 33 |
+
if elem not in other:
|
| 34 |
+
return False
|
| 35 |
+
return True
|
| 36 |
+
elif op == 2: # ==
|
| 37 |
+
if not isinstance(other, Set):
|
| 38 |
+
return NotImplemented
|
| 39 |
+
return len(view) == len(other) and view <= other
|
| 40 |
+
elif op == 3: # !=
|
| 41 |
+
return not view == other
|
| 42 |
+
elif op == 4: # >
|
| 43 |
+
if not isinstance(other, Set):
|
| 44 |
+
return NotImplemented
|
| 45 |
+
return len(view) > len(other) and view >= other
|
| 46 |
+
elif op == 5: # >=
|
| 47 |
+
if not isinstance(other, Set):
|
| 48 |
+
return NotImplemented
|
| 49 |
+
if len(view) < len(other):
|
| 50 |
+
return False
|
| 51 |
+
for elem in other:
|
| 52 |
+
if elem not in view:
|
| 53 |
+
return False
|
| 54 |
+
return True
|
| 55 |
+
else: # pragma: no cover
|
| 56 |
+
assert_never(op)
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def _viewbaseset_and(view, other):
|
| 60 |
+
if not isinstance(other, Iterable):
|
| 61 |
+
return NotImplemented
|
| 62 |
+
if isinstance(view, Set):
|
| 63 |
+
view = set(iter(view))
|
| 64 |
+
if isinstance(other, Set):
|
| 65 |
+
other = set(iter(other))
|
| 66 |
+
if not isinstance(other, Set):
|
| 67 |
+
other = set(iter(other))
|
| 68 |
+
return view & other
|
| 69 |
+
|
| 70 |
+
|
| 71 |
+
def _viewbaseset_or(view, other):
|
| 72 |
+
if not isinstance(other, Iterable):
|
| 73 |
+
return NotImplemented
|
| 74 |
+
if isinstance(view, Set):
|
| 75 |
+
view = set(iter(view))
|
| 76 |
+
if isinstance(other, Set):
|
| 77 |
+
other = set(iter(other))
|
| 78 |
+
if not isinstance(other, Set):
|
| 79 |
+
other = set(iter(other))
|
| 80 |
+
return view | other
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def _viewbaseset_sub(view, other):
|
| 84 |
+
if not isinstance(other, Iterable):
|
| 85 |
+
return NotImplemented
|
| 86 |
+
if isinstance(view, Set):
|
| 87 |
+
view = set(iter(view))
|
| 88 |
+
if isinstance(other, Set):
|
| 89 |
+
other = set(iter(other))
|
| 90 |
+
if not isinstance(other, Set):
|
| 91 |
+
other = set(iter(other))
|
| 92 |
+
return view - other
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
def _viewbaseset_xor(view, other):
|
| 96 |
+
if not isinstance(other, Iterable):
|
| 97 |
+
return NotImplemented
|
| 98 |
+
if isinstance(view, Set):
|
| 99 |
+
view = set(iter(view))
|
| 100 |
+
if isinstance(other, Set):
|
| 101 |
+
other = set(iter(other))
|
| 102 |
+
if not isinstance(other, Set):
|
| 103 |
+
other = set(iter(other))
|
| 104 |
+
return view ^ other
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def _itemsview_isdisjoint(view, other):
|
| 108 |
+
"Return True if two sets have a null intersection."
|
| 109 |
+
for v in other:
|
| 110 |
+
if v in view:
|
| 111 |
+
return False
|
| 112 |
+
return True
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
def _itemsview_repr(view):
|
| 116 |
+
lst = []
|
| 117 |
+
for k, v in view:
|
| 118 |
+
lst.append("{!r}: {!r}".format(k, v))
|
| 119 |
+
body = ", ".join(lst)
|
| 120 |
+
return "{}({})".format(view.__class__.__name__, body)
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
def _keysview_isdisjoint(view, other):
|
| 124 |
+
"Return True if two sets have a null intersection."
|
| 125 |
+
for k in other:
|
| 126 |
+
if k in view:
|
| 127 |
+
return False
|
| 128 |
+
return True
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
def _keysview_repr(view):
|
| 132 |
+
lst = []
|
| 133 |
+
for k in view:
|
| 134 |
+
lst.append("{!r}".format(k))
|
| 135 |
+
body = ", ".join(lst)
|
| 136 |
+
return "{}({})".format(view.__class__.__name__, body)
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
def _valuesview_repr(view):
|
| 140 |
+
lst = []
|
| 141 |
+
for v in view:
|
| 142 |
+
lst.append("{!r}".format(v))
|
| 143 |
+
body = ", ".join(lst)
|
| 144 |
+
return "{}({})".format(view.__class__.__name__, body)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
def _mdrepr(md):
|
| 148 |
+
lst = []
|
| 149 |
+
for k, v in md.items():
|
| 150 |
+
lst.append("'{}': {!r}".format(k, v))
|
| 151 |
+
body = ", ".join(lst)
|
| 152 |
+
return "<{}({})>".format(md.__class__.__name__, body)
|
.venv/lib/python3.11/site-packages/multidict/_multidict_py.py
ADDED
|
@@ -0,0 +1,527 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
import types
|
| 3 |
+
from array import array
|
| 4 |
+
from collections import abc
|
| 5 |
+
|
| 6 |
+
from ._abc import MultiMapping, MutableMultiMapping
|
| 7 |
+
|
| 8 |
+
_marker = object()
|
| 9 |
+
|
| 10 |
+
if sys.version_info >= (3, 9):
|
| 11 |
+
GenericAlias = types.GenericAlias
|
| 12 |
+
else:
|
| 13 |
+
|
| 14 |
+
def GenericAlias(cls):
|
| 15 |
+
return cls
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class istr(str):
|
| 19 |
+
|
| 20 |
+
"""Case insensitive str."""
|
| 21 |
+
|
| 22 |
+
__is_istr__ = True
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
upstr = istr # for relaxing backward compatibility problems
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def getversion(md):
|
| 29 |
+
if not isinstance(md, _Base):
|
| 30 |
+
raise TypeError("Parameter should be multidict or proxy")
|
| 31 |
+
return md._impl._version
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
_version = array("Q", [0])
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
class _Impl:
|
| 38 |
+
__slots__ = ("_items", "_version")
|
| 39 |
+
|
| 40 |
+
def __init__(self):
|
| 41 |
+
self._items = []
|
| 42 |
+
self.incr_version()
|
| 43 |
+
|
| 44 |
+
def incr_version(self):
|
| 45 |
+
global _version
|
| 46 |
+
v = _version
|
| 47 |
+
v[0] += 1
|
| 48 |
+
self._version = v[0]
|
| 49 |
+
|
| 50 |
+
if sys.implementation.name != "pypy":
|
| 51 |
+
|
| 52 |
+
def __sizeof__(self):
|
| 53 |
+
return object.__sizeof__(self) + sys.getsizeof(self._items)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
class _Base:
|
| 57 |
+
def _title(self, key):
|
| 58 |
+
return key
|
| 59 |
+
|
| 60 |
+
def getall(self, key, default=_marker):
|
| 61 |
+
"""Return a list of all values matching the key."""
|
| 62 |
+
identity = self._title(key)
|
| 63 |
+
res = [v for i, k, v in self._impl._items if i == identity]
|
| 64 |
+
if res:
|
| 65 |
+
return res
|
| 66 |
+
if not res and default is not _marker:
|
| 67 |
+
return default
|
| 68 |
+
raise KeyError("Key not found: %r" % key)
|
| 69 |
+
|
| 70 |
+
def getone(self, key, default=_marker):
|
| 71 |
+
"""Get first value matching the key.
|
| 72 |
+
|
| 73 |
+
Raises KeyError if the key is not found and no default is provided.
|
| 74 |
+
"""
|
| 75 |
+
identity = self._title(key)
|
| 76 |
+
for i, k, v in self._impl._items:
|
| 77 |
+
if i == identity:
|
| 78 |
+
return v
|
| 79 |
+
if default is not _marker:
|
| 80 |
+
return default
|
| 81 |
+
raise KeyError("Key not found: %r" % key)
|
| 82 |
+
|
| 83 |
+
# Mapping interface #
|
| 84 |
+
|
| 85 |
+
def __getitem__(self, key):
|
| 86 |
+
return self.getone(key)
|
| 87 |
+
|
| 88 |
+
def get(self, key, default=None):
|
| 89 |
+
"""Get first value matching the key.
|
| 90 |
+
|
| 91 |
+
If the key is not found, returns the default (or None if no default is provided)
|
| 92 |
+
"""
|
| 93 |
+
return self.getone(key, default)
|
| 94 |
+
|
| 95 |
+
def __iter__(self):
|
| 96 |
+
return iter(self.keys())
|
| 97 |
+
|
| 98 |
+
def __len__(self):
|
| 99 |
+
return len(self._impl._items)
|
| 100 |
+
|
| 101 |
+
def keys(self):
|
| 102 |
+
"""Return a new view of the dictionary's keys."""
|
| 103 |
+
return _KeysView(self._impl)
|
| 104 |
+
|
| 105 |
+
def items(self):
|
| 106 |
+
"""Return a new view of the dictionary's items *(key, value) pairs)."""
|
| 107 |
+
return _ItemsView(self._impl)
|
| 108 |
+
|
| 109 |
+
def values(self):
|
| 110 |
+
"""Return a new view of the dictionary's values."""
|
| 111 |
+
return _ValuesView(self._impl)
|
| 112 |
+
|
| 113 |
+
def __eq__(self, other):
|
| 114 |
+
if not isinstance(other, abc.Mapping):
|
| 115 |
+
return NotImplemented
|
| 116 |
+
if isinstance(other, _Base):
|
| 117 |
+
lft = self._impl._items
|
| 118 |
+
rht = other._impl._items
|
| 119 |
+
if len(lft) != len(rht):
|
| 120 |
+
return False
|
| 121 |
+
for (i1, k2, v1), (i2, k2, v2) in zip(lft, rht):
|
| 122 |
+
if i1 != i2 or v1 != v2:
|
| 123 |
+
return False
|
| 124 |
+
return True
|
| 125 |
+
if len(self._impl._items) != len(other):
|
| 126 |
+
return False
|
| 127 |
+
for k, v in self.items():
|
| 128 |
+
nv = other.get(k, _marker)
|
| 129 |
+
if v != nv:
|
| 130 |
+
return False
|
| 131 |
+
return True
|
| 132 |
+
|
| 133 |
+
def __contains__(self, key):
|
| 134 |
+
identity = self._title(key)
|
| 135 |
+
for i, k, v in self._impl._items:
|
| 136 |
+
if i == identity:
|
| 137 |
+
return True
|
| 138 |
+
return False
|
| 139 |
+
|
| 140 |
+
def __repr__(self):
|
| 141 |
+
body = ", ".join("'{}': {!r}".format(k, v) for k, v in self.items())
|
| 142 |
+
return "<{}({})>".format(self.__class__.__name__, body)
|
| 143 |
+
|
| 144 |
+
__class_getitem__ = classmethod(GenericAlias)
|
| 145 |
+
|
| 146 |
+
|
| 147 |
+
class MultiDictProxy(_Base, MultiMapping):
|
| 148 |
+
"""Read-only proxy for MultiDict instance."""
|
| 149 |
+
|
| 150 |
+
def __init__(self, arg):
|
| 151 |
+
if not isinstance(arg, (MultiDict, MultiDictProxy)):
|
| 152 |
+
raise TypeError(
|
| 153 |
+
"ctor requires MultiDict or MultiDictProxy instance"
|
| 154 |
+
", not {}".format(type(arg))
|
| 155 |
+
)
|
| 156 |
+
|
| 157 |
+
self._impl = arg._impl
|
| 158 |
+
|
| 159 |
+
def __reduce__(self):
|
| 160 |
+
raise TypeError("can't pickle {} objects".format(self.__class__.__name__))
|
| 161 |
+
|
| 162 |
+
def copy(self):
|
| 163 |
+
"""Return a copy of itself."""
|
| 164 |
+
return MultiDict(self.items())
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
class CIMultiDictProxy(MultiDictProxy):
|
| 168 |
+
"""Read-only proxy for CIMultiDict instance."""
|
| 169 |
+
|
| 170 |
+
def __init__(self, arg):
|
| 171 |
+
if not isinstance(arg, (CIMultiDict, CIMultiDictProxy)):
|
| 172 |
+
raise TypeError(
|
| 173 |
+
"ctor requires CIMultiDict or CIMultiDictProxy instance"
|
| 174 |
+
", not {}".format(type(arg))
|
| 175 |
+
)
|
| 176 |
+
|
| 177 |
+
self._impl = arg._impl
|
| 178 |
+
|
| 179 |
+
def _title(self, key):
|
| 180 |
+
return key.title()
|
| 181 |
+
|
| 182 |
+
def copy(self):
|
| 183 |
+
"""Return a copy of itself."""
|
| 184 |
+
return CIMultiDict(self.items())
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
class MultiDict(_Base, MutableMultiMapping):
|
| 188 |
+
"""Dictionary with the support for duplicate keys."""
|
| 189 |
+
|
| 190 |
+
def __init__(self, *args, **kwargs):
|
| 191 |
+
self._impl = _Impl()
|
| 192 |
+
|
| 193 |
+
self._extend(args, kwargs, self.__class__.__name__, self._extend_items)
|
| 194 |
+
|
| 195 |
+
if sys.implementation.name != "pypy":
|
| 196 |
+
|
| 197 |
+
def __sizeof__(self):
|
| 198 |
+
return object.__sizeof__(self) + sys.getsizeof(self._impl)
|
| 199 |
+
|
| 200 |
+
def __reduce__(self):
|
| 201 |
+
return (self.__class__, (list(self.items()),))
|
| 202 |
+
|
| 203 |
+
def _title(self, key):
|
| 204 |
+
return key
|
| 205 |
+
|
| 206 |
+
def _key(self, key):
|
| 207 |
+
if isinstance(key, str):
|
| 208 |
+
return key
|
| 209 |
+
else:
|
| 210 |
+
raise TypeError(
|
| 211 |
+
"MultiDict keys should be either str " "or subclasses of str"
|
| 212 |
+
)
|
| 213 |
+
|
| 214 |
+
def add(self, key, value):
|
| 215 |
+
identity = self._title(key)
|
| 216 |
+
self._impl._items.append((identity, self._key(key), value))
|
| 217 |
+
self._impl.incr_version()
|
| 218 |
+
|
| 219 |
+
def copy(self):
|
| 220 |
+
"""Return a copy of itself."""
|
| 221 |
+
cls = self.__class__
|
| 222 |
+
return cls(self.items())
|
| 223 |
+
|
| 224 |
+
__copy__ = copy
|
| 225 |
+
|
| 226 |
+
def extend(self, *args, **kwargs):
|
| 227 |
+
"""Extend current MultiDict with more values.
|
| 228 |
+
|
| 229 |
+
This method must be used instead of update.
|
| 230 |
+
"""
|
| 231 |
+
self._extend(args, kwargs, "extend", self._extend_items)
|
| 232 |
+
|
| 233 |
+
def _extend(self, args, kwargs, name, method):
|
| 234 |
+
if len(args) > 1:
|
| 235 |
+
raise TypeError(
|
| 236 |
+
"{} takes at most 1 positional argument"
|
| 237 |
+
" ({} given)".format(name, len(args))
|
| 238 |
+
)
|
| 239 |
+
if args:
|
| 240 |
+
arg = args[0]
|
| 241 |
+
if isinstance(args[0], (MultiDict, MultiDictProxy)) and not kwargs:
|
| 242 |
+
items = arg._impl._items
|
| 243 |
+
else:
|
| 244 |
+
if hasattr(arg, "items"):
|
| 245 |
+
arg = arg.items()
|
| 246 |
+
if kwargs:
|
| 247 |
+
arg = list(arg)
|
| 248 |
+
arg.extend(list(kwargs.items()))
|
| 249 |
+
items = []
|
| 250 |
+
for item in arg:
|
| 251 |
+
if not len(item) == 2:
|
| 252 |
+
raise TypeError(
|
| 253 |
+
"{} takes either dict or list of (key, value) "
|
| 254 |
+
"tuples".format(name)
|
| 255 |
+
)
|
| 256 |
+
items.append((self._title(item[0]), self._key(item[0]), item[1]))
|
| 257 |
+
|
| 258 |
+
method(items)
|
| 259 |
+
else:
|
| 260 |
+
method(
|
| 261 |
+
[
|
| 262 |
+
(self._title(key), self._key(key), value)
|
| 263 |
+
for key, value in kwargs.items()
|
| 264 |
+
]
|
| 265 |
+
)
|
| 266 |
+
|
| 267 |
+
def _extend_items(self, items):
|
| 268 |
+
for identity, key, value in items:
|
| 269 |
+
self.add(key, value)
|
| 270 |
+
|
| 271 |
+
def clear(self):
|
| 272 |
+
"""Remove all items from MultiDict."""
|
| 273 |
+
self._impl._items.clear()
|
| 274 |
+
self._impl.incr_version()
|
| 275 |
+
|
| 276 |
+
# Mapping interface #
|
| 277 |
+
|
| 278 |
+
def __setitem__(self, key, value):
|
| 279 |
+
self._replace(key, value)
|
| 280 |
+
|
| 281 |
+
def __delitem__(self, key):
|
| 282 |
+
identity = self._title(key)
|
| 283 |
+
items = self._impl._items
|
| 284 |
+
found = False
|
| 285 |
+
for i in range(len(items) - 1, -1, -1):
|
| 286 |
+
if items[i][0] == identity:
|
| 287 |
+
del items[i]
|
| 288 |
+
found = True
|
| 289 |
+
if not found:
|
| 290 |
+
raise KeyError(key)
|
| 291 |
+
else:
|
| 292 |
+
self._impl.incr_version()
|
| 293 |
+
|
| 294 |
+
def setdefault(self, key, default=None):
|
| 295 |
+
"""Return value for key, set value to default if key is not present."""
|
| 296 |
+
identity = self._title(key)
|
| 297 |
+
for i, k, v in self._impl._items:
|
| 298 |
+
if i == identity:
|
| 299 |
+
return v
|
| 300 |
+
self.add(key, default)
|
| 301 |
+
return default
|
| 302 |
+
|
| 303 |
+
def popone(self, key, default=_marker):
|
| 304 |
+
"""Remove specified key and return the corresponding value.
|
| 305 |
+
|
| 306 |
+
If key is not found, d is returned if given, otherwise
|
| 307 |
+
KeyError is raised.
|
| 308 |
+
|
| 309 |
+
"""
|
| 310 |
+
identity = self._title(key)
|
| 311 |
+
for i in range(len(self._impl._items)):
|
| 312 |
+
if self._impl._items[i][0] == identity:
|
| 313 |
+
value = self._impl._items[i][2]
|
| 314 |
+
del self._impl._items[i]
|
| 315 |
+
self._impl.incr_version()
|
| 316 |
+
return value
|
| 317 |
+
if default is _marker:
|
| 318 |
+
raise KeyError(key)
|
| 319 |
+
else:
|
| 320 |
+
return default
|
| 321 |
+
|
| 322 |
+
pop = popone # type: ignore
|
| 323 |
+
|
| 324 |
+
def popall(self, key, default=_marker):
|
| 325 |
+
"""Remove all occurrences of key and return the list of corresponding
|
| 326 |
+
values.
|
| 327 |
+
|
| 328 |
+
If key is not found, default is returned if given, otherwise
|
| 329 |
+
KeyError is raised.
|
| 330 |
+
|
| 331 |
+
"""
|
| 332 |
+
found = False
|
| 333 |
+
identity = self._title(key)
|
| 334 |
+
ret = []
|
| 335 |
+
for i in range(len(self._impl._items) - 1, -1, -1):
|
| 336 |
+
item = self._impl._items[i]
|
| 337 |
+
if item[0] == identity:
|
| 338 |
+
ret.append(item[2])
|
| 339 |
+
del self._impl._items[i]
|
| 340 |
+
self._impl.incr_version()
|
| 341 |
+
found = True
|
| 342 |
+
if not found:
|
| 343 |
+
if default is _marker:
|
| 344 |
+
raise KeyError(key)
|
| 345 |
+
else:
|
| 346 |
+
return default
|
| 347 |
+
else:
|
| 348 |
+
ret.reverse()
|
| 349 |
+
return ret
|
| 350 |
+
|
| 351 |
+
def popitem(self):
|
| 352 |
+
"""Remove and return an arbitrary (key, value) pair."""
|
| 353 |
+
if self._impl._items:
|
| 354 |
+
i = self._impl._items.pop(0)
|
| 355 |
+
self._impl.incr_version()
|
| 356 |
+
return i[1], i[2]
|
| 357 |
+
else:
|
| 358 |
+
raise KeyError("empty multidict")
|
| 359 |
+
|
| 360 |
+
def update(self, *args, **kwargs):
|
| 361 |
+
"""Update the dictionary from *other*, overwriting existing keys."""
|
| 362 |
+
self._extend(args, kwargs, "update", self._update_items)
|
| 363 |
+
|
| 364 |
+
def _update_items(self, items):
|
| 365 |
+
if not items:
|
| 366 |
+
return
|
| 367 |
+
used_keys = {}
|
| 368 |
+
for identity, key, value in items:
|
| 369 |
+
start = used_keys.get(identity, 0)
|
| 370 |
+
for i in range(start, len(self._impl._items)):
|
| 371 |
+
item = self._impl._items[i]
|
| 372 |
+
if item[0] == identity:
|
| 373 |
+
used_keys[identity] = i + 1
|
| 374 |
+
self._impl._items[i] = (identity, key, value)
|
| 375 |
+
break
|
| 376 |
+
else:
|
| 377 |
+
self._impl._items.append((identity, key, value))
|
| 378 |
+
used_keys[identity] = len(self._impl._items)
|
| 379 |
+
|
| 380 |
+
# drop tails
|
| 381 |
+
i = 0
|
| 382 |
+
while i < len(self._impl._items):
|
| 383 |
+
item = self._impl._items[i]
|
| 384 |
+
identity = item[0]
|
| 385 |
+
pos = used_keys.get(identity)
|
| 386 |
+
if pos is None:
|
| 387 |
+
i += 1
|
| 388 |
+
continue
|
| 389 |
+
if i >= pos:
|
| 390 |
+
del self._impl._items[i]
|
| 391 |
+
else:
|
| 392 |
+
i += 1
|
| 393 |
+
|
| 394 |
+
self._impl.incr_version()
|
| 395 |
+
|
| 396 |
+
def _replace(self, key, value):
|
| 397 |
+
key = self._key(key)
|
| 398 |
+
identity = self._title(key)
|
| 399 |
+
items = self._impl._items
|
| 400 |
+
|
| 401 |
+
for i in range(len(items)):
|
| 402 |
+
item = items[i]
|
| 403 |
+
if item[0] == identity:
|
| 404 |
+
items[i] = (identity, key, value)
|
| 405 |
+
# i points to last found item
|
| 406 |
+
rgt = i
|
| 407 |
+
self._impl.incr_version()
|
| 408 |
+
break
|
| 409 |
+
else:
|
| 410 |
+
self._impl._items.append((identity, key, value))
|
| 411 |
+
self._impl.incr_version()
|
| 412 |
+
return
|
| 413 |
+
|
| 414 |
+
# remove all tail items
|
| 415 |
+
i = rgt + 1
|
| 416 |
+
while i < len(items):
|
| 417 |
+
item = items[i]
|
| 418 |
+
if item[0] == identity:
|
| 419 |
+
del items[i]
|
| 420 |
+
else:
|
| 421 |
+
i += 1
|
| 422 |
+
|
| 423 |
+
|
| 424 |
+
class CIMultiDict(MultiDict):
|
| 425 |
+
"""Dictionary with the support for duplicate case-insensitive keys."""
|
| 426 |
+
|
| 427 |
+
def _title(self, key):
|
| 428 |
+
return key.title()
|
| 429 |
+
|
| 430 |
+
|
| 431 |
+
class _Iter:
|
| 432 |
+
__slots__ = ("_size", "_iter")
|
| 433 |
+
|
| 434 |
+
def __init__(self, size, iterator):
|
| 435 |
+
self._size = size
|
| 436 |
+
self._iter = iterator
|
| 437 |
+
|
| 438 |
+
def __iter__(self):
|
| 439 |
+
return self
|
| 440 |
+
|
| 441 |
+
def __next__(self):
|
| 442 |
+
return next(self._iter)
|
| 443 |
+
|
| 444 |
+
def __length_hint__(self):
|
| 445 |
+
return self._size
|
| 446 |
+
|
| 447 |
+
|
| 448 |
+
class _ViewBase:
|
| 449 |
+
def __init__(self, impl):
|
| 450 |
+
self._impl = impl
|
| 451 |
+
|
| 452 |
+
def __len__(self):
|
| 453 |
+
return len(self._impl._items)
|
| 454 |
+
|
| 455 |
+
|
| 456 |
+
class _ItemsView(_ViewBase, abc.ItemsView):
|
| 457 |
+
def __contains__(self, item):
|
| 458 |
+
assert isinstance(item, tuple) or isinstance(item, list)
|
| 459 |
+
assert len(item) == 2
|
| 460 |
+
for i, k, v in self._impl._items:
|
| 461 |
+
if item[0] == k and item[1] == v:
|
| 462 |
+
return True
|
| 463 |
+
return False
|
| 464 |
+
|
| 465 |
+
def __iter__(self):
|
| 466 |
+
return _Iter(len(self), self._iter(self._impl._version))
|
| 467 |
+
|
| 468 |
+
def _iter(self, version):
|
| 469 |
+
for i, k, v in self._impl._items:
|
| 470 |
+
if version != self._impl._version:
|
| 471 |
+
raise RuntimeError("Dictionary changed during iteration")
|
| 472 |
+
yield k, v
|
| 473 |
+
|
| 474 |
+
def __repr__(self):
|
| 475 |
+
lst = []
|
| 476 |
+
for item in self._impl._items:
|
| 477 |
+
lst.append("{!r}: {!r}".format(item[1], item[2]))
|
| 478 |
+
body = ", ".join(lst)
|
| 479 |
+
return "{}({})".format(self.__class__.__name__, body)
|
| 480 |
+
|
| 481 |
+
|
| 482 |
+
class _ValuesView(_ViewBase, abc.ValuesView):
|
| 483 |
+
def __contains__(self, value):
|
| 484 |
+
for item in self._impl._items:
|
| 485 |
+
if item[2] == value:
|
| 486 |
+
return True
|
| 487 |
+
return False
|
| 488 |
+
|
| 489 |
+
def __iter__(self):
|
| 490 |
+
return _Iter(len(self), self._iter(self._impl._version))
|
| 491 |
+
|
| 492 |
+
def _iter(self, version):
|
| 493 |
+
for item in self._impl._items:
|
| 494 |
+
if version != self._impl._version:
|
| 495 |
+
raise RuntimeError("Dictionary changed during iteration")
|
| 496 |
+
yield item[2]
|
| 497 |
+
|
| 498 |
+
def __repr__(self):
|
| 499 |
+
lst = []
|
| 500 |
+
for item in self._impl._items:
|
| 501 |
+
lst.append("{!r}".format(item[2]))
|
| 502 |
+
body = ", ".join(lst)
|
| 503 |
+
return "{}({})".format(self.__class__.__name__, body)
|
| 504 |
+
|
| 505 |
+
|
| 506 |
+
class _KeysView(_ViewBase, abc.KeysView):
|
| 507 |
+
def __contains__(self, key):
|
| 508 |
+
for item in self._impl._items:
|
| 509 |
+
if item[1] == key:
|
| 510 |
+
return True
|
| 511 |
+
return False
|
| 512 |
+
|
| 513 |
+
def __iter__(self):
|
| 514 |
+
return _Iter(len(self), self._iter(self._impl._version))
|
| 515 |
+
|
| 516 |
+
def _iter(self, version):
|
| 517 |
+
for item in self._impl._items:
|
| 518 |
+
if version != self._impl._version:
|
| 519 |
+
raise RuntimeError("Dictionary changed during iteration")
|
| 520 |
+
yield item[1]
|
| 521 |
+
|
| 522 |
+
def __repr__(self):
|
| 523 |
+
lst = []
|
| 524 |
+
for item in self._impl._items:
|
| 525 |
+
lst.append("{!r}".format(item[1]))
|
| 526 |
+
body = ", ".join(lst)
|
| 527 |
+
return "{}({})".format(self.__class__.__name__, body)
|
.venv/lib/python3.11/site-packages/multidict/py.typed
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
PEP-561 marker.
|
.venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/INSTALLER
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
pip
|
.venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
BSD 2-Clause License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2018-2020, Ewald de Wit
|
| 4 |
+
All rights reserved.
|
| 5 |
+
|
| 6 |
+
Redistribution and use in source and binary forms, with or without
|
| 7 |
+
modification, are permitted provided that the following conditions are met:
|
| 8 |
+
|
| 9 |
+
* Redistributions of source code must retain the above copyright notice, this
|
| 10 |
+
list of conditions and the following disclaimer.
|
| 11 |
+
|
| 12 |
+
* Redistributions in binary form must reproduce the above copyright notice,
|
| 13 |
+
this list of conditions and the following disclaimer in the documentation
|
| 14 |
+
and/or other materials provided with the distribution.
|
| 15 |
+
|
| 16 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
| 17 |
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
| 18 |
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
| 19 |
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
| 20 |
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
| 21 |
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
| 22 |
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
| 23 |
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
| 24 |
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| 25 |
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
.venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/METADATA
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Metadata-Version: 2.1
|
| 2 |
+
Name: nest-asyncio
|
| 3 |
+
Version: 1.6.0
|
| 4 |
+
Summary: Patch asyncio to allow nested event loops
|
| 5 |
+
Home-page: https://github.com/erdewit/nest_asyncio
|
| 6 |
+
Author: Ewald R. de Wit
|
| 7 |
+
Author-email: ewald.de.wit@gmail.com
|
| 8 |
+
License: BSD
|
| 9 |
+
Keywords: asyncio,nested,eventloop
|
| 10 |
+
Classifier: Development Status :: 5 - Production/Stable
|
| 11 |
+
Classifier: Intended Audience :: Developers
|
| 12 |
+
Classifier: License :: OSI Approved :: BSD License
|
| 13 |
+
Classifier: Programming Language :: Python :: 3.5
|
| 14 |
+
Classifier: Programming Language :: Python :: 3.6
|
| 15 |
+
Classifier: Programming Language :: Python :: 3.7
|
| 16 |
+
Classifier: Programming Language :: Python :: 3.8
|
| 17 |
+
Classifier: Programming Language :: Python :: 3.9
|
| 18 |
+
Classifier: Programming Language :: Python :: 3.10
|
| 19 |
+
Classifier: Programming Language :: Python :: 3.11
|
| 20 |
+
Classifier: Programming Language :: Python :: 3.12
|
| 21 |
+
Classifier: Programming Language :: Python :: 3 :: Only
|
| 22 |
+
Classifier: Framework :: AsyncIO
|
| 23 |
+
Requires-Python: >=3.5
|
| 24 |
+
Description-Content-Type: text/x-rst
|
| 25 |
+
License-File: LICENSE
|
| 26 |
+
|
| 27 |
+
|Build| |Status| |PyPiVersion| |License| |Downloads|
|
| 28 |
+
|
| 29 |
+
Introduction
|
| 30 |
+
------------
|
| 31 |
+
|
| 32 |
+
By design asyncio `does not allow <https://github.com/python/cpython/issues/66435>`_
|
| 33 |
+
its event loop to be nested. This presents a practical problem:
|
| 34 |
+
When in an environment where the event loop is
|
| 35 |
+
already running it's impossible to run tasks and wait
|
| 36 |
+
for the result. Trying to do so will give the error
|
| 37 |
+
"``RuntimeError: This event loop is already running``".
|
| 38 |
+
|
| 39 |
+
The issue pops up in various environments, such as web servers,
|
| 40 |
+
GUI applications and in Jupyter notebooks.
|
| 41 |
+
|
| 42 |
+
This module patches asyncio to allow nested use of ``asyncio.run`` and
|
| 43 |
+
``loop.run_until_complete``.
|
| 44 |
+
|
| 45 |
+
Installation
|
| 46 |
+
------------
|
| 47 |
+
|
| 48 |
+
.. code-block::
|
| 49 |
+
|
| 50 |
+
pip3 install nest_asyncio
|
| 51 |
+
|
| 52 |
+
Python 3.5 or higher is required.
|
| 53 |
+
|
| 54 |
+
Usage
|
| 55 |
+
-----
|
| 56 |
+
|
| 57 |
+
.. code-block:: python
|
| 58 |
+
|
| 59 |
+
import nest_asyncio
|
| 60 |
+
nest_asyncio.apply()
|
| 61 |
+
|
| 62 |
+
Optionally the specific loop that needs patching can be given
|
| 63 |
+
as argument to ``apply``, otherwise the current event loop is used.
|
| 64 |
+
An event loop can be patched whether it is already running
|
| 65 |
+
or not. Only event loops from asyncio can be patched;
|
| 66 |
+
Loops from other projects, such as uvloop or quamash,
|
| 67 |
+
generally can't be patched.
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
.. |Build| image:: https://github.com/erdewit/nest_asyncio/actions/workflows/test.yml/badge.svg?branche=master
|
| 71 |
+
:alt: Build
|
| 72 |
+
:target: https://github.com/erdewit/nest_asyncio/actions
|
| 73 |
+
|
| 74 |
+
.. |PyPiVersion| image:: https://img.shields.io/pypi/v/nest_asyncio.svg
|
| 75 |
+
:alt: PyPi
|
| 76 |
+
:target: https://pypi.python.org/pypi/nest_asyncio
|
| 77 |
+
|
| 78 |
+
.. |Status| image:: https://img.shields.io/badge/status-stable-green.svg
|
| 79 |
+
:alt:
|
| 80 |
+
|
| 81 |
+
.. |License| image:: https://img.shields.io/badge/license-BSD-blue.svg
|
| 82 |
+
:alt:
|
| 83 |
+
|
| 84 |
+
.. |Downloads| image:: https://static.pepy.tech/badge/nest-asyncio/month
|
| 85 |
+
:alt: Number of downloads
|
| 86 |
+
:target: https://pepy.tech/project/nest-asyncio
|
| 87 |
+
|
.venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/RECORD
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__/nest_asyncio.cpython-311.pyc,,
|
| 2 |
+
nest_asyncio-1.6.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
| 3 |
+
nest_asyncio-1.6.0.dist-info/LICENSE,sha256=vs6faGVf8jt3QTJGwGUDhrh9p8NoIwPdDujj6nYw6Fs,1322
|
| 4 |
+
nest_asyncio-1.6.0.dist-info/METADATA,sha256=f3uY-eGiipWX1w35FYF1oi0FRGzksyiQjZIOcpPTW9I,2812
|
| 5 |
+
nest_asyncio-1.6.0.dist-info/RECORD,,
|
| 6 |
+
nest_asyncio-1.6.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
| 7 |
+
nest_asyncio-1.6.0.dist-info/top_level.txt,sha256=cQFBM_fPbDdhVVihWwS-29WiW17LZ3r4lSXyvwFzNzs,13
|
| 8 |
+
nest_asyncio.py,sha256=KkW14bq07D5BoOTpkjlwv8dFX5uRw9Z84TR_u5wR7_o,7490
|
.venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/WHEEL
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Wheel-Version: 1.0
|
| 2 |
+
Generator: bdist_wheel (0.40.0)
|
| 3 |
+
Root-Is-Purelib: true
|
| 4 |
+
Tag: py3-none-any
|
| 5 |
+
|
.venv/lib/python3.11/site-packages/nest_asyncio-1.6.0.dist-info/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
nest_asyncio
|
.venv/lib/python3.11/site-packages/packaging/__init__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file is dual licensed under the terms of the Apache License, Version
|
| 2 |
+
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
| 3 |
+
# for complete details.
|
| 4 |
+
|
| 5 |
+
__title__ = "packaging"
|
| 6 |
+
__summary__ = "Core utilities for Python packages"
|
| 7 |
+
__uri__ = "https://github.com/pypa/packaging"
|
| 8 |
+
|
| 9 |
+
__version__ = "24.2"
|
| 10 |
+
|
| 11 |
+
__author__ = "Donald Stufft and individual contributors"
|
| 12 |
+
__email__ = "donald@stufft.io"
|
| 13 |
+
|
| 14 |
+
__license__ = "BSD-2-Clause or Apache-2.0"
|
| 15 |
+
__copyright__ = f"2014 {__author__}"
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (542 Bytes). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/_elffile.cpython-311.pyc
ADDED
|
Binary file (5.5 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/_manylinux.cpython-311.pyc
ADDED
|
Binary file (10.9 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/_musllinux.cpython-311.pyc
ADDED
|
Binary file (5.29 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/_parser.cpython-311.pyc
ADDED
|
Binary file (16.3 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/_structures.cpython-311.pyc
ADDED
|
Binary file (3.67 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/_tokenizer.cpython-311.pyc
ADDED
|
Binary file (8.53 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/markers.cpython-311.pyc
ADDED
|
Binary file (13.1 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/metadata.cpython-311.pyc
ADDED
|
Binary file (31.1 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/requirements.cpython-311.pyc
ADDED
|
Binary file (4.71 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/specifiers.cpython-311.pyc
ADDED
|
Binary file (41.5 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/tags.cpython-311.pyc
ADDED
|
Binary file (25.9 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/utils.cpython-311.pyc
ADDED
|
Binary file (7.57 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/__pycache__/version.cpython-311.pyc
ADDED
|
Binary file (22 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/_elffile.py
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
ELF file parser.
|
| 3 |
+
|
| 4 |
+
This provides a class ``ELFFile`` that parses an ELF executable in a similar
|
| 5 |
+
interface to ``ZipFile``. Only the read interface is implemented.
|
| 6 |
+
|
| 7 |
+
Based on: https://gist.github.com/lyssdod/f51579ae8d93c8657a5564aefc2ffbca
|
| 8 |
+
ELF header: https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
from __future__ import annotations
|
| 12 |
+
|
| 13 |
+
import enum
|
| 14 |
+
import os
|
| 15 |
+
import struct
|
| 16 |
+
from typing import IO
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
class ELFInvalid(ValueError):
|
| 20 |
+
pass
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class EIClass(enum.IntEnum):
|
| 24 |
+
C32 = 1
|
| 25 |
+
C64 = 2
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
class EIData(enum.IntEnum):
|
| 29 |
+
Lsb = 1
|
| 30 |
+
Msb = 2
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
class EMachine(enum.IntEnum):
|
| 34 |
+
I386 = 3
|
| 35 |
+
S390 = 22
|
| 36 |
+
Arm = 40
|
| 37 |
+
X8664 = 62
|
| 38 |
+
AArc64 = 183
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class ELFFile:
|
| 42 |
+
"""
|
| 43 |
+
Representation of an ELF executable.
|
| 44 |
+
"""
|
| 45 |
+
|
| 46 |
+
def __init__(self, f: IO[bytes]) -> None:
|
| 47 |
+
self._f = f
|
| 48 |
+
|
| 49 |
+
try:
|
| 50 |
+
ident = self._read("16B")
|
| 51 |
+
except struct.error as e:
|
| 52 |
+
raise ELFInvalid("unable to parse identification") from e
|
| 53 |
+
magic = bytes(ident[:4])
|
| 54 |
+
if magic != b"\x7fELF":
|
| 55 |
+
raise ELFInvalid(f"invalid magic: {magic!r}")
|
| 56 |
+
|
| 57 |
+
self.capacity = ident[4] # Format for program header (bitness).
|
| 58 |
+
self.encoding = ident[5] # Data structure encoding (endianness).
|
| 59 |
+
|
| 60 |
+
try:
|
| 61 |
+
# e_fmt: Format for program header.
|
| 62 |
+
# p_fmt: Format for section header.
|
| 63 |
+
# p_idx: Indexes to find p_type, p_offset, and p_filesz.
|
| 64 |
+
e_fmt, self._p_fmt, self._p_idx = {
|
| 65 |
+
(1, 1): ("<HHIIIIIHHH", "<IIIIIIII", (0, 1, 4)), # 32-bit LSB.
|
| 66 |
+
(1, 2): (">HHIIIIIHHH", ">IIIIIIII", (0, 1, 4)), # 32-bit MSB.
|
| 67 |
+
(2, 1): ("<HHIQQQIHHH", "<IIQQQQQQ", (0, 2, 5)), # 64-bit LSB.
|
| 68 |
+
(2, 2): (">HHIQQQIHHH", ">IIQQQQQQ", (0, 2, 5)), # 64-bit MSB.
|
| 69 |
+
}[(self.capacity, self.encoding)]
|
| 70 |
+
except KeyError as e:
|
| 71 |
+
raise ELFInvalid(
|
| 72 |
+
f"unrecognized capacity ({self.capacity}) or "
|
| 73 |
+
f"encoding ({self.encoding})"
|
| 74 |
+
) from e
|
| 75 |
+
|
| 76 |
+
try:
|
| 77 |
+
(
|
| 78 |
+
_,
|
| 79 |
+
self.machine, # Architecture type.
|
| 80 |
+
_,
|
| 81 |
+
_,
|
| 82 |
+
self._e_phoff, # Offset of program header.
|
| 83 |
+
_,
|
| 84 |
+
self.flags, # Processor-specific flags.
|
| 85 |
+
_,
|
| 86 |
+
self._e_phentsize, # Size of section.
|
| 87 |
+
self._e_phnum, # Number of sections.
|
| 88 |
+
) = self._read(e_fmt)
|
| 89 |
+
except struct.error as e:
|
| 90 |
+
raise ELFInvalid("unable to parse machine and section information") from e
|
| 91 |
+
|
| 92 |
+
def _read(self, fmt: str) -> tuple[int, ...]:
|
| 93 |
+
return struct.unpack(fmt, self._f.read(struct.calcsize(fmt)))
|
| 94 |
+
|
| 95 |
+
@property
|
| 96 |
+
def interpreter(self) -> str | None:
|
| 97 |
+
"""
|
| 98 |
+
The path recorded in the ``PT_INTERP`` section header.
|
| 99 |
+
"""
|
| 100 |
+
for index in range(self._e_phnum):
|
| 101 |
+
self._f.seek(self._e_phoff + self._e_phentsize * index)
|
| 102 |
+
try:
|
| 103 |
+
data = self._read(self._p_fmt)
|
| 104 |
+
except struct.error:
|
| 105 |
+
continue
|
| 106 |
+
if data[self._p_idx[0]] != 3: # Not PT_INTERP.
|
| 107 |
+
continue
|
| 108 |
+
self._f.seek(data[self._p_idx[1]])
|
| 109 |
+
return os.fsdecode(self._f.read(data[self._p_idx[2]])).strip("\0")
|
| 110 |
+
return None
|
.venv/lib/python3.11/site-packages/packaging/_manylinux.py
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import collections
|
| 4 |
+
import contextlib
|
| 5 |
+
import functools
|
| 6 |
+
import os
|
| 7 |
+
import re
|
| 8 |
+
import sys
|
| 9 |
+
import warnings
|
| 10 |
+
from typing import Generator, Iterator, NamedTuple, Sequence
|
| 11 |
+
|
| 12 |
+
from ._elffile import EIClass, EIData, ELFFile, EMachine
|
| 13 |
+
|
| 14 |
+
EF_ARM_ABIMASK = 0xFF000000
|
| 15 |
+
EF_ARM_ABI_VER5 = 0x05000000
|
| 16 |
+
EF_ARM_ABI_FLOAT_HARD = 0x00000400
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
# `os.PathLike` not a generic type until Python 3.9, so sticking with `str`
|
| 20 |
+
# as the type for `path` until then.
|
| 21 |
+
@contextlib.contextmanager
|
| 22 |
+
def _parse_elf(path: str) -> Generator[ELFFile | None, None, None]:
|
| 23 |
+
try:
|
| 24 |
+
with open(path, "rb") as f:
|
| 25 |
+
yield ELFFile(f)
|
| 26 |
+
except (OSError, TypeError, ValueError):
|
| 27 |
+
yield None
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def _is_linux_armhf(executable: str) -> bool:
|
| 31 |
+
# hard-float ABI can be detected from the ELF header of the running
|
| 32 |
+
# process
|
| 33 |
+
# https://static.docs.arm.com/ihi0044/g/aaelf32.pdf
|
| 34 |
+
with _parse_elf(executable) as f:
|
| 35 |
+
return (
|
| 36 |
+
f is not None
|
| 37 |
+
and f.capacity == EIClass.C32
|
| 38 |
+
and f.encoding == EIData.Lsb
|
| 39 |
+
and f.machine == EMachine.Arm
|
| 40 |
+
and f.flags & EF_ARM_ABIMASK == EF_ARM_ABI_VER5
|
| 41 |
+
and f.flags & EF_ARM_ABI_FLOAT_HARD == EF_ARM_ABI_FLOAT_HARD
|
| 42 |
+
)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def _is_linux_i686(executable: str) -> bool:
|
| 46 |
+
with _parse_elf(executable) as f:
|
| 47 |
+
return (
|
| 48 |
+
f is not None
|
| 49 |
+
and f.capacity == EIClass.C32
|
| 50 |
+
and f.encoding == EIData.Lsb
|
| 51 |
+
and f.machine == EMachine.I386
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
def _have_compatible_abi(executable: str, archs: Sequence[str]) -> bool:
|
| 56 |
+
if "armv7l" in archs:
|
| 57 |
+
return _is_linux_armhf(executable)
|
| 58 |
+
if "i686" in archs:
|
| 59 |
+
return _is_linux_i686(executable)
|
| 60 |
+
allowed_archs = {
|
| 61 |
+
"x86_64",
|
| 62 |
+
"aarch64",
|
| 63 |
+
"ppc64",
|
| 64 |
+
"ppc64le",
|
| 65 |
+
"s390x",
|
| 66 |
+
"loongarch64",
|
| 67 |
+
"riscv64",
|
| 68 |
+
}
|
| 69 |
+
return any(arch in allowed_archs for arch in archs)
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
# If glibc ever changes its major version, we need to know what the last
|
| 73 |
+
# minor version was, so we can build the complete list of all versions.
|
| 74 |
+
# For now, guess what the highest minor version might be, assume it will
|
| 75 |
+
# be 50 for testing. Once this actually happens, update the dictionary
|
| 76 |
+
# with the actual value.
|
| 77 |
+
_LAST_GLIBC_MINOR: dict[int, int] = collections.defaultdict(lambda: 50)
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
class _GLibCVersion(NamedTuple):
|
| 81 |
+
major: int
|
| 82 |
+
minor: int
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def _glibc_version_string_confstr() -> str | None:
|
| 86 |
+
"""
|
| 87 |
+
Primary implementation of glibc_version_string using os.confstr.
|
| 88 |
+
"""
|
| 89 |
+
# os.confstr is quite a bit faster than ctypes.DLL. It's also less likely
|
| 90 |
+
# to be broken or missing. This strategy is used in the standard library
|
| 91 |
+
# platform module.
|
| 92 |
+
# https://github.com/python/cpython/blob/fcf1d003bf4f0100c/Lib/platform.py#L175-L183
|
| 93 |
+
try:
|
| 94 |
+
# Should be a string like "glibc 2.17".
|
| 95 |
+
version_string: str | None = os.confstr("CS_GNU_LIBC_VERSION")
|
| 96 |
+
assert version_string is not None
|
| 97 |
+
_, version = version_string.rsplit()
|
| 98 |
+
except (AssertionError, AttributeError, OSError, ValueError):
|
| 99 |
+
# os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)...
|
| 100 |
+
return None
|
| 101 |
+
return version
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
def _glibc_version_string_ctypes() -> str | None:
|
| 105 |
+
"""
|
| 106 |
+
Fallback implementation of glibc_version_string using ctypes.
|
| 107 |
+
"""
|
| 108 |
+
try:
|
| 109 |
+
import ctypes
|
| 110 |
+
except ImportError:
|
| 111 |
+
return None
|
| 112 |
+
|
| 113 |
+
# ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
|
| 114 |
+
# manpage says, "If filename is NULL, then the returned handle is for the
|
| 115 |
+
# main program". This way we can let the linker do the work to figure out
|
| 116 |
+
# which libc our process is actually using.
|
| 117 |
+
#
|
| 118 |
+
# We must also handle the special case where the executable is not a
|
| 119 |
+
# dynamically linked executable. This can occur when using musl libc,
|
| 120 |
+
# for example. In this situation, dlopen() will error, leading to an
|
| 121 |
+
# OSError. Interestingly, at least in the case of musl, there is no
|
| 122 |
+
# errno set on the OSError. The single string argument used to construct
|
| 123 |
+
# OSError comes from libc itself and is therefore not portable to
|
| 124 |
+
# hard code here. In any case, failure to call dlopen() means we
|
| 125 |
+
# can proceed, so we bail on our attempt.
|
| 126 |
+
try:
|
| 127 |
+
process_namespace = ctypes.CDLL(None)
|
| 128 |
+
except OSError:
|
| 129 |
+
return None
|
| 130 |
+
|
| 131 |
+
try:
|
| 132 |
+
gnu_get_libc_version = process_namespace.gnu_get_libc_version
|
| 133 |
+
except AttributeError:
|
| 134 |
+
# Symbol doesn't exist -> therefore, we are not linked to
|
| 135 |
+
# glibc.
|
| 136 |
+
return None
|
| 137 |
+
|
| 138 |
+
# Call gnu_get_libc_version, which returns a string like "2.5"
|
| 139 |
+
gnu_get_libc_version.restype = ctypes.c_char_p
|
| 140 |
+
version_str: str = gnu_get_libc_version()
|
| 141 |
+
# py2 / py3 compatibility:
|
| 142 |
+
if not isinstance(version_str, str):
|
| 143 |
+
version_str = version_str.decode("ascii")
|
| 144 |
+
|
| 145 |
+
return version_str
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
def _glibc_version_string() -> str | None:
|
| 149 |
+
"""Returns glibc version string, or None if not using glibc."""
|
| 150 |
+
return _glibc_version_string_confstr() or _glibc_version_string_ctypes()
|
| 151 |
+
|
| 152 |
+
|
| 153 |
+
def _parse_glibc_version(version_str: str) -> tuple[int, int]:
|
| 154 |
+
"""Parse glibc version.
|
| 155 |
+
|
| 156 |
+
We use a regexp instead of str.split because we want to discard any
|
| 157 |
+
random junk that might come after the minor version -- this might happen
|
| 158 |
+
in patched/forked versions of glibc (e.g. Linaro's version of glibc
|
| 159 |
+
uses version strings like "2.20-2014.11"). See gh-3588.
|
| 160 |
+
"""
|
| 161 |
+
m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str)
|
| 162 |
+
if not m:
|
| 163 |
+
warnings.warn(
|
| 164 |
+
f"Expected glibc version with 2 components major.minor,"
|
| 165 |
+
f" got: {version_str}",
|
| 166 |
+
RuntimeWarning,
|
| 167 |
+
stacklevel=2,
|
| 168 |
+
)
|
| 169 |
+
return -1, -1
|
| 170 |
+
return int(m.group("major")), int(m.group("minor"))
|
| 171 |
+
|
| 172 |
+
|
| 173 |
+
@functools.lru_cache
|
| 174 |
+
def _get_glibc_version() -> tuple[int, int]:
|
| 175 |
+
version_str = _glibc_version_string()
|
| 176 |
+
if version_str is None:
|
| 177 |
+
return (-1, -1)
|
| 178 |
+
return _parse_glibc_version(version_str)
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
# From PEP 513, PEP 600
|
| 182 |
+
def _is_compatible(arch: str, version: _GLibCVersion) -> bool:
|
| 183 |
+
sys_glibc = _get_glibc_version()
|
| 184 |
+
if sys_glibc < version:
|
| 185 |
+
return False
|
| 186 |
+
# Check for presence of _manylinux module.
|
| 187 |
+
try:
|
| 188 |
+
import _manylinux
|
| 189 |
+
except ImportError:
|
| 190 |
+
return True
|
| 191 |
+
if hasattr(_manylinux, "manylinux_compatible"):
|
| 192 |
+
result = _manylinux.manylinux_compatible(version[0], version[1], arch)
|
| 193 |
+
if result is not None:
|
| 194 |
+
return bool(result)
|
| 195 |
+
return True
|
| 196 |
+
if version == _GLibCVersion(2, 5):
|
| 197 |
+
if hasattr(_manylinux, "manylinux1_compatible"):
|
| 198 |
+
return bool(_manylinux.manylinux1_compatible)
|
| 199 |
+
if version == _GLibCVersion(2, 12):
|
| 200 |
+
if hasattr(_manylinux, "manylinux2010_compatible"):
|
| 201 |
+
return bool(_manylinux.manylinux2010_compatible)
|
| 202 |
+
if version == _GLibCVersion(2, 17):
|
| 203 |
+
if hasattr(_manylinux, "manylinux2014_compatible"):
|
| 204 |
+
return bool(_manylinux.manylinux2014_compatible)
|
| 205 |
+
return True
|
| 206 |
+
|
| 207 |
+
|
| 208 |
+
_LEGACY_MANYLINUX_MAP = {
|
| 209 |
+
# CentOS 7 w/ glibc 2.17 (PEP 599)
|
| 210 |
+
(2, 17): "manylinux2014",
|
| 211 |
+
# CentOS 6 w/ glibc 2.12 (PEP 571)
|
| 212 |
+
(2, 12): "manylinux2010",
|
| 213 |
+
# CentOS 5 w/ glibc 2.5 (PEP 513)
|
| 214 |
+
(2, 5): "manylinux1",
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
def platform_tags(archs: Sequence[str]) -> Iterator[str]:
|
| 219 |
+
"""Generate manylinux tags compatible to the current platform.
|
| 220 |
+
|
| 221 |
+
:param archs: Sequence of compatible architectures.
|
| 222 |
+
The first one shall be the closest to the actual architecture and be the part of
|
| 223 |
+
platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
|
| 224 |
+
The ``linux_`` prefix is assumed as a prerequisite for the current platform to
|
| 225 |
+
be manylinux-compatible.
|
| 226 |
+
|
| 227 |
+
:returns: An iterator of compatible manylinux tags.
|
| 228 |
+
"""
|
| 229 |
+
if not _have_compatible_abi(sys.executable, archs):
|
| 230 |
+
return
|
| 231 |
+
# Oldest glibc to be supported regardless of architecture is (2, 17).
|
| 232 |
+
too_old_glibc2 = _GLibCVersion(2, 16)
|
| 233 |
+
if set(archs) & {"x86_64", "i686"}:
|
| 234 |
+
# On x86/i686 also oldest glibc to be supported is (2, 5).
|
| 235 |
+
too_old_glibc2 = _GLibCVersion(2, 4)
|
| 236 |
+
current_glibc = _GLibCVersion(*_get_glibc_version())
|
| 237 |
+
glibc_max_list = [current_glibc]
|
| 238 |
+
# We can assume compatibility across glibc major versions.
|
| 239 |
+
# https://sourceware.org/bugzilla/show_bug.cgi?id=24636
|
| 240 |
+
#
|
| 241 |
+
# Build a list of maximum glibc versions so that we can
|
| 242 |
+
# output the canonical list of all glibc from current_glibc
|
| 243 |
+
# down to too_old_glibc2, including all intermediary versions.
|
| 244 |
+
for glibc_major in range(current_glibc.major - 1, 1, -1):
|
| 245 |
+
glibc_minor = _LAST_GLIBC_MINOR[glibc_major]
|
| 246 |
+
glibc_max_list.append(_GLibCVersion(glibc_major, glibc_minor))
|
| 247 |
+
for arch in archs:
|
| 248 |
+
for glibc_max in glibc_max_list:
|
| 249 |
+
if glibc_max.major == too_old_glibc2.major:
|
| 250 |
+
min_minor = too_old_glibc2.minor
|
| 251 |
+
else:
|
| 252 |
+
# For other glibc major versions oldest supported is (x, 0).
|
| 253 |
+
min_minor = -1
|
| 254 |
+
for glibc_minor in range(glibc_max.minor, min_minor, -1):
|
| 255 |
+
glibc_version = _GLibCVersion(glibc_max.major, glibc_minor)
|
| 256 |
+
tag = "manylinux_{}_{}".format(*glibc_version)
|
| 257 |
+
if _is_compatible(arch, glibc_version):
|
| 258 |
+
yield f"{tag}_{arch}"
|
| 259 |
+
# Handle the legacy manylinux1, manylinux2010, manylinux2014 tags.
|
| 260 |
+
if glibc_version in _LEGACY_MANYLINUX_MAP:
|
| 261 |
+
legacy_tag = _LEGACY_MANYLINUX_MAP[glibc_version]
|
| 262 |
+
if _is_compatible(arch, glibc_version):
|
| 263 |
+
yield f"{legacy_tag}_{arch}"
|
.venv/lib/python3.11/site-packages/packaging/_musllinux.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""PEP 656 support.
|
| 2 |
+
|
| 3 |
+
This module implements logic to detect if the currently running Python is
|
| 4 |
+
linked against musl, and what musl version is used.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from __future__ import annotations
|
| 8 |
+
|
| 9 |
+
import functools
|
| 10 |
+
import re
|
| 11 |
+
import subprocess
|
| 12 |
+
import sys
|
| 13 |
+
from typing import Iterator, NamedTuple, Sequence
|
| 14 |
+
|
| 15 |
+
from ._elffile import ELFFile
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class _MuslVersion(NamedTuple):
|
| 19 |
+
major: int
|
| 20 |
+
minor: int
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
def _parse_musl_version(output: str) -> _MuslVersion | None:
|
| 24 |
+
lines = [n for n in (n.strip() for n in output.splitlines()) if n]
|
| 25 |
+
if len(lines) < 2 or lines[0][:4] != "musl":
|
| 26 |
+
return None
|
| 27 |
+
m = re.match(r"Version (\d+)\.(\d+)", lines[1])
|
| 28 |
+
if not m:
|
| 29 |
+
return None
|
| 30 |
+
return _MuslVersion(major=int(m.group(1)), minor=int(m.group(2)))
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
@functools.lru_cache
|
| 34 |
+
def _get_musl_version(executable: str) -> _MuslVersion | None:
|
| 35 |
+
"""Detect currently-running musl runtime version.
|
| 36 |
+
|
| 37 |
+
This is done by checking the specified executable's dynamic linking
|
| 38 |
+
information, and invoking the loader to parse its output for a version
|
| 39 |
+
string. If the loader is musl, the output would be something like::
|
| 40 |
+
|
| 41 |
+
musl libc (x86_64)
|
| 42 |
+
Version 1.2.2
|
| 43 |
+
Dynamic Program Loader
|
| 44 |
+
"""
|
| 45 |
+
try:
|
| 46 |
+
with open(executable, "rb") as f:
|
| 47 |
+
ld = ELFFile(f).interpreter
|
| 48 |
+
except (OSError, TypeError, ValueError):
|
| 49 |
+
return None
|
| 50 |
+
if ld is None or "musl" not in ld:
|
| 51 |
+
return None
|
| 52 |
+
proc = subprocess.run([ld], stderr=subprocess.PIPE, text=True)
|
| 53 |
+
return _parse_musl_version(proc.stderr)
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
def platform_tags(archs: Sequence[str]) -> Iterator[str]:
|
| 57 |
+
"""Generate musllinux tags compatible to the current platform.
|
| 58 |
+
|
| 59 |
+
:param archs: Sequence of compatible architectures.
|
| 60 |
+
The first one shall be the closest to the actual architecture and be the part of
|
| 61 |
+
platform tag after the ``linux_`` prefix, e.g. ``x86_64``.
|
| 62 |
+
The ``linux_`` prefix is assumed as a prerequisite for the current platform to
|
| 63 |
+
be musllinux-compatible.
|
| 64 |
+
|
| 65 |
+
:returns: An iterator of compatible musllinux tags.
|
| 66 |
+
"""
|
| 67 |
+
sys_musl = _get_musl_version(sys.executable)
|
| 68 |
+
if sys_musl is None: # Python not dynamically linked against musl.
|
| 69 |
+
return
|
| 70 |
+
for arch in archs:
|
| 71 |
+
for minor in range(sys_musl.minor, -1, -1):
|
| 72 |
+
yield f"musllinux_{sys_musl.major}_{minor}_{arch}"
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
if __name__ == "__main__": # pragma: no cover
|
| 76 |
+
import sysconfig
|
| 77 |
+
|
| 78 |
+
plat = sysconfig.get_platform()
|
| 79 |
+
assert plat.startswith("linux-"), "not linux"
|
| 80 |
+
|
| 81 |
+
print("plat:", plat)
|
| 82 |
+
print("musl:", _get_musl_version(sys.executable))
|
| 83 |
+
print("tags:", end=" ")
|
| 84 |
+
for t in platform_tags(re.sub(r"[.-]", "_", plat.split("-", 1)[-1])):
|
| 85 |
+
print(t, end="\n ")
|
.venv/lib/python3.11/site-packages/packaging/_parser.py
ADDED
|
@@ -0,0 +1,354 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Handwritten parser of dependency specifiers.
|
| 2 |
+
|
| 3 |
+
The docstring for each __parse_* function contains EBNF-inspired grammar representing
|
| 4 |
+
the implementation.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from __future__ import annotations
|
| 8 |
+
|
| 9 |
+
import ast
|
| 10 |
+
from typing import NamedTuple, Sequence, Tuple, Union
|
| 11 |
+
|
| 12 |
+
from ._tokenizer import DEFAULT_RULES, Tokenizer
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class Node:
|
| 16 |
+
def __init__(self, value: str) -> None:
|
| 17 |
+
self.value = value
|
| 18 |
+
|
| 19 |
+
def __str__(self) -> str:
|
| 20 |
+
return self.value
|
| 21 |
+
|
| 22 |
+
def __repr__(self) -> str:
|
| 23 |
+
return f"<{self.__class__.__name__}('{self}')>"
|
| 24 |
+
|
| 25 |
+
def serialize(self) -> str:
|
| 26 |
+
raise NotImplementedError
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
class Variable(Node):
|
| 30 |
+
def serialize(self) -> str:
|
| 31 |
+
return str(self)
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
class Value(Node):
|
| 35 |
+
def serialize(self) -> str:
|
| 36 |
+
return f'"{self}"'
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
class Op(Node):
|
| 40 |
+
def serialize(self) -> str:
|
| 41 |
+
return str(self)
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
MarkerVar = Union[Variable, Value]
|
| 45 |
+
MarkerItem = Tuple[MarkerVar, Op, MarkerVar]
|
| 46 |
+
MarkerAtom = Union[MarkerItem, Sequence["MarkerAtom"]]
|
| 47 |
+
MarkerList = Sequence[Union["MarkerList", MarkerAtom, str]]
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
class ParsedRequirement(NamedTuple):
|
| 51 |
+
name: str
|
| 52 |
+
url: str
|
| 53 |
+
extras: list[str]
|
| 54 |
+
specifier: str
|
| 55 |
+
marker: MarkerList | None
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
# --------------------------------------------------------------------------------------
|
| 59 |
+
# Recursive descent parser for dependency specifier
|
| 60 |
+
# --------------------------------------------------------------------------------------
|
| 61 |
+
def parse_requirement(source: str) -> ParsedRequirement:
|
| 62 |
+
return _parse_requirement(Tokenizer(source, rules=DEFAULT_RULES))
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
def _parse_requirement(tokenizer: Tokenizer) -> ParsedRequirement:
|
| 66 |
+
"""
|
| 67 |
+
requirement = WS? IDENTIFIER WS? extras WS? requirement_details
|
| 68 |
+
"""
|
| 69 |
+
tokenizer.consume("WS")
|
| 70 |
+
|
| 71 |
+
name_token = tokenizer.expect(
|
| 72 |
+
"IDENTIFIER", expected="package name at the start of dependency specifier"
|
| 73 |
+
)
|
| 74 |
+
name = name_token.text
|
| 75 |
+
tokenizer.consume("WS")
|
| 76 |
+
|
| 77 |
+
extras = _parse_extras(tokenizer)
|
| 78 |
+
tokenizer.consume("WS")
|
| 79 |
+
|
| 80 |
+
url, specifier, marker = _parse_requirement_details(tokenizer)
|
| 81 |
+
tokenizer.expect("END", expected="end of dependency specifier")
|
| 82 |
+
|
| 83 |
+
return ParsedRequirement(name, url, extras, specifier, marker)
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def _parse_requirement_details(
|
| 87 |
+
tokenizer: Tokenizer,
|
| 88 |
+
) -> tuple[str, str, MarkerList | None]:
|
| 89 |
+
"""
|
| 90 |
+
requirement_details = AT URL (WS requirement_marker?)?
|
| 91 |
+
| specifier WS? (requirement_marker)?
|
| 92 |
+
"""
|
| 93 |
+
|
| 94 |
+
specifier = ""
|
| 95 |
+
url = ""
|
| 96 |
+
marker = None
|
| 97 |
+
|
| 98 |
+
if tokenizer.check("AT"):
|
| 99 |
+
tokenizer.read()
|
| 100 |
+
tokenizer.consume("WS")
|
| 101 |
+
|
| 102 |
+
url_start = tokenizer.position
|
| 103 |
+
url = tokenizer.expect("URL", expected="URL after @").text
|
| 104 |
+
if tokenizer.check("END", peek=True):
|
| 105 |
+
return (url, specifier, marker)
|
| 106 |
+
|
| 107 |
+
tokenizer.expect("WS", expected="whitespace after URL")
|
| 108 |
+
|
| 109 |
+
# The input might end after whitespace.
|
| 110 |
+
if tokenizer.check("END", peek=True):
|
| 111 |
+
return (url, specifier, marker)
|
| 112 |
+
|
| 113 |
+
marker = _parse_requirement_marker(
|
| 114 |
+
tokenizer, span_start=url_start, after="URL and whitespace"
|
| 115 |
+
)
|
| 116 |
+
else:
|
| 117 |
+
specifier_start = tokenizer.position
|
| 118 |
+
specifier = _parse_specifier(tokenizer)
|
| 119 |
+
tokenizer.consume("WS")
|
| 120 |
+
|
| 121 |
+
if tokenizer.check("END", peek=True):
|
| 122 |
+
return (url, specifier, marker)
|
| 123 |
+
|
| 124 |
+
marker = _parse_requirement_marker(
|
| 125 |
+
tokenizer,
|
| 126 |
+
span_start=specifier_start,
|
| 127 |
+
after=(
|
| 128 |
+
"version specifier"
|
| 129 |
+
if specifier
|
| 130 |
+
else "name and no valid version specifier"
|
| 131 |
+
),
|
| 132 |
+
)
|
| 133 |
+
|
| 134 |
+
return (url, specifier, marker)
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
def _parse_requirement_marker(
|
| 138 |
+
tokenizer: Tokenizer, *, span_start: int, after: str
|
| 139 |
+
) -> MarkerList:
|
| 140 |
+
"""
|
| 141 |
+
requirement_marker = SEMICOLON marker WS?
|
| 142 |
+
"""
|
| 143 |
+
|
| 144 |
+
if not tokenizer.check("SEMICOLON"):
|
| 145 |
+
tokenizer.raise_syntax_error(
|
| 146 |
+
f"Expected end or semicolon (after {after})",
|
| 147 |
+
span_start=span_start,
|
| 148 |
+
)
|
| 149 |
+
tokenizer.read()
|
| 150 |
+
|
| 151 |
+
marker = _parse_marker(tokenizer)
|
| 152 |
+
tokenizer.consume("WS")
|
| 153 |
+
|
| 154 |
+
return marker
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def _parse_extras(tokenizer: Tokenizer) -> list[str]:
|
| 158 |
+
"""
|
| 159 |
+
extras = (LEFT_BRACKET wsp* extras_list? wsp* RIGHT_BRACKET)?
|
| 160 |
+
"""
|
| 161 |
+
if not tokenizer.check("LEFT_BRACKET", peek=True):
|
| 162 |
+
return []
|
| 163 |
+
|
| 164 |
+
with tokenizer.enclosing_tokens(
|
| 165 |
+
"LEFT_BRACKET",
|
| 166 |
+
"RIGHT_BRACKET",
|
| 167 |
+
around="extras",
|
| 168 |
+
):
|
| 169 |
+
tokenizer.consume("WS")
|
| 170 |
+
extras = _parse_extras_list(tokenizer)
|
| 171 |
+
tokenizer.consume("WS")
|
| 172 |
+
|
| 173 |
+
return extras
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
def _parse_extras_list(tokenizer: Tokenizer) -> list[str]:
|
| 177 |
+
"""
|
| 178 |
+
extras_list = identifier (wsp* ',' wsp* identifier)*
|
| 179 |
+
"""
|
| 180 |
+
extras: list[str] = []
|
| 181 |
+
|
| 182 |
+
if not tokenizer.check("IDENTIFIER"):
|
| 183 |
+
return extras
|
| 184 |
+
|
| 185 |
+
extras.append(tokenizer.read().text)
|
| 186 |
+
|
| 187 |
+
while True:
|
| 188 |
+
tokenizer.consume("WS")
|
| 189 |
+
if tokenizer.check("IDENTIFIER", peek=True):
|
| 190 |
+
tokenizer.raise_syntax_error("Expected comma between extra names")
|
| 191 |
+
elif not tokenizer.check("COMMA"):
|
| 192 |
+
break
|
| 193 |
+
|
| 194 |
+
tokenizer.read()
|
| 195 |
+
tokenizer.consume("WS")
|
| 196 |
+
|
| 197 |
+
extra_token = tokenizer.expect("IDENTIFIER", expected="extra name after comma")
|
| 198 |
+
extras.append(extra_token.text)
|
| 199 |
+
|
| 200 |
+
return extras
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
def _parse_specifier(tokenizer: Tokenizer) -> str:
|
| 204 |
+
"""
|
| 205 |
+
specifier = LEFT_PARENTHESIS WS? version_many WS? RIGHT_PARENTHESIS
|
| 206 |
+
| WS? version_many WS?
|
| 207 |
+
"""
|
| 208 |
+
with tokenizer.enclosing_tokens(
|
| 209 |
+
"LEFT_PARENTHESIS",
|
| 210 |
+
"RIGHT_PARENTHESIS",
|
| 211 |
+
around="version specifier",
|
| 212 |
+
):
|
| 213 |
+
tokenizer.consume("WS")
|
| 214 |
+
parsed_specifiers = _parse_version_many(tokenizer)
|
| 215 |
+
tokenizer.consume("WS")
|
| 216 |
+
|
| 217 |
+
return parsed_specifiers
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
def _parse_version_many(tokenizer: Tokenizer) -> str:
|
| 221 |
+
"""
|
| 222 |
+
version_many = (SPECIFIER (WS? COMMA WS? SPECIFIER)*)?
|
| 223 |
+
"""
|
| 224 |
+
parsed_specifiers = ""
|
| 225 |
+
while tokenizer.check("SPECIFIER"):
|
| 226 |
+
span_start = tokenizer.position
|
| 227 |
+
parsed_specifiers += tokenizer.read().text
|
| 228 |
+
if tokenizer.check("VERSION_PREFIX_TRAIL", peek=True):
|
| 229 |
+
tokenizer.raise_syntax_error(
|
| 230 |
+
".* suffix can only be used with `==` or `!=` operators",
|
| 231 |
+
span_start=span_start,
|
| 232 |
+
span_end=tokenizer.position + 1,
|
| 233 |
+
)
|
| 234 |
+
if tokenizer.check("VERSION_LOCAL_LABEL_TRAIL", peek=True):
|
| 235 |
+
tokenizer.raise_syntax_error(
|
| 236 |
+
"Local version label can only be used with `==` or `!=` operators",
|
| 237 |
+
span_start=span_start,
|
| 238 |
+
span_end=tokenizer.position,
|
| 239 |
+
)
|
| 240 |
+
tokenizer.consume("WS")
|
| 241 |
+
if not tokenizer.check("COMMA"):
|
| 242 |
+
break
|
| 243 |
+
parsed_specifiers += tokenizer.read().text
|
| 244 |
+
tokenizer.consume("WS")
|
| 245 |
+
|
| 246 |
+
return parsed_specifiers
|
| 247 |
+
|
| 248 |
+
|
| 249 |
+
# --------------------------------------------------------------------------------------
|
| 250 |
+
# Recursive descent parser for marker expression
|
| 251 |
+
# --------------------------------------------------------------------------------------
|
| 252 |
+
def parse_marker(source: str) -> MarkerList:
|
| 253 |
+
return _parse_full_marker(Tokenizer(source, rules=DEFAULT_RULES))
|
| 254 |
+
|
| 255 |
+
|
| 256 |
+
def _parse_full_marker(tokenizer: Tokenizer) -> MarkerList:
|
| 257 |
+
retval = _parse_marker(tokenizer)
|
| 258 |
+
tokenizer.expect("END", expected="end of marker expression")
|
| 259 |
+
return retval
|
| 260 |
+
|
| 261 |
+
|
| 262 |
+
def _parse_marker(tokenizer: Tokenizer) -> MarkerList:
|
| 263 |
+
"""
|
| 264 |
+
marker = marker_atom (BOOLOP marker_atom)+
|
| 265 |
+
"""
|
| 266 |
+
expression = [_parse_marker_atom(tokenizer)]
|
| 267 |
+
while tokenizer.check("BOOLOP"):
|
| 268 |
+
token = tokenizer.read()
|
| 269 |
+
expr_right = _parse_marker_atom(tokenizer)
|
| 270 |
+
expression.extend((token.text, expr_right))
|
| 271 |
+
return expression
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
def _parse_marker_atom(tokenizer: Tokenizer) -> MarkerAtom:
|
| 275 |
+
"""
|
| 276 |
+
marker_atom = WS? LEFT_PARENTHESIS WS? marker WS? RIGHT_PARENTHESIS WS?
|
| 277 |
+
| WS? marker_item WS?
|
| 278 |
+
"""
|
| 279 |
+
|
| 280 |
+
tokenizer.consume("WS")
|
| 281 |
+
if tokenizer.check("LEFT_PARENTHESIS", peek=True):
|
| 282 |
+
with tokenizer.enclosing_tokens(
|
| 283 |
+
"LEFT_PARENTHESIS",
|
| 284 |
+
"RIGHT_PARENTHESIS",
|
| 285 |
+
around="marker expression",
|
| 286 |
+
):
|
| 287 |
+
tokenizer.consume("WS")
|
| 288 |
+
marker: MarkerAtom = _parse_marker(tokenizer)
|
| 289 |
+
tokenizer.consume("WS")
|
| 290 |
+
else:
|
| 291 |
+
marker = _parse_marker_item(tokenizer)
|
| 292 |
+
tokenizer.consume("WS")
|
| 293 |
+
return marker
|
| 294 |
+
|
| 295 |
+
|
| 296 |
+
def _parse_marker_item(tokenizer: Tokenizer) -> MarkerItem:
|
| 297 |
+
"""
|
| 298 |
+
marker_item = WS? marker_var WS? marker_op WS? marker_var WS?
|
| 299 |
+
"""
|
| 300 |
+
tokenizer.consume("WS")
|
| 301 |
+
marker_var_left = _parse_marker_var(tokenizer)
|
| 302 |
+
tokenizer.consume("WS")
|
| 303 |
+
marker_op = _parse_marker_op(tokenizer)
|
| 304 |
+
tokenizer.consume("WS")
|
| 305 |
+
marker_var_right = _parse_marker_var(tokenizer)
|
| 306 |
+
tokenizer.consume("WS")
|
| 307 |
+
return (marker_var_left, marker_op, marker_var_right)
|
| 308 |
+
|
| 309 |
+
|
| 310 |
+
def _parse_marker_var(tokenizer: Tokenizer) -> MarkerVar:
|
| 311 |
+
"""
|
| 312 |
+
marker_var = VARIABLE | QUOTED_STRING
|
| 313 |
+
"""
|
| 314 |
+
if tokenizer.check("VARIABLE"):
|
| 315 |
+
return process_env_var(tokenizer.read().text.replace(".", "_"))
|
| 316 |
+
elif tokenizer.check("QUOTED_STRING"):
|
| 317 |
+
return process_python_str(tokenizer.read().text)
|
| 318 |
+
else:
|
| 319 |
+
tokenizer.raise_syntax_error(
|
| 320 |
+
message="Expected a marker variable or quoted string"
|
| 321 |
+
)
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
def process_env_var(env_var: str) -> Variable:
|
| 325 |
+
if env_var in ("platform_python_implementation", "python_implementation"):
|
| 326 |
+
return Variable("platform_python_implementation")
|
| 327 |
+
else:
|
| 328 |
+
return Variable(env_var)
|
| 329 |
+
|
| 330 |
+
|
| 331 |
+
def process_python_str(python_str: str) -> Value:
|
| 332 |
+
value = ast.literal_eval(python_str)
|
| 333 |
+
return Value(str(value))
|
| 334 |
+
|
| 335 |
+
|
| 336 |
+
def _parse_marker_op(tokenizer: Tokenizer) -> Op:
|
| 337 |
+
"""
|
| 338 |
+
marker_op = IN | NOT IN | OP
|
| 339 |
+
"""
|
| 340 |
+
if tokenizer.check("IN"):
|
| 341 |
+
tokenizer.read()
|
| 342 |
+
return Op("in")
|
| 343 |
+
elif tokenizer.check("NOT"):
|
| 344 |
+
tokenizer.read()
|
| 345 |
+
tokenizer.expect("WS", expected="whitespace after 'not'")
|
| 346 |
+
tokenizer.expect("IN", expected="'in' after 'not'")
|
| 347 |
+
return Op("not in")
|
| 348 |
+
elif tokenizer.check("OP"):
|
| 349 |
+
return Op(tokenizer.read().text)
|
| 350 |
+
else:
|
| 351 |
+
return tokenizer.raise_syntax_error(
|
| 352 |
+
"Expected marker operator, one of "
|
| 353 |
+
"<=, <, !=, ==, >=, >, ~=, ===, in, not in"
|
| 354 |
+
)
|
.venv/lib/python3.11/site-packages/packaging/_structures.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file is dual licensed under the terms of the Apache License, Version
|
| 2 |
+
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
| 3 |
+
# for complete details.
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
class InfinityType:
|
| 7 |
+
def __repr__(self) -> str:
|
| 8 |
+
return "Infinity"
|
| 9 |
+
|
| 10 |
+
def __hash__(self) -> int:
|
| 11 |
+
return hash(repr(self))
|
| 12 |
+
|
| 13 |
+
def __lt__(self, other: object) -> bool:
|
| 14 |
+
return False
|
| 15 |
+
|
| 16 |
+
def __le__(self, other: object) -> bool:
|
| 17 |
+
return False
|
| 18 |
+
|
| 19 |
+
def __eq__(self, other: object) -> bool:
|
| 20 |
+
return isinstance(other, self.__class__)
|
| 21 |
+
|
| 22 |
+
def __gt__(self, other: object) -> bool:
|
| 23 |
+
return True
|
| 24 |
+
|
| 25 |
+
def __ge__(self, other: object) -> bool:
|
| 26 |
+
return True
|
| 27 |
+
|
| 28 |
+
def __neg__(self: object) -> "NegativeInfinityType":
|
| 29 |
+
return NegativeInfinity
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
Infinity = InfinityType()
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
class NegativeInfinityType:
|
| 36 |
+
def __repr__(self) -> str:
|
| 37 |
+
return "-Infinity"
|
| 38 |
+
|
| 39 |
+
def __hash__(self) -> int:
|
| 40 |
+
return hash(repr(self))
|
| 41 |
+
|
| 42 |
+
def __lt__(self, other: object) -> bool:
|
| 43 |
+
return True
|
| 44 |
+
|
| 45 |
+
def __le__(self, other: object) -> bool:
|
| 46 |
+
return True
|
| 47 |
+
|
| 48 |
+
def __eq__(self, other: object) -> bool:
|
| 49 |
+
return isinstance(other, self.__class__)
|
| 50 |
+
|
| 51 |
+
def __gt__(self, other: object) -> bool:
|
| 52 |
+
return False
|
| 53 |
+
|
| 54 |
+
def __ge__(self, other: object) -> bool:
|
| 55 |
+
return False
|
| 56 |
+
|
| 57 |
+
def __neg__(self: object) -> InfinityType:
|
| 58 |
+
return Infinity
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
NegativeInfinity = NegativeInfinityType()
|
.venv/lib/python3.11/site-packages/packaging/_tokenizer.py
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import contextlib
|
| 4 |
+
import re
|
| 5 |
+
from dataclasses import dataclass
|
| 6 |
+
from typing import Iterator, NoReturn
|
| 7 |
+
|
| 8 |
+
from .specifiers import Specifier
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
@dataclass
|
| 12 |
+
class Token:
|
| 13 |
+
name: str
|
| 14 |
+
text: str
|
| 15 |
+
position: int
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class ParserSyntaxError(Exception):
|
| 19 |
+
"""The provided source text could not be parsed correctly."""
|
| 20 |
+
|
| 21 |
+
def __init__(
|
| 22 |
+
self,
|
| 23 |
+
message: str,
|
| 24 |
+
*,
|
| 25 |
+
source: str,
|
| 26 |
+
span: tuple[int, int],
|
| 27 |
+
) -> None:
|
| 28 |
+
self.span = span
|
| 29 |
+
self.message = message
|
| 30 |
+
self.source = source
|
| 31 |
+
|
| 32 |
+
super().__init__()
|
| 33 |
+
|
| 34 |
+
def __str__(self) -> str:
|
| 35 |
+
marker = " " * self.span[0] + "~" * (self.span[1] - self.span[0]) + "^"
|
| 36 |
+
return "\n ".join([self.message, self.source, marker])
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
DEFAULT_RULES: dict[str, str | re.Pattern[str]] = {
|
| 40 |
+
"LEFT_PARENTHESIS": r"\(",
|
| 41 |
+
"RIGHT_PARENTHESIS": r"\)",
|
| 42 |
+
"LEFT_BRACKET": r"\[",
|
| 43 |
+
"RIGHT_BRACKET": r"\]",
|
| 44 |
+
"SEMICOLON": r";",
|
| 45 |
+
"COMMA": r",",
|
| 46 |
+
"QUOTED_STRING": re.compile(
|
| 47 |
+
r"""
|
| 48 |
+
(
|
| 49 |
+
('[^']*')
|
| 50 |
+
|
|
| 51 |
+
("[^"]*")
|
| 52 |
+
)
|
| 53 |
+
""",
|
| 54 |
+
re.VERBOSE,
|
| 55 |
+
),
|
| 56 |
+
"OP": r"(===|==|~=|!=|<=|>=|<|>)",
|
| 57 |
+
"BOOLOP": r"\b(or|and)\b",
|
| 58 |
+
"IN": r"\bin\b",
|
| 59 |
+
"NOT": r"\bnot\b",
|
| 60 |
+
"VARIABLE": re.compile(
|
| 61 |
+
r"""
|
| 62 |
+
\b(
|
| 63 |
+
python_version
|
| 64 |
+
|python_full_version
|
| 65 |
+
|os[._]name
|
| 66 |
+
|sys[._]platform
|
| 67 |
+
|platform_(release|system)
|
| 68 |
+
|platform[._](version|machine|python_implementation)
|
| 69 |
+
|python_implementation
|
| 70 |
+
|implementation_(name|version)
|
| 71 |
+
|extra
|
| 72 |
+
)\b
|
| 73 |
+
""",
|
| 74 |
+
re.VERBOSE,
|
| 75 |
+
),
|
| 76 |
+
"SPECIFIER": re.compile(
|
| 77 |
+
Specifier._operator_regex_str + Specifier._version_regex_str,
|
| 78 |
+
re.VERBOSE | re.IGNORECASE,
|
| 79 |
+
),
|
| 80 |
+
"AT": r"\@",
|
| 81 |
+
"URL": r"[^ \t]+",
|
| 82 |
+
"IDENTIFIER": r"\b[a-zA-Z0-9][a-zA-Z0-9._-]*\b",
|
| 83 |
+
"VERSION_PREFIX_TRAIL": r"\.\*",
|
| 84 |
+
"VERSION_LOCAL_LABEL_TRAIL": r"\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*",
|
| 85 |
+
"WS": r"[ \t]+",
|
| 86 |
+
"END": r"$",
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
class Tokenizer:
|
| 91 |
+
"""Context-sensitive token parsing.
|
| 92 |
+
|
| 93 |
+
Provides methods to examine the input stream to check whether the next token
|
| 94 |
+
matches.
|
| 95 |
+
"""
|
| 96 |
+
|
| 97 |
+
def __init__(
|
| 98 |
+
self,
|
| 99 |
+
source: str,
|
| 100 |
+
*,
|
| 101 |
+
rules: dict[str, str | re.Pattern[str]],
|
| 102 |
+
) -> None:
|
| 103 |
+
self.source = source
|
| 104 |
+
self.rules: dict[str, re.Pattern[str]] = {
|
| 105 |
+
name: re.compile(pattern) for name, pattern in rules.items()
|
| 106 |
+
}
|
| 107 |
+
self.next_token: Token | None = None
|
| 108 |
+
self.position = 0
|
| 109 |
+
|
| 110 |
+
def consume(self, name: str) -> None:
|
| 111 |
+
"""Move beyond provided token name, if at current position."""
|
| 112 |
+
if self.check(name):
|
| 113 |
+
self.read()
|
| 114 |
+
|
| 115 |
+
def check(self, name: str, *, peek: bool = False) -> bool:
|
| 116 |
+
"""Check whether the next token has the provided name.
|
| 117 |
+
|
| 118 |
+
By default, if the check succeeds, the token *must* be read before
|
| 119 |
+
another check. If `peek` is set to `True`, the token is not loaded and
|
| 120 |
+
would need to be checked again.
|
| 121 |
+
"""
|
| 122 |
+
assert (
|
| 123 |
+
self.next_token is None
|
| 124 |
+
), f"Cannot check for {name!r}, already have {self.next_token!r}"
|
| 125 |
+
assert name in self.rules, f"Unknown token name: {name!r}"
|
| 126 |
+
|
| 127 |
+
expression = self.rules[name]
|
| 128 |
+
|
| 129 |
+
match = expression.match(self.source, self.position)
|
| 130 |
+
if match is None:
|
| 131 |
+
return False
|
| 132 |
+
if not peek:
|
| 133 |
+
self.next_token = Token(name, match[0], self.position)
|
| 134 |
+
return True
|
| 135 |
+
|
| 136 |
+
def expect(self, name: str, *, expected: str) -> Token:
|
| 137 |
+
"""Expect a certain token name next, failing with a syntax error otherwise.
|
| 138 |
+
|
| 139 |
+
The token is *not* read.
|
| 140 |
+
"""
|
| 141 |
+
if not self.check(name):
|
| 142 |
+
raise self.raise_syntax_error(f"Expected {expected}")
|
| 143 |
+
return self.read()
|
| 144 |
+
|
| 145 |
+
def read(self) -> Token:
|
| 146 |
+
"""Consume the next token and return it."""
|
| 147 |
+
token = self.next_token
|
| 148 |
+
assert token is not None
|
| 149 |
+
|
| 150 |
+
self.position += len(token.text)
|
| 151 |
+
self.next_token = None
|
| 152 |
+
|
| 153 |
+
return token
|
| 154 |
+
|
| 155 |
+
def raise_syntax_error(
|
| 156 |
+
self,
|
| 157 |
+
message: str,
|
| 158 |
+
*,
|
| 159 |
+
span_start: int | None = None,
|
| 160 |
+
span_end: int | None = None,
|
| 161 |
+
) -> NoReturn:
|
| 162 |
+
"""Raise ParserSyntaxError at the given position."""
|
| 163 |
+
span = (
|
| 164 |
+
self.position if span_start is None else span_start,
|
| 165 |
+
self.position if span_end is None else span_end,
|
| 166 |
+
)
|
| 167 |
+
raise ParserSyntaxError(
|
| 168 |
+
message,
|
| 169 |
+
source=self.source,
|
| 170 |
+
span=span,
|
| 171 |
+
)
|
| 172 |
+
|
| 173 |
+
@contextlib.contextmanager
|
| 174 |
+
def enclosing_tokens(
|
| 175 |
+
self, open_token: str, close_token: str, *, around: str
|
| 176 |
+
) -> Iterator[None]:
|
| 177 |
+
if self.check(open_token):
|
| 178 |
+
open_position = self.position
|
| 179 |
+
self.read()
|
| 180 |
+
else:
|
| 181 |
+
open_position = None
|
| 182 |
+
|
| 183 |
+
yield
|
| 184 |
+
|
| 185 |
+
if open_position is None:
|
| 186 |
+
return
|
| 187 |
+
|
| 188 |
+
if not self.check(close_token):
|
| 189 |
+
self.raise_syntax_error(
|
| 190 |
+
f"Expected matching {close_token} for {open_token}, after {around}",
|
| 191 |
+
span_start=open_position,
|
| 192 |
+
)
|
| 193 |
+
|
| 194 |
+
self.read()
|
.venv/lib/python3.11/site-packages/packaging/licenses/__init__.py
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#######################################################################################
|
| 2 |
+
#
|
| 3 |
+
# Adapted from:
|
| 4 |
+
# https://github.com/pypa/hatch/blob/5352e44/backend/src/hatchling/licenses/parse.py
|
| 5 |
+
#
|
| 6 |
+
# MIT License
|
| 7 |
+
#
|
| 8 |
+
# Copyright (c) 2017-present Ofek Lev <oss@ofek.dev>
|
| 9 |
+
#
|
| 10 |
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
| 11 |
+
# software and associated documentation files (the "Software"), to deal in the Software
|
| 12 |
+
# without restriction, including without limitation the rights to use, copy, modify,
|
| 13 |
+
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
|
| 14 |
+
# permit persons to whom the Software is furnished to do so, subject to the following
|
| 15 |
+
# conditions:
|
| 16 |
+
#
|
| 17 |
+
# The above copyright notice and this permission notice shall be included in all copies
|
| 18 |
+
# or substantial portions of the Software.
|
| 19 |
+
#
|
| 20 |
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
| 21 |
+
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
| 22 |
+
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
| 23 |
+
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
| 24 |
+
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
| 25 |
+
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
| 26 |
+
#
|
| 27 |
+
#
|
| 28 |
+
# With additional allowance of arbitrary `LicenseRef-` identifiers, not just
|
| 29 |
+
# `LicenseRef-Public-Domain` and `LicenseRef-Proprietary`.
|
| 30 |
+
#
|
| 31 |
+
#######################################################################################
|
| 32 |
+
from __future__ import annotations
|
| 33 |
+
|
| 34 |
+
import re
|
| 35 |
+
from typing import NewType, cast
|
| 36 |
+
|
| 37 |
+
from packaging.licenses._spdx import EXCEPTIONS, LICENSES
|
| 38 |
+
|
| 39 |
+
__all__ = [
|
| 40 |
+
"NormalizedLicenseExpression",
|
| 41 |
+
"InvalidLicenseExpression",
|
| 42 |
+
"canonicalize_license_expression",
|
| 43 |
+
]
|
| 44 |
+
|
| 45 |
+
license_ref_allowed = re.compile("^[A-Za-z0-9.-]*$")
|
| 46 |
+
|
| 47 |
+
NormalizedLicenseExpression = NewType("NormalizedLicenseExpression", str)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
class InvalidLicenseExpression(ValueError):
|
| 51 |
+
"""Raised when a license-expression string is invalid
|
| 52 |
+
|
| 53 |
+
>>> canonicalize_license_expression("invalid")
|
| 54 |
+
Traceback (most recent call last):
|
| 55 |
+
...
|
| 56 |
+
packaging.licenses.InvalidLicenseExpression: Invalid license expression: 'invalid'
|
| 57 |
+
"""
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
def canonicalize_license_expression(
|
| 61 |
+
raw_license_expression: str,
|
| 62 |
+
) -> NormalizedLicenseExpression:
|
| 63 |
+
if not raw_license_expression:
|
| 64 |
+
message = f"Invalid license expression: {raw_license_expression!r}"
|
| 65 |
+
raise InvalidLicenseExpression(message)
|
| 66 |
+
|
| 67 |
+
# Pad any parentheses so tokenization can be achieved by merely splitting on
|
| 68 |
+
# whitespace.
|
| 69 |
+
license_expression = raw_license_expression.replace("(", " ( ").replace(")", " ) ")
|
| 70 |
+
licenseref_prefix = "LicenseRef-"
|
| 71 |
+
license_refs = {
|
| 72 |
+
ref.lower(): "LicenseRef-" + ref[len(licenseref_prefix) :]
|
| 73 |
+
for ref in license_expression.split()
|
| 74 |
+
if ref.lower().startswith(licenseref_prefix.lower())
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
# Normalize to lower case so we can look up licenses/exceptions
|
| 78 |
+
# and so boolean operators are Python-compatible.
|
| 79 |
+
license_expression = license_expression.lower()
|
| 80 |
+
|
| 81 |
+
tokens = license_expression.split()
|
| 82 |
+
|
| 83 |
+
# Rather than implementing boolean logic, we create an expression that Python can
|
| 84 |
+
# parse. Everything that is not involved with the grammar itself is treated as
|
| 85 |
+
# `False` and the expression should evaluate as such.
|
| 86 |
+
python_tokens = []
|
| 87 |
+
for token in tokens:
|
| 88 |
+
if token not in {"or", "and", "with", "(", ")"}:
|
| 89 |
+
python_tokens.append("False")
|
| 90 |
+
elif token == "with":
|
| 91 |
+
python_tokens.append("or")
|
| 92 |
+
elif token == "(" and python_tokens and python_tokens[-1] not in {"or", "and"}:
|
| 93 |
+
message = f"Invalid license expression: {raw_license_expression!r}"
|
| 94 |
+
raise InvalidLicenseExpression(message)
|
| 95 |
+
else:
|
| 96 |
+
python_tokens.append(token)
|
| 97 |
+
|
| 98 |
+
python_expression = " ".join(python_tokens)
|
| 99 |
+
try:
|
| 100 |
+
invalid = eval(python_expression, globals(), locals())
|
| 101 |
+
except Exception:
|
| 102 |
+
invalid = True
|
| 103 |
+
|
| 104 |
+
if invalid is not False:
|
| 105 |
+
message = f"Invalid license expression: {raw_license_expression!r}"
|
| 106 |
+
raise InvalidLicenseExpression(message) from None
|
| 107 |
+
|
| 108 |
+
# Take a final pass to check for unknown licenses/exceptions.
|
| 109 |
+
normalized_tokens = []
|
| 110 |
+
for token in tokens:
|
| 111 |
+
if token in {"or", "and", "with", "(", ")"}:
|
| 112 |
+
normalized_tokens.append(token.upper())
|
| 113 |
+
continue
|
| 114 |
+
|
| 115 |
+
if normalized_tokens and normalized_tokens[-1] == "WITH":
|
| 116 |
+
if token not in EXCEPTIONS:
|
| 117 |
+
message = f"Unknown license exception: {token!r}"
|
| 118 |
+
raise InvalidLicenseExpression(message)
|
| 119 |
+
|
| 120 |
+
normalized_tokens.append(EXCEPTIONS[token]["id"])
|
| 121 |
+
else:
|
| 122 |
+
if token.endswith("+"):
|
| 123 |
+
final_token = token[:-1]
|
| 124 |
+
suffix = "+"
|
| 125 |
+
else:
|
| 126 |
+
final_token = token
|
| 127 |
+
suffix = ""
|
| 128 |
+
|
| 129 |
+
if final_token.startswith("licenseref-"):
|
| 130 |
+
if not license_ref_allowed.match(final_token):
|
| 131 |
+
message = f"Invalid licenseref: {final_token!r}"
|
| 132 |
+
raise InvalidLicenseExpression(message)
|
| 133 |
+
normalized_tokens.append(license_refs[final_token] + suffix)
|
| 134 |
+
else:
|
| 135 |
+
if final_token not in LICENSES:
|
| 136 |
+
message = f"Unknown license: {final_token!r}"
|
| 137 |
+
raise InvalidLicenseExpression(message)
|
| 138 |
+
normalized_tokens.append(LICENSES[final_token]["id"] + suffix)
|
| 139 |
+
|
| 140 |
+
normalized_expression = " ".join(normalized_tokens)
|
| 141 |
+
|
| 142 |
+
return cast(
|
| 143 |
+
NormalizedLicenseExpression,
|
| 144 |
+
normalized_expression.replace("( ", "(").replace(" )", ")"),
|
| 145 |
+
)
|
.venv/lib/python3.11/site-packages/packaging/licenses/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (5.03 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/licenses/__pycache__/_spdx.cpython-311.pyc
ADDED
|
Binary file (50.3 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/packaging/licenses/_spdx.py
ADDED
|
@@ -0,0 +1,759 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
from typing import TypedDict
|
| 5 |
+
|
| 6 |
+
class SPDXLicense(TypedDict):
|
| 7 |
+
id: str
|
| 8 |
+
deprecated: bool
|
| 9 |
+
|
| 10 |
+
class SPDXException(TypedDict):
|
| 11 |
+
id: str
|
| 12 |
+
deprecated: bool
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
VERSION = '3.25.0'
|
| 16 |
+
|
| 17 |
+
LICENSES: dict[str, SPDXLicense] = {
|
| 18 |
+
'0bsd': {'id': '0BSD', 'deprecated': False},
|
| 19 |
+
'3d-slicer-1.0': {'id': '3D-Slicer-1.0', 'deprecated': False},
|
| 20 |
+
'aal': {'id': 'AAL', 'deprecated': False},
|
| 21 |
+
'abstyles': {'id': 'Abstyles', 'deprecated': False},
|
| 22 |
+
'adacore-doc': {'id': 'AdaCore-doc', 'deprecated': False},
|
| 23 |
+
'adobe-2006': {'id': 'Adobe-2006', 'deprecated': False},
|
| 24 |
+
'adobe-display-postscript': {'id': 'Adobe-Display-PostScript', 'deprecated': False},
|
| 25 |
+
'adobe-glyph': {'id': 'Adobe-Glyph', 'deprecated': False},
|
| 26 |
+
'adobe-utopia': {'id': 'Adobe-Utopia', 'deprecated': False},
|
| 27 |
+
'adsl': {'id': 'ADSL', 'deprecated': False},
|
| 28 |
+
'afl-1.1': {'id': 'AFL-1.1', 'deprecated': False},
|
| 29 |
+
'afl-1.2': {'id': 'AFL-1.2', 'deprecated': False},
|
| 30 |
+
'afl-2.0': {'id': 'AFL-2.0', 'deprecated': False},
|
| 31 |
+
'afl-2.1': {'id': 'AFL-2.1', 'deprecated': False},
|
| 32 |
+
'afl-3.0': {'id': 'AFL-3.0', 'deprecated': False},
|
| 33 |
+
'afmparse': {'id': 'Afmparse', 'deprecated': False},
|
| 34 |
+
'agpl-1.0': {'id': 'AGPL-1.0', 'deprecated': True},
|
| 35 |
+
'agpl-1.0-only': {'id': 'AGPL-1.0-only', 'deprecated': False},
|
| 36 |
+
'agpl-1.0-or-later': {'id': 'AGPL-1.0-or-later', 'deprecated': False},
|
| 37 |
+
'agpl-3.0': {'id': 'AGPL-3.0', 'deprecated': True},
|
| 38 |
+
'agpl-3.0-only': {'id': 'AGPL-3.0-only', 'deprecated': False},
|
| 39 |
+
'agpl-3.0-or-later': {'id': 'AGPL-3.0-or-later', 'deprecated': False},
|
| 40 |
+
'aladdin': {'id': 'Aladdin', 'deprecated': False},
|
| 41 |
+
'amd-newlib': {'id': 'AMD-newlib', 'deprecated': False},
|
| 42 |
+
'amdplpa': {'id': 'AMDPLPA', 'deprecated': False},
|
| 43 |
+
'aml': {'id': 'AML', 'deprecated': False},
|
| 44 |
+
'aml-glslang': {'id': 'AML-glslang', 'deprecated': False},
|
| 45 |
+
'ampas': {'id': 'AMPAS', 'deprecated': False},
|
| 46 |
+
'antlr-pd': {'id': 'ANTLR-PD', 'deprecated': False},
|
| 47 |
+
'antlr-pd-fallback': {'id': 'ANTLR-PD-fallback', 'deprecated': False},
|
| 48 |
+
'any-osi': {'id': 'any-OSI', 'deprecated': False},
|
| 49 |
+
'apache-1.0': {'id': 'Apache-1.0', 'deprecated': False},
|
| 50 |
+
'apache-1.1': {'id': 'Apache-1.1', 'deprecated': False},
|
| 51 |
+
'apache-2.0': {'id': 'Apache-2.0', 'deprecated': False},
|
| 52 |
+
'apafml': {'id': 'APAFML', 'deprecated': False},
|
| 53 |
+
'apl-1.0': {'id': 'APL-1.0', 'deprecated': False},
|
| 54 |
+
'app-s2p': {'id': 'App-s2p', 'deprecated': False},
|
| 55 |
+
'apsl-1.0': {'id': 'APSL-1.0', 'deprecated': False},
|
| 56 |
+
'apsl-1.1': {'id': 'APSL-1.1', 'deprecated': False},
|
| 57 |
+
'apsl-1.2': {'id': 'APSL-1.2', 'deprecated': False},
|
| 58 |
+
'apsl-2.0': {'id': 'APSL-2.0', 'deprecated': False},
|
| 59 |
+
'arphic-1999': {'id': 'Arphic-1999', 'deprecated': False},
|
| 60 |
+
'artistic-1.0': {'id': 'Artistic-1.0', 'deprecated': False},
|
| 61 |
+
'artistic-1.0-cl8': {'id': 'Artistic-1.0-cl8', 'deprecated': False},
|
| 62 |
+
'artistic-1.0-perl': {'id': 'Artistic-1.0-Perl', 'deprecated': False},
|
| 63 |
+
'artistic-2.0': {'id': 'Artistic-2.0', 'deprecated': False},
|
| 64 |
+
'aswf-digital-assets-1.0': {'id': 'ASWF-Digital-Assets-1.0', 'deprecated': False},
|
| 65 |
+
'aswf-digital-assets-1.1': {'id': 'ASWF-Digital-Assets-1.1', 'deprecated': False},
|
| 66 |
+
'baekmuk': {'id': 'Baekmuk', 'deprecated': False},
|
| 67 |
+
'bahyph': {'id': 'Bahyph', 'deprecated': False},
|
| 68 |
+
'barr': {'id': 'Barr', 'deprecated': False},
|
| 69 |
+
'bcrypt-solar-designer': {'id': 'bcrypt-Solar-Designer', 'deprecated': False},
|
| 70 |
+
'beerware': {'id': 'Beerware', 'deprecated': False},
|
| 71 |
+
'bitstream-charter': {'id': 'Bitstream-Charter', 'deprecated': False},
|
| 72 |
+
'bitstream-vera': {'id': 'Bitstream-Vera', 'deprecated': False},
|
| 73 |
+
'bittorrent-1.0': {'id': 'BitTorrent-1.0', 'deprecated': False},
|
| 74 |
+
'bittorrent-1.1': {'id': 'BitTorrent-1.1', 'deprecated': False},
|
| 75 |
+
'blessing': {'id': 'blessing', 'deprecated': False},
|
| 76 |
+
'blueoak-1.0.0': {'id': 'BlueOak-1.0.0', 'deprecated': False},
|
| 77 |
+
'boehm-gc': {'id': 'Boehm-GC', 'deprecated': False},
|
| 78 |
+
'borceux': {'id': 'Borceux', 'deprecated': False},
|
| 79 |
+
'brian-gladman-2-clause': {'id': 'Brian-Gladman-2-Clause', 'deprecated': False},
|
| 80 |
+
'brian-gladman-3-clause': {'id': 'Brian-Gladman-3-Clause', 'deprecated': False},
|
| 81 |
+
'bsd-1-clause': {'id': 'BSD-1-Clause', 'deprecated': False},
|
| 82 |
+
'bsd-2-clause': {'id': 'BSD-2-Clause', 'deprecated': False},
|
| 83 |
+
'bsd-2-clause-darwin': {'id': 'BSD-2-Clause-Darwin', 'deprecated': False},
|
| 84 |
+
'bsd-2-clause-first-lines': {'id': 'BSD-2-Clause-first-lines', 'deprecated': False},
|
| 85 |
+
'bsd-2-clause-freebsd': {'id': 'BSD-2-Clause-FreeBSD', 'deprecated': True},
|
| 86 |
+
'bsd-2-clause-netbsd': {'id': 'BSD-2-Clause-NetBSD', 'deprecated': True},
|
| 87 |
+
'bsd-2-clause-patent': {'id': 'BSD-2-Clause-Patent', 'deprecated': False},
|
| 88 |
+
'bsd-2-clause-views': {'id': 'BSD-2-Clause-Views', 'deprecated': False},
|
| 89 |
+
'bsd-3-clause': {'id': 'BSD-3-Clause', 'deprecated': False},
|
| 90 |
+
'bsd-3-clause-acpica': {'id': 'BSD-3-Clause-acpica', 'deprecated': False},
|
| 91 |
+
'bsd-3-clause-attribution': {'id': 'BSD-3-Clause-Attribution', 'deprecated': False},
|
| 92 |
+
'bsd-3-clause-clear': {'id': 'BSD-3-Clause-Clear', 'deprecated': False},
|
| 93 |
+
'bsd-3-clause-flex': {'id': 'BSD-3-Clause-flex', 'deprecated': False},
|
| 94 |
+
'bsd-3-clause-hp': {'id': 'BSD-3-Clause-HP', 'deprecated': False},
|
| 95 |
+
'bsd-3-clause-lbnl': {'id': 'BSD-3-Clause-LBNL', 'deprecated': False},
|
| 96 |
+
'bsd-3-clause-modification': {'id': 'BSD-3-Clause-Modification', 'deprecated': False},
|
| 97 |
+
'bsd-3-clause-no-military-license': {'id': 'BSD-3-Clause-No-Military-License', 'deprecated': False},
|
| 98 |
+
'bsd-3-clause-no-nuclear-license': {'id': 'BSD-3-Clause-No-Nuclear-License', 'deprecated': False},
|
| 99 |
+
'bsd-3-clause-no-nuclear-license-2014': {'id': 'BSD-3-Clause-No-Nuclear-License-2014', 'deprecated': False},
|
| 100 |
+
'bsd-3-clause-no-nuclear-warranty': {'id': 'BSD-3-Clause-No-Nuclear-Warranty', 'deprecated': False},
|
| 101 |
+
'bsd-3-clause-open-mpi': {'id': 'BSD-3-Clause-Open-MPI', 'deprecated': False},
|
| 102 |
+
'bsd-3-clause-sun': {'id': 'BSD-3-Clause-Sun', 'deprecated': False},
|
| 103 |
+
'bsd-4-clause': {'id': 'BSD-4-Clause', 'deprecated': False},
|
| 104 |
+
'bsd-4-clause-shortened': {'id': 'BSD-4-Clause-Shortened', 'deprecated': False},
|
| 105 |
+
'bsd-4-clause-uc': {'id': 'BSD-4-Clause-UC', 'deprecated': False},
|
| 106 |
+
'bsd-4.3reno': {'id': 'BSD-4.3RENO', 'deprecated': False},
|
| 107 |
+
'bsd-4.3tahoe': {'id': 'BSD-4.3TAHOE', 'deprecated': False},
|
| 108 |
+
'bsd-advertising-acknowledgement': {'id': 'BSD-Advertising-Acknowledgement', 'deprecated': False},
|
| 109 |
+
'bsd-attribution-hpnd-disclaimer': {'id': 'BSD-Attribution-HPND-disclaimer', 'deprecated': False},
|
| 110 |
+
'bsd-inferno-nettverk': {'id': 'BSD-Inferno-Nettverk', 'deprecated': False},
|
| 111 |
+
'bsd-protection': {'id': 'BSD-Protection', 'deprecated': False},
|
| 112 |
+
'bsd-source-beginning-file': {'id': 'BSD-Source-beginning-file', 'deprecated': False},
|
| 113 |
+
'bsd-source-code': {'id': 'BSD-Source-Code', 'deprecated': False},
|
| 114 |
+
'bsd-systemics': {'id': 'BSD-Systemics', 'deprecated': False},
|
| 115 |
+
'bsd-systemics-w3works': {'id': 'BSD-Systemics-W3Works', 'deprecated': False},
|
| 116 |
+
'bsl-1.0': {'id': 'BSL-1.0', 'deprecated': False},
|
| 117 |
+
'busl-1.1': {'id': 'BUSL-1.1', 'deprecated': False},
|
| 118 |
+
'bzip2-1.0.5': {'id': 'bzip2-1.0.5', 'deprecated': True},
|
| 119 |
+
'bzip2-1.0.6': {'id': 'bzip2-1.0.6', 'deprecated': False},
|
| 120 |
+
'c-uda-1.0': {'id': 'C-UDA-1.0', 'deprecated': False},
|
| 121 |
+
'cal-1.0': {'id': 'CAL-1.0', 'deprecated': False},
|
| 122 |
+
'cal-1.0-combined-work-exception': {'id': 'CAL-1.0-Combined-Work-Exception', 'deprecated': False},
|
| 123 |
+
'caldera': {'id': 'Caldera', 'deprecated': False},
|
| 124 |
+
'caldera-no-preamble': {'id': 'Caldera-no-preamble', 'deprecated': False},
|
| 125 |
+
'catharon': {'id': 'Catharon', 'deprecated': False},
|
| 126 |
+
'catosl-1.1': {'id': 'CATOSL-1.1', 'deprecated': False},
|
| 127 |
+
'cc-by-1.0': {'id': 'CC-BY-1.0', 'deprecated': False},
|
| 128 |
+
'cc-by-2.0': {'id': 'CC-BY-2.0', 'deprecated': False},
|
| 129 |
+
'cc-by-2.5': {'id': 'CC-BY-2.5', 'deprecated': False},
|
| 130 |
+
'cc-by-2.5-au': {'id': 'CC-BY-2.5-AU', 'deprecated': False},
|
| 131 |
+
'cc-by-3.0': {'id': 'CC-BY-3.0', 'deprecated': False},
|
| 132 |
+
'cc-by-3.0-at': {'id': 'CC-BY-3.0-AT', 'deprecated': False},
|
| 133 |
+
'cc-by-3.0-au': {'id': 'CC-BY-3.0-AU', 'deprecated': False},
|
| 134 |
+
'cc-by-3.0-de': {'id': 'CC-BY-3.0-DE', 'deprecated': False},
|
| 135 |
+
'cc-by-3.0-igo': {'id': 'CC-BY-3.0-IGO', 'deprecated': False},
|
| 136 |
+
'cc-by-3.0-nl': {'id': 'CC-BY-3.0-NL', 'deprecated': False},
|
| 137 |
+
'cc-by-3.0-us': {'id': 'CC-BY-3.0-US', 'deprecated': False},
|
| 138 |
+
'cc-by-4.0': {'id': 'CC-BY-4.0', 'deprecated': False},
|
| 139 |
+
'cc-by-nc-1.0': {'id': 'CC-BY-NC-1.0', 'deprecated': False},
|
| 140 |
+
'cc-by-nc-2.0': {'id': 'CC-BY-NC-2.0', 'deprecated': False},
|
| 141 |
+
'cc-by-nc-2.5': {'id': 'CC-BY-NC-2.5', 'deprecated': False},
|
| 142 |
+
'cc-by-nc-3.0': {'id': 'CC-BY-NC-3.0', 'deprecated': False},
|
| 143 |
+
'cc-by-nc-3.0-de': {'id': 'CC-BY-NC-3.0-DE', 'deprecated': False},
|
| 144 |
+
'cc-by-nc-4.0': {'id': 'CC-BY-NC-4.0', 'deprecated': False},
|
| 145 |
+
'cc-by-nc-nd-1.0': {'id': 'CC-BY-NC-ND-1.0', 'deprecated': False},
|
| 146 |
+
'cc-by-nc-nd-2.0': {'id': 'CC-BY-NC-ND-2.0', 'deprecated': False},
|
| 147 |
+
'cc-by-nc-nd-2.5': {'id': 'CC-BY-NC-ND-2.5', 'deprecated': False},
|
| 148 |
+
'cc-by-nc-nd-3.0': {'id': 'CC-BY-NC-ND-3.0', 'deprecated': False},
|
| 149 |
+
'cc-by-nc-nd-3.0-de': {'id': 'CC-BY-NC-ND-3.0-DE', 'deprecated': False},
|
| 150 |
+
'cc-by-nc-nd-3.0-igo': {'id': 'CC-BY-NC-ND-3.0-IGO', 'deprecated': False},
|
| 151 |
+
'cc-by-nc-nd-4.0': {'id': 'CC-BY-NC-ND-4.0', 'deprecated': False},
|
| 152 |
+
'cc-by-nc-sa-1.0': {'id': 'CC-BY-NC-SA-1.0', 'deprecated': False},
|
| 153 |
+
'cc-by-nc-sa-2.0': {'id': 'CC-BY-NC-SA-2.0', 'deprecated': False},
|
| 154 |
+
'cc-by-nc-sa-2.0-de': {'id': 'CC-BY-NC-SA-2.0-DE', 'deprecated': False},
|
| 155 |
+
'cc-by-nc-sa-2.0-fr': {'id': 'CC-BY-NC-SA-2.0-FR', 'deprecated': False},
|
| 156 |
+
'cc-by-nc-sa-2.0-uk': {'id': 'CC-BY-NC-SA-2.0-UK', 'deprecated': False},
|
| 157 |
+
'cc-by-nc-sa-2.5': {'id': 'CC-BY-NC-SA-2.5', 'deprecated': False},
|
| 158 |
+
'cc-by-nc-sa-3.0': {'id': 'CC-BY-NC-SA-3.0', 'deprecated': False},
|
| 159 |
+
'cc-by-nc-sa-3.0-de': {'id': 'CC-BY-NC-SA-3.0-DE', 'deprecated': False},
|
| 160 |
+
'cc-by-nc-sa-3.0-igo': {'id': 'CC-BY-NC-SA-3.0-IGO', 'deprecated': False},
|
| 161 |
+
'cc-by-nc-sa-4.0': {'id': 'CC-BY-NC-SA-4.0', 'deprecated': False},
|
| 162 |
+
'cc-by-nd-1.0': {'id': 'CC-BY-ND-1.0', 'deprecated': False},
|
| 163 |
+
'cc-by-nd-2.0': {'id': 'CC-BY-ND-2.0', 'deprecated': False},
|
| 164 |
+
'cc-by-nd-2.5': {'id': 'CC-BY-ND-2.5', 'deprecated': False},
|
| 165 |
+
'cc-by-nd-3.0': {'id': 'CC-BY-ND-3.0', 'deprecated': False},
|
| 166 |
+
'cc-by-nd-3.0-de': {'id': 'CC-BY-ND-3.0-DE', 'deprecated': False},
|
| 167 |
+
'cc-by-nd-4.0': {'id': 'CC-BY-ND-4.0', 'deprecated': False},
|
| 168 |
+
'cc-by-sa-1.0': {'id': 'CC-BY-SA-1.0', 'deprecated': False},
|
| 169 |
+
'cc-by-sa-2.0': {'id': 'CC-BY-SA-2.0', 'deprecated': False},
|
| 170 |
+
'cc-by-sa-2.0-uk': {'id': 'CC-BY-SA-2.0-UK', 'deprecated': False},
|
| 171 |
+
'cc-by-sa-2.1-jp': {'id': 'CC-BY-SA-2.1-JP', 'deprecated': False},
|
| 172 |
+
'cc-by-sa-2.5': {'id': 'CC-BY-SA-2.5', 'deprecated': False},
|
| 173 |
+
'cc-by-sa-3.0': {'id': 'CC-BY-SA-3.0', 'deprecated': False},
|
| 174 |
+
'cc-by-sa-3.0-at': {'id': 'CC-BY-SA-3.0-AT', 'deprecated': False},
|
| 175 |
+
'cc-by-sa-3.0-de': {'id': 'CC-BY-SA-3.0-DE', 'deprecated': False},
|
| 176 |
+
'cc-by-sa-3.0-igo': {'id': 'CC-BY-SA-3.0-IGO', 'deprecated': False},
|
| 177 |
+
'cc-by-sa-4.0': {'id': 'CC-BY-SA-4.0', 'deprecated': False},
|
| 178 |
+
'cc-pddc': {'id': 'CC-PDDC', 'deprecated': False},
|
| 179 |
+
'cc0-1.0': {'id': 'CC0-1.0', 'deprecated': False},
|
| 180 |
+
'cddl-1.0': {'id': 'CDDL-1.0', 'deprecated': False},
|
| 181 |
+
'cddl-1.1': {'id': 'CDDL-1.1', 'deprecated': False},
|
| 182 |
+
'cdl-1.0': {'id': 'CDL-1.0', 'deprecated': False},
|
| 183 |
+
'cdla-permissive-1.0': {'id': 'CDLA-Permissive-1.0', 'deprecated': False},
|
| 184 |
+
'cdla-permissive-2.0': {'id': 'CDLA-Permissive-2.0', 'deprecated': False},
|
| 185 |
+
'cdla-sharing-1.0': {'id': 'CDLA-Sharing-1.0', 'deprecated': False},
|
| 186 |
+
'cecill-1.0': {'id': 'CECILL-1.0', 'deprecated': False},
|
| 187 |
+
'cecill-1.1': {'id': 'CECILL-1.1', 'deprecated': False},
|
| 188 |
+
'cecill-2.0': {'id': 'CECILL-2.0', 'deprecated': False},
|
| 189 |
+
'cecill-2.1': {'id': 'CECILL-2.1', 'deprecated': False},
|
| 190 |
+
'cecill-b': {'id': 'CECILL-B', 'deprecated': False},
|
| 191 |
+
'cecill-c': {'id': 'CECILL-C', 'deprecated': False},
|
| 192 |
+
'cern-ohl-1.1': {'id': 'CERN-OHL-1.1', 'deprecated': False},
|
| 193 |
+
'cern-ohl-1.2': {'id': 'CERN-OHL-1.2', 'deprecated': False},
|
| 194 |
+
'cern-ohl-p-2.0': {'id': 'CERN-OHL-P-2.0', 'deprecated': False},
|
| 195 |
+
'cern-ohl-s-2.0': {'id': 'CERN-OHL-S-2.0', 'deprecated': False},
|
| 196 |
+
'cern-ohl-w-2.0': {'id': 'CERN-OHL-W-2.0', 'deprecated': False},
|
| 197 |
+
'cfitsio': {'id': 'CFITSIO', 'deprecated': False},
|
| 198 |
+
'check-cvs': {'id': 'check-cvs', 'deprecated': False},
|
| 199 |
+
'checkmk': {'id': 'checkmk', 'deprecated': False},
|
| 200 |
+
'clartistic': {'id': 'ClArtistic', 'deprecated': False},
|
| 201 |
+
'clips': {'id': 'Clips', 'deprecated': False},
|
| 202 |
+
'cmu-mach': {'id': 'CMU-Mach', 'deprecated': False},
|
| 203 |
+
'cmu-mach-nodoc': {'id': 'CMU-Mach-nodoc', 'deprecated': False},
|
| 204 |
+
'cnri-jython': {'id': 'CNRI-Jython', 'deprecated': False},
|
| 205 |
+
'cnri-python': {'id': 'CNRI-Python', 'deprecated': False},
|
| 206 |
+
'cnri-python-gpl-compatible': {'id': 'CNRI-Python-GPL-Compatible', 'deprecated': False},
|
| 207 |
+
'coil-1.0': {'id': 'COIL-1.0', 'deprecated': False},
|
| 208 |
+
'community-spec-1.0': {'id': 'Community-Spec-1.0', 'deprecated': False},
|
| 209 |
+
'condor-1.1': {'id': 'Condor-1.1', 'deprecated': False},
|
| 210 |
+
'copyleft-next-0.3.0': {'id': 'copyleft-next-0.3.0', 'deprecated': False},
|
| 211 |
+
'copyleft-next-0.3.1': {'id': 'copyleft-next-0.3.1', 'deprecated': False},
|
| 212 |
+
'cornell-lossless-jpeg': {'id': 'Cornell-Lossless-JPEG', 'deprecated': False},
|
| 213 |
+
'cpal-1.0': {'id': 'CPAL-1.0', 'deprecated': False},
|
| 214 |
+
'cpl-1.0': {'id': 'CPL-1.0', 'deprecated': False},
|
| 215 |
+
'cpol-1.02': {'id': 'CPOL-1.02', 'deprecated': False},
|
| 216 |
+
'cronyx': {'id': 'Cronyx', 'deprecated': False},
|
| 217 |
+
'crossword': {'id': 'Crossword', 'deprecated': False},
|
| 218 |
+
'crystalstacker': {'id': 'CrystalStacker', 'deprecated': False},
|
| 219 |
+
'cua-opl-1.0': {'id': 'CUA-OPL-1.0', 'deprecated': False},
|
| 220 |
+
'cube': {'id': 'Cube', 'deprecated': False},
|
| 221 |
+
'curl': {'id': 'curl', 'deprecated': False},
|
| 222 |
+
'cve-tou': {'id': 'cve-tou', 'deprecated': False},
|
| 223 |
+
'd-fsl-1.0': {'id': 'D-FSL-1.0', 'deprecated': False},
|
| 224 |
+
'dec-3-clause': {'id': 'DEC-3-Clause', 'deprecated': False},
|
| 225 |
+
'diffmark': {'id': 'diffmark', 'deprecated': False},
|
| 226 |
+
'dl-de-by-2.0': {'id': 'DL-DE-BY-2.0', 'deprecated': False},
|
| 227 |
+
'dl-de-zero-2.0': {'id': 'DL-DE-ZERO-2.0', 'deprecated': False},
|
| 228 |
+
'doc': {'id': 'DOC', 'deprecated': False},
|
| 229 |
+
'docbook-schema': {'id': 'DocBook-Schema', 'deprecated': False},
|
| 230 |
+
'docbook-xml': {'id': 'DocBook-XML', 'deprecated': False},
|
| 231 |
+
'dotseqn': {'id': 'Dotseqn', 'deprecated': False},
|
| 232 |
+
'drl-1.0': {'id': 'DRL-1.0', 'deprecated': False},
|
| 233 |
+
'drl-1.1': {'id': 'DRL-1.1', 'deprecated': False},
|
| 234 |
+
'dsdp': {'id': 'DSDP', 'deprecated': False},
|
| 235 |
+
'dtoa': {'id': 'dtoa', 'deprecated': False},
|
| 236 |
+
'dvipdfm': {'id': 'dvipdfm', 'deprecated': False},
|
| 237 |
+
'ecl-1.0': {'id': 'ECL-1.0', 'deprecated': False},
|
| 238 |
+
'ecl-2.0': {'id': 'ECL-2.0', 'deprecated': False},
|
| 239 |
+
'ecos-2.0': {'id': 'eCos-2.0', 'deprecated': True},
|
| 240 |
+
'efl-1.0': {'id': 'EFL-1.0', 'deprecated': False},
|
| 241 |
+
'efl-2.0': {'id': 'EFL-2.0', 'deprecated': False},
|
| 242 |
+
'egenix': {'id': 'eGenix', 'deprecated': False},
|
| 243 |
+
'elastic-2.0': {'id': 'Elastic-2.0', 'deprecated': False},
|
| 244 |
+
'entessa': {'id': 'Entessa', 'deprecated': False},
|
| 245 |
+
'epics': {'id': 'EPICS', 'deprecated': False},
|
| 246 |
+
'epl-1.0': {'id': 'EPL-1.0', 'deprecated': False},
|
| 247 |
+
'epl-2.0': {'id': 'EPL-2.0', 'deprecated': False},
|
| 248 |
+
'erlpl-1.1': {'id': 'ErlPL-1.1', 'deprecated': False},
|
| 249 |
+
'etalab-2.0': {'id': 'etalab-2.0', 'deprecated': False},
|
| 250 |
+
'eudatagrid': {'id': 'EUDatagrid', 'deprecated': False},
|
| 251 |
+
'eupl-1.0': {'id': 'EUPL-1.0', 'deprecated': False},
|
| 252 |
+
'eupl-1.1': {'id': 'EUPL-1.1', 'deprecated': False},
|
| 253 |
+
'eupl-1.2': {'id': 'EUPL-1.2', 'deprecated': False},
|
| 254 |
+
'eurosym': {'id': 'Eurosym', 'deprecated': False},
|
| 255 |
+
'fair': {'id': 'Fair', 'deprecated': False},
|
| 256 |
+
'fbm': {'id': 'FBM', 'deprecated': False},
|
| 257 |
+
'fdk-aac': {'id': 'FDK-AAC', 'deprecated': False},
|
| 258 |
+
'ferguson-twofish': {'id': 'Ferguson-Twofish', 'deprecated': False},
|
| 259 |
+
'frameworx-1.0': {'id': 'Frameworx-1.0', 'deprecated': False},
|
| 260 |
+
'freebsd-doc': {'id': 'FreeBSD-DOC', 'deprecated': False},
|
| 261 |
+
'freeimage': {'id': 'FreeImage', 'deprecated': False},
|
| 262 |
+
'fsfap': {'id': 'FSFAP', 'deprecated': False},
|
| 263 |
+
'fsfap-no-warranty-disclaimer': {'id': 'FSFAP-no-warranty-disclaimer', 'deprecated': False},
|
| 264 |
+
'fsful': {'id': 'FSFUL', 'deprecated': False},
|
| 265 |
+
'fsfullr': {'id': 'FSFULLR', 'deprecated': False},
|
| 266 |
+
'fsfullrwd': {'id': 'FSFULLRWD', 'deprecated': False},
|
| 267 |
+
'ftl': {'id': 'FTL', 'deprecated': False},
|
| 268 |
+
'furuseth': {'id': 'Furuseth', 'deprecated': False},
|
| 269 |
+
'fwlw': {'id': 'fwlw', 'deprecated': False},
|
| 270 |
+
'gcr-docs': {'id': 'GCR-docs', 'deprecated': False},
|
| 271 |
+
'gd': {'id': 'GD', 'deprecated': False},
|
| 272 |
+
'gfdl-1.1': {'id': 'GFDL-1.1', 'deprecated': True},
|
| 273 |
+
'gfdl-1.1-invariants-only': {'id': 'GFDL-1.1-invariants-only', 'deprecated': False},
|
| 274 |
+
'gfdl-1.1-invariants-or-later': {'id': 'GFDL-1.1-invariants-or-later', 'deprecated': False},
|
| 275 |
+
'gfdl-1.1-no-invariants-only': {'id': 'GFDL-1.1-no-invariants-only', 'deprecated': False},
|
| 276 |
+
'gfdl-1.1-no-invariants-or-later': {'id': 'GFDL-1.1-no-invariants-or-later', 'deprecated': False},
|
| 277 |
+
'gfdl-1.1-only': {'id': 'GFDL-1.1-only', 'deprecated': False},
|
| 278 |
+
'gfdl-1.1-or-later': {'id': 'GFDL-1.1-or-later', 'deprecated': False},
|
| 279 |
+
'gfdl-1.2': {'id': 'GFDL-1.2', 'deprecated': True},
|
| 280 |
+
'gfdl-1.2-invariants-only': {'id': 'GFDL-1.2-invariants-only', 'deprecated': False},
|
| 281 |
+
'gfdl-1.2-invariants-or-later': {'id': 'GFDL-1.2-invariants-or-later', 'deprecated': False},
|
| 282 |
+
'gfdl-1.2-no-invariants-only': {'id': 'GFDL-1.2-no-invariants-only', 'deprecated': False},
|
| 283 |
+
'gfdl-1.2-no-invariants-or-later': {'id': 'GFDL-1.2-no-invariants-or-later', 'deprecated': False},
|
| 284 |
+
'gfdl-1.2-only': {'id': 'GFDL-1.2-only', 'deprecated': False},
|
| 285 |
+
'gfdl-1.2-or-later': {'id': 'GFDL-1.2-or-later', 'deprecated': False},
|
| 286 |
+
'gfdl-1.3': {'id': 'GFDL-1.3', 'deprecated': True},
|
| 287 |
+
'gfdl-1.3-invariants-only': {'id': 'GFDL-1.3-invariants-only', 'deprecated': False},
|
| 288 |
+
'gfdl-1.3-invariants-or-later': {'id': 'GFDL-1.3-invariants-or-later', 'deprecated': False},
|
| 289 |
+
'gfdl-1.3-no-invariants-only': {'id': 'GFDL-1.3-no-invariants-only', 'deprecated': False},
|
| 290 |
+
'gfdl-1.3-no-invariants-or-later': {'id': 'GFDL-1.3-no-invariants-or-later', 'deprecated': False},
|
| 291 |
+
'gfdl-1.3-only': {'id': 'GFDL-1.3-only', 'deprecated': False},
|
| 292 |
+
'gfdl-1.3-or-later': {'id': 'GFDL-1.3-or-later', 'deprecated': False},
|
| 293 |
+
'giftware': {'id': 'Giftware', 'deprecated': False},
|
| 294 |
+
'gl2ps': {'id': 'GL2PS', 'deprecated': False},
|
| 295 |
+
'glide': {'id': 'Glide', 'deprecated': False},
|
| 296 |
+
'glulxe': {'id': 'Glulxe', 'deprecated': False},
|
| 297 |
+
'glwtpl': {'id': 'GLWTPL', 'deprecated': False},
|
| 298 |
+
'gnuplot': {'id': 'gnuplot', 'deprecated': False},
|
| 299 |
+
'gpl-1.0': {'id': 'GPL-1.0', 'deprecated': True},
|
| 300 |
+
'gpl-1.0+': {'id': 'GPL-1.0+', 'deprecated': True},
|
| 301 |
+
'gpl-1.0-only': {'id': 'GPL-1.0-only', 'deprecated': False},
|
| 302 |
+
'gpl-1.0-or-later': {'id': 'GPL-1.0-or-later', 'deprecated': False},
|
| 303 |
+
'gpl-2.0': {'id': 'GPL-2.0', 'deprecated': True},
|
| 304 |
+
'gpl-2.0+': {'id': 'GPL-2.0+', 'deprecated': True},
|
| 305 |
+
'gpl-2.0-only': {'id': 'GPL-2.0-only', 'deprecated': False},
|
| 306 |
+
'gpl-2.0-or-later': {'id': 'GPL-2.0-or-later', 'deprecated': False},
|
| 307 |
+
'gpl-2.0-with-autoconf-exception': {'id': 'GPL-2.0-with-autoconf-exception', 'deprecated': True},
|
| 308 |
+
'gpl-2.0-with-bison-exception': {'id': 'GPL-2.0-with-bison-exception', 'deprecated': True},
|
| 309 |
+
'gpl-2.0-with-classpath-exception': {'id': 'GPL-2.0-with-classpath-exception', 'deprecated': True},
|
| 310 |
+
'gpl-2.0-with-font-exception': {'id': 'GPL-2.0-with-font-exception', 'deprecated': True},
|
| 311 |
+
'gpl-2.0-with-gcc-exception': {'id': 'GPL-2.0-with-GCC-exception', 'deprecated': True},
|
| 312 |
+
'gpl-3.0': {'id': 'GPL-3.0', 'deprecated': True},
|
| 313 |
+
'gpl-3.0+': {'id': 'GPL-3.0+', 'deprecated': True},
|
| 314 |
+
'gpl-3.0-only': {'id': 'GPL-3.0-only', 'deprecated': False},
|
| 315 |
+
'gpl-3.0-or-later': {'id': 'GPL-3.0-or-later', 'deprecated': False},
|
| 316 |
+
'gpl-3.0-with-autoconf-exception': {'id': 'GPL-3.0-with-autoconf-exception', 'deprecated': True},
|
| 317 |
+
'gpl-3.0-with-gcc-exception': {'id': 'GPL-3.0-with-GCC-exception', 'deprecated': True},
|
| 318 |
+
'graphics-gems': {'id': 'Graphics-Gems', 'deprecated': False},
|
| 319 |
+
'gsoap-1.3b': {'id': 'gSOAP-1.3b', 'deprecated': False},
|
| 320 |
+
'gtkbook': {'id': 'gtkbook', 'deprecated': False},
|
| 321 |
+
'gutmann': {'id': 'Gutmann', 'deprecated': False},
|
| 322 |
+
'haskellreport': {'id': 'HaskellReport', 'deprecated': False},
|
| 323 |
+
'hdparm': {'id': 'hdparm', 'deprecated': False},
|
| 324 |
+
'hidapi': {'id': 'HIDAPI', 'deprecated': False},
|
| 325 |
+
'hippocratic-2.1': {'id': 'Hippocratic-2.1', 'deprecated': False},
|
| 326 |
+
'hp-1986': {'id': 'HP-1986', 'deprecated': False},
|
| 327 |
+
'hp-1989': {'id': 'HP-1989', 'deprecated': False},
|
| 328 |
+
'hpnd': {'id': 'HPND', 'deprecated': False},
|
| 329 |
+
'hpnd-dec': {'id': 'HPND-DEC', 'deprecated': False},
|
| 330 |
+
'hpnd-doc': {'id': 'HPND-doc', 'deprecated': False},
|
| 331 |
+
'hpnd-doc-sell': {'id': 'HPND-doc-sell', 'deprecated': False},
|
| 332 |
+
'hpnd-export-us': {'id': 'HPND-export-US', 'deprecated': False},
|
| 333 |
+
'hpnd-export-us-acknowledgement': {'id': 'HPND-export-US-acknowledgement', 'deprecated': False},
|
| 334 |
+
'hpnd-export-us-modify': {'id': 'HPND-export-US-modify', 'deprecated': False},
|
| 335 |
+
'hpnd-export2-us': {'id': 'HPND-export2-US', 'deprecated': False},
|
| 336 |
+
'hpnd-fenneberg-livingston': {'id': 'HPND-Fenneberg-Livingston', 'deprecated': False},
|
| 337 |
+
'hpnd-inria-imag': {'id': 'HPND-INRIA-IMAG', 'deprecated': False},
|
| 338 |
+
'hpnd-intel': {'id': 'HPND-Intel', 'deprecated': False},
|
| 339 |
+
'hpnd-kevlin-henney': {'id': 'HPND-Kevlin-Henney', 'deprecated': False},
|
| 340 |
+
'hpnd-markus-kuhn': {'id': 'HPND-Markus-Kuhn', 'deprecated': False},
|
| 341 |
+
'hpnd-merchantability-variant': {'id': 'HPND-merchantability-variant', 'deprecated': False},
|
| 342 |
+
'hpnd-mit-disclaimer': {'id': 'HPND-MIT-disclaimer', 'deprecated': False},
|
| 343 |
+
'hpnd-netrek': {'id': 'HPND-Netrek', 'deprecated': False},
|
| 344 |
+
'hpnd-pbmplus': {'id': 'HPND-Pbmplus', 'deprecated': False},
|
| 345 |
+
'hpnd-sell-mit-disclaimer-xserver': {'id': 'HPND-sell-MIT-disclaimer-xserver', 'deprecated': False},
|
| 346 |
+
'hpnd-sell-regexpr': {'id': 'HPND-sell-regexpr', 'deprecated': False},
|
| 347 |
+
'hpnd-sell-variant': {'id': 'HPND-sell-variant', 'deprecated': False},
|
| 348 |
+
'hpnd-sell-variant-mit-disclaimer': {'id': 'HPND-sell-variant-MIT-disclaimer', 'deprecated': False},
|
| 349 |
+
'hpnd-sell-variant-mit-disclaimer-rev': {'id': 'HPND-sell-variant-MIT-disclaimer-rev', 'deprecated': False},
|
| 350 |
+
'hpnd-uc': {'id': 'HPND-UC', 'deprecated': False},
|
| 351 |
+
'hpnd-uc-export-us': {'id': 'HPND-UC-export-US', 'deprecated': False},
|
| 352 |
+
'htmltidy': {'id': 'HTMLTIDY', 'deprecated': False},
|
| 353 |
+
'ibm-pibs': {'id': 'IBM-pibs', 'deprecated': False},
|
| 354 |
+
'icu': {'id': 'ICU', 'deprecated': False},
|
| 355 |
+
'iec-code-components-eula': {'id': 'IEC-Code-Components-EULA', 'deprecated': False},
|
| 356 |
+
'ijg': {'id': 'IJG', 'deprecated': False},
|
| 357 |
+
'ijg-short': {'id': 'IJG-short', 'deprecated': False},
|
| 358 |
+
'imagemagick': {'id': 'ImageMagick', 'deprecated': False},
|
| 359 |
+
'imatix': {'id': 'iMatix', 'deprecated': False},
|
| 360 |
+
'imlib2': {'id': 'Imlib2', 'deprecated': False},
|
| 361 |
+
'info-zip': {'id': 'Info-ZIP', 'deprecated': False},
|
| 362 |
+
'inner-net-2.0': {'id': 'Inner-Net-2.0', 'deprecated': False},
|
| 363 |
+
'intel': {'id': 'Intel', 'deprecated': False},
|
| 364 |
+
'intel-acpi': {'id': 'Intel-ACPI', 'deprecated': False},
|
| 365 |
+
'interbase-1.0': {'id': 'Interbase-1.0', 'deprecated': False},
|
| 366 |
+
'ipa': {'id': 'IPA', 'deprecated': False},
|
| 367 |
+
'ipl-1.0': {'id': 'IPL-1.0', 'deprecated': False},
|
| 368 |
+
'isc': {'id': 'ISC', 'deprecated': False},
|
| 369 |
+
'isc-veillard': {'id': 'ISC-Veillard', 'deprecated': False},
|
| 370 |
+
'jam': {'id': 'Jam', 'deprecated': False},
|
| 371 |
+
'jasper-2.0': {'id': 'JasPer-2.0', 'deprecated': False},
|
| 372 |
+
'jpl-image': {'id': 'JPL-image', 'deprecated': False},
|
| 373 |
+
'jpnic': {'id': 'JPNIC', 'deprecated': False},
|
| 374 |
+
'json': {'id': 'JSON', 'deprecated': False},
|
| 375 |
+
'kastrup': {'id': 'Kastrup', 'deprecated': False},
|
| 376 |
+
'kazlib': {'id': 'Kazlib', 'deprecated': False},
|
| 377 |
+
'knuth-ctan': {'id': 'Knuth-CTAN', 'deprecated': False},
|
| 378 |
+
'lal-1.2': {'id': 'LAL-1.2', 'deprecated': False},
|
| 379 |
+
'lal-1.3': {'id': 'LAL-1.3', 'deprecated': False},
|
| 380 |
+
'latex2e': {'id': 'Latex2e', 'deprecated': False},
|
| 381 |
+
'latex2e-translated-notice': {'id': 'Latex2e-translated-notice', 'deprecated': False},
|
| 382 |
+
'leptonica': {'id': 'Leptonica', 'deprecated': False},
|
| 383 |
+
'lgpl-2.0': {'id': 'LGPL-2.0', 'deprecated': True},
|
| 384 |
+
'lgpl-2.0+': {'id': 'LGPL-2.0+', 'deprecated': True},
|
| 385 |
+
'lgpl-2.0-only': {'id': 'LGPL-2.0-only', 'deprecated': False},
|
| 386 |
+
'lgpl-2.0-or-later': {'id': 'LGPL-2.0-or-later', 'deprecated': False},
|
| 387 |
+
'lgpl-2.1': {'id': 'LGPL-2.1', 'deprecated': True},
|
| 388 |
+
'lgpl-2.1+': {'id': 'LGPL-2.1+', 'deprecated': True},
|
| 389 |
+
'lgpl-2.1-only': {'id': 'LGPL-2.1-only', 'deprecated': False},
|
| 390 |
+
'lgpl-2.1-or-later': {'id': 'LGPL-2.1-or-later', 'deprecated': False},
|
| 391 |
+
'lgpl-3.0': {'id': 'LGPL-3.0', 'deprecated': True},
|
| 392 |
+
'lgpl-3.0+': {'id': 'LGPL-3.0+', 'deprecated': True},
|
| 393 |
+
'lgpl-3.0-only': {'id': 'LGPL-3.0-only', 'deprecated': False},
|
| 394 |
+
'lgpl-3.0-or-later': {'id': 'LGPL-3.0-or-later', 'deprecated': False},
|
| 395 |
+
'lgpllr': {'id': 'LGPLLR', 'deprecated': False},
|
| 396 |
+
'libpng': {'id': 'Libpng', 'deprecated': False},
|
| 397 |
+
'libpng-2.0': {'id': 'libpng-2.0', 'deprecated': False},
|
| 398 |
+
'libselinux-1.0': {'id': 'libselinux-1.0', 'deprecated': False},
|
| 399 |
+
'libtiff': {'id': 'libtiff', 'deprecated': False},
|
| 400 |
+
'libutil-david-nugent': {'id': 'libutil-David-Nugent', 'deprecated': False},
|
| 401 |
+
'liliq-p-1.1': {'id': 'LiLiQ-P-1.1', 'deprecated': False},
|
| 402 |
+
'liliq-r-1.1': {'id': 'LiLiQ-R-1.1', 'deprecated': False},
|
| 403 |
+
'liliq-rplus-1.1': {'id': 'LiLiQ-Rplus-1.1', 'deprecated': False},
|
| 404 |
+
'linux-man-pages-1-para': {'id': 'Linux-man-pages-1-para', 'deprecated': False},
|
| 405 |
+
'linux-man-pages-copyleft': {'id': 'Linux-man-pages-copyleft', 'deprecated': False},
|
| 406 |
+
'linux-man-pages-copyleft-2-para': {'id': 'Linux-man-pages-copyleft-2-para', 'deprecated': False},
|
| 407 |
+
'linux-man-pages-copyleft-var': {'id': 'Linux-man-pages-copyleft-var', 'deprecated': False},
|
| 408 |
+
'linux-openib': {'id': 'Linux-OpenIB', 'deprecated': False},
|
| 409 |
+
'loop': {'id': 'LOOP', 'deprecated': False},
|
| 410 |
+
'lpd-document': {'id': 'LPD-document', 'deprecated': False},
|
| 411 |
+
'lpl-1.0': {'id': 'LPL-1.0', 'deprecated': False},
|
| 412 |
+
'lpl-1.02': {'id': 'LPL-1.02', 'deprecated': False},
|
| 413 |
+
'lppl-1.0': {'id': 'LPPL-1.0', 'deprecated': False},
|
| 414 |
+
'lppl-1.1': {'id': 'LPPL-1.1', 'deprecated': False},
|
| 415 |
+
'lppl-1.2': {'id': 'LPPL-1.2', 'deprecated': False},
|
| 416 |
+
'lppl-1.3a': {'id': 'LPPL-1.3a', 'deprecated': False},
|
| 417 |
+
'lppl-1.3c': {'id': 'LPPL-1.3c', 'deprecated': False},
|
| 418 |
+
'lsof': {'id': 'lsof', 'deprecated': False},
|
| 419 |
+
'lucida-bitmap-fonts': {'id': 'Lucida-Bitmap-Fonts', 'deprecated': False},
|
| 420 |
+
'lzma-sdk-9.11-to-9.20': {'id': 'LZMA-SDK-9.11-to-9.20', 'deprecated': False},
|
| 421 |
+
'lzma-sdk-9.22': {'id': 'LZMA-SDK-9.22', 'deprecated': False},
|
| 422 |
+
'mackerras-3-clause': {'id': 'Mackerras-3-Clause', 'deprecated': False},
|
| 423 |
+
'mackerras-3-clause-acknowledgment': {'id': 'Mackerras-3-Clause-acknowledgment', 'deprecated': False},
|
| 424 |
+
'magaz': {'id': 'magaz', 'deprecated': False},
|
| 425 |
+
'mailprio': {'id': 'mailprio', 'deprecated': False},
|
| 426 |
+
'makeindex': {'id': 'MakeIndex', 'deprecated': False},
|
| 427 |
+
'martin-birgmeier': {'id': 'Martin-Birgmeier', 'deprecated': False},
|
| 428 |
+
'mcphee-slideshow': {'id': 'McPhee-slideshow', 'deprecated': False},
|
| 429 |
+
'metamail': {'id': 'metamail', 'deprecated': False},
|
| 430 |
+
'minpack': {'id': 'Minpack', 'deprecated': False},
|
| 431 |
+
'miros': {'id': 'MirOS', 'deprecated': False},
|
| 432 |
+
'mit': {'id': 'MIT', 'deprecated': False},
|
| 433 |
+
'mit-0': {'id': 'MIT-0', 'deprecated': False},
|
| 434 |
+
'mit-advertising': {'id': 'MIT-advertising', 'deprecated': False},
|
| 435 |
+
'mit-cmu': {'id': 'MIT-CMU', 'deprecated': False},
|
| 436 |
+
'mit-enna': {'id': 'MIT-enna', 'deprecated': False},
|
| 437 |
+
'mit-feh': {'id': 'MIT-feh', 'deprecated': False},
|
| 438 |
+
'mit-festival': {'id': 'MIT-Festival', 'deprecated': False},
|
| 439 |
+
'mit-khronos-old': {'id': 'MIT-Khronos-old', 'deprecated': False},
|
| 440 |
+
'mit-modern-variant': {'id': 'MIT-Modern-Variant', 'deprecated': False},
|
| 441 |
+
'mit-open-group': {'id': 'MIT-open-group', 'deprecated': False},
|
| 442 |
+
'mit-testregex': {'id': 'MIT-testregex', 'deprecated': False},
|
| 443 |
+
'mit-wu': {'id': 'MIT-Wu', 'deprecated': False},
|
| 444 |
+
'mitnfa': {'id': 'MITNFA', 'deprecated': False},
|
| 445 |
+
'mmixware': {'id': 'MMIXware', 'deprecated': False},
|
| 446 |
+
'motosoto': {'id': 'Motosoto', 'deprecated': False},
|
| 447 |
+
'mpeg-ssg': {'id': 'MPEG-SSG', 'deprecated': False},
|
| 448 |
+
'mpi-permissive': {'id': 'mpi-permissive', 'deprecated': False},
|
| 449 |
+
'mpich2': {'id': 'mpich2', 'deprecated': False},
|
| 450 |
+
'mpl-1.0': {'id': 'MPL-1.0', 'deprecated': False},
|
| 451 |
+
'mpl-1.1': {'id': 'MPL-1.1', 'deprecated': False},
|
| 452 |
+
'mpl-2.0': {'id': 'MPL-2.0', 'deprecated': False},
|
| 453 |
+
'mpl-2.0-no-copyleft-exception': {'id': 'MPL-2.0-no-copyleft-exception', 'deprecated': False},
|
| 454 |
+
'mplus': {'id': 'mplus', 'deprecated': False},
|
| 455 |
+
'ms-lpl': {'id': 'MS-LPL', 'deprecated': False},
|
| 456 |
+
'ms-pl': {'id': 'MS-PL', 'deprecated': False},
|
| 457 |
+
'ms-rl': {'id': 'MS-RL', 'deprecated': False},
|
| 458 |
+
'mtll': {'id': 'MTLL', 'deprecated': False},
|
| 459 |
+
'mulanpsl-1.0': {'id': 'MulanPSL-1.0', 'deprecated': False},
|
| 460 |
+
'mulanpsl-2.0': {'id': 'MulanPSL-2.0', 'deprecated': False},
|
| 461 |
+
'multics': {'id': 'Multics', 'deprecated': False},
|
| 462 |
+
'mup': {'id': 'Mup', 'deprecated': False},
|
| 463 |
+
'naist-2003': {'id': 'NAIST-2003', 'deprecated': False},
|
| 464 |
+
'nasa-1.3': {'id': 'NASA-1.3', 'deprecated': False},
|
| 465 |
+
'naumen': {'id': 'Naumen', 'deprecated': False},
|
| 466 |
+
'nbpl-1.0': {'id': 'NBPL-1.0', 'deprecated': False},
|
| 467 |
+
'ncbi-pd': {'id': 'NCBI-PD', 'deprecated': False},
|
| 468 |
+
'ncgl-uk-2.0': {'id': 'NCGL-UK-2.0', 'deprecated': False},
|
| 469 |
+
'ncl': {'id': 'NCL', 'deprecated': False},
|
| 470 |
+
'ncsa': {'id': 'NCSA', 'deprecated': False},
|
| 471 |
+
'net-snmp': {'id': 'Net-SNMP', 'deprecated': True},
|
| 472 |
+
'netcdf': {'id': 'NetCDF', 'deprecated': False},
|
| 473 |
+
'newsletr': {'id': 'Newsletr', 'deprecated': False},
|
| 474 |
+
'ngpl': {'id': 'NGPL', 'deprecated': False},
|
| 475 |
+
'nicta-1.0': {'id': 'NICTA-1.0', 'deprecated': False},
|
| 476 |
+
'nist-pd': {'id': 'NIST-PD', 'deprecated': False},
|
| 477 |
+
'nist-pd-fallback': {'id': 'NIST-PD-fallback', 'deprecated': False},
|
| 478 |
+
'nist-software': {'id': 'NIST-Software', 'deprecated': False},
|
| 479 |
+
'nlod-1.0': {'id': 'NLOD-1.0', 'deprecated': False},
|
| 480 |
+
'nlod-2.0': {'id': 'NLOD-2.0', 'deprecated': False},
|
| 481 |
+
'nlpl': {'id': 'NLPL', 'deprecated': False},
|
| 482 |
+
'nokia': {'id': 'Nokia', 'deprecated': False},
|
| 483 |
+
'nosl': {'id': 'NOSL', 'deprecated': False},
|
| 484 |
+
'noweb': {'id': 'Noweb', 'deprecated': False},
|
| 485 |
+
'npl-1.0': {'id': 'NPL-1.0', 'deprecated': False},
|
| 486 |
+
'npl-1.1': {'id': 'NPL-1.1', 'deprecated': False},
|
| 487 |
+
'nposl-3.0': {'id': 'NPOSL-3.0', 'deprecated': False},
|
| 488 |
+
'nrl': {'id': 'NRL', 'deprecated': False},
|
| 489 |
+
'ntp': {'id': 'NTP', 'deprecated': False},
|
| 490 |
+
'ntp-0': {'id': 'NTP-0', 'deprecated': False},
|
| 491 |
+
'nunit': {'id': 'Nunit', 'deprecated': True},
|
| 492 |
+
'o-uda-1.0': {'id': 'O-UDA-1.0', 'deprecated': False},
|
| 493 |
+
'oar': {'id': 'OAR', 'deprecated': False},
|
| 494 |
+
'occt-pl': {'id': 'OCCT-PL', 'deprecated': False},
|
| 495 |
+
'oclc-2.0': {'id': 'OCLC-2.0', 'deprecated': False},
|
| 496 |
+
'odbl-1.0': {'id': 'ODbL-1.0', 'deprecated': False},
|
| 497 |
+
'odc-by-1.0': {'id': 'ODC-By-1.0', 'deprecated': False},
|
| 498 |
+
'offis': {'id': 'OFFIS', 'deprecated': False},
|
| 499 |
+
'ofl-1.0': {'id': 'OFL-1.0', 'deprecated': False},
|
| 500 |
+
'ofl-1.0-no-rfn': {'id': 'OFL-1.0-no-RFN', 'deprecated': False},
|
| 501 |
+
'ofl-1.0-rfn': {'id': 'OFL-1.0-RFN', 'deprecated': False},
|
| 502 |
+
'ofl-1.1': {'id': 'OFL-1.1', 'deprecated': False},
|
| 503 |
+
'ofl-1.1-no-rfn': {'id': 'OFL-1.1-no-RFN', 'deprecated': False},
|
| 504 |
+
'ofl-1.1-rfn': {'id': 'OFL-1.1-RFN', 'deprecated': False},
|
| 505 |
+
'ogc-1.0': {'id': 'OGC-1.0', 'deprecated': False},
|
| 506 |
+
'ogdl-taiwan-1.0': {'id': 'OGDL-Taiwan-1.0', 'deprecated': False},
|
| 507 |
+
'ogl-canada-2.0': {'id': 'OGL-Canada-2.0', 'deprecated': False},
|
| 508 |
+
'ogl-uk-1.0': {'id': 'OGL-UK-1.0', 'deprecated': False},
|
| 509 |
+
'ogl-uk-2.0': {'id': 'OGL-UK-2.0', 'deprecated': False},
|
| 510 |
+
'ogl-uk-3.0': {'id': 'OGL-UK-3.0', 'deprecated': False},
|
| 511 |
+
'ogtsl': {'id': 'OGTSL', 'deprecated': False},
|
| 512 |
+
'oldap-1.1': {'id': 'OLDAP-1.1', 'deprecated': False},
|
| 513 |
+
'oldap-1.2': {'id': 'OLDAP-1.2', 'deprecated': False},
|
| 514 |
+
'oldap-1.3': {'id': 'OLDAP-1.3', 'deprecated': False},
|
| 515 |
+
'oldap-1.4': {'id': 'OLDAP-1.4', 'deprecated': False},
|
| 516 |
+
'oldap-2.0': {'id': 'OLDAP-2.0', 'deprecated': False},
|
| 517 |
+
'oldap-2.0.1': {'id': 'OLDAP-2.0.1', 'deprecated': False},
|
| 518 |
+
'oldap-2.1': {'id': 'OLDAP-2.1', 'deprecated': False},
|
| 519 |
+
'oldap-2.2': {'id': 'OLDAP-2.2', 'deprecated': False},
|
| 520 |
+
'oldap-2.2.1': {'id': 'OLDAP-2.2.1', 'deprecated': False},
|
| 521 |
+
'oldap-2.2.2': {'id': 'OLDAP-2.2.2', 'deprecated': False},
|
| 522 |
+
'oldap-2.3': {'id': 'OLDAP-2.3', 'deprecated': False},
|
| 523 |
+
'oldap-2.4': {'id': 'OLDAP-2.4', 'deprecated': False},
|
| 524 |
+
'oldap-2.5': {'id': 'OLDAP-2.5', 'deprecated': False},
|
| 525 |
+
'oldap-2.6': {'id': 'OLDAP-2.6', 'deprecated': False},
|
| 526 |
+
'oldap-2.7': {'id': 'OLDAP-2.7', 'deprecated': False},
|
| 527 |
+
'oldap-2.8': {'id': 'OLDAP-2.8', 'deprecated': False},
|
| 528 |
+
'olfl-1.3': {'id': 'OLFL-1.3', 'deprecated': False},
|
| 529 |
+
'oml': {'id': 'OML', 'deprecated': False},
|
| 530 |
+
'openpbs-2.3': {'id': 'OpenPBS-2.3', 'deprecated': False},
|
| 531 |
+
'openssl': {'id': 'OpenSSL', 'deprecated': False},
|
| 532 |
+
'openssl-standalone': {'id': 'OpenSSL-standalone', 'deprecated': False},
|
| 533 |
+
'openvision': {'id': 'OpenVision', 'deprecated': False},
|
| 534 |
+
'opl-1.0': {'id': 'OPL-1.0', 'deprecated': False},
|
| 535 |
+
'opl-uk-3.0': {'id': 'OPL-UK-3.0', 'deprecated': False},
|
| 536 |
+
'opubl-1.0': {'id': 'OPUBL-1.0', 'deprecated': False},
|
| 537 |
+
'oset-pl-2.1': {'id': 'OSET-PL-2.1', 'deprecated': False},
|
| 538 |
+
'osl-1.0': {'id': 'OSL-1.0', 'deprecated': False},
|
| 539 |
+
'osl-1.1': {'id': 'OSL-1.1', 'deprecated': False},
|
| 540 |
+
'osl-2.0': {'id': 'OSL-2.0', 'deprecated': False},
|
| 541 |
+
'osl-2.1': {'id': 'OSL-2.1', 'deprecated': False},
|
| 542 |
+
'osl-3.0': {'id': 'OSL-3.0', 'deprecated': False},
|
| 543 |
+
'padl': {'id': 'PADL', 'deprecated': False},
|
| 544 |
+
'parity-6.0.0': {'id': 'Parity-6.0.0', 'deprecated': False},
|
| 545 |
+
'parity-7.0.0': {'id': 'Parity-7.0.0', 'deprecated': False},
|
| 546 |
+
'pddl-1.0': {'id': 'PDDL-1.0', 'deprecated': False},
|
| 547 |
+
'php-3.0': {'id': 'PHP-3.0', 'deprecated': False},
|
| 548 |
+
'php-3.01': {'id': 'PHP-3.01', 'deprecated': False},
|
| 549 |
+
'pixar': {'id': 'Pixar', 'deprecated': False},
|
| 550 |
+
'pkgconf': {'id': 'pkgconf', 'deprecated': False},
|
| 551 |
+
'plexus': {'id': 'Plexus', 'deprecated': False},
|
| 552 |
+
'pnmstitch': {'id': 'pnmstitch', 'deprecated': False},
|
| 553 |
+
'polyform-noncommercial-1.0.0': {'id': 'PolyForm-Noncommercial-1.0.0', 'deprecated': False},
|
| 554 |
+
'polyform-small-business-1.0.0': {'id': 'PolyForm-Small-Business-1.0.0', 'deprecated': False},
|
| 555 |
+
'postgresql': {'id': 'PostgreSQL', 'deprecated': False},
|
| 556 |
+
'ppl': {'id': 'PPL', 'deprecated': False},
|
| 557 |
+
'psf-2.0': {'id': 'PSF-2.0', 'deprecated': False},
|
| 558 |
+
'psfrag': {'id': 'psfrag', 'deprecated': False},
|
| 559 |
+
'psutils': {'id': 'psutils', 'deprecated': False},
|
| 560 |
+
'python-2.0': {'id': 'Python-2.0', 'deprecated': False},
|
| 561 |
+
'python-2.0.1': {'id': 'Python-2.0.1', 'deprecated': False},
|
| 562 |
+
'python-ldap': {'id': 'python-ldap', 'deprecated': False},
|
| 563 |
+
'qhull': {'id': 'Qhull', 'deprecated': False},
|
| 564 |
+
'qpl-1.0': {'id': 'QPL-1.0', 'deprecated': False},
|
| 565 |
+
'qpl-1.0-inria-2004': {'id': 'QPL-1.0-INRIA-2004', 'deprecated': False},
|
| 566 |
+
'radvd': {'id': 'radvd', 'deprecated': False},
|
| 567 |
+
'rdisc': {'id': 'Rdisc', 'deprecated': False},
|
| 568 |
+
'rhecos-1.1': {'id': 'RHeCos-1.1', 'deprecated': False},
|
| 569 |
+
'rpl-1.1': {'id': 'RPL-1.1', 'deprecated': False},
|
| 570 |
+
'rpl-1.5': {'id': 'RPL-1.5', 'deprecated': False},
|
| 571 |
+
'rpsl-1.0': {'id': 'RPSL-1.0', 'deprecated': False},
|
| 572 |
+
'rsa-md': {'id': 'RSA-MD', 'deprecated': False},
|
| 573 |
+
'rscpl': {'id': 'RSCPL', 'deprecated': False},
|
| 574 |
+
'ruby': {'id': 'Ruby', 'deprecated': False},
|
| 575 |
+
'ruby-pty': {'id': 'Ruby-pty', 'deprecated': False},
|
| 576 |
+
'sax-pd': {'id': 'SAX-PD', 'deprecated': False},
|
| 577 |
+
'sax-pd-2.0': {'id': 'SAX-PD-2.0', 'deprecated': False},
|
| 578 |
+
'saxpath': {'id': 'Saxpath', 'deprecated': False},
|
| 579 |
+
'scea': {'id': 'SCEA', 'deprecated': False},
|
| 580 |
+
'schemereport': {'id': 'SchemeReport', 'deprecated': False},
|
| 581 |
+
'sendmail': {'id': 'Sendmail', 'deprecated': False},
|
| 582 |
+
'sendmail-8.23': {'id': 'Sendmail-8.23', 'deprecated': False},
|
| 583 |
+
'sgi-b-1.0': {'id': 'SGI-B-1.0', 'deprecated': False},
|
| 584 |
+
'sgi-b-1.1': {'id': 'SGI-B-1.1', 'deprecated': False},
|
| 585 |
+
'sgi-b-2.0': {'id': 'SGI-B-2.0', 'deprecated': False},
|
| 586 |
+
'sgi-opengl': {'id': 'SGI-OpenGL', 'deprecated': False},
|
| 587 |
+
'sgp4': {'id': 'SGP4', 'deprecated': False},
|
| 588 |
+
'shl-0.5': {'id': 'SHL-0.5', 'deprecated': False},
|
| 589 |
+
'shl-0.51': {'id': 'SHL-0.51', 'deprecated': False},
|
| 590 |
+
'simpl-2.0': {'id': 'SimPL-2.0', 'deprecated': False},
|
| 591 |
+
'sissl': {'id': 'SISSL', 'deprecated': False},
|
| 592 |
+
'sissl-1.2': {'id': 'SISSL-1.2', 'deprecated': False},
|
| 593 |
+
'sl': {'id': 'SL', 'deprecated': False},
|
| 594 |
+
'sleepycat': {'id': 'Sleepycat', 'deprecated': False},
|
| 595 |
+
'smlnj': {'id': 'SMLNJ', 'deprecated': False},
|
| 596 |
+
'smppl': {'id': 'SMPPL', 'deprecated': False},
|
| 597 |
+
'snia': {'id': 'SNIA', 'deprecated': False},
|
| 598 |
+
'snprintf': {'id': 'snprintf', 'deprecated': False},
|
| 599 |
+
'softsurfer': {'id': 'softSurfer', 'deprecated': False},
|
| 600 |
+
'soundex': {'id': 'Soundex', 'deprecated': False},
|
| 601 |
+
'spencer-86': {'id': 'Spencer-86', 'deprecated': False},
|
| 602 |
+
'spencer-94': {'id': 'Spencer-94', 'deprecated': False},
|
| 603 |
+
'spencer-99': {'id': 'Spencer-99', 'deprecated': False},
|
| 604 |
+
'spl-1.0': {'id': 'SPL-1.0', 'deprecated': False},
|
| 605 |
+
'ssh-keyscan': {'id': 'ssh-keyscan', 'deprecated': False},
|
| 606 |
+
'ssh-openssh': {'id': 'SSH-OpenSSH', 'deprecated': False},
|
| 607 |
+
'ssh-short': {'id': 'SSH-short', 'deprecated': False},
|
| 608 |
+
'ssleay-standalone': {'id': 'SSLeay-standalone', 'deprecated': False},
|
| 609 |
+
'sspl-1.0': {'id': 'SSPL-1.0', 'deprecated': False},
|
| 610 |
+
'standardml-nj': {'id': 'StandardML-NJ', 'deprecated': True},
|
| 611 |
+
'sugarcrm-1.1.3': {'id': 'SugarCRM-1.1.3', 'deprecated': False},
|
| 612 |
+
'sun-ppp': {'id': 'Sun-PPP', 'deprecated': False},
|
| 613 |
+
'sun-ppp-2000': {'id': 'Sun-PPP-2000', 'deprecated': False},
|
| 614 |
+
'sunpro': {'id': 'SunPro', 'deprecated': False},
|
| 615 |
+
'swl': {'id': 'SWL', 'deprecated': False},
|
| 616 |
+
'swrule': {'id': 'swrule', 'deprecated': False},
|
| 617 |
+
'symlinks': {'id': 'Symlinks', 'deprecated': False},
|
| 618 |
+
'tapr-ohl-1.0': {'id': 'TAPR-OHL-1.0', 'deprecated': False},
|
| 619 |
+
'tcl': {'id': 'TCL', 'deprecated': False},
|
| 620 |
+
'tcp-wrappers': {'id': 'TCP-wrappers', 'deprecated': False},
|
| 621 |
+
'termreadkey': {'id': 'TermReadKey', 'deprecated': False},
|
| 622 |
+
'tgppl-1.0': {'id': 'TGPPL-1.0', 'deprecated': False},
|
| 623 |
+
'threeparttable': {'id': 'threeparttable', 'deprecated': False},
|
| 624 |
+
'tmate': {'id': 'TMate', 'deprecated': False},
|
| 625 |
+
'torque-1.1': {'id': 'TORQUE-1.1', 'deprecated': False},
|
| 626 |
+
'tosl': {'id': 'TOSL', 'deprecated': False},
|
| 627 |
+
'tpdl': {'id': 'TPDL', 'deprecated': False},
|
| 628 |
+
'tpl-1.0': {'id': 'TPL-1.0', 'deprecated': False},
|
| 629 |
+
'ttwl': {'id': 'TTWL', 'deprecated': False},
|
| 630 |
+
'ttyp0': {'id': 'TTYP0', 'deprecated': False},
|
| 631 |
+
'tu-berlin-1.0': {'id': 'TU-Berlin-1.0', 'deprecated': False},
|
| 632 |
+
'tu-berlin-2.0': {'id': 'TU-Berlin-2.0', 'deprecated': False},
|
| 633 |
+
'ubuntu-font-1.0': {'id': 'Ubuntu-font-1.0', 'deprecated': False},
|
| 634 |
+
'ucar': {'id': 'UCAR', 'deprecated': False},
|
| 635 |
+
'ucl-1.0': {'id': 'UCL-1.0', 'deprecated': False},
|
| 636 |
+
'ulem': {'id': 'ulem', 'deprecated': False},
|
| 637 |
+
'umich-merit': {'id': 'UMich-Merit', 'deprecated': False},
|
| 638 |
+
'unicode-3.0': {'id': 'Unicode-3.0', 'deprecated': False},
|
| 639 |
+
'unicode-dfs-2015': {'id': 'Unicode-DFS-2015', 'deprecated': False},
|
| 640 |
+
'unicode-dfs-2016': {'id': 'Unicode-DFS-2016', 'deprecated': False},
|
| 641 |
+
'unicode-tou': {'id': 'Unicode-TOU', 'deprecated': False},
|
| 642 |
+
'unixcrypt': {'id': 'UnixCrypt', 'deprecated': False},
|
| 643 |
+
'unlicense': {'id': 'Unlicense', 'deprecated': False},
|
| 644 |
+
'upl-1.0': {'id': 'UPL-1.0', 'deprecated': False},
|
| 645 |
+
'urt-rle': {'id': 'URT-RLE', 'deprecated': False},
|
| 646 |
+
'vim': {'id': 'Vim', 'deprecated': False},
|
| 647 |
+
'vostrom': {'id': 'VOSTROM', 'deprecated': False},
|
| 648 |
+
'vsl-1.0': {'id': 'VSL-1.0', 'deprecated': False},
|
| 649 |
+
'w3c': {'id': 'W3C', 'deprecated': False},
|
| 650 |
+
'w3c-19980720': {'id': 'W3C-19980720', 'deprecated': False},
|
| 651 |
+
'w3c-20150513': {'id': 'W3C-20150513', 'deprecated': False},
|
| 652 |
+
'w3m': {'id': 'w3m', 'deprecated': False},
|
| 653 |
+
'watcom-1.0': {'id': 'Watcom-1.0', 'deprecated': False},
|
| 654 |
+
'widget-workshop': {'id': 'Widget-Workshop', 'deprecated': False},
|
| 655 |
+
'wsuipa': {'id': 'Wsuipa', 'deprecated': False},
|
| 656 |
+
'wtfpl': {'id': 'WTFPL', 'deprecated': False},
|
| 657 |
+
'wxwindows': {'id': 'wxWindows', 'deprecated': True},
|
| 658 |
+
'x11': {'id': 'X11', 'deprecated': False},
|
| 659 |
+
'x11-distribute-modifications-variant': {'id': 'X11-distribute-modifications-variant', 'deprecated': False},
|
| 660 |
+
'x11-swapped': {'id': 'X11-swapped', 'deprecated': False},
|
| 661 |
+
'xdebug-1.03': {'id': 'Xdebug-1.03', 'deprecated': False},
|
| 662 |
+
'xerox': {'id': 'Xerox', 'deprecated': False},
|
| 663 |
+
'xfig': {'id': 'Xfig', 'deprecated': False},
|
| 664 |
+
'xfree86-1.1': {'id': 'XFree86-1.1', 'deprecated': False},
|
| 665 |
+
'xinetd': {'id': 'xinetd', 'deprecated': False},
|
| 666 |
+
'xkeyboard-config-zinoviev': {'id': 'xkeyboard-config-Zinoviev', 'deprecated': False},
|
| 667 |
+
'xlock': {'id': 'xlock', 'deprecated': False},
|
| 668 |
+
'xnet': {'id': 'Xnet', 'deprecated': False},
|
| 669 |
+
'xpp': {'id': 'xpp', 'deprecated': False},
|
| 670 |
+
'xskat': {'id': 'XSkat', 'deprecated': False},
|
| 671 |
+
'xzoom': {'id': 'xzoom', 'deprecated': False},
|
| 672 |
+
'ypl-1.0': {'id': 'YPL-1.0', 'deprecated': False},
|
| 673 |
+
'ypl-1.1': {'id': 'YPL-1.1', 'deprecated': False},
|
| 674 |
+
'zed': {'id': 'Zed', 'deprecated': False},
|
| 675 |
+
'zeeff': {'id': 'Zeeff', 'deprecated': False},
|
| 676 |
+
'zend-2.0': {'id': 'Zend-2.0', 'deprecated': False},
|
| 677 |
+
'zimbra-1.3': {'id': 'Zimbra-1.3', 'deprecated': False},
|
| 678 |
+
'zimbra-1.4': {'id': 'Zimbra-1.4', 'deprecated': False},
|
| 679 |
+
'zlib': {'id': 'Zlib', 'deprecated': False},
|
| 680 |
+
'zlib-acknowledgement': {'id': 'zlib-acknowledgement', 'deprecated': False},
|
| 681 |
+
'zpl-1.1': {'id': 'ZPL-1.1', 'deprecated': False},
|
| 682 |
+
'zpl-2.0': {'id': 'ZPL-2.0', 'deprecated': False},
|
| 683 |
+
'zpl-2.1': {'id': 'ZPL-2.1', 'deprecated': False},
|
| 684 |
+
}
|
| 685 |
+
|
| 686 |
+
EXCEPTIONS: dict[str, SPDXException] = {
|
| 687 |
+
'389-exception': {'id': '389-exception', 'deprecated': False},
|
| 688 |
+
'asterisk-exception': {'id': 'Asterisk-exception', 'deprecated': False},
|
| 689 |
+
'asterisk-linking-protocols-exception': {'id': 'Asterisk-linking-protocols-exception', 'deprecated': False},
|
| 690 |
+
'autoconf-exception-2.0': {'id': 'Autoconf-exception-2.0', 'deprecated': False},
|
| 691 |
+
'autoconf-exception-3.0': {'id': 'Autoconf-exception-3.0', 'deprecated': False},
|
| 692 |
+
'autoconf-exception-generic': {'id': 'Autoconf-exception-generic', 'deprecated': False},
|
| 693 |
+
'autoconf-exception-generic-3.0': {'id': 'Autoconf-exception-generic-3.0', 'deprecated': False},
|
| 694 |
+
'autoconf-exception-macro': {'id': 'Autoconf-exception-macro', 'deprecated': False},
|
| 695 |
+
'bison-exception-1.24': {'id': 'Bison-exception-1.24', 'deprecated': False},
|
| 696 |
+
'bison-exception-2.2': {'id': 'Bison-exception-2.2', 'deprecated': False},
|
| 697 |
+
'bootloader-exception': {'id': 'Bootloader-exception', 'deprecated': False},
|
| 698 |
+
'classpath-exception-2.0': {'id': 'Classpath-exception-2.0', 'deprecated': False},
|
| 699 |
+
'clisp-exception-2.0': {'id': 'CLISP-exception-2.0', 'deprecated': False},
|
| 700 |
+
'cryptsetup-openssl-exception': {'id': 'cryptsetup-OpenSSL-exception', 'deprecated': False},
|
| 701 |
+
'digirule-foss-exception': {'id': 'DigiRule-FOSS-exception', 'deprecated': False},
|
| 702 |
+
'ecos-exception-2.0': {'id': 'eCos-exception-2.0', 'deprecated': False},
|
| 703 |
+
'erlang-otp-linking-exception': {'id': 'erlang-otp-linking-exception', 'deprecated': False},
|
| 704 |
+
'fawkes-runtime-exception': {'id': 'Fawkes-Runtime-exception', 'deprecated': False},
|
| 705 |
+
'fltk-exception': {'id': 'FLTK-exception', 'deprecated': False},
|
| 706 |
+
'fmt-exception': {'id': 'fmt-exception', 'deprecated': False},
|
| 707 |
+
'font-exception-2.0': {'id': 'Font-exception-2.0', 'deprecated': False},
|
| 708 |
+
'freertos-exception-2.0': {'id': 'freertos-exception-2.0', 'deprecated': False},
|
| 709 |
+
'gcc-exception-2.0': {'id': 'GCC-exception-2.0', 'deprecated': False},
|
| 710 |
+
'gcc-exception-2.0-note': {'id': 'GCC-exception-2.0-note', 'deprecated': False},
|
| 711 |
+
'gcc-exception-3.1': {'id': 'GCC-exception-3.1', 'deprecated': False},
|
| 712 |
+
'gmsh-exception': {'id': 'Gmsh-exception', 'deprecated': False},
|
| 713 |
+
'gnat-exception': {'id': 'GNAT-exception', 'deprecated': False},
|
| 714 |
+
'gnome-examples-exception': {'id': 'GNOME-examples-exception', 'deprecated': False},
|
| 715 |
+
'gnu-compiler-exception': {'id': 'GNU-compiler-exception', 'deprecated': False},
|
| 716 |
+
'gnu-javamail-exception': {'id': 'gnu-javamail-exception', 'deprecated': False},
|
| 717 |
+
'gpl-3.0-interface-exception': {'id': 'GPL-3.0-interface-exception', 'deprecated': False},
|
| 718 |
+
'gpl-3.0-linking-exception': {'id': 'GPL-3.0-linking-exception', 'deprecated': False},
|
| 719 |
+
'gpl-3.0-linking-source-exception': {'id': 'GPL-3.0-linking-source-exception', 'deprecated': False},
|
| 720 |
+
'gpl-cc-1.0': {'id': 'GPL-CC-1.0', 'deprecated': False},
|
| 721 |
+
'gstreamer-exception-2005': {'id': 'GStreamer-exception-2005', 'deprecated': False},
|
| 722 |
+
'gstreamer-exception-2008': {'id': 'GStreamer-exception-2008', 'deprecated': False},
|
| 723 |
+
'i2p-gpl-java-exception': {'id': 'i2p-gpl-java-exception', 'deprecated': False},
|
| 724 |
+
'kicad-libraries-exception': {'id': 'KiCad-libraries-exception', 'deprecated': False},
|
| 725 |
+
'lgpl-3.0-linking-exception': {'id': 'LGPL-3.0-linking-exception', 'deprecated': False},
|
| 726 |
+
'libpri-openh323-exception': {'id': 'libpri-OpenH323-exception', 'deprecated': False},
|
| 727 |
+
'libtool-exception': {'id': 'Libtool-exception', 'deprecated': False},
|
| 728 |
+
'linux-syscall-note': {'id': 'Linux-syscall-note', 'deprecated': False},
|
| 729 |
+
'llgpl': {'id': 'LLGPL', 'deprecated': False},
|
| 730 |
+
'llvm-exception': {'id': 'LLVM-exception', 'deprecated': False},
|
| 731 |
+
'lzma-exception': {'id': 'LZMA-exception', 'deprecated': False},
|
| 732 |
+
'mif-exception': {'id': 'mif-exception', 'deprecated': False},
|
| 733 |
+
'nokia-qt-exception-1.1': {'id': 'Nokia-Qt-exception-1.1', 'deprecated': True},
|
| 734 |
+
'ocaml-lgpl-linking-exception': {'id': 'OCaml-LGPL-linking-exception', 'deprecated': False},
|
| 735 |
+
'occt-exception-1.0': {'id': 'OCCT-exception-1.0', 'deprecated': False},
|
| 736 |
+
'openjdk-assembly-exception-1.0': {'id': 'OpenJDK-assembly-exception-1.0', 'deprecated': False},
|
| 737 |
+
'openvpn-openssl-exception': {'id': 'openvpn-openssl-exception', 'deprecated': False},
|
| 738 |
+
'pcre2-exception': {'id': 'PCRE2-exception', 'deprecated': False},
|
| 739 |
+
'ps-or-pdf-font-exception-20170817': {'id': 'PS-or-PDF-font-exception-20170817', 'deprecated': False},
|
| 740 |
+
'qpl-1.0-inria-2004-exception': {'id': 'QPL-1.0-INRIA-2004-exception', 'deprecated': False},
|
| 741 |
+
'qt-gpl-exception-1.0': {'id': 'Qt-GPL-exception-1.0', 'deprecated': False},
|
| 742 |
+
'qt-lgpl-exception-1.1': {'id': 'Qt-LGPL-exception-1.1', 'deprecated': False},
|
| 743 |
+
'qwt-exception-1.0': {'id': 'Qwt-exception-1.0', 'deprecated': False},
|
| 744 |
+
'romic-exception': {'id': 'romic-exception', 'deprecated': False},
|
| 745 |
+
'rrdtool-floss-exception-2.0': {'id': 'RRDtool-FLOSS-exception-2.0', 'deprecated': False},
|
| 746 |
+
'sane-exception': {'id': 'SANE-exception', 'deprecated': False},
|
| 747 |
+
'shl-2.0': {'id': 'SHL-2.0', 'deprecated': False},
|
| 748 |
+
'shl-2.1': {'id': 'SHL-2.1', 'deprecated': False},
|
| 749 |
+
'stunnel-exception': {'id': 'stunnel-exception', 'deprecated': False},
|
| 750 |
+
'swi-exception': {'id': 'SWI-exception', 'deprecated': False},
|
| 751 |
+
'swift-exception': {'id': 'Swift-exception', 'deprecated': False},
|
| 752 |
+
'texinfo-exception': {'id': 'Texinfo-exception', 'deprecated': False},
|
| 753 |
+
'u-boot-exception-2.0': {'id': 'u-boot-exception-2.0', 'deprecated': False},
|
| 754 |
+
'ubdl-exception': {'id': 'UBDL-exception', 'deprecated': False},
|
| 755 |
+
'universal-foss-exception-1.0': {'id': 'Universal-FOSS-exception-1.0', 'deprecated': False},
|
| 756 |
+
'vsftpd-openssl-exception': {'id': 'vsftpd-openssl-exception', 'deprecated': False},
|
| 757 |
+
'wxwindows-exception-3.1': {'id': 'WxWindows-exception-3.1', 'deprecated': False},
|
| 758 |
+
'x11vnc-openssl-exception': {'id': 'x11vnc-openssl-exception', 'deprecated': False},
|
| 759 |
+
}
|
.venv/lib/python3.11/site-packages/packaging/py.typed
ADDED
|
File without changes
|
.venv/lib/python3.11/site-packages/packaging/requirements.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file is dual licensed under the terms of the Apache License, Version
|
| 2 |
+
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
| 3 |
+
# for complete details.
|
| 4 |
+
from __future__ import annotations
|
| 5 |
+
|
| 6 |
+
from typing import Any, Iterator
|
| 7 |
+
|
| 8 |
+
from ._parser import parse_requirement as _parse_requirement
|
| 9 |
+
from ._tokenizer import ParserSyntaxError
|
| 10 |
+
from .markers import Marker, _normalize_extra_values
|
| 11 |
+
from .specifiers import SpecifierSet
|
| 12 |
+
from .utils import canonicalize_name
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
class InvalidRequirement(ValueError):
|
| 16 |
+
"""
|
| 17 |
+
An invalid requirement was found, users should refer to PEP 508.
|
| 18 |
+
"""
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class Requirement:
|
| 22 |
+
"""Parse a requirement.
|
| 23 |
+
|
| 24 |
+
Parse a given requirement string into its parts, such as name, specifier,
|
| 25 |
+
URL, and extras. Raises InvalidRequirement on a badly-formed requirement
|
| 26 |
+
string.
|
| 27 |
+
"""
|
| 28 |
+
|
| 29 |
+
# TODO: Can we test whether something is contained within a requirement?
|
| 30 |
+
# If so how do we do that? Do we need to test against the _name_ of
|
| 31 |
+
# the thing as well as the version? What about the markers?
|
| 32 |
+
# TODO: Can we normalize the name and extra name?
|
| 33 |
+
|
| 34 |
+
def __init__(self, requirement_string: str) -> None:
|
| 35 |
+
try:
|
| 36 |
+
parsed = _parse_requirement(requirement_string)
|
| 37 |
+
except ParserSyntaxError as e:
|
| 38 |
+
raise InvalidRequirement(str(e)) from e
|
| 39 |
+
|
| 40 |
+
self.name: str = parsed.name
|
| 41 |
+
self.url: str | None = parsed.url or None
|
| 42 |
+
self.extras: set[str] = set(parsed.extras or [])
|
| 43 |
+
self.specifier: SpecifierSet = SpecifierSet(parsed.specifier)
|
| 44 |
+
self.marker: Marker | None = None
|
| 45 |
+
if parsed.marker is not None:
|
| 46 |
+
self.marker = Marker.__new__(Marker)
|
| 47 |
+
self.marker._markers = _normalize_extra_values(parsed.marker)
|
| 48 |
+
|
| 49 |
+
def _iter_parts(self, name: str) -> Iterator[str]:
|
| 50 |
+
yield name
|
| 51 |
+
|
| 52 |
+
if self.extras:
|
| 53 |
+
formatted_extras = ",".join(sorted(self.extras))
|
| 54 |
+
yield f"[{formatted_extras}]"
|
| 55 |
+
|
| 56 |
+
if self.specifier:
|
| 57 |
+
yield str(self.specifier)
|
| 58 |
+
|
| 59 |
+
if self.url:
|
| 60 |
+
yield f"@ {self.url}"
|
| 61 |
+
if self.marker:
|
| 62 |
+
yield " "
|
| 63 |
+
|
| 64 |
+
if self.marker:
|
| 65 |
+
yield f"; {self.marker}"
|
| 66 |
+
|
| 67 |
+
def __str__(self) -> str:
|
| 68 |
+
return "".join(self._iter_parts(self.name))
|
| 69 |
+
|
| 70 |
+
def __repr__(self) -> str:
|
| 71 |
+
return f"<Requirement('{self}')>"
|
| 72 |
+
|
| 73 |
+
def __hash__(self) -> int:
|
| 74 |
+
return hash(
|
| 75 |
+
(
|
| 76 |
+
self.__class__.__name__,
|
| 77 |
+
*self._iter_parts(canonicalize_name(self.name)),
|
| 78 |
+
)
|
| 79 |
+
)
|
| 80 |
+
|
| 81 |
+
def __eq__(self, other: Any) -> bool:
|
| 82 |
+
if not isinstance(other, Requirement):
|
| 83 |
+
return NotImplemented
|
| 84 |
+
|
| 85 |
+
return (
|
| 86 |
+
canonicalize_name(self.name) == canonicalize_name(other.name)
|
| 87 |
+
and self.extras == other.extras
|
| 88 |
+
and self.specifier == other.specifier
|
| 89 |
+
and self.url == other.url
|
| 90 |
+
and self.marker == other.marker
|
| 91 |
+
)
|
.venv/lib/python3.11/site-packages/packaging/specifiers.py
ADDED
|
@@ -0,0 +1,1020 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file is dual licensed under the terms of the Apache License, Version
|
| 2 |
+
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
| 3 |
+
# for complete details.
|
| 4 |
+
"""
|
| 5 |
+
.. testsetup::
|
| 6 |
+
|
| 7 |
+
from packaging.specifiers import Specifier, SpecifierSet, InvalidSpecifier
|
| 8 |
+
from packaging.version import Version
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
from __future__ import annotations
|
| 12 |
+
|
| 13 |
+
import abc
|
| 14 |
+
import itertools
|
| 15 |
+
import re
|
| 16 |
+
from typing import Callable, Iterable, Iterator, TypeVar, Union
|
| 17 |
+
|
| 18 |
+
from .utils import canonicalize_version
|
| 19 |
+
from .version import Version
|
| 20 |
+
|
| 21 |
+
UnparsedVersion = Union[Version, str]
|
| 22 |
+
UnparsedVersionVar = TypeVar("UnparsedVersionVar", bound=UnparsedVersion)
|
| 23 |
+
CallableOperator = Callable[[Version, str], bool]
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def _coerce_version(version: UnparsedVersion) -> Version:
|
| 27 |
+
if not isinstance(version, Version):
|
| 28 |
+
version = Version(version)
|
| 29 |
+
return version
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
class InvalidSpecifier(ValueError):
|
| 33 |
+
"""
|
| 34 |
+
Raised when attempting to create a :class:`Specifier` with a specifier
|
| 35 |
+
string that is invalid.
|
| 36 |
+
|
| 37 |
+
>>> Specifier("lolwat")
|
| 38 |
+
Traceback (most recent call last):
|
| 39 |
+
...
|
| 40 |
+
packaging.specifiers.InvalidSpecifier: Invalid specifier: 'lolwat'
|
| 41 |
+
"""
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
class BaseSpecifier(metaclass=abc.ABCMeta):
|
| 45 |
+
@abc.abstractmethod
|
| 46 |
+
def __str__(self) -> str:
|
| 47 |
+
"""
|
| 48 |
+
Returns the str representation of this Specifier-like object. This
|
| 49 |
+
should be representative of the Specifier itself.
|
| 50 |
+
"""
|
| 51 |
+
|
| 52 |
+
@abc.abstractmethod
|
| 53 |
+
def __hash__(self) -> int:
|
| 54 |
+
"""
|
| 55 |
+
Returns a hash value for this Specifier-like object.
|
| 56 |
+
"""
|
| 57 |
+
|
| 58 |
+
@abc.abstractmethod
|
| 59 |
+
def __eq__(self, other: object) -> bool:
|
| 60 |
+
"""
|
| 61 |
+
Returns a boolean representing whether or not the two Specifier-like
|
| 62 |
+
objects are equal.
|
| 63 |
+
|
| 64 |
+
:param other: The other object to check against.
|
| 65 |
+
"""
|
| 66 |
+
|
| 67 |
+
@property
|
| 68 |
+
@abc.abstractmethod
|
| 69 |
+
def prereleases(self) -> bool | None:
|
| 70 |
+
"""Whether or not pre-releases as a whole are allowed.
|
| 71 |
+
|
| 72 |
+
This can be set to either ``True`` or ``False`` to explicitly enable or disable
|
| 73 |
+
prereleases or it can be set to ``None`` (the default) to use default semantics.
|
| 74 |
+
"""
|
| 75 |
+
|
| 76 |
+
@prereleases.setter
|
| 77 |
+
def prereleases(self, value: bool) -> None:
|
| 78 |
+
"""Setter for :attr:`prereleases`.
|
| 79 |
+
|
| 80 |
+
:param value: The value to set.
|
| 81 |
+
"""
|
| 82 |
+
|
| 83 |
+
@abc.abstractmethod
|
| 84 |
+
def contains(self, item: str, prereleases: bool | None = None) -> bool:
|
| 85 |
+
"""
|
| 86 |
+
Determines if the given item is contained within this specifier.
|
| 87 |
+
"""
|
| 88 |
+
|
| 89 |
+
@abc.abstractmethod
|
| 90 |
+
def filter(
|
| 91 |
+
self, iterable: Iterable[UnparsedVersionVar], prereleases: bool | None = None
|
| 92 |
+
) -> Iterator[UnparsedVersionVar]:
|
| 93 |
+
"""
|
| 94 |
+
Takes an iterable of items and filters them so that only items which
|
| 95 |
+
are contained within this specifier are allowed in it.
|
| 96 |
+
"""
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
class Specifier(BaseSpecifier):
|
| 100 |
+
"""This class abstracts handling of version specifiers.
|
| 101 |
+
|
| 102 |
+
.. tip::
|
| 103 |
+
|
| 104 |
+
It is generally not required to instantiate this manually. You should instead
|
| 105 |
+
prefer to work with :class:`SpecifierSet` instead, which can parse
|
| 106 |
+
comma-separated version specifiers (which is what package metadata contains).
|
| 107 |
+
"""
|
| 108 |
+
|
| 109 |
+
_operator_regex_str = r"""
|
| 110 |
+
(?P<operator>(~=|==|!=|<=|>=|<|>|===))
|
| 111 |
+
"""
|
| 112 |
+
_version_regex_str = r"""
|
| 113 |
+
(?P<version>
|
| 114 |
+
(?:
|
| 115 |
+
# The identity operators allow for an escape hatch that will
|
| 116 |
+
# do an exact string match of the version you wish to install.
|
| 117 |
+
# This will not be parsed by PEP 440 and we cannot determine
|
| 118 |
+
# any semantic meaning from it. This operator is discouraged
|
| 119 |
+
# but included entirely as an escape hatch.
|
| 120 |
+
(?<====) # Only match for the identity operator
|
| 121 |
+
\s*
|
| 122 |
+
[^\s;)]* # The arbitrary version can be just about anything,
|
| 123 |
+
# we match everything except for whitespace, a
|
| 124 |
+
# semi-colon for marker support, and a closing paren
|
| 125 |
+
# since versions can be enclosed in them.
|
| 126 |
+
)
|
| 127 |
+
|
|
| 128 |
+
(?:
|
| 129 |
+
# The (non)equality operators allow for wild card and local
|
| 130 |
+
# versions to be specified so we have to define these two
|
| 131 |
+
# operators separately to enable that.
|
| 132 |
+
(?<===|!=) # Only match for equals and not equals
|
| 133 |
+
|
| 134 |
+
\s*
|
| 135 |
+
v?
|
| 136 |
+
(?:[0-9]+!)? # epoch
|
| 137 |
+
[0-9]+(?:\.[0-9]+)* # release
|
| 138 |
+
|
| 139 |
+
# You cannot use a wild card and a pre-release, post-release, a dev or
|
| 140 |
+
# local version together so group them with a | and make them optional.
|
| 141 |
+
(?:
|
| 142 |
+
\.\* # Wild card syntax of .*
|
| 143 |
+
|
|
| 144 |
+
(?: # pre release
|
| 145 |
+
[-_\.]?
|
| 146 |
+
(alpha|beta|preview|pre|a|b|c|rc)
|
| 147 |
+
[-_\.]?
|
| 148 |
+
[0-9]*
|
| 149 |
+
)?
|
| 150 |
+
(?: # post release
|
| 151 |
+
(?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
|
| 152 |
+
)?
|
| 153 |
+
(?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release
|
| 154 |
+
(?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local
|
| 155 |
+
)?
|
| 156 |
+
)
|
| 157 |
+
|
|
| 158 |
+
(?:
|
| 159 |
+
# The compatible operator requires at least two digits in the
|
| 160 |
+
# release segment.
|
| 161 |
+
(?<=~=) # Only match for the compatible operator
|
| 162 |
+
|
| 163 |
+
\s*
|
| 164 |
+
v?
|
| 165 |
+
(?:[0-9]+!)? # epoch
|
| 166 |
+
[0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *)
|
| 167 |
+
(?: # pre release
|
| 168 |
+
[-_\.]?
|
| 169 |
+
(alpha|beta|preview|pre|a|b|c|rc)
|
| 170 |
+
[-_\.]?
|
| 171 |
+
[0-9]*
|
| 172 |
+
)?
|
| 173 |
+
(?: # post release
|
| 174 |
+
(?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
|
| 175 |
+
)?
|
| 176 |
+
(?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release
|
| 177 |
+
)
|
| 178 |
+
|
|
| 179 |
+
(?:
|
| 180 |
+
# All other operators only allow a sub set of what the
|
| 181 |
+
# (non)equality operators do. Specifically they do not allow
|
| 182 |
+
# local versions to be specified nor do they allow the prefix
|
| 183 |
+
# matching wild cards.
|
| 184 |
+
(?<!==|!=|~=) # We have special cases for these
|
| 185 |
+
# operators so we want to make sure they
|
| 186 |
+
# don't match here.
|
| 187 |
+
|
| 188 |
+
\s*
|
| 189 |
+
v?
|
| 190 |
+
(?:[0-9]+!)? # epoch
|
| 191 |
+
[0-9]+(?:\.[0-9]+)* # release
|
| 192 |
+
(?: # pre release
|
| 193 |
+
[-_\.]?
|
| 194 |
+
(alpha|beta|preview|pre|a|b|c|rc)
|
| 195 |
+
[-_\.]?
|
| 196 |
+
[0-9]*
|
| 197 |
+
)?
|
| 198 |
+
(?: # post release
|
| 199 |
+
(?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*)
|
| 200 |
+
)?
|
| 201 |
+
(?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release
|
| 202 |
+
)
|
| 203 |
+
)
|
| 204 |
+
"""
|
| 205 |
+
|
| 206 |
+
_regex = re.compile(
|
| 207 |
+
r"^\s*" + _operator_regex_str + _version_regex_str + r"\s*$",
|
| 208 |
+
re.VERBOSE | re.IGNORECASE,
|
| 209 |
+
)
|
| 210 |
+
|
| 211 |
+
_operators = {
|
| 212 |
+
"~=": "compatible",
|
| 213 |
+
"==": "equal",
|
| 214 |
+
"!=": "not_equal",
|
| 215 |
+
"<=": "less_than_equal",
|
| 216 |
+
">=": "greater_than_equal",
|
| 217 |
+
"<": "less_than",
|
| 218 |
+
">": "greater_than",
|
| 219 |
+
"===": "arbitrary",
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
def __init__(self, spec: str = "", prereleases: bool | None = None) -> None:
|
| 223 |
+
"""Initialize a Specifier instance.
|
| 224 |
+
|
| 225 |
+
:param spec:
|
| 226 |
+
The string representation of a specifier which will be parsed and
|
| 227 |
+
normalized before use.
|
| 228 |
+
:param prereleases:
|
| 229 |
+
This tells the specifier if it should accept prerelease versions if
|
| 230 |
+
applicable or not. The default of ``None`` will autodetect it from the
|
| 231 |
+
given specifiers.
|
| 232 |
+
:raises InvalidSpecifier:
|
| 233 |
+
If the given specifier is invalid (i.e. bad syntax).
|
| 234 |
+
"""
|
| 235 |
+
match = self._regex.search(spec)
|
| 236 |
+
if not match:
|
| 237 |
+
raise InvalidSpecifier(f"Invalid specifier: {spec!r}")
|
| 238 |
+
|
| 239 |
+
self._spec: tuple[str, str] = (
|
| 240 |
+
match.group("operator").strip(),
|
| 241 |
+
match.group("version").strip(),
|
| 242 |
+
)
|
| 243 |
+
|
| 244 |
+
# Store whether or not this Specifier should accept prereleases
|
| 245 |
+
self._prereleases = prereleases
|
| 246 |
+
|
| 247 |
+
# https://github.com/python/mypy/pull/13475#pullrequestreview-1079784515
|
| 248 |
+
@property # type: ignore[override]
|
| 249 |
+
def prereleases(self) -> bool:
|
| 250 |
+
# If there is an explicit prereleases set for this, then we'll just
|
| 251 |
+
# blindly use that.
|
| 252 |
+
if self._prereleases is not None:
|
| 253 |
+
return self._prereleases
|
| 254 |
+
|
| 255 |
+
# Look at all of our specifiers and determine if they are inclusive
|
| 256 |
+
# operators, and if they are if they are including an explicit
|
| 257 |
+
# prerelease.
|
| 258 |
+
operator, version = self._spec
|
| 259 |
+
if operator in ["==", ">=", "<=", "~=", "===", ">", "<"]:
|
| 260 |
+
# The == specifier can include a trailing .*, if it does we
|
| 261 |
+
# want to remove before parsing.
|
| 262 |
+
if operator == "==" and version.endswith(".*"):
|
| 263 |
+
version = version[:-2]
|
| 264 |
+
|
| 265 |
+
# Parse the version, and if it is a pre-release than this
|
| 266 |
+
# specifier allows pre-releases.
|
| 267 |
+
if Version(version).is_prerelease:
|
| 268 |
+
return True
|
| 269 |
+
|
| 270 |
+
return False
|
| 271 |
+
|
| 272 |
+
@prereleases.setter
|
| 273 |
+
def prereleases(self, value: bool) -> None:
|
| 274 |
+
self._prereleases = value
|
| 275 |
+
|
| 276 |
+
@property
|
| 277 |
+
def operator(self) -> str:
|
| 278 |
+
"""The operator of this specifier.
|
| 279 |
+
|
| 280 |
+
>>> Specifier("==1.2.3").operator
|
| 281 |
+
'=='
|
| 282 |
+
"""
|
| 283 |
+
return self._spec[0]
|
| 284 |
+
|
| 285 |
+
@property
|
| 286 |
+
def version(self) -> str:
|
| 287 |
+
"""The version of this specifier.
|
| 288 |
+
|
| 289 |
+
>>> Specifier("==1.2.3").version
|
| 290 |
+
'1.2.3'
|
| 291 |
+
"""
|
| 292 |
+
return self._spec[1]
|
| 293 |
+
|
| 294 |
+
def __repr__(self) -> str:
|
| 295 |
+
"""A representation of the Specifier that shows all internal state.
|
| 296 |
+
|
| 297 |
+
>>> Specifier('>=1.0.0')
|
| 298 |
+
<Specifier('>=1.0.0')>
|
| 299 |
+
>>> Specifier('>=1.0.0', prereleases=False)
|
| 300 |
+
<Specifier('>=1.0.0', prereleases=False)>
|
| 301 |
+
>>> Specifier('>=1.0.0', prereleases=True)
|
| 302 |
+
<Specifier('>=1.0.0', prereleases=True)>
|
| 303 |
+
"""
|
| 304 |
+
pre = (
|
| 305 |
+
f", prereleases={self.prereleases!r}"
|
| 306 |
+
if self._prereleases is not None
|
| 307 |
+
else ""
|
| 308 |
+
)
|
| 309 |
+
|
| 310 |
+
return f"<{self.__class__.__name__}({str(self)!r}{pre})>"
|
| 311 |
+
|
| 312 |
+
def __str__(self) -> str:
|
| 313 |
+
"""A string representation of the Specifier that can be round-tripped.
|
| 314 |
+
|
| 315 |
+
>>> str(Specifier('>=1.0.0'))
|
| 316 |
+
'>=1.0.0'
|
| 317 |
+
>>> str(Specifier('>=1.0.0', prereleases=False))
|
| 318 |
+
'>=1.0.0'
|
| 319 |
+
"""
|
| 320 |
+
return "{}{}".format(*self._spec)
|
| 321 |
+
|
| 322 |
+
@property
|
| 323 |
+
def _canonical_spec(self) -> tuple[str, str]:
|
| 324 |
+
canonical_version = canonicalize_version(
|
| 325 |
+
self._spec[1],
|
| 326 |
+
strip_trailing_zero=(self._spec[0] != "~="),
|
| 327 |
+
)
|
| 328 |
+
return self._spec[0], canonical_version
|
| 329 |
+
|
| 330 |
+
def __hash__(self) -> int:
|
| 331 |
+
return hash(self._canonical_spec)
|
| 332 |
+
|
| 333 |
+
def __eq__(self, other: object) -> bool:
|
| 334 |
+
"""Whether or not the two Specifier-like objects are equal.
|
| 335 |
+
|
| 336 |
+
:param other: The other object to check against.
|
| 337 |
+
|
| 338 |
+
The value of :attr:`prereleases` is ignored.
|
| 339 |
+
|
| 340 |
+
>>> Specifier("==1.2.3") == Specifier("== 1.2.3.0")
|
| 341 |
+
True
|
| 342 |
+
>>> (Specifier("==1.2.3", prereleases=False) ==
|
| 343 |
+
... Specifier("==1.2.3", prereleases=True))
|
| 344 |
+
True
|
| 345 |
+
>>> Specifier("==1.2.3") == "==1.2.3"
|
| 346 |
+
True
|
| 347 |
+
>>> Specifier("==1.2.3") == Specifier("==1.2.4")
|
| 348 |
+
False
|
| 349 |
+
>>> Specifier("==1.2.3") == Specifier("~=1.2.3")
|
| 350 |
+
False
|
| 351 |
+
"""
|
| 352 |
+
if isinstance(other, str):
|
| 353 |
+
try:
|
| 354 |
+
other = self.__class__(str(other))
|
| 355 |
+
except InvalidSpecifier:
|
| 356 |
+
return NotImplemented
|
| 357 |
+
elif not isinstance(other, self.__class__):
|
| 358 |
+
return NotImplemented
|
| 359 |
+
|
| 360 |
+
return self._canonical_spec == other._canonical_spec
|
| 361 |
+
|
| 362 |
+
def _get_operator(self, op: str) -> CallableOperator:
|
| 363 |
+
operator_callable: CallableOperator = getattr(
|
| 364 |
+
self, f"_compare_{self._operators[op]}"
|
| 365 |
+
)
|
| 366 |
+
return operator_callable
|
| 367 |
+
|
| 368 |
+
def _compare_compatible(self, prospective: Version, spec: str) -> bool:
|
| 369 |
+
# Compatible releases have an equivalent combination of >= and ==. That
|
| 370 |
+
# is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to
|
| 371 |
+
# implement this in terms of the other specifiers instead of
|
| 372 |
+
# implementing it ourselves. The only thing we need to do is construct
|
| 373 |
+
# the other specifiers.
|
| 374 |
+
|
| 375 |
+
# We want everything but the last item in the version, but we want to
|
| 376 |
+
# ignore suffix segments.
|
| 377 |
+
prefix = _version_join(
|
| 378 |
+
list(itertools.takewhile(_is_not_suffix, _version_split(spec)))[:-1]
|
| 379 |
+
)
|
| 380 |
+
|
| 381 |
+
# Add the prefix notation to the end of our string
|
| 382 |
+
prefix += ".*"
|
| 383 |
+
|
| 384 |
+
return self._get_operator(">=")(prospective, spec) and self._get_operator("==")(
|
| 385 |
+
prospective, prefix
|
| 386 |
+
)
|
| 387 |
+
|
| 388 |
+
def _compare_equal(self, prospective: Version, spec: str) -> bool:
|
| 389 |
+
# We need special logic to handle prefix matching
|
| 390 |
+
if spec.endswith(".*"):
|
| 391 |
+
# In the case of prefix matching we want to ignore local segment.
|
| 392 |
+
normalized_prospective = canonicalize_version(
|
| 393 |
+
prospective.public, strip_trailing_zero=False
|
| 394 |
+
)
|
| 395 |
+
# Get the normalized version string ignoring the trailing .*
|
| 396 |
+
normalized_spec = canonicalize_version(spec[:-2], strip_trailing_zero=False)
|
| 397 |
+
# Split the spec out by bangs and dots, and pretend that there is
|
| 398 |
+
# an implicit dot in between a release segment and a pre-release segment.
|
| 399 |
+
split_spec = _version_split(normalized_spec)
|
| 400 |
+
|
| 401 |
+
# Split the prospective version out by bangs and dots, and pretend
|
| 402 |
+
# that there is an implicit dot in between a release segment and
|
| 403 |
+
# a pre-release segment.
|
| 404 |
+
split_prospective = _version_split(normalized_prospective)
|
| 405 |
+
|
| 406 |
+
# 0-pad the prospective version before shortening it to get the correct
|
| 407 |
+
# shortened version.
|
| 408 |
+
padded_prospective, _ = _pad_version(split_prospective, split_spec)
|
| 409 |
+
|
| 410 |
+
# Shorten the prospective version to be the same length as the spec
|
| 411 |
+
# so that we can determine if the specifier is a prefix of the
|
| 412 |
+
# prospective version or not.
|
| 413 |
+
shortened_prospective = padded_prospective[: len(split_spec)]
|
| 414 |
+
|
| 415 |
+
return shortened_prospective == split_spec
|
| 416 |
+
else:
|
| 417 |
+
# Convert our spec string into a Version
|
| 418 |
+
spec_version = Version(spec)
|
| 419 |
+
|
| 420 |
+
# If the specifier does not have a local segment, then we want to
|
| 421 |
+
# act as if the prospective version also does not have a local
|
| 422 |
+
# segment.
|
| 423 |
+
if not spec_version.local:
|
| 424 |
+
prospective = Version(prospective.public)
|
| 425 |
+
|
| 426 |
+
return prospective == spec_version
|
| 427 |
+
|
| 428 |
+
def _compare_not_equal(self, prospective: Version, spec: str) -> bool:
|
| 429 |
+
return not self._compare_equal(prospective, spec)
|
| 430 |
+
|
| 431 |
+
def _compare_less_than_equal(self, prospective: Version, spec: str) -> bool:
|
| 432 |
+
# NB: Local version identifiers are NOT permitted in the version
|
| 433 |
+
# specifier, so local version labels can be universally removed from
|
| 434 |
+
# the prospective version.
|
| 435 |
+
return Version(prospective.public) <= Version(spec)
|
| 436 |
+
|
| 437 |
+
def _compare_greater_than_equal(self, prospective: Version, spec: str) -> bool:
|
| 438 |
+
# NB: Local version identifiers are NOT permitted in the version
|
| 439 |
+
# specifier, so local version labels can be universally removed from
|
| 440 |
+
# the prospective version.
|
| 441 |
+
return Version(prospective.public) >= Version(spec)
|
| 442 |
+
|
| 443 |
+
def _compare_less_than(self, prospective: Version, spec_str: str) -> bool:
|
| 444 |
+
# Convert our spec to a Version instance, since we'll want to work with
|
| 445 |
+
# it as a version.
|
| 446 |
+
spec = Version(spec_str)
|
| 447 |
+
|
| 448 |
+
# Check to see if the prospective version is less than the spec
|
| 449 |
+
# version. If it's not we can short circuit and just return False now
|
| 450 |
+
# instead of doing extra unneeded work.
|
| 451 |
+
if not prospective < spec:
|
| 452 |
+
return False
|
| 453 |
+
|
| 454 |
+
# This special case is here so that, unless the specifier itself
|
| 455 |
+
# includes is a pre-release version, that we do not accept pre-release
|
| 456 |
+
# versions for the version mentioned in the specifier (e.g. <3.1 should
|
| 457 |
+
# not match 3.1.dev0, but should match 3.0.dev0).
|
| 458 |
+
if not spec.is_prerelease and prospective.is_prerelease:
|
| 459 |
+
if Version(prospective.base_version) == Version(spec.base_version):
|
| 460 |
+
return False
|
| 461 |
+
|
| 462 |
+
# If we've gotten to here, it means that prospective version is both
|
| 463 |
+
# less than the spec version *and* it's not a pre-release of the same
|
| 464 |
+
# version in the spec.
|
| 465 |
+
return True
|
| 466 |
+
|
| 467 |
+
def _compare_greater_than(self, prospective: Version, spec_str: str) -> bool:
|
| 468 |
+
# Convert our spec to a Version instance, since we'll want to work with
|
| 469 |
+
# it as a version.
|
| 470 |
+
spec = Version(spec_str)
|
| 471 |
+
|
| 472 |
+
# Check to see if the prospective version is greater than the spec
|
| 473 |
+
# version. If it's not we can short circuit and just return False now
|
| 474 |
+
# instead of doing extra unneeded work.
|
| 475 |
+
if not prospective > spec:
|
| 476 |
+
return False
|
| 477 |
+
|
| 478 |
+
# This special case is here so that, unless the specifier itself
|
| 479 |
+
# includes is a post-release version, that we do not accept
|
| 480 |
+
# post-release versions for the version mentioned in the specifier
|
| 481 |
+
# (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0).
|
| 482 |
+
if not spec.is_postrelease and prospective.is_postrelease:
|
| 483 |
+
if Version(prospective.base_version) == Version(spec.base_version):
|
| 484 |
+
return False
|
| 485 |
+
|
| 486 |
+
# Ensure that we do not allow a local version of the version mentioned
|
| 487 |
+
# in the specifier, which is technically greater than, to match.
|
| 488 |
+
if prospective.local is not None:
|
| 489 |
+
if Version(prospective.base_version) == Version(spec.base_version):
|
| 490 |
+
return False
|
| 491 |
+
|
| 492 |
+
# If we've gotten to here, it means that prospective version is both
|
| 493 |
+
# greater than the spec version *and* it's not a pre-release of the
|
| 494 |
+
# same version in the spec.
|
| 495 |
+
return True
|
| 496 |
+
|
| 497 |
+
def _compare_arbitrary(self, prospective: Version, spec: str) -> bool:
|
| 498 |
+
return str(prospective).lower() == str(spec).lower()
|
| 499 |
+
|
| 500 |
+
def __contains__(self, item: str | Version) -> bool:
|
| 501 |
+
"""Return whether or not the item is contained in this specifier.
|
| 502 |
+
|
| 503 |
+
:param item: The item to check for.
|
| 504 |
+
|
| 505 |
+
This is used for the ``in`` operator and behaves the same as
|
| 506 |
+
:meth:`contains` with no ``prereleases`` argument passed.
|
| 507 |
+
|
| 508 |
+
>>> "1.2.3" in Specifier(">=1.2.3")
|
| 509 |
+
True
|
| 510 |
+
>>> Version("1.2.3") in Specifier(">=1.2.3")
|
| 511 |
+
True
|
| 512 |
+
>>> "1.0.0" in Specifier(">=1.2.3")
|
| 513 |
+
False
|
| 514 |
+
>>> "1.3.0a1" in Specifier(">=1.2.3")
|
| 515 |
+
False
|
| 516 |
+
>>> "1.3.0a1" in Specifier(">=1.2.3", prereleases=True)
|
| 517 |
+
True
|
| 518 |
+
"""
|
| 519 |
+
return self.contains(item)
|
| 520 |
+
|
| 521 |
+
def contains(self, item: UnparsedVersion, prereleases: bool | None = None) -> bool:
|
| 522 |
+
"""Return whether or not the item is contained in this specifier.
|
| 523 |
+
|
| 524 |
+
:param item:
|
| 525 |
+
The item to check for, which can be a version string or a
|
| 526 |
+
:class:`Version` instance.
|
| 527 |
+
:param prereleases:
|
| 528 |
+
Whether or not to match prereleases with this Specifier. If set to
|
| 529 |
+
``None`` (the default), it uses :attr:`prereleases` to determine
|
| 530 |
+
whether or not prereleases are allowed.
|
| 531 |
+
|
| 532 |
+
>>> Specifier(">=1.2.3").contains("1.2.3")
|
| 533 |
+
True
|
| 534 |
+
>>> Specifier(">=1.2.3").contains(Version("1.2.3"))
|
| 535 |
+
True
|
| 536 |
+
>>> Specifier(">=1.2.3").contains("1.0.0")
|
| 537 |
+
False
|
| 538 |
+
>>> Specifier(">=1.2.3").contains("1.3.0a1")
|
| 539 |
+
False
|
| 540 |
+
>>> Specifier(">=1.2.3", prereleases=True).contains("1.3.0a1")
|
| 541 |
+
True
|
| 542 |
+
>>> Specifier(">=1.2.3").contains("1.3.0a1", prereleases=True)
|
| 543 |
+
True
|
| 544 |
+
"""
|
| 545 |
+
|
| 546 |
+
# Determine if prereleases are to be allowed or not.
|
| 547 |
+
if prereleases is None:
|
| 548 |
+
prereleases = self.prereleases
|
| 549 |
+
|
| 550 |
+
# Normalize item to a Version, this allows us to have a shortcut for
|
| 551 |
+
# "2.0" in Specifier(">=2")
|
| 552 |
+
normalized_item = _coerce_version(item)
|
| 553 |
+
|
| 554 |
+
# Determine if we should be supporting prereleases in this specifier
|
| 555 |
+
# or not, if we do not support prereleases than we can short circuit
|
| 556 |
+
# logic if this version is a prereleases.
|
| 557 |
+
if normalized_item.is_prerelease and not prereleases:
|
| 558 |
+
return False
|
| 559 |
+
|
| 560 |
+
# Actually do the comparison to determine if this item is contained
|
| 561 |
+
# within this Specifier or not.
|
| 562 |
+
operator_callable: CallableOperator = self._get_operator(self.operator)
|
| 563 |
+
return operator_callable(normalized_item, self.version)
|
| 564 |
+
|
| 565 |
+
def filter(
|
| 566 |
+
self, iterable: Iterable[UnparsedVersionVar], prereleases: bool | None = None
|
| 567 |
+
) -> Iterator[UnparsedVersionVar]:
|
| 568 |
+
"""Filter items in the given iterable, that match the specifier.
|
| 569 |
+
|
| 570 |
+
:param iterable:
|
| 571 |
+
An iterable that can contain version strings and :class:`Version` instances.
|
| 572 |
+
The items in the iterable will be filtered according to the specifier.
|
| 573 |
+
:param prereleases:
|
| 574 |
+
Whether or not to allow prereleases in the returned iterator. If set to
|
| 575 |
+
``None`` (the default), it will be intelligently decide whether to allow
|
| 576 |
+
prereleases or not (based on the :attr:`prereleases` attribute, and
|
| 577 |
+
whether the only versions matching are prereleases).
|
| 578 |
+
|
| 579 |
+
This method is smarter than just ``filter(Specifier().contains, [...])``
|
| 580 |
+
because it implements the rule from :pep:`440` that a prerelease item
|
| 581 |
+
SHOULD be accepted if no other versions match the given specifier.
|
| 582 |
+
|
| 583 |
+
>>> list(Specifier(">=1.2.3").filter(["1.2", "1.3", "1.5a1"]))
|
| 584 |
+
['1.3']
|
| 585 |
+
>>> list(Specifier(">=1.2.3").filter(["1.2", "1.2.3", "1.3", Version("1.4")]))
|
| 586 |
+
['1.2.3', '1.3', <Version('1.4')>]
|
| 587 |
+
>>> list(Specifier(">=1.2.3").filter(["1.2", "1.5a1"]))
|
| 588 |
+
['1.5a1']
|
| 589 |
+
>>> list(Specifier(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True))
|
| 590 |
+
['1.3', '1.5a1']
|
| 591 |
+
>>> list(Specifier(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"]))
|
| 592 |
+
['1.3', '1.5a1']
|
| 593 |
+
"""
|
| 594 |
+
|
| 595 |
+
yielded = False
|
| 596 |
+
found_prereleases = []
|
| 597 |
+
|
| 598 |
+
kw = {"prereleases": prereleases if prereleases is not None else True}
|
| 599 |
+
|
| 600 |
+
# Attempt to iterate over all the values in the iterable and if any of
|
| 601 |
+
# them match, yield them.
|
| 602 |
+
for version in iterable:
|
| 603 |
+
parsed_version = _coerce_version(version)
|
| 604 |
+
|
| 605 |
+
if self.contains(parsed_version, **kw):
|
| 606 |
+
# If our version is a prerelease, and we were not set to allow
|
| 607 |
+
# prereleases, then we'll store it for later in case nothing
|
| 608 |
+
# else matches this specifier.
|
| 609 |
+
if parsed_version.is_prerelease and not (
|
| 610 |
+
prereleases or self.prereleases
|
| 611 |
+
):
|
| 612 |
+
found_prereleases.append(version)
|
| 613 |
+
# Either this is not a prerelease, or we should have been
|
| 614 |
+
# accepting prereleases from the beginning.
|
| 615 |
+
else:
|
| 616 |
+
yielded = True
|
| 617 |
+
yield version
|
| 618 |
+
|
| 619 |
+
# Now that we've iterated over everything, determine if we've yielded
|
| 620 |
+
# any values, and if we have not and we have any prereleases stored up
|
| 621 |
+
# then we will go ahead and yield the prereleases.
|
| 622 |
+
if not yielded and found_prereleases:
|
| 623 |
+
for version in found_prereleases:
|
| 624 |
+
yield version
|
| 625 |
+
|
| 626 |
+
|
| 627 |
+
_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$")
|
| 628 |
+
|
| 629 |
+
|
| 630 |
+
def _version_split(version: str) -> list[str]:
|
| 631 |
+
"""Split version into components.
|
| 632 |
+
|
| 633 |
+
The split components are intended for version comparison. The logic does
|
| 634 |
+
not attempt to retain the original version string, so joining the
|
| 635 |
+
components back with :func:`_version_join` may not produce the original
|
| 636 |
+
version string.
|
| 637 |
+
"""
|
| 638 |
+
result: list[str] = []
|
| 639 |
+
|
| 640 |
+
epoch, _, rest = version.rpartition("!")
|
| 641 |
+
result.append(epoch or "0")
|
| 642 |
+
|
| 643 |
+
for item in rest.split("."):
|
| 644 |
+
match = _prefix_regex.search(item)
|
| 645 |
+
if match:
|
| 646 |
+
result.extend(match.groups())
|
| 647 |
+
else:
|
| 648 |
+
result.append(item)
|
| 649 |
+
return result
|
| 650 |
+
|
| 651 |
+
|
| 652 |
+
def _version_join(components: list[str]) -> str:
|
| 653 |
+
"""Join split version components into a version string.
|
| 654 |
+
|
| 655 |
+
This function assumes the input came from :func:`_version_split`, where the
|
| 656 |
+
first component must be the epoch (either empty or numeric), and all other
|
| 657 |
+
components numeric.
|
| 658 |
+
"""
|
| 659 |
+
epoch, *rest = components
|
| 660 |
+
return f"{epoch}!{'.'.join(rest)}"
|
| 661 |
+
|
| 662 |
+
|
| 663 |
+
def _is_not_suffix(segment: str) -> bool:
|
| 664 |
+
return not any(
|
| 665 |
+
segment.startswith(prefix) for prefix in ("dev", "a", "b", "rc", "post")
|
| 666 |
+
)
|
| 667 |
+
|
| 668 |
+
|
| 669 |
+
def _pad_version(left: list[str], right: list[str]) -> tuple[list[str], list[str]]:
|
| 670 |
+
left_split, right_split = [], []
|
| 671 |
+
|
| 672 |
+
# Get the release segment of our versions
|
| 673 |
+
left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left)))
|
| 674 |
+
right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right)))
|
| 675 |
+
|
| 676 |
+
# Get the rest of our versions
|
| 677 |
+
left_split.append(left[len(left_split[0]) :])
|
| 678 |
+
right_split.append(right[len(right_split[0]) :])
|
| 679 |
+
|
| 680 |
+
# Insert our padding
|
| 681 |
+
left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0])))
|
| 682 |
+
right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0])))
|
| 683 |
+
|
| 684 |
+
return (
|
| 685 |
+
list(itertools.chain.from_iterable(left_split)),
|
| 686 |
+
list(itertools.chain.from_iterable(right_split)),
|
| 687 |
+
)
|
| 688 |
+
|
| 689 |
+
|
| 690 |
+
class SpecifierSet(BaseSpecifier):
|
| 691 |
+
"""This class abstracts handling of a set of version specifiers.
|
| 692 |
+
|
| 693 |
+
It can be passed a single specifier (``>=3.0``), a comma-separated list of
|
| 694 |
+
specifiers (``>=3.0,!=3.1``), or no specifier at all.
|
| 695 |
+
"""
|
| 696 |
+
|
| 697 |
+
def __init__(
|
| 698 |
+
self,
|
| 699 |
+
specifiers: str | Iterable[Specifier] = "",
|
| 700 |
+
prereleases: bool | None = None,
|
| 701 |
+
) -> None:
|
| 702 |
+
"""Initialize a SpecifierSet instance.
|
| 703 |
+
|
| 704 |
+
:param specifiers:
|
| 705 |
+
The string representation of a specifier or a comma-separated list of
|
| 706 |
+
specifiers which will be parsed and normalized before use.
|
| 707 |
+
May also be an iterable of ``Specifier`` instances, which will be used
|
| 708 |
+
as is.
|
| 709 |
+
:param prereleases:
|
| 710 |
+
This tells the SpecifierSet if it should accept prerelease versions if
|
| 711 |
+
applicable or not. The default of ``None`` will autodetect it from the
|
| 712 |
+
given specifiers.
|
| 713 |
+
|
| 714 |
+
:raises InvalidSpecifier:
|
| 715 |
+
If the given ``specifiers`` are not parseable than this exception will be
|
| 716 |
+
raised.
|
| 717 |
+
"""
|
| 718 |
+
|
| 719 |
+
if isinstance(specifiers, str):
|
| 720 |
+
# Split on `,` to break each individual specifier into its own item, and
|
| 721 |
+
# strip each item to remove leading/trailing whitespace.
|
| 722 |
+
split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
|
| 723 |
+
|
| 724 |
+
# Make each individual specifier a Specifier and save in a frozen set
|
| 725 |
+
# for later.
|
| 726 |
+
self._specs = frozenset(map(Specifier, split_specifiers))
|
| 727 |
+
else:
|
| 728 |
+
# Save the supplied specifiers in a frozen set.
|
| 729 |
+
self._specs = frozenset(specifiers)
|
| 730 |
+
|
| 731 |
+
# Store our prereleases value so we can use it later to determine if
|
| 732 |
+
# we accept prereleases or not.
|
| 733 |
+
self._prereleases = prereleases
|
| 734 |
+
|
| 735 |
+
@property
|
| 736 |
+
def prereleases(self) -> bool | None:
|
| 737 |
+
# If we have been given an explicit prerelease modifier, then we'll
|
| 738 |
+
# pass that through here.
|
| 739 |
+
if self._prereleases is not None:
|
| 740 |
+
return self._prereleases
|
| 741 |
+
|
| 742 |
+
# If we don't have any specifiers, and we don't have a forced value,
|
| 743 |
+
# then we'll just return None since we don't know if this should have
|
| 744 |
+
# pre-releases or not.
|
| 745 |
+
if not self._specs:
|
| 746 |
+
return None
|
| 747 |
+
|
| 748 |
+
# Otherwise we'll see if any of the given specifiers accept
|
| 749 |
+
# prereleases, if any of them do we'll return True, otherwise False.
|
| 750 |
+
return any(s.prereleases for s in self._specs)
|
| 751 |
+
|
| 752 |
+
@prereleases.setter
|
| 753 |
+
def prereleases(self, value: bool) -> None:
|
| 754 |
+
self._prereleases = value
|
| 755 |
+
|
| 756 |
+
def __repr__(self) -> str:
|
| 757 |
+
"""A representation of the specifier set that shows all internal state.
|
| 758 |
+
|
| 759 |
+
Note that the ordering of the individual specifiers within the set may not
|
| 760 |
+
match the input string.
|
| 761 |
+
|
| 762 |
+
>>> SpecifierSet('>=1.0.0,!=2.0.0')
|
| 763 |
+
<SpecifierSet('!=2.0.0,>=1.0.0')>
|
| 764 |
+
>>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=False)
|
| 765 |
+
<SpecifierSet('!=2.0.0,>=1.0.0', prereleases=False)>
|
| 766 |
+
>>> SpecifierSet('>=1.0.0,!=2.0.0', prereleases=True)
|
| 767 |
+
<SpecifierSet('!=2.0.0,>=1.0.0', prereleases=True)>
|
| 768 |
+
"""
|
| 769 |
+
pre = (
|
| 770 |
+
f", prereleases={self.prereleases!r}"
|
| 771 |
+
if self._prereleases is not None
|
| 772 |
+
else ""
|
| 773 |
+
)
|
| 774 |
+
|
| 775 |
+
return f"<SpecifierSet({str(self)!r}{pre})>"
|
| 776 |
+
|
| 777 |
+
def __str__(self) -> str:
|
| 778 |
+
"""A string representation of the specifier set that can be round-tripped.
|
| 779 |
+
|
| 780 |
+
Note that the ordering of the individual specifiers within the set may not
|
| 781 |
+
match the input string.
|
| 782 |
+
|
| 783 |
+
>>> str(SpecifierSet(">=1.0.0,!=1.0.1"))
|
| 784 |
+
'!=1.0.1,>=1.0.0'
|
| 785 |
+
>>> str(SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False))
|
| 786 |
+
'!=1.0.1,>=1.0.0'
|
| 787 |
+
"""
|
| 788 |
+
return ",".join(sorted(str(s) for s in self._specs))
|
| 789 |
+
|
| 790 |
+
def __hash__(self) -> int:
|
| 791 |
+
return hash(self._specs)
|
| 792 |
+
|
| 793 |
+
def __and__(self, other: SpecifierSet | str) -> SpecifierSet:
|
| 794 |
+
"""Return a SpecifierSet which is a combination of the two sets.
|
| 795 |
+
|
| 796 |
+
:param other: The other object to combine with.
|
| 797 |
+
|
| 798 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1") & '<=2.0.0,!=2.0.1'
|
| 799 |
+
<SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')>
|
| 800 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1") & SpecifierSet('<=2.0.0,!=2.0.1')
|
| 801 |
+
<SpecifierSet('!=1.0.1,!=2.0.1,<=2.0.0,>=1.0.0')>
|
| 802 |
+
"""
|
| 803 |
+
if isinstance(other, str):
|
| 804 |
+
other = SpecifierSet(other)
|
| 805 |
+
elif not isinstance(other, SpecifierSet):
|
| 806 |
+
return NotImplemented
|
| 807 |
+
|
| 808 |
+
specifier = SpecifierSet()
|
| 809 |
+
specifier._specs = frozenset(self._specs | other._specs)
|
| 810 |
+
|
| 811 |
+
if self._prereleases is None and other._prereleases is not None:
|
| 812 |
+
specifier._prereleases = other._prereleases
|
| 813 |
+
elif self._prereleases is not None and other._prereleases is None:
|
| 814 |
+
specifier._prereleases = self._prereleases
|
| 815 |
+
elif self._prereleases == other._prereleases:
|
| 816 |
+
specifier._prereleases = self._prereleases
|
| 817 |
+
else:
|
| 818 |
+
raise ValueError(
|
| 819 |
+
"Cannot combine SpecifierSets with True and False prerelease "
|
| 820 |
+
"overrides."
|
| 821 |
+
)
|
| 822 |
+
|
| 823 |
+
return specifier
|
| 824 |
+
|
| 825 |
+
def __eq__(self, other: object) -> bool:
|
| 826 |
+
"""Whether or not the two SpecifierSet-like objects are equal.
|
| 827 |
+
|
| 828 |
+
:param other: The other object to check against.
|
| 829 |
+
|
| 830 |
+
The value of :attr:`prereleases` is ignored.
|
| 831 |
+
|
| 832 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.1")
|
| 833 |
+
True
|
| 834 |
+
>>> (SpecifierSet(">=1.0.0,!=1.0.1", prereleases=False) ==
|
| 835 |
+
... SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True))
|
| 836 |
+
True
|
| 837 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1") == ">=1.0.0,!=1.0.1"
|
| 838 |
+
True
|
| 839 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0")
|
| 840 |
+
False
|
| 841 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1") == SpecifierSet(">=1.0.0,!=1.0.2")
|
| 842 |
+
False
|
| 843 |
+
"""
|
| 844 |
+
if isinstance(other, (str, Specifier)):
|
| 845 |
+
other = SpecifierSet(str(other))
|
| 846 |
+
elif not isinstance(other, SpecifierSet):
|
| 847 |
+
return NotImplemented
|
| 848 |
+
|
| 849 |
+
return self._specs == other._specs
|
| 850 |
+
|
| 851 |
+
def __len__(self) -> int:
|
| 852 |
+
"""Returns the number of specifiers in this specifier set."""
|
| 853 |
+
return len(self._specs)
|
| 854 |
+
|
| 855 |
+
def __iter__(self) -> Iterator[Specifier]:
|
| 856 |
+
"""
|
| 857 |
+
Returns an iterator over all the underlying :class:`Specifier` instances
|
| 858 |
+
in this specifier set.
|
| 859 |
+
|
| 860 |
+
>>> sorted(SpecifierSet(">=1.0.0,!=1.0.1"), key=str)
|
| 861 |
+
[<Specifier('!=1.0.1')>, <Specifier('>=1.0.0')>]
|
| 862 |
+
"""
|
| 863 |
+
return iter(self._specs)
|
| 864 |
+
|
| 865 |
+
def __contains__(self, item: UnparsedVersion) -> bool:
|
| 866 |
+
"""Return whether or not the item is contained in this specifier.
|
| 867 |
+
|
| 868 |
+
:param item: The item to check for.
|
| 869 |
+
|
| 870 |
+
This is used for the ``in`` operator and behaves the same as
|
| 871 |
+
:meth:`contains` with no ``prereleases`` argument passed.
|
| 872 |
+
|
| 873 |
+
>>> "1.2.3" in SpecifierSet(">=1.0.0,!=1.0.1")
|
| 874 |
+
True
|
| 875 |
+
>>> Version("1.2.3") in SpecifierSet(">=1.0.0,!=1.0.1")
|
| 876 |
+
True
|
| 877 |
+
>>> "1.0.1" in SpecifierSet(">=1.0.0,!=1.0.1")
|
| 878 |
+
False
|
| 879 |
+
>>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1")
|
| 880 |
+
False
|
| 881 |
+
>>> "1.3.0a1" in SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True)
|
| 882 |
+
True
|
| 883 |
+
"""
|
| 884 |
+
return self.contains(item)
|
| 885 |
+
|
| 886 |
+
def contains(
|
| 887 |
+
self,
|
| 888 |
+
item: UnparsedVersion,
|
| 889 |
+
prereleases: bool | None = None,
|
| 890 |
+
installed: bool | None = None,
|
| 891 |
+
) -> bool:
|
| 892 |
+
"""Return whether or not the item is contained in this SpecifierSet.
|
| 893 |
+
|
| 894 |
+
:param item:
|
| 895 |
+
The item to check for, which can be a version string or a
|
| 896 |
+
:class:`Version` instance.
|
| 897 |
+
:param prereleases:
|
| 898 |
+
Whether or not to match prereleases with this SpecifierSet. If set to
|
| 899 |
+
``None`` (the default), it uses :attr:`prereleases` to determine
|
| 900 |
+
whether or not prereleases are allowed.
|
| 901 |
+
|
| 902 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.2.3")
|
| 903 |
+
True
|
| 904 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1").contains(Version("1.2.3"))
|
| 905 |
+
True
|
| 906 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.0.1")
|
| 907 |
+
False
|
| 908 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1")
|
| 909 |
+
False
|
| 910 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1", prereleases=True).contains("1.3.0a1")
|
| 911 |
+
True
|
| 912 |
+
>>> SpecifierSet(">=1.0.0,!=1.0.1").contains("1.3.0a1", prereleases=True)
|
| 913 |
+
True
|
| 914 |
+
"""
|
| 915 |
+
# Ensure that our item is a Version instance.
|
| 916 |
+
if not isinstance(item, Version):
|
| 917 |
+
item = Version(item)
|
| 918 |
+
|
| 919 |
+
# Determine if we're forcing a prerelease or not, if we're not forcing
|
| 920 |
+
# one for this particular filter call, then we'll use whatever the
|
| 921 |
+
# SpecifierSet thinks for whether or not we should support prereleases.
|
| 922 |
+
if prereleases is None:
|
| 923 |
+
prereleases = self.prereleases
|
| 924 |
+
|
| 925 |
+
# We can determine if we're going to allow pre-releases by looking to
|
| 926 |
+
# see if any of the underlying items supports them. If none of them do
|
| 927 |
+
# and this item is a pre-release then we do not allow it and we can
|
| 928 |
+
# short circuit that here.
|
| 929 |
+
# Note: This means that 1.0.dev1 would not be contained in something
|
| 930 |
+
# like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0
|
| 931 |
+
if not prereleases and item.is_prerelease:
|
| 932 |
+
return False
|
| 933 |
+
|
| 934 |
+
if installed and item.is_prerelease:
|
| 935 |
+
item = Version(item.base_version)
|
| 936 |
+
|
| 937 |
+
# We simply dispatch to the underlying specs here to make sure that the
|
| 938 |
+
# given version is contained within all of them.
|
| 939 |
+
# Note: This use of all() here means that an empty set of specifiers
|
| 940 |
+
# will always return True, this is an explicit design decision.
|
| 941 |
+
return all(s.contains(item, prereleases=prereleases) for s in self._specs)
|
| 942 |
+
|
| 943 |
+
def filter(
|
| 944 |
+
self, iterable: Iterable[UnparsedVersionVar], prereleases: bool | None = None
|
| 945 |
+
) -> Iterator[UnparsedVersionVar]:
|
| 946 |
+
"""Filter items in the given iterable, that match the specifiers in this set.
|
| 947 |
+
|
| 948 |
+
:param iterable:
|
| 949 |
+
An iterable that can contain version strings and :class:`Version` instances.
|
| 950 |
+
The items in the iterable will be filtered according to the specifier.
|
| 951 |
+
:param prereleases:
|
| 952 |
+
Whether or not to allow prereleases in the returned iterator. If set to
|
| 953 |
+
``None`` (the default), it will be intelligently decide whether to allow
|
| 954 |
+
prereleases or not (based on the :attr:`prereleases` attribute, and
|
| 955 |
+
whether the only versions matching are prereleases).
|
| 956 |
+
|
| 957 |
+
This method is smarter than just ``filter(SpecifierSet(...).contains, [...])``
|
| 958 |
+
because it implements the rule from :pep:`440` that a prerelease item
|
| 959 |
+
SHOULD be accepted if no other versions match the given specifier.
|
| 960 |
+
|
| 961 |
+
>>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", "1.5a1"]))
|
| 962 |
+
['1.3']
|
| 963 |
+
>>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.3", Version("1.4")]))
|
| 964 |
+
['1.3', <Version('1.4')>]
|
| 965 |
+
>>> list(SpecifierSet(">=1.2.3").filter(["1.2", "1.5a1"]))
|
| 966 |
+
[]
|
| 967 |
+
>>> list(SpecifierSet(">=1.2.3").filter(["1.3", "1.5a1"], prereleases=True))
|
| 968 |
+
['1.3', '1.5a1']
|
| 969 |
+
>>> list(SpecifierSet(">=1.2.3", prereleases=True).filter(["1.3", "1.5a1"]))
|
| 970 |
+
['1.3', '1.5a1']
|
| 971 |
+
|
| 972 |
+
An "empty" SpecifierSet will filter items based on the presence of prerelease
|
| 973 |
+
versions in the set.
|
| 974 |
+
|
| 975 |
+
>>> list(SpecifierSet("").filter(["1.3", "1.5a1"]))
|
| 976 |
+
['1.3']
|
| 977 |
+
>>> list(SpecifierSet("").filter(["1.5a1"]))
|
| 978 |
+
['1.5a1']
|
| 979 |
+
>>> list(SpecifierSet("", prereleases=True).filter(["1.3", "1.5a1"]))
|
| 980 |
+
['1.3', '1.5a1']
|
| 981 |
+
>>> list(SpecifierSet("").filter(["1.3", "1.5a1"], prereleases=True))
|
| 982 |
+
['1.3', '1.5a1']
|
| 983 |
+
"""
|
| 984 |
+
# Determine if we're forcing a prerelease or not, if we're not forcing
|
| 985 |
+
# one for this particular filter call, then we'll use whatever the
|
| 986 |
+
# SpecifierSet thinks for whether or not we should support prereleases.
|
| 987 |
+
if prereleases is None:
|
| 988 |
+
prereleases = self.prereleases
|
| 989 |
+
|
| 990 |
+
# If we have any specifiers, then we want to wrap our iterable in the
|
| 991 |
+
# filter method for each one, this will act as a logical AND amongst
|
| 992 |
+
# each specifier.
|
| 993 |
+
if self._specs:
|
| 994 |
+
for spec in self._specs:
|
| 995 |
+
iterable = spec.filter(iterable, prereleases=bool(prereleases))
|
| 996 |
+
return iter(iterable)
|
| 997 |
+
# If we do not have any specifiers, then we need to have a rough filter
|
| 998 |
+
# which will filter out any pre-releases, unless there are no final
|
| 999 |
+
# releases.
|
| 1000 |
+
else:
|
| 1001 |
+
filtered: list[UnparsedVersionVar] = []
|
| 1002 |
+
found_prereleases: list[UnparsedVersionVar] = []
|
| 1003 |
+
|
| 1004 |
+
for item in iterable:
|
| 1005 |
+
parsed_version = _coerce_version(item)
|
| 1006 |
+
|
| 1007 |
+
# Store any item which is a pre-release for later unless we've
|
| 1008 |
+
# already found a final version or we are accepting prereleases
|
| 1009 |
+
if parsed_version.is_prerelease and not prereleases:
|
| 1010 |
+
if not filtered:
|
| 1011 |
+
found_prereleases.append(item)
|
| 1012 |
+
else:
|
| 1013 |
+
filtered.append(item)
|
| 1014 |
+
|
| 1015 |
+
# If we've found no items except for pre-releases, then we'll go
|
| 1016 |
+
# ahead and use the pre-releases
|
| 1017 |
+
if not filtered and found_prereleases and prereleases is None:
|
| 1018 |
+
return iter(found_prereleases)
|
| 1019 |
+
|
| 1020 |
+
return iter(filtered)
|
.venv/lib/python3.11/site-packages/packaging/utils.py
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# This file is dual licensed under the terms of the Apache License, Version
|
| 2 |
+
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
|
| 3 |
+
# for complete details.
|
| 4 |
+
|
| 5 |
+
from __future__ import annotations
|
| 6 |
+
|
| 7 |
+
import functools
|
| 8 |
+
import re
|
| 9 |
+
from typing import NewType, Tuple, Union, cast
|
| 10 |
+
|
| 11 |
+
from .tags import Tag, parse_tag
|
| 12 |
+
from .version import InvalidVersion, Version, _TrimmedRelease
|
| 13 |
+
|
| 14 |
+
BuildTag = Union[Tuple[()], Tuple[int, str]]
|
| 15 |
+
NormalizedName = NewType("NormalizedName", str)
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class InvalidName(ValueError):
|
| 19 |
+
"""
|
| 20 |
+
An invalid distribution name; users should refer to the packaging user guide.
|
| 21 |
+
"""
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class InvalidWheelFilename(ValueError):
|
| 25 |
+
"""
|
| 26 |
+
An invalid wheel filename was found, users should refer to PEP 427.
|
| 27 |
+
"""
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
class InvalidSdistFilename(ValueError):
|
| 31 |
+
"""
|
| 32 |
+
An invalid sdist filename was found, users should refer to the packaging user guide.
|
| 33 |
+
"""
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
# Core metadata spec for `Name`
|
| 37 |
+
_validate_regex = re.compile(
|
| 38 |
+
r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE
|
| 39 |
+
)
|
| 40 |
+
_canonicalize_regex = re.compile(r"[-_.]+")
|
| 41 |
+
_normalized_regex = re.compile(r"^([a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9])$")
|
| 42 |
+
# PEP 427: The build number must start with a digit.
|
| 43 |
+
_build_tag_regex = re.compile(r"(\d+)(.*)")
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
|
| 47 |
+
if validate and not _validate_regex.match(name):
|
| 48 |
+
raise InvalidName(f"name is invalid: {name!r}")
|
| 49 |
+
# This is taken from PEP 503.
|
| 50 |
+
value = _canonicalize_regex.sub("-", name).lower()
|
| 51 |
+
return cast(NormalizedName, value)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def is_normalized_name(name: str) -> bool:
|
| 55 |
+
return _normalized_regex.match(name) is not None
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
@functools.singledispatch
|
| 59 |
+
def canonicalize_version(
|
| 60 |
+
version: Version | str, *, strip_trailing_zero: bool = True
|
| 61 |
+
) -> str:
|
| 62 |
+
"""
|
| 63 |
+
Return a canonical form of a version as a string.
|
| 64 |
+
|
| 65 |
+
>>> canonicalize_version('1.0.1')
|
| 66 |
+
'1.0.1'
|
| 67 |
+
|
| 68 |
+
Per PEP 625, versions may have multiple canonical forms, differing
|
| 69 |
+
only by trailing zeros.
|
| 70 |
+
|
| 71 |
+
>>> canonicalize_version('1.0.0')
|
| 72 |
+
'1'
|
| 73 |
+
>>> canonicalize_version('1.0.0', strip_trailing_zero=False)
|
| 74 |
+
'1.0.0'
|
| 75 |
+
|
| 76 |
+
Invalid versions are returned unaltered.
|
| 77 |
+
|
| 78 |
+
>>> canonicalize_version('foo bar baz')
|
| 79 |
+
'foo bar baz'
|
| 80 |
+
"""
|
| 81 |
+
return str(_TrimmedRelease(str(version)) if strip_trailing_zero else version)
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
@canonicalize_version.register
|
| 85 |
+
def _(version: str, *, strip_trailing_zero: bool = True) -> str:
|
| 86 |
+
try:
|
| 87 |
+
parsed = Version(version)
|
| 88 |
+
except InvalidVersion:
|
| 89 |
+
# Legacy versions cannot be normalized
|
| 90 |
+
return version
|
| 91 |
+
return canonicalize_version(parsed, strip_trailing_zero=strip_trailing_zero)
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def parse_wheel_filename(
|
| 95 |
+
filename: str,
|
| 96 |
+
) -> tuple[NormalizedName, Version, BuildTag, frozenset[Tag]]:
|
| 97 |
+
if not filename.endswith(".whl"):
|
| 98 |
+
raise InvalidWheelFilename(
|
| 99 |
+
f"Invalid wheel filename (extension must be '.whl'): {filename!r}"
|
| 100 |
+
)
|
| 101 |
+
|
| 102 |
+
filename = filename[:-4]
|
| 103 |
+
dashes = filename.count("-")
|
| 104 |
+
if dashes not in (4, 5):
|
| 105 |
+
raise InvalidWheelFilename(
|
| 106 |
+
f"Invalid wheel filename (wrong number of parts): {filename!r}"
|
| 107 |
+
)
|
| 108 |
+
|
| 109 |
+
parts = filename.split("-", dashes - 2)
|
| 110 |
+
name_part = parts[0]
|
| 111 |
+
# See PEP 427 for the rules on escaping the project name.
|
| 112 |
+
if "__" in name_part or re.match(r"^[\w\d._]*$", name_part, re.UNICODE) is None:
|
| 113 |
+
raise InvalidWheelFilename(f"Invalid project name: {filename!r}")
|
| 114 |
+
name = canonicalize_name(name_part)
|
| 115 |
+
|
| 116 |
+
try:
|
| 117 |
+
version = Version(parts[1])
|
| 118 |
+
except InvalidVersion as e:
|
| 119 |
+
raise InvalidWheelFilename(
|
| 120 |
+
f"Invalid wheel filename (invalid version): {filename!r}"
|
| 121 |
+
) from e
|
| 122 |
+
|
| 123 |
+
if dashes == 5:
|
| 124 |
+
build_part = parts[2]
|
| 125 |
+
build_match = _build_tag_regex.match(build_part)
|
| 126 |
+
if build_match is None:
|
| 127 |
+
raise InvalidWheelFilename(
|
| 128 |
+
f"Invalid build number: {build_part} in {filename!r}"
|
| 129 |
+
)
|
| 130 |
+
build = cast(BuildTag, (int(build_match.group(1)), build_match.group(2)))
|
| 131 |
+
else:
|
| 132 |
+
build = ()
|
| 133 |
+
tags = parse_tag(parts[-1])
|
| 134 |
+
return (name, version, build, tags)
|
| 135 |
+
|
| 136 |
+
|
| 137 |
+
def parse_sdist_filename(filename: str) -> tuple[NormalizedName, Version]:
|
| 138 |
+
if filename.endswith(".tar.gz"):
|
| 139 |
+
file_stem = filename[: -len(".tar.gz")]
|
| 140 |
+
elif filename.endswith(".zip"):
|
| 141 |
+
file_stem = filename[: -len(".zip")]
|
| 142 |
+
else:
|
| 143 |
+
raise InvalidSdistFilename(
|
| 144 |
+
f"Invalid sdist filename (extension must be '.tar.gz' or '.zip'):"
|
| 145 |
+
f" {filename!r}"
|
| 146 |
+
)
|
| 147 |
+
|
| 148 |
+
# We are requiring a PEP 440 version, which cannot contain dashes,
|
| 149 |
+
# so we split on the last dash.
|
| 150 |
+
name_part, sep, version_part = file_stem.rpartition("-")
|
| 151 |
+
if not sep:
|
| 152 |
+
raise InvalidSdistFilename(f"Invalid sdist filename: {filename!r}")
|
| 153 |
+
|
| 154 |
+
name = canonicalize_name(name_part)
|
| 155 |
+
|
| 156 |
+
try:
|
| 157 |
+
version = Version(version_part)
|
| 158 |
+
except InvalidVersion as e:
|
| 159 |
+
raise InvalidSdistFilename(
|
| 160 |
+
f"Invalid sdist filename (invalid version): {filename!r}"
|
| 161 |
+
) from e
|
| 162 |
+
|
| 163 |
+
return (name, version)
|
.venv/lib/python3.11/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (1.09 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pip/_vendor/pkg_resources/__init__.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
.venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__init__.py
ADDED
|
@@ -0,0 +1,566 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Utilities for determining application-specific dirs. See <https://github.com/platformdirs/platformdirs> for details and
|
| 3 |
+
usage.
|
| 4 |
+
"""
|
| 5 |
+
from __future__ import annotations
|
| 6 |
+
|
| 7 |
+
import os
|
| 8 |
+
import sys
|
| 9 |
+
from typing import TYPE_CHECKING
|
| 10 |
+
|
| 11 |
+
from .api import PlatformDirsABC
|
| 12 |
+
from .version import __version__
|
| 13 |
+
from .version import __version_tuple__ as __version_info__
|
| 14 |
+
|
| 15 |
+
if TYPE_CHECKING:
|
| 16 |
+
from pathlib import Path
|
| 17 |
+
|
| 18 |
+
if sys.version_info >= (3, 8): # pragma: no cover (py38+)
|
| 19 |
+
from typing import Literal
|
| 20 |
+
else: # pragma: no cover (py38+)
|
| 21 |
+
from pip._vendor.typing_extensions import Literal
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def _set_platform_dir_class() -> type[PlatformDirsABC]:
|
| 25 |
+
if sys.platform == "win32":
|
| 26 |
+
from pip._vendor.platformdirs.windows import Windows as Result
|
| 27 |
+
elif sys.platform == "darwin":
|
| 28 |
+
from pip._vendor.platformdirs.macos import MacOS as Result
|
| 29 |
+
else:
|
| 30 |
+
from pip._vendor.platformdirs.unix import Unix as Result
|
| 31 |
+
|
| 32 |
+
if os.getenv("ANDROID_DATA") == "/data" and os.getenv("ANDROID_ROOT") == "/system":
|
| 33 |
+
if os.getenv("SHELL") or os.getenv("PREFIX"):
|
| 34 |
+
return Result
|
| 35 |
+
|
| 36 |
+
from pip._vendor.platformdirs.android import _android_folder
|
| 37 |
+
|
| 38 |
+
if _android_folder() is not None:
|
| 39 |
+
from pip._vendor.platformdirs.android import Android
|
| 40 |
+
|
| 41 |
+
return Android # return to avoid redefinition of result
|
| 42 |
+
|
| 43 |
+
return Result
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
PlatformDirs = _set_platform_dir_class() #: Currently active platform
|
| 47 |
+
AppDirs = PlatformDirs #: Backwards compatibility with appdirs
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def user_data_dir(
|
| 51 |
+
appname: str | None = None,
|
| 52 |
+
appauthor: str | None | Literal[False] = None,
|
| 53 |
+
version: str | None = None,
|
| 54 |
+
roaming: bool = False, # noqa: FBT001, FBT002
|
| 55 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 56 |
+
) -> str:
|
| 57 |
+
"""
|
| 58 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 59 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 60 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 61 |
+
:param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
|
| 62 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 63 |
+
:returns: data directory tied to the user
|
| 64 |
+
"""
|
| 65 |
+
return PlatformDirs(
|
| 66 |
+
appname=appname,
|
| 67 |
+
appauthor=appauthor,
|
| 68 |
+
version=version,
|
| 69 |
+
roaming=roaming,
|
| 70 |
+
ensure_exists=ensure_exists,
|
| 71 |
+
).user_data_dir
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
def site_data_dir(
|
| 75 |
+
appname: str | None = None,
|
| 76 |
+
appauthor: str | None | Literal[False] = None,
|
| 77 |
+
version: str | None = None,
|
| 78 |
+
multipath: bool = False, # noqa: FBT001, FBT002
|
| 79 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 80 |
+
) -> str:
|
| 81 |
+
"""
|
| 82 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 83 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 84 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 85 |
+
:param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
|
| 86 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 87 |
+
:returns: data directory shared by users
|
| 88 |
+
"""
|
| 89 |
+
return PlatformDirs(
|
| 90 |
+
appname=appname,
|
| 91 |
+
appauthor=appauthor,
|
| 92 |
+
version=version,
|
| 93 |
+
multipath=multipath,
|
| 94 |
+
ensure_exists=ensure_exists,
|
| 95 |
+
).site_data_dir
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
def user_config_dir(
|
| 99 |
+
appname: str | None = None,
|
| 100 |
+
appauthor: str | None | Literal[False] = None,
|
| 101 |
+
version: str | None = None,
|
| 102 |
+
roaming: bool = False, # noqa: FBT001, FBT002
|
| 103 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 104 |
+
) -> str:
|
| 105 |
+
"""
|
| 106 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 107 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 108 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 109 |
+
:param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
|
| 110 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 111 |
+
:returns: config directory tied to the user
|
| 112 |
+
"""
|
| 113 |
+
return PlatformDirs(
|
| 114 |
+
appname=appname,
|
| 115 |
+
appauthor=appauthor,
|
| 116 |
+
version=version,
|
| 117 |
+
roaming=roaming,
|
| 118 |
+
ensure_exists=ensure_exists,
|
| 119 |
+
).user_config_dir
|
| 120 |
+
|
| 121 |
+
|
| 122 |
+
def site_config_dir(
|
| 123 |
+
appname: str | None = None,
|
| 124 |
+
appauthor: str | None | Literal[False] = None,
|
| 125 |
+
version: str | None = None,
|
| 126 |
+
multipath: bool = False, # noqa: FBT001, FBT002
|
| 127 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 128 |
+
) -> str:
|
| 129 |
+
"""
|
| 130 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 131 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 132 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 133 |
+
:param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
|
| 134 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 135 |
+
:returns: config directory shared by the users
|
| 136 |
+
"""
|
| 137 |
+
return PlatformDirs(
|
| 138 |
+
appname=appname,
|
| 139 |
+
appauthor=appauthor,
|
| 140 |
+
version=version,
|
| 141 |
+
multipath=multipath,
|
| 142 |
+
ensure_exists=ensure_exists,
|
| 143 |
+
).site_config_dir
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
def user_cache_dir(
|
| 147 |
+
appname: str | None = None,
|
| 148 |
+
appauthor: str | None | Literal[False] = None,
|
| 149 |
+
version: str | None = None,
|
| 150 |
+
opinion: bool = True, # noqa: FBT001, FBT002
|
| 151 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 152 |
+
) -> str:
|
| 153 |
+
"""
|
| 154 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 155 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 156 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 157 |
+
:param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
|
| 158 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 159 |
+
:returns: cache directory tied to the user
|
| 160 |
+
"""
|
| 161 |
+
return PlatformDirs(
|
| 162 |
+
appname=appname,
|
| 163 |
+
appauthor=appauthor,
|
| 164 |
+
version=version,
|
| 165 |
+
opinion=opinion,
|
| 166 |
+
ensure_exists=ensure_exists,
|
| 167 |
+
).user_cache_dir
|
| 168 |
+
|
| 169 |
+
|
| 170 |
+
def site_cache_dir(
|
| 171 |
+
appname: str | None = None,
|
| 172 |
+
appauthor: str | None | Literal[False] = None,
|
| 173 |
+
version: str | None = None,
|
| 174 |
+
opinion: bool = True, # noqa: FBT001, FBT002
|
| 175 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 176 |
+
) -> str:
|
| 177 |
+
"""
|
| 178 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 179 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 180 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 181 |
+
:param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
|
| 182 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 183 |
+
:returns: cache directory tied to the user
|
| 184 |
+
"""
|
| 185 |
+
return PlatformDirs(
|
| 186 |
+
appname=appname,
|
| 187 |
+
appauthor=appauthor,
|
| 188 |
+
version=version,
|
| 189 |
+
opinion=opinion,
|
| 190 |
+
ensure_exists=ensure_exists,
|
| 191 |
+
).site_cache_dir
|
| 192 |
+
|
| 193 |
+
|
| 194 |
+
def user_state_dir(
|
| 195 |
+
appname: str | None = None,
|
| 196 |
+
appauthor: str | None | Literal[False] = None,
|
| 197 |
+
version: str | None = None,
|
| 198 |
+
roaming: bool = False, # noqa: FBT001, FBT002
|
| 199 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 200 |
+
) -> str:
|
| 201 |
+
"""
|
| 202 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 203 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 204 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 205 |
+
:param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
|
| 206 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 207 |
+
:returns: state directory tied to the user
|
| 208 |
+
"""
|
| 209 |
+
return PlatformDirs(
|
| 210 |
+
appname=appname,
|
| 211 |
+
appauthor=appauthor,
|
| 212 |
+
version=version,
|
| 213 |
+
roaming=roaming,
|
| 214 |
+
ensure_exists=ensure_exists,
|
| 215 |
+
).user_state_dir
|
| 216 |
+
|
| 217 |
+
|
| 218 |
+
def user_log_dir(
|
| 219 |
+
appname: str | None = None,
|
| 220 |
+
appauthor: str | None | Literal[False] = None,
|
| 221 |
+
version: str | None = None,
|
| 222 |
+
opinion: bool = True, # noqa: FBT001, FBT002
|
| 223 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 224 |
+
) -> str:
|
| 225 |
+
"""
|
| 226 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 227 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 228 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 229 |
+
:param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
|
| 230 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 231 |
+
:returns: log directory tied to the user
|
| 232 |
+
"""
|
| 233 |
+
return PlatformDirs(
|
| 234 |
+
appname=appname,
|
| 235 |
+
appauthor=appauthor,
|
| 236 |
+
version=version,
|
| 237 |
+
opinion=opinion,
|
| 238 |
+
ensure_exists=ensure_exists,
|
| 239 |
+
).user_log_dir
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
def user_documents_dir() -> str:
|
| 243 |
+
""":returns: documents directory tied to the user"""
|
| 244 |
+
return PlatformDirs().user_documents_dir
|
| 245 |
+
|
| 246 |
+
|
| 247 |
+
def user_downloads_dir() -> str:
|
| 248 |
+
""":returns: downloads directory tied to the user"""
|
| 249 |
+
return PlatformDirs().user_downloads_dir
|
| 250 |
+
|
| 251 |
+
|
| 252 |
+
def user_pictures_dir() -> str:
|
| 253 |
+
""":returns: pictures directory tied to the user"""
|
| 254 |
+
return PlatformDirs().user_pictures_dir
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
def user_videos_dir() -> str:
|
| 258 |
+
""":returns: videos directory tied to the user"""
|
| 259 |
+
return PlatformDirs().user_videos_dir
|
| 260 |
+
|
| 261 |
+
|
| 262 |
+
def user_music_dir() -> str:
|
| 263 |
+
""":returns: music directory tied to the user"""
|
| 264 |
+
return PlatformDirs().user_music_dir
|
| 265 |
+
|
| 266 |
+
|
| 267 |
+
def user_runtime_dir(
|
| 268 |
+
appname: str | None = None,
|
| 269 |
+
appauthor: str | None | Literal[False] = None,
|
| 270 |
+
version: str | None = None,
|
| 271 |
+
opinion: bool = True, # noqa: FBT001, FBT002
|
| 272 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 273 |
+
) -> str:
|
| 274 |
+
"""
|
| 275 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 276 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 277 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 278 |
+
:param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
|
| 279 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 280 |
+
:returns: runtime directory tied to the user
|
| 281 |
+
"""
|
| 282 |
+
return PlatformDirs(
|
| 283 |
+
appname=appname,
|
| 284 |
+
appauthor=appauthor,
|
| 285 |
+
version=version,
|
| 286 |
+
opinion=opinion,
|
| 287 |
+
ensure_exists=ensure_exists,
|
| 288 |
+
).user_runtime_dir
|
| 289 |
+
|
| 290 |
+
|
| 291 |
+
def user_data_path(
|
| 292 |
+
appname: str | None = None,
|
| 293 |
+
appauthor: str | None | Literal[False] = None,
|
| 294 |
+
version: str | None = None,
|
| 295 |
+
roaming: bool = False, # noqa: FBT001, FBT002
|
| 296 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 297 |
+
) -> Path:
|
| 298 |
+
"""
|
| 299 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 300 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 301 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 302 |
+
:param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
|
| 303 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 304 |
+
:returns: data path tied to the user
|
| 305 |
+
"""
|
| 306 |
+
return PlatformDirs(
|
| 307 |
+
appname=appname,
|
| 308 |
+
appauthor=appauthor,
|
| 309 |
+
version=version,
|
| 310 |
+
roaming=roaming,
|
| 311 |
+
ensure_exists=ensure_exists,
|
| 312 |
+
).user_data_path
|
| 313 |
+
|
| 314 |
+
|
| 315 |
+
def site_data_path(
|
| 316 |
+
appname: str | None = None,
|
| 317 |
+
appauthor: str | None | Literal[False] = None,
|
| 318 |
+
version: str | None = None,
|
| 319 |
+
multipath: bool = False, # noqa: FBT001, FBT002
|
| 320 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 321 |
+
) -> Path:
|
| 322 |
+
"""
|
| 323 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 324 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 325 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 326 |
+
:param multipath: See `multipath <platformdirs.api.PlatformDirsABC.multipath>`.
|
| 327 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 328 |
+
:returns: data path shared by users
|
| 329 |
+
"""
|
| 330 |
+
return PlatformDirs(
|
| 331 |
+
appname=appname,
|
| 332 |
+
appauthor=appauthor,
|
| 333 |
+
version=version,
|
| 334 |
+
multipath=multipath,
|
| 335 |
+
ensure_exists=ensure_exists,
|
| 336 |
+
).site_data_path
|
| 337 |
+
|
| 338 |
+
|
| 339 |
+
def user_config_path(
|
| 340 |
+
appname: str | None = None,
|
| 341 |
+
appauthor: str | None | Literal[False] = None,
|
| 342 |
+
version: str | None = None,
|
| 343 |
+
roaming: bool = False, # noqa: FBT001, FBT002
|
| 344 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 345 |
+
) -> Path:
|
| 346 |
+
"""
|
| 347 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 348 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 349 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 350 |
+
:param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
|
| 351 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 352 |
+
:returns: config path tied to the user
|
| 353 |
+
"""
|
| 354 |
+
return PlatformDirs(
|
| 355 |
+
appname=appname,
|
| 356 |
+
appauthor=appauthor,
|
| 357 |
+
version=version,
|
| 358 |
+
roaming=roaming,
|
| 359 |
+
ensure_exists=ensure_exists,
|
| 360 |
+
).user_config_path
|
| 361 |
+
|
| 362 |
+
|
| 363 |
+
def site_config_path(
|
| 364 |
+
appname: str | None = None,
|
| 365 |
+
appauthor: str | None | Literal[False] = None,
|
| 366 |
+
version: str | None = None,
|
| 367 |
+
multipath: bool = False, # noqa: FBT001, FBT002
|
| 368 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 369 |
+
) -> Path:
|
| 370 |
+
"""
|
| 371 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 372 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 373 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 374 |
+
:param multipath: See `roaming <platformdirs.api.PlatformDirsABC.multipath>`.
|
| 375 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 376 |
+
:returns: config path shared by the users
|
| 377 |
+
"""
|
| 378 |
+
return PlatformDirs(
|
| 379 |
+
appname=appname,
|
| 380 |
+
appauthor=appauthor,
|
| 381 |
+
version=version,
|
| 382 |
+
multipath=multipath,
|
| 383 |
+
ensure_exists=ensure_exists,
|
| 384 |
+
).site_config_path
|
| 385 |
+
|
| 386 |
+
|
| 387 |
+
def site_cache_path(
|
| 388 |
+
appname: str | None = None,
|
| 389 |
+
appauthor: str | None | Literal[False] = None,
|
| 390 |
+
version: str | None = None,
|
| 391 |
+
opinion: bool = True, # noqa: FBT001, FBT002
|
| 392 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 393 |
+
) -> Path:
|
| 394 |
+
"""
|
| 395 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 396 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 397 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 398 |
+
:param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
|
| 399 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 400 |
+
:returns: cache directory tied to the user
|
| 401 |
+
"""
|
| 402 |
+
return PlatformDirs(
|
| 403 |
+
appname=appname,
|
| 404 |
+
appauthor=appauthor,
|
| 405 |
+
version=version,
|
| 406 |
+
opinion=opinion,
|
| 407 |
+
ensure_exists=ensure_exists,
|
| 408 |
+
).site_cache_path
|
| 409 |
+
|
| 410 |
+
|
| 411 |
+
def user_cache_path(
|
| 412 |
+
appname: str | None = None,
|
| 413 |
+
appauthor: str | None | Literal[False] = None,
|
| 414 |
+
version: str | None = None,
|
| 415 |
+
opinion: bool = True, # noqa: FBT001, FBT002
|
| 416 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 417 |
+
) -> Path:
|
| 418 |
+
"""
|
| 419 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 420 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 421 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 422 |
+
:param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
|
| 423 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 424 |
+
:returns: cache path tied to the user
|
| 425 |
+
"""
|
| 426 |
+
return PlatformDirs(
|
| 427 |
+
appname=appname,
|
| 428 |
+
appauthor=appauthor,
|
| 429 |
+
version=version,
|
| 430 |
+
opinion=opinion,
|
| 431 |
+
ensure_exists=ensure_exists,
|
| 432 |
+
).user_cache_path
|
| 433 |
+
|
| 434 |
+
|
| 435 |
+
def user_state_path(
|
| 436 |
+
appname: str | None = None,
|
| 437 |
+
appauthor: str | None | Literal[False] = None,
|
| 438 |
+
version: str | None = None,
|
| 439 |
+
roaming: bool = False, # noqa: FBT001, FBT002
|
| 440 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 441 |
+
) -> Path:
|
| 442 |
+
"""
|
| 443 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 444 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 445 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 446 |
+
:param roaming: See `roaming <platformdirs.api.PlatformDirsABC.roaming>`.
|
| 447 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 448 |
+
:returns: state path tied to the user
|
| 449 |
+
"""
|
| 450 |
+
return PlatformDirs(
|
| 451 |
+
appname=appname,
|
| 452 |
+
appauthor=appauthor,
|
| 453 |
+
version=version,
|
| 454 |
+
roaming=roaming,
|
| 455 |
+
ensure_exists=ensure_exists,
|
| 456 |
+
).user_state_path
|
| 457 |
+
|
| 458 |
+
|
| 459 |
+
def user_log_path(
|
| 460 |
+
appname: str | None = None,
|
| 461 |
+
appauthor: str | None | Literal[False] = None,
|
| 462 |
+
version: str | None = None,
|
| 463 |
+
opinion: bool = True, # noqa: FBT001, FBT002
|
| 464 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 465 |
+
) -> Path:
|
| 466 |
+
"""
|
| 467 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 468 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 469 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 470 |
+
:param opinion: See `roaming <platformdirs.api.PlatformDirsABC.opinion>`.
|
| 471 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 472 |
+
:returns: log path tied to the user
|
| 473 |
+
"""
|
| 474 |
+
return PlatformDirs(
|
| 475 |
+
appname=appname,
|
| 476 |
+
appauthor=appauthor,
|
| 477 |
+
version=version,
|
| 478 |
+
opinion=opinion,
|
| 479 |
+
ensure_exists=ensure_exists,
|
| 480 |
+
).user_log_path
|
| 481 |
+
|
| 482 |
+
|
| 483 |
+
def user_documents_path() -> Path:
|
| 484 |
+
""":returns: documents path tied to the user"""
|
| 485 |
+
return PlatformDirs().user_documents_path
|
| 486 |
+
|
| 487 |
+
|
| 488 |
+
def user_downloads_path() -> Path:
|
| 489 |
+
""":returns: downloads path tied to the user"""
|
| 490 |
+
return PlatformDirs().user_downloads_path
|
| 491 |
+
|
| 492 |
+
|
| 493 |
+
def user_pictures_path() -> Path:
|
| 494 |
+
""":returns: pictures path tied to the user"""
|
| 495 |
+
return PlatformDirs().user_pictures_path
|
| 496 |
+
|
| 497 |
+
|
| 498 |
+
def user_videos_path() -> Path:
|
| 499 |
+
""":returns: videos path tied to the user"""
|
| 500 |
+
return PlatformDirs().user_videos_path
|
| 501 |
+
|
| 502 |
+
|
| 503 |
+
def user_music_path() -> Path:
|
| 504 |
+
""":returns: music path tied to the user"""
|
| 505 |
+
return PlatformDirs().user_music_path
|
| 506 |
+
|
| 507 |
+
|
| 508 |
+
def user_runtime_path(
|
| 509 |
+
appname: str | None = None,
|
| 510 |
+
appauthor: str | None | Literal[False] = None,
|
| 511 |
+
version: str | None = None,
|
| 512 |
+
opinion: bool = True, # noqa: FBT001, FBT002
|
| 513 |
+
ensure_exists: bool = False, # noqa: FBT001, FBT002
|
| 514 |
+
) -> Path:
|
| 515 |
+
"""
|
| 516 |
+
:param appname: See `appname <platformdirs.api.PlatformDirsABC.appname>`.
|
| 517 |
+
:param appauthor: See `appauthor <platformdirs.api.PlatformDirsABC.appauthor>`.
|
| 518 |
+
:param version: See `version <platformdirs.api.PlatformDirsABC.version>`.
|
| 519 |
+
:param opinion: See `opinion <platformdirs.api.PlatformDirsABC.opinion>`.
|
| 520 |
+
:param ensure_exists: See `ensure_exists <platformdirs.api.PlatformDirsABC.ensure_exists>`.
|
| 521 |
+
:returns: runtime path tied to the user
|
| 522 |
+
"""
|
| 523 |
+
return PlatformDirs(
|
| 524 |
+
appname=appname,
|
| 525 |
+
appauthor=appauthor,
|
| 526 |
+
version=version,
|
| 527 |
+
opinion=opinion,
|
| 528 |
+
ensure_exists=ensure_exists,
|
| 529 |
+
).user_runtime_path
|
| 530 |
+
|
| 531 |
+
|
| 532 |
+
__all__ = [
|
| 533 |
+
"__version__",
|
| 534 |
+
"__version_info__",
|
| 535 |
+
"PlatformDirs",
|
| 536 |
+
"AppDirs",
|
| 537 |
+
"PlatformDirsABC",
|
| 538 |
+
"user_data_dir",
|
| 539 |
+
"user_config_dir",
|
| 540 |
+
"user_cache_dir",
|
| 541 |
+
"user_state_dir",
|
| 542 |
+
"user_log_dir",
|
| 543 |
+
"user_documents_dir",
|
| 544 |
+
"user_downloads_dir",
|
| 545 |
+
"user_pictures_dir",
|
| 546 |
+
"user_videos_dir",
|
| 547 |
+
"user_music_dir",
|
| 548 |
+
"user_runtime_dir",
|
| 549 |
+
"site_data_dir",
|
| 550 |
+
"site_config_dir",
|
| 551 |
+
"site_cache_dir",
|
| 552 |
+
"user_data_path",
|
| 553 |
+
"user_config_path",
|
| 554 |
+
"user_cache_path",
|
| 555 |
+
"user_state_path",
|
| 556 |
+
"user_log_path",
|
| 557 |
+
"user_documents_path",
|
| 558 |
+
"user_downloads_path",
|
| 559 |
+
"user_pictures_path",
|
| 560 |
+
"user_videos_path",
|
| 561 |
+
"user_music_path",
|
| 562 |
+
"user_runtime_path",
|
| 563 |
+
"site_data_path",
|
| 564 |
+
"site_config_path",
|
| 565 |
+
"site_cache_path",
|
| 566 |
+
]
|
.venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__main__.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Main entry point."""
|
| 2 |
+
from __future__ import annotations
|
| 3 |
+
|
| 4 |
+
from pip._vendor.platformdirs import PlatformDirs, __version__
|
| 5 |
+
|
| 6 |
+
PROPS = (
|
| 7 |
+
"user_data_dir",
|
| 8 |
+
"user_config_dir",
|
| 9 |
+
"user_cache_dir",
|
| 10 |
+
"user_state_dir",
|
| 11 |
+
"user_log_dir",
|
| 12 |
+
"user_documents_dir",
|
| 13 |
+
"user_downloads_dir",
|
| 14 |
+
"user_pictures_dir",
|
| 15 |
+
"user_videos_dir",
|
| 16 |
+
"user_music_dir",
|
| 17 |
+
"user_runtime_dir",
|
| 18 |
+
"site_data_dir",
|
| 19 |
+
"site_config_dir",
|
| 20 |
+
"site_cache_dir",
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def main() -> None:
|
| 25 |
+
"""Run main entry point."""
|
| 26 |
+
app_name = "MyApp"
|
| 27 |
+
app_author = "MyCompany"
|
| 28 |
+
|
| 29 |
+
print(f"-- platformdirs {__version__} --") # noqa: T201
|
| 30 |
+
|
| 31 |
+
print("-- app dirs (with optional 'version')") # noqa: T201
|
| 32 |
+
dirs = PlatformDirs(app_name, app_author, version="1.0")
|
| 33 |
+
for prop in PROPS:
|
| 34 |
+
print(f"{prop}: {getattr(dirs, prop)}") # noqa: T201
|
| 35 |
+
|
| 36 |
+
print("\n-- app dirs (without optional 'version')") # noqa: T201
|
| 37 |
+
dirs = PlatformDirs(app_name, app_author)
|
| 38 |
+
for prop in PROPS:
|
| 39 |
+
print(f"{prop}: {getattr(dirs, prop)}") # noqa: T201
|
| 40 |
+
|
| 41 |
+
print("\n-- app dirs (without optional 'appauthor')") # noqa: T201
|
| 42 |
+
dirs = PlatformDirs(app_name)
|
| 43 |
+
for prop in PROPS:
|
| 44 |
+
print(f"{prop}: {getattr(dirs, prop)}") # noqa: T201
|
| 45 |
+
|
| 46 |
+
print("\n-- app dirs (with disabled 'appauthor')") # noqa: T201
|
| 47 |
+
dirs = PlatformDirs(app_name, appauthor=False)
|
| 48 |
+
for prop in PROPS:
|
| 49 |
+
print(f"{prop}: {getattr(dirs, prop)}") # noqa: T201
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
if __name__ == "__main__":
|
| 53 |
+
main()
|
.venv/lib/python3.11/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (17.5 kB). View file
|
|
|