Skip to content

0.7.0: tests is falling in exceptions #37

Open
@ancieg

Description

@ancieg

Description

Tests crash during check bad config.

Steps to Reproduce

  1. Run python3 -m pytest

Actual result:

Output:

____________________ test_pep621_class_bad_config[bad_name] ____________________

config = '[project]\nname = "???????12345=============☃"\nversion = "2020.0.0"'
expects = <class 'dom_toml.parser.BadConfigError'>
match = "The value for 'project.name' is invalid."
tmp_pathplus = PosixPathPlus('/usr/src/tmp/pytest-of-builder/pytest-0/test_pep621_class_bad_config_b0')

    @pytest.mark.parametrize(
    		"config, expects, match",
    		[
    				*bad_pep621_config,
    				# pytest.param(
    				# 		'[project]\nname = "foo"\nversion = "1.2.3"\n[project.optional-dependencies]\nwith-hyphen = []',
    				# 		TypeError,
    				# 		"Invalid extra name 'with-hyphen'",
    				# 		id="extra_invalid_a",
    				# 		),
    				pytest.param(
    						'[project]\nname = "foo"\nversion = "1.2.3"\n[project.optional-dependencies]\n"quoted?" = []',
    						TypeError,
    						r"Invalid extra name 'quoted\?'",
    						id="extra_invalid_b",
    						),
    				pytest.param(
    						'[project]\nname = "foo"\nversion = "1.2.3"\n[project.optional-dependencies]\n"number#1" = []',
    						TypeError,
    						"Invalid extra name 'number#1'",
    						id="extra_invalid_c",
    						),
    				]
    		)
    def test_pep621_class_bad_config(
    		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:323: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pyproject_parser.parsers.PEP621Parser object at 0x7fcf62cde440>
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:`self.defaults <dom_toml.parser.AbstractConfigParser.defaults>` and
    		:attr:`self.factories <dom_toml.parser.AbstractConfigParser.factories>`
    		will be set as defaults for the returned mapping.
    	"""
    
    	dynamic_fields = config.get("dynamic", [])
    
    	if "name" in dynamic_fields:
    		raise BadConfigError("The 'project.name' field may not be dynamic.")
    
>   	super_parsed_config = super().parse(config, set_defaults=set_defaults)

pyproject_parser/parsers.py:1093: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pyproject_parser.parsers.PEP621Parser object at 0x7fcf62cde440>
config = {'name': '???????12345=============☃', 'version': '2020.0.0'}
set_defaults = False

    def parse(
    		self,
    		config: Dict[str, TOML_TYPES],
    		set_defaults: bool = False,
    		) -> Dict[str, TOML_TYPES]:
    	"""
    	Parse the TOML configuration.
    
    	:param config:
    	:param set_defaults: If :py:obj:`True`, the values in
    		:attr:`self.defaults <dom_toml.parser.AbstractConfigParser.defaults>` and
    		:attr:`self.factories <dom_toml.parser.AbstractConfigParser.factories>`
    		will be set as defaults for the returned mapping.
    	"""
    
    	for key in self.required_keys:
    		if key in config:
    			continue
    		elif set_defaults and (key in self.defaults or key in self.factories):
    			continue  # pragma: no cover https://github.com/nedbat/coveragepy/issues/198
    		else:
    			raise BadConfigError(f"The {construct_path([self.table_name, key])!r} field must be provided.")
    
>   	return super().parse(config, set_defaults)

pyproject_parser/parsers.py:116: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pyproject_parser.parsers.PEP621Parser object at 0x7fcf62cde440>
config = {'name': '???????12345=============☃', 'version': '2020.0.0'}
set_defaults = False

    def parse(
    		self,
    		config: Dict[str, TOML_TYPES],
    		set_defaults: bool = False,
    		) -> Dict[str, TOML_TYPES]:
    	r"""
    	Parse the TOML configuration.
    
    	This function iterates over the list of keys given in :attr:`~.keys`.
    	For each key, it searches for a method on the class called :file:`parse_{<key>}`.
    
    	* If the method exists, that method is called, passing the value as the only argument.
    	  The value returned from that method is included in the parsed configuration.
    	  The signature of those methods is:
    
    	  .. parsed-literal::
    
    		def visit_<key>(
    			self,
    			config: :class:`typing.Dict`\[:class:`str`\, :py:obj:`typing.Any`\],
    			) -> :py:obj:`typing.Any`\:
    
    	* If the method doesn't exist, the value is included in the parsed configuration unchanged.
    
    	* Missing keys are ignored. Override this function in a subclass if you need that behaviour.
    
    	Once all keys have been parsed the configuration is returned.
    
    	:param config:
    	:param set_defaults: If :py:obj:`True`, the values in :attr:`.AbstractConfigParser.defaults`
    		and :attr:`.AbstractConfigParser.factories` will be set as defaults for the returned mapping.
    
    	.. versionchanged:: 0.3.0
    
    		Added the ``set_defaults`` keyword argument.
    	"""
    
    	parsed_config = {}
    
    	for key in self.keys:
    		if 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)

/usr/lib/python3/site-packages/dom_toml/parser.py:233: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = ({'name': '???????12345=============☃', 'version': '2020.0.0'},)
kwds = {}

    @functools.wraps(f)
    def wrapper(*args, **kwds):
    	try:
>   		return f(*args, **kwds)

pyproject_parser/parsers.py:72: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

config = {'name': '???????12345=============☃', 'version': '2020.0.0'}

    @staticmethod
    @_documentation_url("https://whey.readthedocs.io/en/latest/configuration.html#tconf-project.name")
    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>`.
    	"""
    
    	name = config["name"]
    	normalized_name = _NormalisedName(normalize(name))
    	normalized_name.unnormalized = name
    
    	# https://packaging.python.org/specifications/core-metadata/#name
    	if not name_re.match(normalized_name):
>   		raise BadConfigError(f"The value {name!r} for 'project.name' is invalid.")
E     dom_toml.parser.BadConfigError: The value '???????12345=============☃' for 'project.name' is invalid.

pyproject_parser/parsers.py:328: 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 for 'project.name' is invalid."
tmp_pathplus = PosixPathPlus('/usr/src/tmp/pytest-of-builder/pytest-0/test_pep621_class_bad_config_b0')

    @pytest.mark.parametrize(
    		"config, expects, match",
    		[
    				*bad_pep621_config,
    				# pytest.param(
    				# 		'[project]\nname = "foo"\nversion = "1.2.3"\n[project.optional-dependencies]\nwith-hyphen = []',
    				# 		TypeError,
    				# 		"Invalid extra name 'with-hyphen'",
    				# 		id="extra_invalid_a",
    				# 		),
    				pytest.param(
    						'[project]\nname = "foo"\nversion = "1.2.3"\n[project.optional-dependencies]\n"quoted?" = []',
    						TypeError,
    						r"Invalid extra name 'quoted\?'",
    						id="extra_invalid_b",
    						),
    				pytest.param(
    						'[project]\nname = "foo"\nversion = "1.2.3"\n[project.optional-dependencies]\n"number#1" = []',
    						TypeError,
    						"Invalid extra name 'number#1'",
    						id="extra_invalid_c",
    						),
    				]
    		)
    def test_pep621_class_bad_config(
    		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):
E    AssertionError: Regex pattern "The value for 'project.name' is invalid." does not match "The value '???????12345=============☃' for 'project.name' is invalid.".

tests/test_config.py:322: AssertionError

and few similar cases.

Expected result:

Tests pass.

Reproduces how often:

Always.

Version

  • Operating System: ALT Workstation K 10.1, with Sisyphus repository (01.10.2022).
  • Python: Python 3.10.7 (main, Sep 13 2022, 12:33:40) [GCC 12.1.1 20220518 (ALT Sisyphus 12.1.1-alt1)]
  • pyproject-parser: git checkout v0.7.0

Installation source

GitHub repository.

Other Additional Information:

It looks like an error in pytest.raises or in packaging (incompatible versions?). I think so because an BadConfigError exception leads to raise another one (AssertionError).

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingstale

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions