Skip to content

Commit

Permalink
Merge pull request #391 from python/ghpython-93259/from-name-arg-vali…
Browse files Browse the repository at this point in the history
…dation-simple

Validate name arg in Distribution.from_name
  • Loading branch information
jaraco committed Jun 25, 2022
2 parents f52757d + 91b7149 commit c8d7285
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 1 deletion.
7 changes: 7 additions & 0 deletions CHANGES.rst
@@ -1,3 +1,10 @@
v4.12.0
=======

* py-93259: Now raise ``ValueError`` when ``None`` or an empty
string are passed to ``Distribution.from_name`` (and other
callers).

v4.11.4
=======

Expand Down
4 changes: 4 additions & 0 deletions docs/conf.py
Expand Up @@ -20,6 +20,10 @@
pattern=r'PEP[- ](?P<pep_number>\d+)',
url='https://peps.python.org/pep-{pep_number:0>4}/',
),
dict(
pattern=r'(Python #|py-)(?P<python>\d+)',
url='https://github.com/python/cpython/issues/{python}',
),
],
)
}
Expand Down
5 changes: 4 additions & 1 deletion importlib_metadata/__init__.py
Expand Up @@ -548,15 +548,18 @@ def locate_file(self, path):
"""

@classmethod
def from_name(cls, name):
def from_name(cls, name: str):
"""Return the Distribution for the given package name.
:param name: The name of the distribution package to search for.
:return: The Distribution instance (or subclass thereof) for the named
package, if found.
:raises PackageNotFoundError: When the named package's distribution
metadata cannot be found.
:raises ValueError: When an invalid value is supplied for name.
"""
if not name:
raise ValueError("A distribution name is required.")
try:
return next(cls.discover(name=name))
except StopIteration:
Expand Down
16 changes: 16 additions & 0 deletions tests/fixtures.py
Expand Up @@ -5,6 +5,7 @@
import pathlib
import tempfile
import textwrap
import functools
import contextlib

from .py39compat import FS_NONASCII
Expand Down Expand Up @@ -294,3 +295,18 @@ def setUp(self):
# Add self.zip_name to the front of sys.path.
self.resources = contextlib.ExitStack()
self.addCleanup(self.resources.close)


def parameterize(*args_set):
"""Run test method with a series of parameters."""

def wrapper(func):
@functools.wraps(func)
def _inner(self):
for args in args_set:
with self.subTest(**args):
func(self, **args)

return _inner

return wrapper
8 changes: 8 additions & 0 deletions tests/test_main.py
Expand Up @@ -50,6 +50,14 @@ def test_new_style_classes(self):
self.assertIsInstance(Distribution, type)
self.assertIsInstance(MetadataPathFinder, type)

@fixtures.parameterize(
dict(name=None),
dict(name=''),
)
def test_invalid_inputs_to_from_name(self, name):
with self.assertRaises(Exception):
Distribution.from_name(name)


class ImportTests(fixtures.DistInfoPkg, unittest.TestCase):
def test_import_nonexistent_module(self):
Expand Down

0 comments on commit c8d7285

Please sign in to comment.