Skip to content

Commit

Permalink
Add deprecation warning for non utf-8
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri committed Apr 22, 2024
1 parent 39a8ef4 commit 3fbaa4c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 15 deletions.
21 changes: 20 additions & 1 deletion pkg_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3323,14 +3323,33 @@ def _initialize_master_working_set():
globals().update(locals())


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


def _read_utf8_with_fallback(file: str, fallback_encoding=LOCALE_ENCODING) -> str:
"""See setuptools.unicode_utils._read_utf8_with_fallback"""
try:
with open(file, "r", encoding="utf-8") as f:
return f.read()
except UnicodeDecodeError: # pragma: no cover
msg = f"""\
********************************************************************************
`encoding="utf-8"` fails with {file!r}, trying `encoding={fallback_encoding!r}`.
This fallback behaviour is considered **deprecated** and future versions of
`setuptools/pkg_resources` may not implement it.
Please encode {file!r} with "utf-8" to ensure future builds will succeed.
If this file was produced by `setuptools` itself, cleaning up the cached files
and re-building/re-installing the package with a newer version of `setuptools`
(e.g. by updating `build-system.requires` in its `pyproject.toml`)
might solve the problem.
********************************************************************************
"""
# TODO: Add a deadline?
# See comment in setuptools.unicode_utils._Utf8EncodingNeeded
warnings.warns(msg, PkgResourcesDeprecationWarning, stacklevel=2)
with open(file, "r", encoding=fallback_encoding) as f:
return f.read()
9 changes: 2 additions & 7 deletions setuptools/command/setopt.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import configparser

from .. import Command
from ..compat import py39
from ..unicode_utils import _cfg_read_utf8_with_fallback

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

Expand Down Expand Up @@ -37,12 +37,7 @@ def edit_config(filename, settings, dry_run=False):
log.debug("Reading configuration from %s", filename)
opts = configparser.RawConfigParser()
opts.optionxform = lambda x: x

try:
opts.read([filename], encoding="utf-8")
except UnicodeDecodeError: # pragma: no cover
opts.clear()
opts.read([filename], encoding=py39.LOCALE_ENCODING)
_cfg_read_utf8_with_fallback(opts, filename)

for section, options in settings.items():
if options is None:
Expand Down
9 changes: 2 additions & 7 deletions setuptools/package_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@
from setuptools.wheel import Wheel
from setuptools.extern.more_itertools import unique_everseen

from .compat import py39
from .unicode_utils import _read_utf8_with_fallback
from .unicode_utils import _read_utf8_with_fallback, _cfg_read_utf8_with_fallback


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

rc = os.path.join(os.path.expanduser('~'), '.pypirc')
if os.path.exists(rc):
try:
self.read(rc, encoding="utf-8")
except UnicodeDecodeError: # pragma: no cover
self.clean()
self.read(rc, encoding=py39.LOCALE_ENCODING)
_cfg_read_utf8_with_fallback(self, rc)

@property
def creds_by_repository(self):
Expand Down
41 changes: 41 additions & 0 deletions setuptools/unicode_utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import unicodedata
import sys
from configparser import ConfigParser

from .compat import py39
from .warnings import SetuptoolsDeprecationWarning


# HFS Plus uses decomposed UTF-8
Expand Down Expand Up @@ -57,5 +59,44 @@ def _read_utf8_with_fallback(file: str, fallback_encoding=py39.LOCALE_ENCODING)
with open(file, "r", encoding="utf-8") as f:
return f.read()
except UnicodeDecodeError: # pragma: no cover
_Utf8EncodingNeeded.emit(file=file, fallback_encoding=fallback_encoding)
with open(file, "r", encoding=fallback_encoding) as f:
return f.read()


def _cfg_read_utf8_with_fallback(
cfg: ConfigParser, file: str, fallback_encoding=py39.LOCALE_ENCODING
) -> str:
"""Same idea as :func:`_read_utf8_with_fallback`, but for the
:meth:`ConfigParser.read` method.
This method may call ``cfg.clear()``.
"""
try:
cfg.read(file, encoding="utf-8")
except UnicodeDecodeError: # pragma: no cover
_Utf8EncodingNeeded.emit(file=file, fallback_encoding=fallback_encoding)
cfg.clear()
cfg.read(file, encoding=fallback_encoding)


class _Utf8EncodingNeeded(SetuptoolsDeprecationWarning):
_SUMMARY = """
`encoding="utf-8"` fails with {file!r}, trying `encoding={fallback_encoding!r}`.
"""

_DETAILS = """
Fallback behaviour for UTF-8 is considered **deprecated** and future versions of
`setuptools` may not implement it.
Please encode {file!r} with "utf-8" to ensure future builds will succeed.
If this file was produced by `setuptools` itself, cleaning up the cached files
and re-building/re-installing the package with a newer version of `setuptools`
(e.g. by updating `build-system.requires` in its `pyproject.toml`)
might solve the problem.
"""
# TODO: Add a deadline?
# Will we be able to remove this?
# The question comes to mind mainly because of sdists that have been produced
# by old versions of setuptools and published to PyPI...

0 comments on commit 3fbaa4c

Please sign in to comment.