Skip to content

Commit 3ca81a7

Browse files
committed
_adapters: make CompatibilityFiles return path-like traversables if possible
Signed-off-by: Filipe Laíns <[email protected]>
1 parent 54a61c4 commit 3ca81a7

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

importlib_resources/_adapters.py

+39-3
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,19 @@ def __init__(self, spec, reader):
5555
self._spec = spec
5656
self._reader = reader
5757

58+
@classmethod
59+
def new(cls, spec, reader):
60+
try:
61+
fspath = reader.resource_path(None)
62+
except FileNotFoundError:
63+
return cls(spec, reader)
64+
return CompatibilityFiles.PathLikeSpecPath(spec, reader, fspath)
65+
5866
def iterdir(self):
5967
if not self._reader:
6068
return iter(())
6169
return iter(
62-
CompatibilityFiles.ChildPath(self._reader, path)
70+
CompatibilityFiles.ChildPath.new(self._reader, path)
6371
for path in self._reader.contents()
6472
)
6573

@@ -71,7 +79,7 @@ def is_file(self):
7179
def joinpath(self, other):
7280
if not self._reader:
7381
return CompatibilityFiles.OrphanPath(other)
74-
return CompatibilityFiles.ChildPath(self._reader, other)
82+
return CompatibilityFiles.ChildPath.new(self._reader, other)
7583

7684
@property
7785
def name(self):
@@ -80,6 +88,16 @@ def name(self):
8088
def open(self, mode='r', *args, **kwargs):
8189
return _io_wrapper(self._reader.open_resource(None), mode, *args, **kwargs)
8290

91+
class PathLikeSpecPath(SpecPath):
92+
"""SpecPath but os.PathLike"""
93+
94+
def __init__(self, spec, reader, fspath):
95+
super().__init__(spec, reader)
96+
self._fspath = fspath
97+
98+
def __fspath__(self):
99+
return self._fspath
100+
83101
class ChildPath(abc.Traversable):
84102
"""
85103
Path tied to a resource reader child.
@@ -90,6 +108,14 @@ def __init__(self, reader, name):
90108
self._reader = reader
91109
self._name = name
92110

111+
@classmethod
112+
def new(cls, reader, name):
113+
try:
114+
fspath = reader.resource_path(name)
115+
except FileNotFoundError:
116+
return cls(reader, name)
117+
return CompatibilityFiles.PathLikeChildPath(reader, name, fspath)
118+
93119
def iterdir(self):
94120
return iter(())
95121

@@ -111,6 +137,16 @@ def open(self, mode='r', *args, **kwargs):
111137
self._reader.open_resource(self.name), mode, *args, **kwargs
112138
)
113139

140+
class PathLikeChildPath(SpecPath):
141+
"""ChildPath but os.PathLike"""
142+
143+
def __init__(self, reader, name, fspath):
144+
super().__init__(reader, name)
145+
self._fspath = fspath
146+
147+
def __fspath__(self):
148+
return self._fspath
149+
114150
class OrphanPath(abc.Traversable):
115151
"""
116152
Orphan path, not tied to a module spec or resource reader.
@@ -159,7 +195,7 @@ def __getattr__(self, attr):
159195
return getattr(self._reader, attr)
160196

161197
def files(self):
162-
return CompatibilityFiles.SpecPath(self.spec, self._reader)
198+
return CompatibilityFiles.SpecPath.new(self.spec, self._reader)
163199

164200

165201
def wrap_spec(package):

importlib_resources/tests/test_compatibilty_files.py

+5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import io
2+
import os
23
import unittest
34

45
import importlib_resources as resources
@@ -88,6 +89,10 @@ def test_wrap_spec(self):
8889
spec = wrap_spec(self.package)
8990
self.assertIsInstance(spec.loader.get_resource_reader(None), CompatibilityFiles)
9091

92+
def test_fspath(self):
93+
self.assertEqual(os.fspath(self.files), 'some_path')
94+
self.assertEqual(os.fspath(self.files / 'a'), 'some_path')
95+
9196

9297
class CompatibilityFilesNoReaderTests(unittest.TestCase):
9398
@property

0 commit comments

Comments
 (0)