From cfd9b2641451c3af78c0a3ca0d13367fc94bdddc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 25 Mar 2023 10:46:40 -0400 Subject: [PATCH 1/9] Mark test as xfail as it's about to fail. Ref #442. --- tests/test_main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/test_main.py b/tests/test_main.py index 16367793..3c8103d8 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -323,6 +323,9 @@ def test_packages_distributions_neither_toplevel_nor_files(self): ) packages_distributions() + import pytest + + @pytest.mark.xfail(reason="442") def test_packages_distributions_all_module_types(self): """ Test top-level modules detected on a package without 'top-level.txt'. From 5e8260c8e545d7f21c779fb8b57004bc280ae330 Mon Sep 17 00:00:00 2001 From: Johan Herland Date: Sat, 25 Mar 2023 10:49:47 -0400 Subject: [PATCH 2/9] Add test capturing missed expectation. Ref #442. --- tests/test_main.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 3c8103d8..96a02788 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -339,10 +339,10 @@ def test_packages_distributions_all_module_types(self): Version: 1.0.0 """, 'RECORD': ''.join( - f'{i}-top-level{suffix},,\n' - f'{i}-in-namespace/mod{suffix},,\n' - f'{i}-in-package/__init__.py,,\n' - f'{i}-in-package/mod{suffix},,\n' + f'top_level_{i}{suffix},,\n' + f'in_namespace_{i}/mod{suffix},,\n' + f'in_package_{i}/__init__.py,,\n' + f'in_package_{i}/mod{suffix},,\n' for i, suffix in enumerate(suffixes) ), }, @@ -353,6 +353,11 @@ def test_packages_distributions_all_module_types(self): distributions = packages_distributions() for i in range(len(suffixes)): - assert distributions[f'{i}-top-level'] == ['all_distributions'] - assert distributions[f'{i}-in-namespace'] == ['all_distributions'] - assert distributions[f'{i}-in-package'] == ['all_distributions'] + assert distributions[f'top_level_{i}'] == ['all_distributions'] + assert distributions[f'in_namespace_{i}'] == ['all_distributions'] + assert distributions[f'in_package_{i}'] == ['all_distributions'] + + # All keys return from packages_distributions() should be valid import + # names, which means that they must _at least_ be valid identifiers: + for import_name in distributions.keys(): + assert import_name.isidentifier(), import_name From da5785526aeeb0cfbf4842fd640bf84570489515 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 25 Mar 2023 10:50:33 -0400 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=91=B9=20Feed=20the=20hobgoblins=20(d?= =?UTF-8?q?elint).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pep8 states that comments should be limited to 72 characters. --- tests/test_main.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 96a02788..83f04f80 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -357,7 +357,8 @@ def test_packages_distributions_all_module_types(self): assert distributions[f'in_namespace_{i}'] == ['all_distributions'] assert distributions[f'in_package_{i}'] == ['all_distributions'] - # All keys return from packages_distributions() should be valid import - # names, which means that they must _at least_ be valid identifiers: + # All keys return from packages_distributions() should be valid + # import names, which means that they must _at least_ be valid + # identifiers: for import_name in distributions.keys(): assert import_name.isidentifier(), import_name From c8676416f80bb8ef79f46c24b8cc25812cc0708b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 25 Mar 2023 10:51:52 -0400 Subject: [PATCH 4/9] Prefer all when asserting all. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚫ Fade to black. --- tests/test_main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index 83f04f80..73747405 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -360,5 +360,4 @@ def test_packages_distributions_all_module_types(self): # All keys return from packages_distributions() should be valid # import names, which means that they must _at least_ be valid # identifiers: - for import_name in distributions.keys(): - assert import_name.isidentifier(), import_name + assert all(import_name.isidentifier() for import_name in distributions.keys()) From 340cac39996ed9cb9f0522993cdd259ce4b99480 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 25 Mar 2023 11:19:29 -0400 Subject: [PATCH 5/9] Filter non-identifiers from module names. Fixes #442. --- importlib_metadata/__init__.py | 7 ++++++- tests/test_main.py | 3 --- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/importlib_metadata/__init__.py b/importlib_metadata/__init__.py index 8d9f0016..e44ea31a 100644 --- a/importlib_metadata/__init__.py +++ b/importlib_metadata/__init__.py @@ -902,4 +902,9 @@ def _top_level_inferred(dist): f.parts[0] if len(f.parts) > 1 else inspect.getmodulename(f) for f in always_iterable(dist.files) } - return filter(None, opt_names) + + @pass_none + def valid_module(name): + return name.isidentifier() + + return filter(valid_module, opt_names) diff --git a/tests/test_main.py b/tests/test_main.py index 73747405..ba752d88 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -323,9 +323,6 @@ def test_packages_distributions_neither_toplevel_nor_files(self): ) packages_distributions() - import pytest - - @pytest.mark.xfail(reason="442") def test_packages_distributions_all_module_types(self): """ Test top-level modules detected on a package without 'top-level.txt'. From a4e2a9b0905992e3ccad9d3dfb59cbeeb1a3b8b9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 9 Apr 2023 10:45:29 -0400 Subject: [PATCH 6/9] Relax assertion that all names in packages_distributions are identifiers. The main contstraint here for an importable module is that it must not contain a module separator ('.'). Other names that contain dashes or spaces cannot be imported with the 'import' statement, but can be imported with 'importlib.import_module' or invoked with 'runpy'. --- tests/test_main.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_main.py b/tests/test_main.py index ba752d88..7f711f16 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -354,7 +354,9 @@ def test_packages_distributions_all_module_types(self): assert distributions[f'in_namespace_{i}'] == ['all_distributions'] assert distributions[f'in_package_{i}'] == ['all_distributions'] - # All keys return from packages_distributions() should be valid - # import names, which means that they must _at least_ be valid - # identifiers: - assert all(import_name.isidentifier() for import_name in distributions.keys()) + def is_importable(name): + return '.' not in name + + # All keys returned from packages_distributions() should be + # importable. + assert all(map(is_importable, distributions)) From 7968a088e5ec63313d19100010d7a10a7f66b729 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 9 Apr 2023 11:02:51 -0400 Subject: [PATCH 7/9] Expand test to include importable names that aren't identifiers and honor that expectation. --- importlib_metadata/__init__.py | 6 +++--- tests/test_main.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/importlib_metadata/__init__.py b/importlib_metadata/__init__.py index e44ea31a..217ca9cc 100644 --- a/importlib_metadata/__init__.py +++ b/importlib_metadata/__init__.py @@ -904,7 +904,7 @@ def _top_level_inferred(dist): } @pass_none - def valid_module(name): - return name.isidentifier() + def importable_name(name): + return '.' not in name - return filter(valid_module, opt_names) + return filter(importable_name, opt_names) diff --git a/tests/test_main.py b/tests/test_main.py index 7f711f16..d04deba0 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -336,7 +336,7 @@ def test_packages_distributions_all_module_types(self): Version: 1.0.0 """, 'RECORD': ''.join( - f'top_level_{i}{suffix},,\n' + f'importable-name {i}{suffix},,\n' f'in_namespace_{i}/mod{suffix},,\n' f'in_package_{i}/__init__.py,,\n' f'in_package_{i}/mod{suffix},,\n' @@ -350,7 +350,7 @@ def test_packages_distributions_all_module_types(self): distributions = packages_distributions() for i in range(len(suffixes)): - assert distributions[f'top_level_{i}'] == ['all_distributions'] + assert distributions[f'importable-name {i}'] == ['all_distributions'] assert distributions[f'in_namespace_{i}'] == ['all_distributions'] assert distributions[f'in_package_{i}'] == ['all_distributions'] From 1a831b670b9521acedc8bef80c19bbf7eb524588 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 9 Apr 2023 11:07:12 -0400 Subject: [PATCH 8/9] Capture expectation that 'dist-info' should not appear in inferred top-level names. Ref #442. --- tests/test_main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_main.py b/tests/test_main.py index 3c8103d8..e24acf37 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -338,7 +338,8 @@ def test_packages_distributions_all_module_types(self): Name: all_distributions Version: 1.0.0 """, - 'RECORD': ''.join( + 'RECORD': 'all_distributions-1.0.0.dist-info/METADATA\n' + + ''.join( f'{i}-top-level{suffix},,\n' f'{i}-in-namespace/mod{suffix},,\n' f'{i}-in-package/__init__.py,,\n' @@ -356,3 +357,5 @@ def test_packages_distributions_all_module_types(self): assert distributions[f'{i}-top-level'] == ['all_distributions'] assert distributions[f'{i}-in-namespace'] == ['all_distributions'] assert distributions[f'{i}-in-package'] == ['all_distributions'] + + assert not any(name.endswith('.dist-info') for name in distributions) From 4c02b186ba77cb02dbc153515146e15f9bcfc16a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 9 Apr 2023 11:16:12 -0400 Subject: [PATCH 9/9] Update changelog. --- CHANGES.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index eccdd5ba..bab2571b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,10 @@ +v6.1.1 +====== + +* #442: Fixed issue introduced in v6.1.0 where non-importable + names (metadata dirs) began appearing in + ``packages_distributions``. + v6.1.0 ======