Skip to content

Commit 8ac7ab5

Browse files
authored
Merge pull request #236 from python/feature/deprecate-legacy
Deprecate legacy functions
2 parents b665a3e + 239ae6d commit 8ac7ab5

File tree

9 files changed

+193
-80
lines changed

9 files changed

+193
-80
lines changed

CHANGES.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
v5.3.0
2+
======
3+
4+
* #80: Now raise a ``DeprecationWarning`` for all legacy
5+
functions. Instead, users should rely on the ``files()``
6+
API introduced in importlib_resources 1.3. See
7+
`Migrating from Legacy <https://importlib-resources.readthedocs.io/en/latest/using.html#migrating-from-legacy>`_
8+
for guidance on avoiding the deprecated functions.
9+
110
v5.2.3
211
======
312

docs/using.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,23 @@ manager.
163163
Both relative and absolute paths work for Python 3.7 and newer.
164164

165165

166+
Migrating from Legacy
167+
=====================
168+
169+
Starting with Python 3.9 and ``importlib_resources`` 1.4, this package
170+
introduced the ``files()`` API, to be preferred over the legacy API,
171+
i.e. the functions ``open_binary``, ``open_text``, ``path``,
172+
``contents``, ``read_text``, ``read_binary``, and ``is_resource``.
173+
174+
To port to the ``files()`` API, refer to the
175+
`_legacy module <https://github.com/python/importlib_resources/blob/66ea2dc7eb12b1be2322b7ad002cefb12d364dff/importlib_resources/_legacy.py>`_
176+
to see simple wrappers that enable drop-in replacement based on the
177+
preferred API, and either copy those or adapt the usage to utilize the
178+
``files`` and
179+
`Traversable <https://github.com/python/importlib_resources/blob/b665a3ea907d93b1b6457217f34e1bfc06f51fe6/importlib_resources/abc.py#L49-L114>`_
180+
interfaces directly.
181+
182+
166183
Extending
167184
=========
168185

importlib_resources/_legacy.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import functools
12
import os
23
import pathlib
34
import types
5+
import warnings
46

57
from typing import Union, Iterable, ContextManager, BinaryIO, TextIO
68

@@ -10,16 +12,34 @@
1012
Resource = Union[str, os.PathLike]
1113

1214

15+
def deprecated(func):
16+
@functools.wraps(func)
17+
def wrapper(*args, **kwargs):
18+
warnings.warn(
19+
f"{func.__name__} is deprecated. Use files() instead. "
20+
"Refer to https://importlib-resources.readthedocs.io"
21+
"/en/latest/using.html#migrating-from-legacy for migration advice.",
22+
DeprecationWarning,
23+
stacklevel=2,
24+
)
25+
return func(*args, **kwargs)
26+
27+
return wrapper
28+
29+
30+
@deprecated
1331
def open_binary(package: Package, resource: Resource) -> BinaryIO:
1432
"""Return a file-like object opened for binary reading of the resource."""
1533
return (_common.files(package) / _common.normalize_path(resource)).open('rb')
1634

1735

36+
@deprecated
1837
def read_binary(package: Package, resource: Resource) -> bytes:
1938
"""Return the binary contents of the resource."""
2039
return (_common.files(package) / _common.normalize_path(resource)).read_bytes()
2140

2241

