-
-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
0.0.23: pytest is failing in few units #67
Comments
Here is pytest output: + PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-whey-0.0.23-2.fc35.x86_64/usr/lib64/python3.8/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-whey-0.0.23-2.fc35.x86_64/usr/lib/python3.8/site-packages
+ /usr/bin/pytest -ra --ignore tests/test_cli.py --ignore tests/test_utils.py
=========================================================================== test session starts ============================================================================
platform linux -- Python 3.8.13, pytest-7.1.2, pluggy-1.0.0
Test session started at 16:24:03
rootdir: /home/tkloczko/rpmbuild/BUILD/whey-0.0.23, configfile: tox.ini
plugins: datadir-1.3.1, regressions-2.3.1, timeout-2.1.0
timeout: 300.0s
timeout method: signal
timeout func_only: False
collected 240 items
tests/test_build.py ...................sss............................ [ 20%]
tests/test_builder_methods.py s. [ 21%]
tests/test_config.py ............................................................................FFF.....F..ss....FFF.....F..ss..................................... [ 81%]
. [ 81%]
tests/test_foreman.py ................... [ 89%]
tests/test_pep517_backend.py ..................ss..... [100%]
================================================================================= FAILURES =================================================================================
____________________________________________________________________ test_parse_config_errors[bad_name] ____________________________________________________________________
config = '[project]\nname = "???????12345=============☃"\nversion = "2020.0.0"', expects = <class 'dom_toml.parser.BadConfigError'>
match = "The\\ value\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'\\ for\\ 'project\\.name'\\ is\\ invalid\\."
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_parse_config_errors_bad_n0')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param('', KeyError, "'project' table not found in '.*'", id="no_config"),
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_parse_config_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with pytest.raises(expects, match=match):
> load_toml(tmp_pathplus / "pyproject.toml")
tests/test_config.py:659:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
filename = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_parse_config_errors_bad_n0/pyproject.toml')
def load_toml(filename: PathLike) -> Dict[str, Any]: # TODO: TypedDict
"""
Load the ``whey`` configuration mapping from the given TOML file.
:param filename:
"""
filename = PathPlus(filename)
project_dir = filename.parent
config = dom_toml.load(filename, decoder=dom_toml.decoder.TomlPureDecoder)
parsed_config = {}
tool_table = config.get("tool", {})
with in_directory(project_dir):
parsed_config.update(WheyParser().parse(tool_table.get("whey", {}), set_defaults=True))
if "project" in config:
> parsed_config.update(PEP621Parser().parse(config["project"], set_defaults=True))
whey/config/__init__.py:82:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe1901bfd0>, config = {'name': '???????12345=============☃', 'version': '2020.0.0'}, set_defaults = True
def parse( # type: ignore[override]
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> ProjectDict:
"""
Parse the TOML configuration.
:param config:
:param set_defaults: If :py:obj:`True`, the values in
:attr:`dom_toml.parser.AbstractConfigParser.defaults` and
:attr:`dom_toml.parser.AbstractConfigParser.factories`
will be set as defaults for the returned mapping.
"""
dynamic_fields = set(config.get("dynamic", []))
if "name" in dynamic_fields:
raise BadConfigError("The 'project.name' field may not be dynamic.")
elif "name" not in config:
raise BadConfigError("The 'project.name' field must be provided.")
if dynamic_fields:
# TODO: Support the remaining fields as dynamic
# TODO: dynamic version numbers by parsing AST for __version__ in __init__.py
supported_dynamic = {"classifiers", "requires-python", "dependencies"}
unsupported_fields = dynamic_fields - supported_dynamic
if unsupported_fields:
supported = word_join(sorted(supported_dynamic), oxford=True, use_repr=True)
unsupported = word_join(sorted(unsupported_fields), oxford=True, use_repr=True)
raise BadConfigError(
f"Unsupported dynamic {_field(len(unsupported_fields))} {unsupported}.\n"
f"note: whey only supports {supported} as dynamic fields."
)
if "version" not in config:
raise BadConfigError("The 'project.version' field must be provided.")
> return self._parse(config, set_defaults)
whey/config/pep621.py:126:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe1901bfd0>, config = {'name': '???????12345=============☃', 'version': '2020.0.0'}, set_defaults = True
def _parse(
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> ProjectDict:
dynamic_fields = config.get("dynamic", [])
parsed_config = {"dynamic": dynamic_fields}
for key in self.keys:
if key in config and key in dynamic_fields:
raise BadConfigError(f"{key!r} was listed in 'project.dynamic' but a value was given.")
elif key not in config:
# Ignore absent values
pass
elif hasattr(self, f"parse_{key.replace('-', '_')}"):
> parsed_config[key] = getattr(self, f"parse_{key.replace('-', '_')}")(config)
whey/config/pep621.py:72:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
config = {'name': '???????12345=============☃', 'version': '2020.0.0'}
@staticmethod
def parse_name(config: Dict[str, TOML_TYPES]) -> str:
"""
Parse the :pep621:`name` key, giving the name of the project.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Name`
This key is required, and must be defined statically.
Tools SHOULD normalize this name, as specified by :pep:`503`,
as soon as it is read for internal consistency.
:bold-title:`Example:`
.. code-block:: TOML
[project]
name = "spam"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
"""
normalized_name = _NormalisedName(normalize(config["name"]))
normalized_name.unnormalized = config["name"]
# https://packaging.python.org/specifications/core-metadata/#name
if not name_re.match(normalized_name):
> raise BadConfigError("The value for 'project.name' is invalid.")
E dom_toml.parser.BadConfigError: The value for 'project.name' is invalid.
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:297: BadConfigError
During handling of the above exception, another exception occurred:
config = '[project]\nname = "???????12345=============☃"\nversion = "2020.0.0"', expects = <class 'dom_toml.parser.BadConfigError'>
match = "The\\ value\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'\\ for\\ 'project\\.name'\\ is\\ invalid\\."
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_parse_config_errors_bad_n0')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param('', KeyError, "'project' table not found in '.*'", id="no_config"),
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_parse_config_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with pytest.raises(expects, match=match):
> load_toml(tmp_pathplus / "pyproject.toml")
E AssertionError: Regex pattern "The\\ value\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'\\ for\\ 'project\\.name'\\ is\\ invalid\\." does not match "The value for 'project.name' is invalid.".
tests/test_config.py:659: AssertionError
__________________________________________________________________ test_parse_config_errors[bad_version] ___________________________________________________________________
config = {'name': 'spam', 'version': '???????12345=============☃'}
@staticmethod
def parse_version(config: Dict[str, TOML_TYPES]) -> Version:
"""
Parse the :pep621:`version` key, giving the version of the project as supported by :pep:`440`.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Version`
Users SHOULD prefer to specify normalized versions.
:bold-title:`Example:`
.. code-block:: TOML
[project]
version = "2020.0.0"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
"""
version = str(config["version"])
try:
> return Version(str(version))
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:324:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'Version' object has no attribute '_version'") raised in repr()] Version object at 0x7fbe190633d0>, version = '???????12345=============☃'
def __init__(self, version: str) -> None:
# Validate the version and parse it into pieces
match = self._regex.search(version)
if not match:
> raise InvalidVersion(f"Invalid version: '{version}'")
E packaging.version.InvalidVersion: Invalid version: '???????12345=============☃'
/usr/lib/python3.8/site-packages/packaging/version.py:266: InvalidVersion
During handling of the above exception, another exception occurred:
config = '[project]\nname = "spam"\nversion = "???????12345=============☃"', expects = <class 'packaging.version.InvalidVersion'>
match = "Invalid\\ version:\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'", tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_parse_config_errors_bad_v0')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param('', KeyError, "'project' table not found in '.*'", id="no_config"),
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_parse_config_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with pytest.raises(expects, match=match):
> load_toml(tmp_pathplus / "pyproject.toml")
tests/test_config.py:659:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
whey/config/__init__.py:82: in load_toml
parsed_config.update(PEP621Parser().parse(config["project"], set_defaults=True))
whey/config/pep621.py:126: in parse
return self._parse(config, set_defaults)
whey/config/pep621.py:72: in _parse
parsed_config[key] = getattr(self, f"parse_{key.replace('-', '_')}")(config)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
config = {'name': 'spam', 'version': '???????12345=============☃'}
@staticmethod
def parse_version(config: Dict[str, TOML_TYPES]) -> Version:
"""
Parse the :pep621:`version` key, giving the version of the project as supported by :pep:`440`.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Version`
Users SHOULD prefer to specify normalized versions.
:bold-title:`Example:`
.. code-block:: TOML
[project]
version = "2020.0.0"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
"""
version = str(config["version"])
try:
return Version(str(version))
except InvalidVersion as e:
> raise BadConfigError(str(e))
E dom_toml.parser.BadConfigError: Invalid version: '???????12345=============☃'
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:326: BadConfigError
______________________________________________________________ test_parse_config_errors[bad_requires_python] _______________________________________________________________
self = <[AttributeError("'SpecifierSet' object has no attribute '_prereleases'") raised in repr()] SpecifierSet object at 0x7fbe18f5cd60>
specifiers = '???????12345=============☃', prereleases = None
def __init__(
self, specifiers: str = "", prereleases: Optional[bool] = None
) -> None:
# Split on , to break each individual specifier into it's own item, and
# strip each item to remove leading/trailing whitespace.
split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
# Parsed each individual specifier, attempting first to make it a
# Specifier and falling back to a LegacySpecifier.
parsed: Set[_IndividualSpecifier] = set()
for specifier in split_specifiers:
try:
> parsed.add(Specifier(specifier))
/usr/lib/python3.8/site-packages/packaging/specifiers.py:634:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'Specifier' object has no attribute '_prereleases'") raised in repr()] Specifier object at 0x7fbe18f5cdc0>, spec = '???????12345=============☃'
prereleases = None
def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None:
match = self._regex.search(spec)
if not match:
> raise InvalidSpecifier(f"Invalid specifier: '{spec}'")
E packaging.specifiers.InvalidSpecifier: Invalid specifier: '???????12345=============☃'
/usr/lib/python3.8/site-packages/packaging/specifiers.py:98: InvalidSpecifier
During handling of the above exception, another exception occurred:
config = {'name': 'spam', 'requires-python': '???????12345=============☃', 'version': '2020.0.0'}
@staticmethod
def parse_requires_python(config: Dict[str, TOML_TYPES]) -> SpecifierSet:
"""
Parse the :pep621:`requires-python` key, giving the Python version requirements of the project.
The requirement should be in the form of a :pep:`508` marker.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Requires-Python`
:bold-title:`Example:`
.. code-block:: TOML
[project]
requires-python = ">=3.6"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
:rtype:
.. latex:clearpage::
"""
version = str(config["requires-python"])
try:
> return SpecifierSet(str(version))
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:495:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'SpecifierSet' object has no attribute '_prereleases'") raised in repr()] SpecifierSet object at 0x7fbe18f5cd60>
specifiers = '???????12345=============☃', prereleases = None
def __init__(
self, specifiers: str = "", prereleases: Optional[bool] = None
) -> None:
# Split on , to break each individual specifier into it's own item, and
# strip each item to remove leading/trailing whitespace.
split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
# Parsed each individual specifier, attempting first to make it a
# Specifier and falling back to a LegacySpecifier.
parsed: Set[_IndividualSpecifier] = set()
for specifier in split_specifiers:
try:
parsed.add(Specifier(specifier))
except InvalidSpecifier:
> parsed.add(LegacySpecifier(specifier))
/usr/lib/python3.8/site-packages/packaging/specifiers.py:636:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'LegacySpecifier' object has no attribute '_prereleases'") raised in repr()] LegacySpecifier object at 0x7fbe18f5cdf0>
spec = '???????12345=============☃', prereleases = None
def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None:
> super().__init__(spec, prereleases)
/usr/lib/python3.8/site-packages/packaging/specifiers.py:253:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'LegacySpecifier' object has no attribute '_prereleases'") raised in repr()] LegacySpecifier object at 0x7fbe18f5cdf0>
spec = '???????12345=============☃', prereleases = None
def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None:
match = self._regex.search(spec)
if not match:
> raise InvalidSpecifier(f"Invalid specifier: '{spec}'")
E packaging.specifiers.InvalidSpecifier: Invalid specifier: '???????12345=============☃'
/usr/lib/python3.8/site-packages/packaging/specifiers.py:98: InvalidSpecifier
During handling of the above exception, another exception occurred:
config = '[project]\nname = "spam"\nversion = "2020.0.0"\nrequires-python = "???????12345=============☃"', expects = <class 'packaging.specifiers.InvalidSpecifier'>
match = "Invalid\\ specifier:\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'"
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_parse_config_errors_bad_r0')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param('', KeyError, "'project' table not found in '.*'", id="no_config"),
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_parse_config_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with pytest.raises(expects, match=match):
> load_toml(tmp_pathplus / "pyproject.toml")
tests/test_config.py:659:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
whey/config/__init__.py:82: in load_toml
parsed_config.update(PEP621Parser().parse(config["project"], set_defaults=True))
whey/config/pep621.py:126: in parse
return self._parse(config, set_defaults)
whey/config/pep621.py:72: in _parse
parsed_config[key] = getattr(self, f"parse_{key.replace('-', '_')}")(config)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
config = {'name': 'spam', 'requires-python': '???????12345=============☃', 'version': '2020.0.0'}
@staticmethod
def parse_requires_python(config: Dict[str, TOML_TYPES]) -> SpecifierSet:
"""
Parse the :pep621:`requires-python` key, giving the Python version requirements of the project.
The requirement should be in the form of a :pep:`508` marker.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Requires-Python`
:bold-title:`Example:`
.. code-block:: TOML
[project]
requires-python = ">=3.6"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
:rtype:
.. latex:clearpage::
"""
version = str(config["requires-python"])
try:
return SpecifierSet(str(version))
except InvalidSpecifier as e:
> raise BadConfigError(str(e))
E dom_toml.parser.BadConfigError: Invalid specifier: '???????12345=============☃'
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:497: BadConfigError
________________________________________________________ test_parse_config_errors[dependencies_invalid_requirement] ________________________________________________________
self = <[AttributeError("'ComparableRequirement' object has no attribute 'name'") raised in repr()] ComparableRequirement object at 0x7fbe18f7dd60>
requirement_string = 'foo]]]'
def __init__(self, requirement_string: str) -> None:
try:
> req = REQUIREMENT.parseString(requirement_string)
/usr/lib/python3.8/site-packages/packaging/requirements.py:102:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = {string_start Combine:({W:(0-9A-Za-z) [{W:(0-9A-Za-z) | {[W:(-._)]... W:(0-9A-Za-z)}}]...}) [Suppress:('[') [Combine:(... {string enclosed in "'" | string enclosed in '"'}) | Group:({{Suppress:('(') : ...} Suppress:(') Empty}]}} string_end}
instring = 'foo]]]', parse_all = False
def parse_string(
self, instring: str, parse_all: bool = False, *, parseAll: bool = False
) -> ParseResults:
"""
Parse a string with respect to the parser definition. This function is intended as the primary interface to the
client code.
:param instring: The input string to be parsed.
:param parse_all: If set, the entire input string must match the grammar.
:param parseAll: retained for pre-PEP8 compatibility, will be removed in a future release.
:raises ParseException: Raised if ``parse_all`` is set and the input string does not match the whole grammar.
:returns: the parsed data as a :class:`ParseResults` object, which may be accessed as a `list`, a `dict`, or
an object with attributes if the given parser includes results names.
If the input string is required to match the entire grammar, ``parse_all`` flag must be set to ``True``. This
is also equivalent to ending the grammar with :class:`StringEnd`().
To report proper column numbers, ``parse_string`` operates on a copy of the input string where all tabs are
converted to spaces (8 spaces per tab, as per the default in ``string.expandtabs``). If the input string
contains tabs and the grammar uses parse actions that use the ``loc`` argument to index into the string
being parsed, one can ensure a consistent view of the input string by doing one of the following:
- calling ``parse_with_tabs`` on your grammar before calling ``parse_string`` (see :class:`parse_with_tabs`),
- define your parse action using the full ``(s,loc,toks)`` signature, and reference the input string using the
parse action's ``s`` argument, or
- explicitly expand the tabs in your input string before calling ``parse_string``.
Examples:
By default, partial matches are OK.
>>> res = Word('a').parse_string('aaaaabaaa')
>>> print(res)
['aaaaa']
The parsing behavior varies by the inheriting class of this abstract class. Please refer to the children
directly to see more examples.
It raises an exception if parse_all flag is set and instring does not match the whole grammar.
>>> res = Word('a').parse_string('aaaaabaaa', parse_all=True)
Traceback (most recent call last):
...
pyparsing.ParseException: Expected end of text, found 'b' (at char 5), (line:1, col:6)
"""
parseAll = parse_all or parseAll
ParserElement.reset_cache()
if not self.streamlined:
self.streamline()
for e in self.ignoreExprs:
e.streamline()
if not self.keepTabs:
instring = instring.expandtabs()
try:
loc, tokens = self._parse(instring, 0)
if parseAll:
loc = self.preParse(instring, loc)
se = Empty() + StringEnd()
se._parse(instring, loc)
except ParseBaseException as exc:
if ParserElement.verbose_stacktrace:
raise
else:
# catch and re-raise exception from here, clearing out pyparsing internal stack trace
> raise exc.with_traceback(None)
E pyparsing.exceptions.ParseException: Expected string_end, found ']' (at char 3), (line:1, col:4)
/usr/lib/python3.8/site-packages/pyparsing/core.py:1141: ParseException
During handling of the above exception, another exception occurred:
config = '[project]\nname = "spam"\nversion = "2020.0.0"\ndependencies = ["foo]]]"]', expects = <class 'packaging.requirements.InvalidRequirement'>
match = '\'foo]]]\'\\n Parse error at \\"\']]]\'\\": Expected string_end'
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_parse_config_errors_depen1')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param('', KeyError, "'project' table not found in '.*'", id="no_config"),
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_parse_config_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with pytest.raises(expects, match=match):
> load_toml(tmp_pathplus / "pyproject.toml")
tests/test_config.py:659:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
filename = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_parse_config_errors_depen1/pyproject.toml')
def load_toml(filename: PathLike) -> Dict[str, Any]: # TODO: TypedDict
"""
Load the ``whey`` configuration mapping from the given TOML file.
:param filename:
"""
filename = PathPlus(filename)
project_dir = filename.parent
config = dom_toml.load(filename, decoder=dom_toml.decoder.TomlPureDecoder)
parsed_config = {}
tool_table = config.get("tool", {})
with in_directory(project_dir):
parsed_config.update(WheyParser().parse(tool_table.get("whey", {}), set_defaults=True))
if "project" in config:
> parsed_config.update(PEP621Parser().parse(config["project"], set_defaults=True))
whey/config/__init__.py:82:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe18f7dbb0>, config = {'dependencies': ['foo]]]'], 'name': 'spam', 'version': '2020.0.0'}, set_defaults = True
def parse( # type: ignore[override]
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> ProjectDict:
"""
Parse the TOML configuration.
:param config:
:param set_defaults: If :py:obj:`True`, the values in
:attr:`dom_toml.parser.AbstractConfigParser.defaults` and
:attr:`dom_toml.parser.AbstractConfigParser.factories`
will be set as defaults for the returned mapping.
"""
dynamic_fields = set(config.get("dynamic", []))
if "name" in dynamic_fields:
raise BadConfigError("The 'project.name' field may not be dynamic.")
elif "name" not in config:
raise BadConfigError("The 'project.name' field must be provided.")
if dynamic_fields:
# TODO: Support the remaining fields as dynamic
# TODO: dynamic version numbers by parsing AST for __version__ in __init__.py
supported_dynamic = {"classifiers", "requires-python", "dependencies"}
unsupported_fields = dynamic_fields - supported_dynamic
if unsupported_fields:
supported = word_join(sorted(supported_dynamic), oxford=True, use_repr=True)
unsupported = word_join(sorted(unsupported_fields), oxford=True, use_repr=True)
raise BadConfigError(
f"Unsupported dynamic {_field(len(unsupported_fields))} {unsupported}.\n"
f"note: whey only supports {supported} as dynamic fields."
)
if "version" not in config:
raise BadConfigError("The 'project.version' field must be provided.")
> return self._parse(config, set_defaults)
whey/config/pep621.py:126:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe18f7dbb0>, config = {'dependencies': ['foo]]]'], 'name': 'spam', 'version': '2020.0.0'}, set_defaults = True
def _parse(
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> ProjectDict:
dynamic_fields = config.get("dynamic", [])
parsed_config = {"dynamic": dynamic_fields}
for key in self.keys:
if key in config and key in dynamic_fields:
raise BadConfigError(f"{key!r} was listed in 'project.dynamic' but a value was given.")
elif key not in config:
# Ignore absent values
pass
elif hasattr(self, f"parse_{key.replace('-', '_')}"):
> parsed_config[key] = getattr(self, f"parse_{key.replace('-', '_')}")(config)
whey/config/pep621.py:72:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe18f7dbb0>, config = {'dependencies': ['foo]]]'], 'name': 'spam', 'version': '2020.0.0'}
def parse_dependencies(self, config: Dict[str, TOML_TYPES]) -> List[ComparableRequirement]:
"""
Parse the :pep621:`dependencies` key, giving the dependencies of the project.
* **Format**: :toml:`Array` of :pep:`508` strings
* **Core Metadata**: :core-meta:`Requires-Dist`
Each string MUST be formatted as a valid :pep:`508` string.
:bold-title:`Example:`
.. code-block:: TOML
[project]
dependencies = [
"httpx",
"gidgethub[httpx]>4.0.0",
"django>2.1; os_name != 'nt'",
"django>2.0; os_name == 'nt'"
]
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
"""
parsed_dependencies = set()
key_path = [self.table_name, "dependencies"]
self.assert_sequence_not_str(config["dependencies"], key_path)
for idx, keyword in enumerate(config["dependencies"]):
self.assert_indexed_type(keyword, str, key_path, idx=idx)
> parsed_dependencies.add(ComparableRequirement(keyword))
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:899:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'ComparableRequirement' object has no attribute 'name'") raised in repr()] ComparableRequirement object at 0x7fbe18f7dd60>
requirement_string = 'foo]]]'
def __init__(self, requirement_string: str) -> None:
try:
req = REQUIREMENT.parseString(requirement_string)
except ParseException as e:
> raise InvalidRequirement(
f'Parse error at "{ requirement_string[e.loc : e.loc + 8]!r}": {e.msg}'
)
E packaging.requirements.InvalidRequirement: Parse error at "']]]'": Expected string_end
/usr/lib/python3.8/site-packages/packaging/requirements.py:104: InvalidRequirement
During handling of the above exception, another exception occurred:
config = '[project]\nname = "spam"\nversion = "2020.0.0"\ndependencies = ["foo]]]"]', expects = <class 'packaging.requirements.InvalidRequirement'>
match = '\'foo]]]\'\\n Parse error at \\"\']]]\'\\": Expected string_end'
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_parse_config_errors_depen1')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param('', KeyError, "'project' table not found in '.*'", id="no_config"),
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_parse_config_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with pytest.raises(expects, match=match):
> load_toml(tmp_pathplus / "pyproject.toml")
E AssertionError: Regex pattern '\'foo]]]\'\\n Parse error at \\"\']]]\'\\": Expected string_end' does not match 'Parse error at "\']]]\'": Expected string_end'.
tests/test_config.py:659: AssertionError
_________________________________________________________________ test_pep621parser_class_errors[bad_name] _________________________________________________________________
config = '[project]\nname = "???????12345=============☃"\nversion = "2020.0.0"', expects = <class 'dom_toml.parser.BadConfigError'>
match = "The\\ value\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'\\ for\\ 'project\\.name'\\ is\\ invalid\\."
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_pep621parser_class_errors3')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_pep621parser_class_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with in_directory(tmp_pathplus), pytest.raises(expects, match=match):
> PEP621Parser().parse(dom_toml.load(tmp_pathplus / "pyproject.toml")["project"])
tests/test_config.py:678:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe19080eb0>, config = {'name': '???????12345=============☃', 'version': '2020.0.0'}, set_defaults = False
def parse( # type: ignore[override]
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> ProjectDict:
"""
Parse the TOML configuration.
:param config:
:param set_defaults: If :py:obj:`True`, the values in
:attr:`dom_toml.parser.AbstractConfigParser.defaults` and
:attr:`dom_toml.parser.AbstractConfigParser.factories`
will be set as defaults for the returned mapping.
"""
dynamic_fields = set(config.get("dynamic", []))
if "name" in dynamic_fields:
raise BadConfigError("The 'project.name' field may not be dynamic.")
elif "name" not in config:
raise BadConfigError("The 'project.name' field must be provided.")
if dynamic_fields:
# TODO: Support the remaining fields as dynamic
# TODO: dynamic version numbers by parsing AST for __version__ in __init__.py
supported_dynamic = {"classifiers", "requires-python", "dependencies"}
unsupported_fields = dynamic_fields - supported_dynamic
if unsupported_fields:
supported = word_join(sorted(supported_dynamic), oxford=True, use_repr=True)
unsupported = word_join(sorted(unsupported_fields), oxford=True, use_repr=True)
raise BadConfigError(
f"Unsupported dynamic {_field(len(unsupported_fields))} {unsupported}.\n"
f"note: whey only supports {supported} as dynamic fields."
)
if "version" not in config:
raise BadConfigError("The 'project.version' field must be provided.")
> return self._parse(config, set_defaults)
whey/config/pep621.py:126:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe19080eb0>, config = {'name': '???????12345=============☃', 'version': '2020.0.0'}, set_defaults = False
def _parse(
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> ProjectDict:
dynamic_fields = config.get("dynamic", [])
parsed_config = {"dynamic": dynamic_fields}
for key in self.keys:
if key in config and key in dynamic_fields:
raise BadConfigError(f"{key!r} was listed in 'project.dynamic' but a value was given.")
elif key not in config:
# Ignore absent values
pass
elif hasattr(self, f"parse_{key.replace('-', '_')}"):
> parsed_config[key] = getattr(self, f"parse_{key.replace('-', '_')}")(config)
whey/config/pep621.py:72:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
config = {'name': '???????12345=============☃', 'version': '2020.0.0'}
@staticmethod
def parse_name(config: Dict[str, TOML_TYPES]) -> str:
"""
Parse the :pep621:`name` key, giving the name of the project.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Name`
This key is required, and must be defined statically.
Tools SHOULD normalize this name, as specified by :pep:`503`,
as soon as it is read for internal consistency.
:bold-title:`Example:`
.. code-block:: TOML
[project]
name = "spam"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
"""
normalized_name = _NormalisedName(normalize(config["name"]))
normalized_name.unnormalized = config["name"]
# https://packaging.python.org/specifications/core-metadata/#name
if not name_re.match(normalized_name):
> raise BadConfigError("The value for 'project.name' is invalid.")
E dom_toml.parser.BadConfigError: The value for 'project.name' is invalid.
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:297: BadConfigError
During handling of the above exception, another exception occurred:
config = '[project]\nname = "???????12345=============☃"\nversion = "2020.0.0"', expects = <class 'dom_toml.parser.BadConfigError'>
match = "The\\ value\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'\\ for\\ 'project\\.name'\\ is\\ invalid\\."
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_pep621parser_class_errors3')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_pep621parser_class_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with in_directory(tmp_pathplus), pytest.raises(expects, match=match):
> PEP621Parser().parse(dom_toml.load(tmp_pathplus / "pyproject.toml")["project"])
E AssertionError: Regex pattern "The\\ value\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'\\ for\\ 'project\\.name'\\ is\\ invalid\\." does not match "The value for 'project.name' is invalid.".
tests/test_config.py:678: AssertionError
_______________________________________________________________ test_pep621parser_class_errors[bad_version] ________________________________________________________________
config = {'name': 'spam', 'version': '???????12345=============☃'}
@staticmethod
def parse_version(config: Dict[str, TOML_TYPES]) -> Version:
"""
Parse the :pep621:`version` key, giving the version of the project as supported by :pep:`440`.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Version`
Users SHOULD prefer to specify normalized versions.
:bold-title:`Example:`
.. code-block:: TOML
[project]
version = "2020.0.0"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
"""
version = str(config["version"])
try:
> return Version(str(version))
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:324:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'Version' object has no attribute '_version'") raised in repr()] Version object at 0x7fbe190a9670>, version = '???????12345=============☃'
def __init__(self, version: str) -> None:
# Validate the version and parse it into pieces
match = self._regex.search(version)
if not match:
> raise InvalidVersion(f"Invalid version: '{version}'")
E packaging.version.InvalidVersion: Invalid version: '???????12345=============☃'
/usr/lib/python3.8/site-packages/packaging/version.py:266: InvalidVersion
During handling of the above exception, another exception occurred:
config = '[project]\nname = "spam"\nversion = "???????12345=============☃"', expects = <class 'packaging.version.InvalidVersion'>
match = "Invalid\\ version:\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'", tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_pep621parser_class_errors4')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_pep621parser_class_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with in_directory(tmp_pathplus), pytest.raises(expects, match=match):
> PEP621Parser().parse(dom_toml.load(tmp_pathplus / "pyproject.toml")["project"])
tests/test_config.py:678:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
whey/config/pep621.py:126: in parse
return self._parse(config, set_defaults)
whey/config/pep621.py:72: in _parse
parsed_config[key] = getattr(self, f"parse_{key.replace('-', '_')}")(config)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
config = {'name': 'spam', 'version': '???????12345=============☃'}
@staticmethod
def parse_version(config: Dict[str, TOML_TYPES]) -> Version:
"""
Parse the :pep621:`version` key, giving the version of the project as supported by :pep:`440`.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Version`
Users SHOULD prefer to specify normalized versions.
:bold-title:`Example:`
.. code-block:: TOML
[project]
version = "2020.0.0"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
"""
version = str(config["version"])
try:
return Version(str(version))
except InvalidVersion as e:
> raise BadConfigError(str(e))
E dom_toml.parser.BadConfigError: Invalid version: '???????12345=============☃'
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:326: BadConfigError
___________________________________________________________ test_pep621parser_class_errors[bad_requires_python] ____________________________________________________________
self = <[AttributeError("'SpecifierSet' object has no attribute '_prereleases'") raised in repr()] SpecifierSet object at 0x7fbe18ef53a0>
specifiers = '???????12345=============☃', prereleases = None
def __init__(
self, specifiers: str = "", prereleases: Optional[bool] = None
) -> None:
# Split on , to break each individual specifier into it's own item, and
# strip each item to remove leading/trailing whitespace.
split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
# Parsed each individual specifier, attempting first to make it a
# Specifier and falling back to a LegacySpecifier.
parsed: Set[_IndividualSpecifier] = set()
for specifier in split_specifiers:
try:
> parsed.add(Specifier(specifier))
/usr/lib/python3.8/site-packages/packaging/specifiers.py:634:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'Specifier' object has no attribute '_prereleases'") raised in repr()] Specifier object at 0x7fbe18ef5280>, spec = '???????12345=============☃'
prereleases = None
def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None:
match = self._regex.search(spec)
if not match:
> raise InvalidSpecifier(f"Invalid specifier: '{spec}'")
E packaging.specifiers.InvalidSpecifier: Invalid specifier: '???????12345=============☃'
/usr/lib/python3.8/site-packages/packaging/specifiers.py:98: InvalidSpecifier
During handling of the above exception, another exception occurred:
config = {'name': 'spam', 'requires-python': '???????12345=============☃', 'version': '2020.0.0'}
@staticmethod
def parse_requires_python(config: Dict[str, TOML_TYPES]) -> SpecifierSet:
"""
Parse the :pep621:`requires-python` key, giving the Python version requirements of the project.
The requirement should be in the form of a :pep:`508` marker.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Requires-Python`
:bold-title:`Example:`
.. code-block:: TOML
[project]
requires-python = ">=3.6"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
:rtype:
.. latex:clearpage::
"""
version = str(config["requires-python"])
try:
> return SpecifierSet(str(version))
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:495:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'SpecifierSet' object has no attribute '_prereleases'") raised in repr()] SpecifierSet object at 0x7fbe18ef53a0>
specifiers = '???????12345=============☃', prereleases = None
def __init__(
self, specifiers: str = "", prereleases: Optional[bool] = None
) -> None:
# Split on , to break each individual specifier into it's own item, and
# strip each item to remove leading/trailing whitespace.
split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()]
# Parsed each individual specifier, attempting first to make it a
# Specifier and falling back to a LegacySpecifier.
parsed: Set[_IndividualSpecifier] = set()
for specifier in split_specifiers:
try:
parsed.add(Specifier(specifier))
except InvalidSpecifier:
> parsed.add(LegacySpecifier(specifier))
/usr/lib/python3.8/site-packages/packaging/specifiers.py:636:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'LegacySpecifier' object has no attribute '_prereleases'") raised in repr()] LegacySpecifier object at 0x7fbe18ef5400>
spec = '???????12345=============☃', prereleases = None
def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None:
> super().__init__(spec, prereleases)
/usr/lib/python3.8/site-packages/packaging/specifiers.py:253:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'LegacySpecifier' object has no attribute '_prereleases'") raised in repr()] LegacySpecifier object at 0x7fbe18ef5400>
spec = '???????12345=============☃', prereleases = None
def __init__(self, spec: str = "", prereleases: Optional[bool] = None) -> None:
match = self._regex.search(spec)
if not match:
> raise InvalidSpecifier(f"Invalid specifier: '{spec}'")
E packaging.specifiers.InvalidSpecifier: Invalid specifier: '???????12345=============☃'
/usr/lib/python3.8/site-packages/packaging/specifiers.py:98: InvalidSpecifier
During handling of the above exception, another exception occurred:
config = '[project]\nname = "spam"\nversion = "2020.0.0"\nrequires-python = "???????12345=============☃"', expects = <class 'packaging.specifiers.InvalidSpecifier'>
match = "Invalid\\ specifier:\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'"
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_pep621parser_class_errors5')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_pep621parser_class_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with in_directory(tmp_pathplus), pytest.raises(expects, match=match):
> PEP621Parser().parse(dom_toml.load(tmp_pathplus / "pyproject.toml")["project"])
tests/test_config.py:678:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
whey/config/pep621.py:126: in parse
return self._parse(config, set_defaults)
whey/config/pep621.py:72: in _parse
parsed_config[key] = getattr(self, f"parse_{key.replace('-', '_')}")(config)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
config = {'name': 'spam', 'requires-python': '???????12345=============☃', 'version': '2020.0.0'}
@staticmethod
def parse_requires_python(config: Dict[str, TOML_TYPES]) -> SpecifierSet:
"""
Parse the :pep621:`requires-python` key, giving the Python version requirements of the project.
The requirement should be in the form of a :pep:`508` marker.
* **Format**: :toml:`String`
* **Core Metadata**: :core-meta:`Requires-Python`
:bold-title:`Example:`
.. code-block:: TOML
[project]
requires-python = ">=3.6"
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
:rtype:
.. latex:clearpage::
"""
version = str(config["requires-python"])
try:
return SpecifierSet(str(version))
except InvalidSpecifier as e:
> raise BadConfigError(str(e))
E dom_toml.parser.BadConfigError: Invalid specifier: '???????12345=============☃'
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:497: BadConfigError
_____________________________________________________ test_pep621parser_class_errors[dependencies_invalid_requirement] _____________________________________________________
self = <[AttributeError("'ComparableRequirement' object has no attribute 'name'") raised in repr()] ComparableRequirement object at 0x7fbe1a0f9160>
requirement_string = 'foo]]]'
def __init__(self, requirement_string: str) -> None:
try:
> req = REQUIREMENT.parseString(requirement_string)
/usr/lib/python3.8/site-packages/packaging/requirements.py:102:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = {string_start Combine:({W:(0-9A-Za-z) [{W:(0-9A-Za-z) | {[W:(-._)]... W:(0-9A-Za-z)}}]...}) [Suppress:('[') [Combine:(... {string enclosed in "'" | string enclosed in '"'}) | Group:({{Suppress:('(') : ...} Suppress:(') Empty}]}} string_end}
instring = 'foo]]]', parse_all = False
def parse_string(
self, instring: str, parse_all: bool = False, *, parseAll: bool = False
) -> ParseResults:
"""
Parse a string with respect to the parser definition. This function is intended as the primary interface to the
client code.
:param instring: The input string to be parsed.
:param parse_all: If set, the entire input string must match the grammar.
:param parseAll: retained for pre-PEP8 compatibility, will be removed in a future release.
:raises ParseException: Raised if ``parse_all`` is set and the input string does not match the whole grammar.
:returns: the parsed data as a :class:`ParseResults` object, which may be accessed as a `list`, a `dict`, or
an object with attributes if the given parser includes results names.
If the input string is required to match the entire grammar, ``parse_all`` flag must be set to ``True``. This
is also equivalent to ending the grammar with :class:`StringEnd`().
To report proper column numbers, ``parse_string`` operates on a copy of the input string where all tabs are
converted to spaces (8 spaces per tab, as per the default in ``string.expandtabs``). If the input string
contains tabs and the grammar uses parse actions that use the ``loc`` argument to index into the string
being parsed, one can ensure a consistent view of the input string by doing one of the following:
- calling ``parse_with_tabs`` on your grammar before calling ``parse_string`` (see :class:`parse_with_tabs`),
- define your parse action using the full ``(s,loc,toks)`` signature, and reference the input string using the
parse action's ``s`` argument, or
- explicitly expand the tabs in your input string before calling ``parse_string``.
Examples:
By default, partial matches are OK.
>>> res = Word('a').parse_string('aaaaabaaa')
>>> print(res)
['aaaaa']
The parsing behavior varies by the inheriting class of this abstract class. Please refer to the children
directly to see more examples.
It raises an exception if parse_all flag is set and instring does not match the whole grammar.
>>> res = Word('a').parse_string('aaaaabaaa', parse_all=True)
Traceback (most recent call last):
...
pyparsing.ParseException: Expected end of text, found 'b' (at char 5), (line:1, col:6)
"""
parseAll = parse_all or parseAll
ParserElement.reset_cache()
if not self.streamlined:
self.streamline()
for e in self.ignoreExprs:
e.streamline()
if not self.keepTabs:
instring = instring.expandtabs()
try:
loc, tokens = self._parse(instring, 0)
if parseAll:
loc = self.preParse(instring, loc)
se = Empty() + StringEnd()
se._parse(instring, loc)
except ParseBaseException as exc:
if ParserElement.verbose_stacktrace:
raise
else:
# catch and re-raise exception from here, clearing out pyparsing internal stack trace
> raise exc.with_traceback(None)
E pyparsing.exceptions.ParseException: Expected string_end, found ']' (at char 3), (line:1, col:4)
/usr/lib/python3.8/site-packages/pyparsing/core.py:1141: ParseException
During handling of the above exception, another exception occurred:
config = '[project]\nname = "spam"\nversion = "2020.0.0"\ndependencies = ["foo]]]"]', expects = <class 'packaging.requirements.InvalidRequirement'>
match = '\'foo]]]\'\\n Parse error at \\"\']]]\'\\": Expected string_end'
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_pep621parser_class_errors11')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_pep621parser_class_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with in_directory(tmp_pathplus), pytest.raises(expects, match=match):
> PEP621Parser().parse(dom_toml.load(tmp_pathplus / "pyproject.toml")["project"])
tests/test_config.py:678:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe18e0d820>, config = {'dependencies': ['foo]]]'], 'name': 'spam', 'version': '2020.0.0'}, set_defaults = False
def parse( # type: ignore[override]
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> ProjectDict:
"""
Parse the TOML configuration.
:param config:
:param set_defaults: If :py:obj:`True`, the values in
:attr:`dom_toml.parser.AbstractConfigParser.defaults` and
:attr:`dom_toml.parser.AbstractConfigParser.factories`
will be set as defaults for the returned mapping.
"""
dynamic_fields = set(config.get("dynamic", []))
if "name" in dynamic_fields:
raise BadConfigError("The 'project.name' field may not be dynamic.")
elif "name" not in config:
raise BadConfigError("The 'project.name' field must be provided.")
if dynamic_fields:
# TODO: Support the remaining fields as dynamic
# TODO: dynamic version numbers by parsing AST for __version__ in __init__.py
supported_dynamic = {"classifiers", "requires-python", "dependencies"}
unsupported_fields = dynamic_fields - supported_dynamic
if unsupported_fields:
supported = word_join(sorted(supported_dynamic), oxford=True, use_repr=True)
unsupported = word_join(sorted(unsupported_fields), oxford=True, use_repr=True)
raise BadConfigError(
f"Unsupported dynamic {_field(len(unsupported_fields))} {unsupported}.\n"
f"note: whey only supports {supported} as dynamic fields."
)
if "version" not in config:
raise BadConfigError("The 'project.version' field must be provided.")
> return self._parse(config, set_defaults)
whey/config/pep621.py:126:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe18e0d820>, config = {'dependencies': ['foo]]]'], 'name': 'spam', 'version': '2020.0.0'}, set_defaults = False
def _parse(
self,
config: Dict[str, TOML_TYPES],
set_defaults: bool = False,
) -> ProjectDict:
dynamic_fields = config.get("dynamic", [])
parsed_config = {"dynamic": dynamic_fields}
for key in self.keys:
if key in config and key in dynamic_fields:
raise BadConfigError(f"{key!r} was listed in 'project.dynamic' but a value was given.")
elif key not in config:
# Ignore absent values
pass
elif hasattr(self, f"parse_{key.replace('-', '_')}"):
> parsed_config[key] = getattr(self, f"parse_{key.replace('-', '_')}")(config)
whey/config/pep621.py:72:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <whey.config.pep621.PEP621Parser object at 0x7fbe18e0d820>, config = {'dependencies': ['foo]]]'], 'name': 'spam', 'version': '2020.0.0'}
def parse_dependencies(self, config: Dict[str, TOML_TYPES]) -> List[ComparableRequirement]:
"""
Parse the :pep621:`dependencies` key, giving the dependencies of the project.
* **Format**: :toml:`Array` of :pep:`508` strings
* **Core Metadata**: :core-meta:`Requires-Dist`
Each string MUST be formatted as a valid :pep:`508` string.
:bold-title:`Example:`
.. code-block:: TOML
[project]
dependencies = [
"httpx",
"gidgethub[httpx]>4.0.0",
"django>2.1; os_name != 'nt'",
"django>2.0; os_name == 'nt'"
]
:param config: The unparsed TOML config for the :pep621:`project table <table-name>`.
"""
parsed_dependencies = set()
key_path = [self.table_name, "dependencies"]
self.assert_sequence_not_str(config["dependencies"], key_path)
for idx, keyword in enumerate(config["dependencies"]):
self.assert_indexed_type(keyword, str, key_path, idx=idx)
> parsed_dependencies.add(ComparableRequirement(keyword))
/usr/lib/python3.8/site-packages/pyproject_parser/parsers.py:899:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'ComparableRequirement' object has no attribute 'name'") raised in repr()] ComparableRequirement object at 0x7fbe1a0f9160>
requirement_string = 'foo]]]'
def __init__(self, requirement_string: str) -> None:
try:
req = REQUIREMENT.parseString(requirement_string)
except ParseException as e:
> raise InvalidRequirement(
f'Parse error at "{ requirement_string[e.loc : e.loc + 8]!r}": {e.msg}'
)
E packaging.requirements.InvalidRequirement: Parse error at "']]]'": Expected string_end
/usr/lib/python3.8/site-packages/packaging/requirements.py:104: InvalidRequirement
During handling of the above exception, another exception occurred:
config = '[project]\nname = "spam"\nversion = "2020.0.0"\ndependencies = ["foo]]]"]', expects = <class 'packaging.requirements.InvalidRequirement'>
match = '\'foo]]]\'\\n Parse error at \\"\']]]\'\\": Expected string_end'
tmp_pathplus = PosixPathPlus('/tmp/pytest-of-tkloczko/pytest-47/test_pep621parser_class_errors11')
@pytest.mark.parametrize(
"config, expects, match",
[
pytest.param(
'[project]\nname = "spam"',
BadConfigError,
"The 'project.version' field must be provided.",
id="no_version"
),
*bad_pep621_config,
]
)
def test_pep621parser_class_errors(config: str, expects: Type[Exception], match: str, tmp_pathplus: PathPlus):
(tmp_pathplus / "pyproject.toml").write_clean(config)
with in_directory(tmp_pathplus), pytest.raises(expects, match=match):
> PEP621Parser().parse(dom_toml.load(tmp_pathplus / "pyproject.toml")["project"])
E AssertionError: Regex pattern '\'foo]]]\'\\n Parse error at \\"\']]]\'\\": Expected string_end' does not match 'Parse error at "\']]]\'": Expected string_end'.
tests/test_config.py:678: AssertionError
=========================================================================== slowest 25 durations ===========================================================================
0.04s call tests/test_build.py::test_build_additional_files
0.04s call tests/test_build.py::test_build_additional_files_source_dir
0.04s call tests/test_pep517_backend.py::test_build_additional_files[1]
0.04s call tests/test_pep517_backend.py::test_build_additional_files[None]
0.04s call tests/test_build.py::test_build_success[optional-dependencies]
0.04s call tests/test_foreman.py::test_build_success[optional-dependencies]
0.04s call tests/test_pep517_backend.py::test_build_additional_files[0]
0.04s call tests/test_foreman.py::test_build_additional_files
0.03s call tests/test_build.py::test_build_complete[LONG_REQUIREMENTS]
0.03s call tests/test_build.py::test_build_complete[COMPLETE_A]
0.03s call tests/test_build.py::test_build_wheel_from_sdist[DYNAMIC_REQUIREMENTS]
0.03s call tests/test_build.py::test_build_wheel_from_sdist[LONG_REQUIREMENTS]
0.03s call tests/test_build.py::test_build_source_dir_complete[COMPLETE_A]
0.03s call tests/test_pep517_backend.py::test_build_complete[COMPLETE_B-1]
0.03s call tests/test_build.py::test_build_wheel_from_sdist[COMPLETE_B]
0.03s call tests/test_build.py::test_build_source_dir_complete[COMPLETE_B]
0.03s call tests/test_build.py::test_build_source_dir_different_package
0.03s call tests/test_build.py::test_build_wheel_from_sdist[COMPLETE_A]
0.03s call tests/test_build.py::test_build_complete[COMPLETE_B]
0.03s call tests/test_build.py::test_build_wheel_from_sdist_source_dir[COMPLETE_A]
0.03s call tests/test_build.py::test_build_markdown_readme
0.03s call tests/test_build.py::test_build_wheel_from_sdist_source_dir[COMPLETE_B]
0.03s call tests/test_pep517_backend.py::test_build_complete[COMPLETE_A-None]
0.03s call tests/test_pep517_backend.py::test_build_complete[COMPLETE_A-1]
0.03s call tests/test_pep517_backend.py::test_build_complete[COMPLETE_B-0]
========================================================================= short test summary info ==========================================================================
SKIPPED [3] tests/test_build.py:251: Not needed on Python v3.6.0.
SKIPPED [1] tests/test_builder_methods.py:21: Not needed on Python v3.6.0.
SKIPPED [2] tests/test_config.py:642: Message differs on Windows.
SKIPPED [2] tests/test_config.py:662: Message differs on Windows.
SKIPPED [2] tests/test_pep517_backend.py:278: Not needed on Python v3.6.0.
FAILED tests/test_config.py::test_parse_config_errors[bad_name] - AssertionError: Regex pattern "The\\ value\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'\\ for\\ 'projec...
FAILED tests/test_config.py::test_parse_config_errors[bad_version] - dom_toml.parser.BadConfigError: Invalid version: '???????12345=============☃'
FAILED tests/test_config.py::test_parse_config_errors[bad_requires_python] - dom_toml.parser.BadConfigError: Invalid specifier: '???????12345=============☃'
FAILED tests/test_config.py::test_parse_config_errors[dependencies_invalid_requirement] - AssertionError: Regex pattern '\'foo]]]\'\\n Parse error at \\"\']]]\'\\": E...
FAILED tests/test_config.py::test_pep621parser_class_errors[bad_name] - AssertionError: Regex pattern "The\\ value\\ '\\?\\?\\?\\?\\?\\?\\?12345=============☃'\\ for\\ '...
FAILED tests/test_config.py::test_pep621parser_class_errors[bad_version] - dom_toml.parser.BadConfigError: Invalid version: '???????12345=============☃'
FAILED tests/test_config.py::test_pep621parser_class_errors[bad_requires_python] - dom_toml.parser.BadConfigError: Invalid specifier: '???????12345=============☃'
FAILED tests/test_config.py::test_pep621parser_class_errors[dependencies_invalid_requirement] - AssertionError: Regex pattern '\'foo]]]\'\\n Parse error at \\"\']]]\'...
================================================================ 8 failed, 222 passed, 10 skipped in 4.54s ================================================================= |
I'm going to add above failing units temporary to --deselect list so .. no rush 😋 BTW: I have question. In pytest parames I've dded to --ignore list two fiels whoch are doing |
I'm packaging your module as an rpm package so I'm using the typical PEP517 based build, install and test cycle used on building packages from non-root account.
python3 -sBm build -w --no-isolation
build
with--no-isolation
I'm using during all processes only locally installed modulesHere is list of modules installed in build env
The text was updated successfully, but these errors were encountered: