Skip to content

Commit 2c145c5

Browse files
committed
Omit sentinel values from a namespace path.
When editable installs create sentinels, as they are not a valid directory, they're unsuitable for constructing a `MultiplexedPath`. Filter them out. Fixes #311
1 parent 47d73b1 commit 2c145c5

File tree

3 files changed

+9
-7
lines changed

3 files changed

+9
-7
lines changed

importlib_resources/readers.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,19 +138,23 @@ class NamespaceReader(abc.TraversableResources):
138138
def __init__(self, namespace_path):
139139
if 'NamespacePath' not in str(namespace_path):
140140
raise ValueError('Invalid path')
141-
self.path = MultiplexedPath(*map(self._resolve, namespace_path))
141+
self.path = MultiplexedPath(*filter(bool, map(self._resolve, namespace_path)))
142142

143143
@classmethod
144-
def _resolve(cls, path_str) -> abc.Traversable:
144+
def _resolve(cls, path_str) -> abc.Traversable | None:
145145
r"""
146146
Given an item from a namespace path, resolve it to a Traversable.
147147
148148
path_str might be a directory on the filesystem or a path to a
149149
zipfile plus the path within the zipfile, e.g. ``/foo/bar`` or
150150
``/foo/baz.zip/inner_dir`` or ``foo\baz.zip\inner_dir\sub``.
151+
152+
path_str might also be a sentinel used by editable packages to
153+
trigger other behaviors (see python/importlib_resources#311).
154+
In that case, return None.
151155
"""
152-
(dir,) = (cand for cand in cls._candidate_paths(path_str) if cand.is_dir())
153-
return dir
156+
dirs = (cand for cand in cls._candidate_paths(path_str) if cand.is_dir())
157+
return next(dirs, None)
154158

155159
@classmethod
156160
def _candidate_paths(cls, path_str: str) -> Iterator[abc.Traversable]:

importlib_resources/tests/test_files.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
import importlib
99
import contextlib
1010

11-
import pytest
12-
1311
import importlib_resources as resources
1412
from ..abc import Traversable
1513
from . import util
@@ -62,7 +60,6 @@ class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase):
6260
class OpenNamespaceTests(FilesTests, util.DiskSetup, unittest.TestCase):
6361
MODULE = 'namespacedata01'
6462

65-
@pytest.mark.xfail(reason="#311")
6663
def test_non_paths_in_dunder_path(self):
6764
"""
6865
Non-path items in a namespace package's ``__path__`` are ignored.

newsfragments/311.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Omit sentinel values from a namespace path.

0 commit comments

Comments
 (0)