42+
@deprecated
2343
def open_text(
2444
package: Package,
2545
resource: Resource,
@@ -32,6 +52,7 @@ def open_text(
3252
)
3353

3454

55+
@deprecated
3556
def read_text(
3657
package: Package,
3758
resource: Resource,
@@ -47,6 +68,7 @@ def read_text(
4768
return fp.read()
4869

4970

71+
@deprecated
5072
def contents(package: Package) -> Iterable[str]:
5173
"""Return an iterable of entries in `package`.
5274
@@ -57,6 +79,7 @@ def contents(package: Package) -> Iterable[str]:
5779
return [path.name for path in _common.files(package).iterdir()]
5880

5981

82+
@deprecated
6083
def is_resource(package: Package, name: str) -> bool:
6184
"""True if `name` is a resource inside `package`.
6285
@@ -69,6 +92,7 @@ def is_resource(package: Package, name: str) -> bool:
6992
)
7093

7194

95+
@deprecated
7296
def path(
7397
package: Package,
7498
resource: Resource,

importlib_resources/tests/test_contents.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class ContentsTests:
1515
}
1616

1717
def test_contents(self):
18-
assert self.expected <= set(resources.contents(self.data))
18+
with util.suppress_known_deprecation():
19+
assert self.expected <= set(resources.contents(self.data))
1920

2021

2122
class ContentsDiskTests(ContentsTests, unittest.TestCase):

importlib_resources/tests/test_open.py

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,47 @@
77

88
class CommonBinaryTests(util.CommonTests, unittest.TestCase):
99
def execute(self, package, path):
10-
with resources.open_binary(package, path):
11-
pass
10+
with util.suppress_known_deprecation():
11+
with resources.open_binary(package, path):
12+
pass
1213

1314

1415
class CommonTextTests(util.CommonTests, unittest.TestCase):
1516
def execute(self, package, path):
16-
with resources.open_text(package, path):
17-
pass
17+
with util.suppress_known_deprecation():
18+
with resources.open_text(package, path):
19+
pass
1820

1921

2022
class OpenTests:
2123
def test_open_binary(self):
22-
with resources.open_binary(self.data, 'utf-8.file') as fp:
23-
result = fp.read()
24+
with util.suppress_known_deprecation():
25+
with resources.open_binary(self.data, 'utf-8.file') as fp:
26+
result = fp.read()
2427
self.assertEqual(result, b'Hello, UTF-8 world!\n')
2528

2629
def test_open_text_default_encoding(self):
27-
with resources.open_text(self.data, 'utf-8.file') as fp:
28-
result = fp.read()
30+
with util.suppress_known_deprecation():
31+
with resources.open_text(self.data, 'utf-8.file') as fp:
32+
result = fp.read()
2933
self.assertEqual(result, 'Hello, UTF-8 world!\n')
3034

3135
def test_open_text_given_encoding(self):
32-
with resources.open_text(self.data, 'utf-16.file', 'utf-16', 'strict') as fp:
33-
result = fp.read()
36+
with util.suppress_known_deprecation():
37+
with resources.open_text(
38+
self.data, 'utf-16.file', 'utf-16', 'strict'
39+
) as fp:
40+
result = fp.read()
3441
self.assertEqual(result, 'Hello, UTF-16 world!\n')
3542

3643
def test_open_text_with_errors(self):
3744
# Raises UnicodeError without the 'errors' argument.
38-
with resources.open_text(self.data, 'utf-16.file', 'utf-8', 'strict') as fp:
39-
self.assertRaises(UnicodeError, fp.read)
40-
with resources.open_text(self.data, 'utf-16.file', 'utf-8', 'ignore') as fp:
41-
result = fp.read()
45+
with util.suppress_known_deprecation():
46+
with resources.open_text(self.data, 'utf-16.file', 'utf-8', 'strict') as fp:
47+
self.assertRaises(UnicodeError, fp.read)
48+
with util.suppress_known_deprecation():
49+
with resources.open_text(self.data, 'utf-16.file', 'utf-8', 'ignore') as fp:
50+
result = fp.read()
4251
self.assertEqual(
4352
result,
4453
'H\x00e\x00l\x00l\x00o\x00,\x00 '
@@ -47,14 +56,16 @@ def test_open_text_with_errors(self):
4756
)
4857

4958
def test_open_binary_FileNotFoundError(self):
50-
self.assertRaises(
51-
FileNotFoundError, resources.open_binary, self.data, 'does-not-exist'
52-
)
59+
with util.suppress_known_deprecation():
60+
self.assertRaises(
61+
FileNotFoundError, resources.open_binary, self.data, 'does-not-exist'
62+
)
5363

5464
def test_open_text_FileNotFoundError(self):
55-
self.assertRaises(
56-
FileNotFoundError, resources.open_text, self.data, 'does-not-exist'
57-
)
65+
with util.suppress_known_deprecation():
66+
self.assertRaises(
67+
FileNotFoundError, resources.open_text, self.data, 'does-not-exist'
68+
)
5869

5970

6071
class OpenDiskTests(OpenTests, unittest.TestCase):

importlib_resources/tests/test_path.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,23 @@
88

99
class CommonTests(util.CommonTests, unittest.TestCase):
1010
def execute(self, package, path):
11-
with resources.path(package, path):
12-
pass
11+
with util.suppress_known_deprecation():
12+
with resources.path(package, path):
13+
pass
1314

1415

1516
class PathTests:
1617
def test_reading(self):
1718
# Path should be readable.
1819
# Test also implicitly verifies the returned object is a pathlib.Path
1920
# instance.
20-
with resources.path(self.data, 'utf-8.file') as path:
21-
self.assertTrue(path.name.endswith("utf-8.file"), repr(path))
22-
# pathlib.Path.read_text() was introduced in Python 3.5.
23-
with path.open('r', encoding='utf-8') as file:
24-
text = file.read()
25-
self.assertEqual('Hello, UTF-8 world!\n', text)
21+
with util.suppress_known_deprecation():
22+
with resources.path(self.data, 'utf-8.file') as path:
23+
self.assertTrue(path.name.endswith("utf-8.file"), repr(path))
24+
# pathlib.Path.read_text() was introduced in Python 3.5.
25+
with path.open('r', encoding='utf-8') as file:
26+
text = file.read()
27+
self.assertEqual('Hello, UTF-8 world!\n', text)
2628

2729

2830
class PathDiskTests(PathTests, unittest.TestCase):
@@ -34,8 +36,9 @@ def test_natural_path(self):
3436
file-system-backed resources do not get the tempdir
3537
treatment.
3638
"""
37-
with resources.path(self.data, 'utf-8.file') as path:
38-
assert 'data' in str(path)
39+
with util.suppress_known_deprecation():
40+
with resources.path(self.data, 'utf-8.file') as path:
41+
assert 'data' in str(path)
3942

4043

4144
class PathMemoryTests(PathTests, unittest.TestCase):
@@ -53,8 +56,9 @@ class PathZipTests(PathTests, util.ZipSetup, unittest.TestCase):
5356
def test_remove_in_context_manager(self):
5457
# It is not an error if the file that was temporarily stashed on the
5558
# file system is removed inside the `with` stanza.
56-
with resources.path(self.data, 'utf-8.file') as path:
57-
path.unlink()
59+
with util.suppress_known_deprecation():
60+
with resources.path(self.data, 'utf-8.file') as path:
61+
path.unlink()
5862

5963

6064
if __name__ == '__main__':

importlib_resources/tests/test_read.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,40 @@
88

99
class CommonBinaryTests(util.CommonTests, unittest.TestCase):
1010
def execute(self, package, path):
11-
resources.read_binary(package, path)
11+
with util.suppress_known_deprecation():
12+
resources.read_binary(package, path)
1213

1314

1415
class CommonTextTests(util.CommonTests, unittest.TestCase):
1516
def execute(self, package, path):
16-
resources.read_text(package, path)
17+
with util.suppress_known_deprecation():
18+
resources.read_text(package, path)
1719

1820

1921
class ReadTests:
2022
def test_read_binary(self):
21-
result = resources.read_binary(self.data, 'binary.file')
23+
with util.suppress_known_deprecation():
24+
result = resources.read_binary(self.data, 'binary.file')
2225
self.assertEqual(result, b'\0\1\2\3')
2326

2427
def test_read_text_default_encoding(self):
25-
result = resources.read_text(self.data, 'utf-8.file')
28+
with util.suppress_known_deprecation():
29+
result = resources.read_text(self.data, 'utf-8.file')
2630
self.assertEqual(result, 'Hello, UTF-8 world!\n')
2731

2832
def test_read_text_given_encoding(self):
29-
result = resources.read_text(self.data, 'utf-16.file', encoding='utf-16')
33+
with util.suppress_known_deprecation():
34+
result = resources.read_text(self.data, 'utf-16.file', encoding='utf-16')
3035
self.assertEqual(result, 'Hello, UTF-16 world!\n')
3136

3237
def test_read_text_with_errors(self):
3338
# Raises UnicodeError without the 'errors' argument.
34-
self.assertRaises(UnicodeError, resources.read_text, self.data, 'utf-16.file')
35-
result = resources.read_text(self.data, 'utf-16.file', errors='ignore')
39+
with util.suppress_known_deprecation():
40+
self.assertRaises(
41+
UnicodeError, resources.read_text, self.data, 'utf-16.file'
42+
)
43+
with util.suppress_known_deprecation():
44+
result = resources.read_text(self.data, 'utf-16.file', errors='ignore')
3645
self.assertEqual(
3746
result,
3847
'H\x00e\x00l\x00l\x00o\x00,\x00 '
@@ -48,11 +57,13 @@ class ReadDiskTests(ReadTests, unittest.TestCase):
4857
class ReadZipTests(ReadTests, util.ZipSetup, unittest.TestCase):
4958
def test_read_submodule_resource(self):
5059
submodule = import_module('ziptestdata.subdirectory')
51-
result = resources.read_binary(submodule, 'binary.file')
60+
with util.suppress_known_deprecation():
61+
result = resources.read_binary(submodule, 'binary.file')
5262
self.assertEqual(result, b'\0\1\2\3')
5363

5464
def test_read_submodule_resource_by_name(self):
55-
result = resources.read_binary('ziptestdata.subdirectory', 'binary.file')
65+
with util.suppress_known_deprecation():
66+
result = resources.read_binary('ziptestdata.subdirectory', 'binary.file')
5667
self.assertEqual(result, b'\0\1\2\3')
5768

5869

0 commit comments

Comments
 (0)