Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt to avoid error with _read_utf8_with_fallback by moving code in pkg_resources #4422

Merged
merged 6 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/4422.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Reorder code in ``pkg_resources/__init__.py`` to avoid definitions after ``@_call_aside``.
64 changes: 32 additions & 32 deletions pkg_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3426,6 +3426,38 @@ class PkgResourcesDeprecationWarning(Warning):
"""


# 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.warn(msg, PkgResourcesDeprecationWarning, stacklevel=2)
with open(file, "r", encoding=fallback_encoding) as f:
return f.read()


# from jaraco.functools 1.3
def _call_aside(f, *args, **kwargs):
f(*args, **kwargs)
Expand Down Expand Up @@ -3498,35 +3530,3 @@ def _initialize_master_working_set():
add_activation_listener = working_set.subscribe
run_script = working_set.run_script
run_main = run_script


# ---- 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.warn(msg, PkgResourcesDeprecationWarning, stacklevel=2)
with open(file, "r", encoding=fallback_encoding) as f:
return f.read()
54 changes: 54 additions & 0 deletions pkg_resources/tests/test_integration_zope_interface.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import platform
from inspect import cleandoc

import jaraco.path
import pytest

pytestmark = pytest.mark.integration


# For the sake of simplicity this test uses fixtures defined in
# `setuptools.test.fixtures`,
# and it also exercise conditions considered deprecated...
# So if needed this test can be deleted.
@pytest.mark.skipif(
platform.system() != "Linux",
reason="only demonstrated to fail on Linux in #4399",
)
def test_interop_pkg_resources_iter_entry_points(tmp_path, venv):
"""
Importing pkg_resources.iter_entry_points on console_scripts
seems to cause trouble with zope-interface, when deprecates installation method
is used. See #4399.
"""
project = {
"pkg": {
"foo.py": cleandoc(
"""
from pkg_resources import iter_entry_points

def bar():
print("Print me if you can")
"""
),
"setup.py": cleandoc(
"""
from setuptools import setup, find_packages

setup(
install_requires=["zope-interface==6.4.post2"],
entry_points={
"console_scripts": [
"foo=foo:bar",
],
},
)
"""
),
}
}
jaraco.path.build(project, prefix=tmp_path)
cmd = ["pip", "install", "-e", ".", "--no-use-pep517"]
venv.run(cmd, cwd=tmp_path / "pkg") # Needs this version of pkg_resources installed
out = venv.run(["foo"])
assert "Print me if you can" in out
Loading