nab-python 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. nab_python/__init__.py +1 -0
  2. nab_python/_build/__init__.py +1 -0
  3. nab_python/_build/env.py +364 -0
  4. nab_python/_build/errors.py +17 -0
  5. nab_python/_build/runner.py +254 -0
  6. nab_python/_lockfile/__init__.py +1 -0
  7. nab_python/_lockfile/builder.py +339 -0
  8. nab_python/_lockfile/disjointness.py +207 -0
  9. nab_python/_lockfile/pylock.py +323 -0
  10. nab_python/_lockfile/requirements.py +121 -0
  11. nab_python/_packaging_provider.py +98 -0
  12. nab_python/_provider/__init__.py +1 -0
  13. nab_python/_provider/build_remote.py +95 -0
  14. nab_python/_provider/extras.py +231 -0
  15. nab_python/_provider/listing.py +442 -0
  16. nab_python/_provider/lookahead.py +156 -0
  17. nab_python/_provider/metadata_resolver.py +450 -0
  18. nab_python/_provider/priority.py +174 -0
  19. nab_python/_provider/sources.py +215 -0
  20. nab_python/_testing/__init__.py +1 -0
  21. nab_python/_testing/coordinator_fake.py +240 -0
  22. nab_python/_vcs_admission.py +209 -0
  23. nab_python/_vendor/__init__.py +6 -0
  24. nab_python/_vendor/packaging/LICENSE +3 -0
  25. nab_python/_vendor/packaging/LICENSE.APACHE +177 -0
  26. nab_python/_vendor/packaging/LICENSE.BSD +23 -0
  27. nab_python/_vendor/packaging/PROVENANCE.md +73 -0
  28. nab_python/_vendor/packaging/__init__.py +15 -0
  29. nab_python/_vendor/packaging/_elffile.py +108 -0
  30. nab_python/_vendor/packaging/_manylinux.py +265 -0
  31. nab_python/_vendor/packaging/_musllinux.py +88 -0
  32. nab_python/_vendor/packaging/_parser.py +394 -0
  33. nab_python/_vendor/packaging/_structures.py +33 -0
  34. nab_python/_vendor/packaging/_tokenizer.py +196 -0
  35. nab_python/_vendor/packaging/dependency_groups.py +302 -0
  36. nab_python/_vendor/packaging/direct_url.py +325 -0
  37. nab_python/_vendor/packaging/errors.py +94 -0
  38. nab_python/_vendor/packaging/licenses/__init__.py +186 -0
  39. nab_python/_vendor/packaging/licenses/_spdx.py +799 -0
  40. nab_python/_vendor/packaging/markers.py +506 -0
  41. nab_python/_vendor/packaging/metadata.py +964 -0
  42. nab_python/_vendor/packaging/py.typed +0 -0
  43. nab_python/_vendor/packaging/pylock.py +910 -0
  44. nab_python/_vendor/packaging/ranges.py +1803 -0
  45. nab_python/_vendor/packaging/requirements.py +132 -0
  46. nab_python/_vendor/packaging/specifiers.py +1141 -0
  47. nab_python/_vendor/packaging/tags.py +929 -0
  48. nab_python/_vendor/packaging/utils.py +296 -0
  49. nab_python/_vendor/packaging/version.py +1230 -0
  50. nab_python/build_backend.py +184 -0
  51. nab_python/config.py +805 -0
  52. nab_python/download.py +170 -0
  53. nab_python/fetch.py +827 -0
  54. nab_python/lockfile.py +238 -0
  55. nab_python/metadata.py +145 -0
  56. nab_python/provider.py +1235 -0
  57. nab_python/py.typed +0 -0
  58. nab_python/requirements_file.py +180 -0
  59. nab_python/resolve.py +497 -0
  60. nab_python/universal/__init__.py +1 -0
  61. nab_python/universal/matrix.py +235 -0
  62. nab_python/universal/provider.py +214 -0
  63. nab_python/universal/reresolve.py +310 -0
  64. nab_python/universal/resolve.py +508 -0
  65. nab_python/universal/validate.py +439 -0
  66. nab_python/universal/wheel_selection.py +327 -0
  67. nab_python/workspace.py +214 -0
  68. nab_python-0.0.1.dist-info/METADATA +49 -0
  69. nab_python-0.0.1.dist-info/RECORD +71 -0
  70. nab_python-0.0.1.dist-info/WHEEL +4 -0
  71. nab_python-0.0.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,94 @@
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ import dataclasses
5
+ import sys
6
+ import typing
7
+
8
+ __all__ = ["ExceptionGroup"]
9
+
10
+
11
+ def __dir__() -> list[str]:
12
+ return __all__
13
+
14
+
15
+ if sys.version_info >= (3, 11): # pragma: no cover
16
+ from builtins import ExceptionGroup
17
+ else: # pragma: no cover
18
+
19
+ class ExceptionGroup(Exception):
20
+ """A minimal implementation of :external:exc:`ExceptionGroup` from Python 3.11.
21
+
22
+ If :external:exc:`ExceptionGroup` is already defined by Python itself,
23
+ that version is used instead.
24
+ """
25
+
26
+ message: str
27
+ exceptions: list[Exception]
28
+
29
+ def __init__(self, message: str, exceptions: list[Exception]) -> None:
30
+ self.message = message
31
+ self.exceptions = exceptions
32
+
33
+ def __repr__(self) -> str:
34
+ return f"{self.__class__.__name__}({self.message!r}, {self.exceptions!r})"
35
+
36
+
37
+ @dataclasses.dataclass
38
+ class _ErrorCollector:
39
+ """
40
+ Collect errors into ExceptionGroups.
41
+
42
+ Used like this:
43
+
44
+ collector = _ErrorCollector()
45
+ # Add a single exception
46
+ collector.error(ValueError("one"))
47
+
48
+ # Supports nesting, including combining ExceptionGroups
49
+ with collector.collect():
50
+ raise ValueError("two")
51
+ collector.finalize("Found some errors")
52
+
53
+ Since making a collector and then calling finalize later is a common pattern,
54
+ a convenience method ``on_exit`` is provided.
55
+ """
56
+
57
+ errors: list[Exception] = dataclasses.field(default_factory=list, init=False)
58
+
59
+ def finalize(self, msg: str) -> None:
60
+ """Raise a group exception if there are any errors."""
61
+ if self.errors:
62
+ raise ExceptionGroup(msg, self.errors)
63
+
64
+ @contextlib.contextmanager
65
+ def on_exit(self, msg: str) -> typing.Generator[_ErrorCollector, None, None]:
66
+ """
67
+ Calls finalize if no uncollected errors were present.
68
+
69
+ Uncollected errors are raised normally.
70
+ """
71
+ yield self
72
+ self.finalize(msg)
73
+
74
+ @contextlib.contextmanager
75
+ def collect(self, *err_cls: type[Exception]) -> typing.Generator[None, None, None]:
76
+ """
77
+ Context manager to collect errors into the error list.
78
+
79
+ Must be inside loops, as only one error can be collected at a time.
80
+ """
81
+ error_classes = err_cls or (Exception,)
82
+ try:
83
+ yield
84
+ except ExceptionGroup as error:
85
+ self.errors.extend(error.exceptions)
86
+ except error_classes as error:
87
+ self.errors.append(error)
88
+
89
+ def error(
90
+ self,
91
+ error: Exception,
92
+ ) -> None:
93
+ """Add an error to the list."""
94
+ self.errors.append(error)
@@ -0,0 +1,186 @@
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 ._spdx import EXCEPTIONS, LICENSES
38
+
39
+ __all__ = [
40
+ "InvalidLicenseExpression",
41
+ "NormalizedLicenseExpression",
42
+ "canonicalize_license_expression",
43
+ ]
44
+
45
+
46
+ # Simple __dir__ implementation since there are no public submodules
47
+ def __dir__() -> list[str]:
48
+ return __all__
49
+
50
+
51
+ license_ref_allowed = re.compile("^[A-Za-z0-9.-]*$")
52
+
53
+ NormalizedLicenseExpression = NewType("NormalizedLicenseExpression", str)
54
+ """
55
+ A :class:`typing.NewType` of :class:`str`, representing a normalized
56
+ License-Expression.
57
+ """
58
+
59
+
60
+ class InvalidLicenseExpression(ValueError):
61
+ """Raised when a license-expression string is invalid
62
+
63
+ >>> from packaging.licenses import canonicalize_license_expression
64
+ >>> canonicalize_license_expression("invalid")
65
+ Traceback (most recent call last):
66
+ ...
67
+ packaging.licenses.InvalidLicenseExpression: Invalid license expression: 'invalid'
68
+ """
69
+
70
+
71
+ def canonicalize_license_expression(
72
+ raw_license_expression: str,
73
+ ) -> NormalizedLicenseExpression:
74
+ """
75
+ This function takes a valid License-Expression, and returns the normalized
76
+ form of it.
77
+
78
+ The return type is typed as :class:`NormalizedLicenseExpression`. This
79
+ allows type checkers to help require that a string has passed through this
80
+ function before use.
81
+
82
+ :param str raw_license_expression: The License-Expression to canonicalize.
83
+ :raises InvalidLicenseExpression: If the License-Expression is invalid due to an
84
+ invalid/unknown license identifier or invalid syntax.
85
+
86
+ .. doctest::
87
+
88
+ >>> from packaging.licenses import canonicalize_license_expression
89
+ >>> canonicalize_license_expression("mit")
90
+ 'MIT'
91
+ >>> canonicalize_license_expression("mit and (apache-2.0 or bsd-2-clause)")
92
+ 'MIT AND (Apache-2.0 OR BSD-2-Clause)'
93
+ >>> canonicalize_license_expression("(mit")
94
+ Traceback (most recent call last):
95
+ ...
96
+ InvalidLicenseExpression: Invalid license expression: '(mit'
97
+ >>> canonicalize_license_expression("Use-it-after-midnight")
98
+ Traceback (most recent call last):
99
+ ...
100
+ InvalidLicenseExpression: Unknown license: 'Use-it-after-midnight'
101
+ """
102
+ if not raw_license_expression:
103
+ message = f"Invalid license expression: {raw_license_expression!r}"
104
+ raise InvalidLicenseExpression(message)
105
+
106
+ # Pad any parentheses so tokenization can be achieved by merely splitting on
107
+ # whitespace.
108
+ license_expression = raw_license_expression.replace("(", " ( ").replace(")", " ) ")
109
+ licenseref_prefix = "LicenseRef-"
110
+ license_refs = {
111
+ ref.lower(): "LicenseRef-" + ref[len(licenseref_prefix) :]
112
+ for ref in license_expression.split()
113
+ if ref.lower().startswith(licenseref_prefix.lower())
114
+ }
115
+
116
+ # Normalize to lower case so we can look up licenses/exceptions
117
+ # and so boolean operators are Python-compatible.
118
+ license_expression = license_expression.lower()
119
+
120
+ tokens = license_expression.split()
121
+
122
+ # Rather than implementing a parenthesis/boolean logic parser, create an
123
+ # expression that Python can parse. Everything that is not involved with the
124
+ # grammar itself is replaced with the placeholder `False` and the resultant
125
+ # expression should become a valid Python expression.
126
+ python_tokens = []
127
+ for token in tokens:
128
+ if token not in {"or", "and", "with", "(", ")"}:
129
+ python_tokens.append("False")
130
+ elif token == "with":
131
+ python_tokens.append("or")
132
+ elif (
133
+ token == "("
134
+ and python_tokens
135
+ and python_tokens[-1] not in {"or", "and", "("}
136
+ ) or (token == ")" and python_tokens and python_tokens[-1] == "("):
137
+ message = f"Invalid license expression: {raw_license_expression!r}"
138
+ raise InvalidLicenseExpression(message)
139
+ else:
140
+ python_tokens.append(token)
141
+
142
+ python_expression = " ".join(python_tokens)
143
+ try:
144
+ compile(python_expression, "", "eval")
145
+ except SyntaxError:
146
+ message = f"Invalid license expression: {raw_license_expression!r}"
147
+ raise InvalidLicenseExpression(message) from None
148
+
149
+ # Take a final pass to check for unknown licenses/exceptions.
150
+ normalized_tokens = []
151
+ for token in tokens:
152
+ if token in {"or", "and", "with", "(", ")"}:
153
+ normalized_tokens.append(token.upper())
154
+ continue
155
+
156
+ if normalized_tokens and normalized_tokens[-1] == "WITH":
157
+ if token not in EXCEPTIONS:
158
+ message = f"Unknown license exception: {token!r}"
159
+ raise InvalidLicenseExpression(message)
160
+
161
+ normalized_tokens.append(EXCEPTIONS[token]["id"])
162
+ else:
163
+ if token.endswith("+"):
164
+ final_token = token[:-1]
165
+ suffix = "+"
166
+ else:
167
+ final_token = token
168
+ suffix = ""
169
+
170
+ if final_token.startswith("licenseref-"):
171
+ if not license_ref_allowed.match(final_token):
172
+ message = f"Invalid licenseref: {final_token!r}"
173
+ raise InvalidLicenseExpression(message)
174
+ normalized_tokens.append(license_refs[final_token] + suffix)
175
+ else:
176
+ if final_token not in LICENSES:
177
+ message = f"Unknown license: {final_token!r}"
178
+ raise InvalidLicenseExpression(message)
179
+ normalized_tokens.append(LICENSES[final_token]["id"] + suffix)
180
+
181
+ normalized_expression = " ".join(normalized_tokens)
182
+
183
+ return cast(
184
+ "NormalizedLicenseExpression",
185
+ normalized_expression.replace("( ", "(").replace(" )", ")"),
186
+ )