Skip to content

Commit 3fbaa4c

Browse files
committed
Add deprecation warning for non utf-8
1 parent 39a8ef4 commit 3fbaa4c

File tree

4 files changed

+65
-15
lines changed

4 files changed

+65
-15
lines changed

pkg_resources/__init__.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3323,14 +3323,33 @@ def _initialize_master_working_set():
33233323
globals().update(locals())
33243324

33253325

3326-
# ---- Ported from ``setuptools`` to avoid introducing dependencies ----
3326+
# ---- Ported from ``setuptools`` to avoid introducing an import inter-dependency ----
33273327
LOCALE_ENCODING = "locale" if sys.version_info >= (3, 10) else None
33283328

33293329

33303330
def _read_utf8_with_fallback(file: str, fallback_encoding=LOCALE_ENCODING) -> str:
3331+
"""See setuptools.unicode_utils._read_utf8_with_fallback"""
33313332
try:
33323333
with open(file, "r", encoding="utf-8") as f:
33333334
return f.read()
33343335
except UnicodeDecodeError: # pragma: no cover
3336+
msg = f"""\
3337+
********************************************************************************
3338+
`encoding="utf-8"` fails with {file!r}, trying `encoding={fallback_encoding!r}`.
3339+
3340+
This fallback behaviour is considered **deprecated** and future versions of
3341+
`setuptools/pkg_resources` may not implement it.
3342+
3343+
Please encode {file!r} with "utf-8" to ensure future builds will succeed.
3344+
3345+
If this file was produced by `setuptools` itself, cleaning up the cached files
3346+
and re-building/re-installing the package with a newer version of `setuptools`
3347+
(e.g. by updating `build-system.requires` in its `pyproject.toml`)
3348+
might solve the problem.
3349+
********************************************************************************
3350+
"""
3351+
# TODO: Add a deadline?
3352+
# See comment in setuptools.unicode_utils._Utf8EncodingNeeded
3353+
warnings.warns(msg, PkgResourcesDeprecationWarning, stacklevel=2)
33353354
with open(file, "r", encoding=fallback_encoding) as f:
33363355
return f.read()

setuptools/command/setopt.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import configparser
77

88
from .. import Command
9-
from ..compat import py39
9+
from ..unicode_utils import _cfg_read_utf8_with_fallback
1010

1111
__all__ = ['config_file', 'edit_config', 'option_base', 'setopt']
1212

@@ -37,12 +37,7 @@ def edit_config(filename, settings, dry_run=False):
3737
log.debug("Reading configuration from %s", filename)
3838
opts = configparser.RawConfigParser()
3939
opts.optionxform = lambda x: x
40-
41-
try:
42-
opts.read([filename], encoding="utf-8")
43-
except UnicodeDecodeError: # pragma: no cover
44-
opts.clear()
45-
opts.read([filename], encoding=py39.LOCALE_ENCODING)
40+
_cfg_read_utf8_with_fallback(opts, filename)
4641

4742
for section, options in settings.items():
4843
if options is None:

setuptools/package_index.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@
4040
from setuptools.wheel import Wheel
4141
from setuptools.extern.more_itertools import unique_everseen
4242

43-
from .compat import py39
44-
from .unicode_utils import _read_utf8_with_fallback
43+
from .unicode_utils import _read_utf8_with_fallback, _cfg_read_utf8_with_fallback
4544

4645

4746
EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$')
@@ -1014,11 +1013,7 @@ def __init__(self):
10141013

10151014
rc = os.path.join(os.path.expanduser('~'), '.pypirc')
10161015
if os.path.exists(rc):
1017-
try:
1018-
self.read(rc, encoding="utf-8")
1019-
except UnicodeDecodeError: # pragma: no cover
1020-
self.clean()
1021-
self.read(rc, encoding=py39.LOCALE_ENCODING)
1016+
_cfg_read_utf8_with_fallback(self, rc)
10221017

10231018
@property
10241019
def creds_by_repository(self):

setuptools/unicode_utils.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import unicodedata
22
import sys
3+
from configparser import ConfigParser
34

45
from .compat import py39
6+
from .warnings import SetuptoolsDeprecationWarning
57

68

79
# HFS Plus uses decomposed UTF-8
@@ -57,5 +59,44 @@ def _read_utf8_with_fallback(file: str, fallback_encoding=py39.LOCALE_ENCODING)
5759
with open(file, "r", encoding="utf-8") as f:
5860
return f.read()
5961
except UnicodeDecodeError: # pragma: no cover
62+
_Utf8EncodingNeeded.emit(file=file, fallback_encoding=fallback_encoding)
6063
with open(file, "r", encoding=fallback_encoding) as f:
6164
return f.read()
65+
66+
67+
def _cfg_read_utf8_with_fallback(
68+
cfg: ConfigParser, file: str, fallback_encoding=py39.LOCALE_ENCODING
69+
) -> str:
70+
"""Same idea as :func:`_read_utf8_with_fallback`, but for the
71+
:meth:`ConfigParser.read` method.
72+
73+
This method may call ``cfg.clear()``.
74+
"""
75+
try:
76+
cfg.read(file, encoding="utf-8")
77+
except UnicodeDecodeError: # pragma: no cover
78+
_Utf8EncodingNeeded.emit(file=file, fallback_encoding=fallback_encoding)
79+
cfg.clear()
80+
cfg.read(file, encoding=fallback_encoding)
81+
82+
83+
class _Utf8EncodingNeeded(SetuptoolsDeprecationWarning):
84+
_SUMMARY = """
85+
`encoding="utf-8"` fails with {file!r}, trying `encoding={fallback_encoding!r}`.
86+
"""
87+
88+
_DETAILS = """
89+
Fallback behaviour for UTF-8 is considered **deprecated** and future versions of
90+
`setuptools` may not implement it.
91+
92+
Please encode {file!r} with "utf-8" to ensure future builds will succeed.
93+
94+
If this file was produced by `setuptools` itself, cleaning up the cached files
95+
and re-building/re-installing the package with a newer version of `setuptools`
96+
(e.g. by updating `build-system.requires` in its `pyproject.toml`)
97+
might solve the problem.
98+
"""
99+
# TODO: Add a deadline?
100+
# Will we be able to remove this?
101+
# The question comes to mind mainly because of sdists that have been produced
102+
# by old versions of setuptools and published to PyPI...

0 commit comments

Comments
 (0)