Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-unearth for openSUSE:Factory checked in at 2024-09-27 17:11:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-unearth (Old) and /work/SRC/openSUSE:Factory/.python-unearth.new.29891 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-unearth" Fri Sep 27 17:11:11 2024 rev:9 rq:1204011 version:0.17.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-unearth/python-unearth.changes 2024-07-05 19:52:57.046196009 +0200 +++ /work/SRC/openSUSE:Factory/.python-unearth.new.29891/python-unearth.changes 2024-09-27 17:11:51.303560863 +0200 @@ -1,0 +2,11 @@ +Fri Sep 27 05:05:46 UTC 2024 - Steve Kowalik <steven.kowa...@suse.com> + +- Update to 0.17.2: + * Really drop python<=3.7 support + * Don't show warning message when no netrc exists + * Show warning message when failing to parse netrc file + * Report download status when checking out vcs repo + * Allow using local file:// locations with find_links and index_urls + * New method check_wheel_tags for override + +------------------------------------------------------------------- Old: ---- unearth-0.15.5.tar.gz New: ---- unearth-0.17.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-unearth.spec ++++++ --- /var/tmp/diff_new_pack.9bzpOB/_old 2024-09-27 17:11:53.127637023 +0200 +++ /var/tmp/diff_new_pack.9bzpOB/_new 2024-09-27 17:11:53.131637191 +0200 @@ -18,29 +18,23 @@ %{?sle15_python_module_pythons} Name: python-unearth -Version: 0.15.5 +Version: 0.17.2 Release: 0 Summary: A utility to fetch and download python packages License: MIT URL: https://unearth.readthedocs.io/ Source: https://files.pythonhosted.org/packages/source/u/unearth/unearth-%{version}.tar.gz -BuildRequires: %{python_module base >= 3.7} -BuildRequires: %{python_module cached-property >= 1.5.2 if %python-base < 3.8} +BuildRequires: %{python_module base >= 3.8} BuildRequires: %{python_module packaging >= 20} BuildRequires: %{python_module pdm-backend} BuildRequires: %{python_module pip} -BuildRequires: %{python_module requests >= 2.25} BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-httpx Requires: python-packaging >= 20 -Requires: python-requests >= 2.25 Requires(post): update-alternatives Requires(postun): update-alternatives BuildArch: noarch -%if 0%{?python_version_nodots} < 38 -Requires: python-cached-property >= 1.5.2 -%endif # SECTION test BuildRequires: %{python_module Flask >= 2.1.2} BuildRequires: %{python_module httpx} @@ -87,5 +81,5 @@ %license LICENSE %python_alternative %{_bindir}/unearth %{python_sitelib}/unearth -%{python_sitelib}/unearth-%{version}*-info +%{python_sitelib}/unearth-%{version}.dist-info ++++++ unearth-0.15.5.tar.gz -> unearth-0.17.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/PKG-INFO new/unearth-0.17.2/PKG-INFO --- old/unearth-0.15.5/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 +++ new/unearth-0.17.2/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: unearth -Version: 0.15.5 +Version: 0.17.2 Summary: A utility to fetch and download python packages Author-Email: Frost Ming <m...@frostming.com> License: MIT @@ -32,7 +32,7 @@ [](https://github.com/frostming/unearth/actions?query=workflow%3Aci) [](https://pypi.org/project/unearth/) [](https://github.com/psf/black) -[](https://pdm.fming.dev) +[](https://pdm-project.org) A utility to fetch and download python packages diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/README.md new/unearth-0.17.2/README.md --- old/unearth-0.15.5/README.md 2024-06-25 04:35:28.059207400 +0200 +++ new/unearth-0.17.2/README.md 2024-09-02 06:27:25.260641800 +0200 @@ -5,7 +5,7 @@ [](https://github.com/frostming/unearth/actions?query=workflow%3Aci) [](https://pypi.org/project/unearth/) [](https://github.com/psf/black) -[](https://pdm.fming.dev) +[](https://pdm-project.org) A utility to fetch and download python packages diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/pyproject.toml new/unearth-0.17.2/pyproject.toml --- old/unearth-0.15.5/pyproject.toml 2024-06-25 04:35:41.159253800 +0200 +++ new/unearth-0.17.2/pyproject.toml 2024-09-02 06:27:33.176705100 +0200 @@ -28,7 +28,7 @@ "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3 :: Only", ] -version = "0.15.5" +version = "0.17.2" [project.license] text = "MIT" @@ -99,10 +99,10 @@ "tests/fixtures", ] -[tool.ruff.mccabe] +[tool.ruff.lint.mccabe] max-complexity = 10 -[tool.ruff.isort] +[tool.ruff.lint.isort] known-first-party = [ "unearth", ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/src/unearth/auth.py new/unearth-0.17.2/src/unearth/auth.py --- old/unearth-0.15.5/src/unearth/auth.py 2024-06-25 04:35:28.059207400 +0200 +++ new/unearth-0.17.2/src/unearth/auth.py 2024-09-02 06:27:25.260641800 +0200 @@ -50,6 +50,11 @@ """Set the password for the given url and username.""" ... + @abc.abstractmethod + def delete_auth_info(self, url: str, username: str) -> None: + """Delete the password for the given url and username.""" + ... + class KeyringModuleProvider(KeyringBaseProvider): """Keyring provider that uses the keyring module.""" @@ -77,6 +82,9 @@ def save_auth_info(self, url: str, username: str, password: str) -> None: self.keyring.set_password(url, username, password) + def delete_auth_info(self, url: str, username: str) -> None: + self.keyring.delete_password(url, username) + class KeyringCliProvider(KeyringBaseProvider): def __init__(self, cmd: str) -> None: @@ -100,6 +108,11 @@ def save_auth_info(self, url: str, username: str, password: str) -> None: return self._set_password(url, username, password) + def delete_auth_info(self, url: str, username: str) -> None: + cmd = [self.keyring, "del", url, username] + env = dict(os.environ, PYTHONIOENCODING="utf-8") + subprocess.run(cmd, env=env, check=True) + def _get_secret( self, service_name: str, @@ -125,7 +138,6 @@ input_ = (password + os.linesep).encode("utf-8") env = dict(os.environ, PYTHONIOENCODING="utf-8") subprocess.run(cmd, input=input_, env=env, check=True) - return None def get_keyring_provider() -> KeyringBaseProvider | None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/src/unearth/collector.py new/unearth-0.17.2/src/unearth/collector.py --- old/unearth-0.15.5/src/unearth/collector.py 2024-06-25 04:35:28.059207400 +0200 +++ new/unearth-0.17.2/src/unearth/collector.py 2024-09-02 06:27:25.260641800 +0200 @@ -176,9 +176,14 @@ index_html = Link(path_to_url(path.joinpath("index.html").as_posix())) yield from _collect_links_from_index(session, index_html, headers) else: - yield from _collect_links_from_index(session, location, headers) + if _is_html_file(str(path)): + yield from _collect_links_from_index(session, location, headers) + else: + yield location - else: + else: # remote url, can be either a remote file or an index URL containing files + if is_secure_origin(session, location) and not location.is_vcs: + yield location yield from _collect_links_from_index(session, location) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/src/unearth/evaluator.py new/unearth-0.17.2/src/unearth/evaluator.py --- old/unearth-0.15.5/src/unearth/evaluator.py 2024-06-25 04:35:28.059207400 +0200 +++ new/unearth-0.17.2/src/unearth/evaluator.py 2024-09-02 06:27:25.260641800 +0200 @@ -8,7 +8,7 @@ import os import sys from datetime import datetime -from typing import Any, Iterable +from typing import Any import packaging.requirements from packaging.specifiers import InvalidSpecifier, SpecifierSet @@ -190,15 +190,27 @@ ), ) - def validate_wheel_tag(self, tags: Iterable[Tag]) -> bool: - """Check if the wheel tags are compatible with the target Python. + def validate_wheel_tag(self, tags: frozenset[Tag]) -> bool: + """(DEPRECATED) Check if the wheel tags are compatible with the target Python. Args: tags (Iterable[Tag]): The wheel tags to check. """ if self.ignore_compatibility: return True - return not set(tags).isdisjoint(self.target_python.supported_tags()) + return not tags.isdisjoint(self.target_python.supported_tags()) + + def check_wheel_tags(self, filename: str): + """Check if the wheel tags are compatible with the target Python. + + Args: + filename: The filename of the wheel + """ + if self.ignore_compatibility: + return + tags = parse_wheel_filename(filename)[-1] + if not self.validate_wheel_tag(tags): + raise LinkMismatchError(f"The wheel tags in {filename} are not compatible") def evaluate_link(self, link: Link) -> Package | None: """ @@ -219,12 +231,7 @@ raise LinkMismatchError( f"The package name doesn't match {wheel_info[0]}" ) - if not self.validate_wheel_tag(wheel_info[3]): - raise LinkMismatchError( - "none of the wheel tags({}) are compatible".format( - ", ".join(sorted(str(tag) for tag in wheel_info[3])) - ), - ) + self.check_wheel_tags(link.filename) version = str(wheel_info[1]) else: if link._fragment_dict.get("egg"): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/src/unearth/fetchers/legacy.py new/unearth-0.17.2/src/unearth/fetchers/legacy.py --- old/unearth-0.15.5/src/unearth/fetchers/legacy.py 2024-06-25 04:35:28.059207400 +0200 +++ new/unearth-0.17.2/src/unearth/fetchers/legacy.py 2024-09-02 06:27:25.260641800 +0200 @@ -57,7 +57,7 @@ # to return a better error message: resp.status_code = 404 resp.reason = type(exc).__name__ - resp.raw = io.BytesIO(f"{resp.reason}: {exc}".encode("utf8")) + resp.raw = io.BytesIO(f"{resp.reason}: {exc}".encode()) else: modified = email.utils.formatdate(stats.st_mtime, usegmt=True) content_type = mimetypes.guess_type(path)[0] or "text/plain" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/src/unearth/finder.py new/unearth-0.17.2/src/unearth/finder.py --- old/unearth-0.15.5/src/unearth/finder.py 2024-06-25 04:35:28.059207400 +0200 +++ new/unearth-0.17.2/src/unearth/finder.py 2024-09-02 06:27:25.260641800 +0200 @@ -7,11 +7,11 @@ import itertools import os import pathlib +import posixpath import warnings from datetime import datetime from tempfile import TemporaryDirectory from typing import TYPE_CHECKING, Any, Iterable, NamedTuple, Sequence -from urllib.parse import urljoin import packaging.requirements from packaging.utils import BuildTag, canonicalize_name, parse_wheel_filename @@ -190,9 +190,8 @@ ) def _build_index_page_link(self, index_url: str, package_name: str) -> Link: - return Link( - urljoin(index_url.rstrip("/") + "/", canonicalize_name(package_name) + "/") - ) + url = posixpath.join(index_url, canonicalize_name(package_name)) + "/" + return self._build_find_link(url) def _build_find_link(self, find_link: str) -> Link: if os.path.exists(find_link): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/src/unearth/preparer.py new/unearth-0.17.2/src/unearth/preparer.py --- old/unearth-0.15.5/src/unearth/preparer.py 2024-06-25 04:35:28.059207400 +0200 +++ new/unearth-0.17.2/src/unearth/preparer.py 2024-09-02 06:27:25.260641800 +0200 @@ -318,7 +318,9 @@ location.parent.mkdir(parents=True, exist_ok=True) if link.is_vcs: backend = vcs_support.get_backend(cast(str, link.vcs), verbosity=verbosity) + download_reporter(link, 0, 1) backend.fetch(link, location) + download_reporter(link, 1, 1) return location validator = HashValidator(link, hashes) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/src/unearth/utils.py new/unearth-0.17.2/src/unearth/utils.py --- old/unearth-0.15.5/src/unearth/utils.py 2024-06-25 04:35:28.059207400 +0200 +++ new/unearth-0.17.2/src/unearth/utils.py 2024-09-02 06:27:25.260641800 +0200 @@ -4,6 +4,7 @@ import functools import itertools +import logging import os import re import sys @@ -14,6 +15,7 @@ from urllib.request import pathname2url, url2pathname WINDOWS = sys.platform == "win32" +logger = logging.getLogger(__name__) def parse_query(query: str) -> dict[str, str]: @@ -29,7 +31,7 @@ parsed = parse.urlparse(uri) if ":" in parsed.netloc: netloc, _, path_start = parsed.netloc.rpartition(":") - path = "/{0}{1}".format(path_start, parsed.path) + path = f"/{path_start}{parsed.path}" uri = parse.urlunparse(parsed._replace(netloc=netloc, path=path)) return uri @@ -225,7 +227,7 @@ _legacy_specifier_re = re.compile(r"(==|!=|<=|>=|<|>)(\s*)([^,;\s)]*)") -@functools.lru_cache() +@functools.lru_cache def fix_legacy_specifier(specifier: str) -> str: """Since packaging 22.0, legacy specifiers like '>=4.*' are no longer supported. We try to normalize them to the new format. @@ -285,8 +287,12 @@ return s1 +_netrc_warned = False + + def get_netrc_auth(url: str) -> tuple[str, str] | None: """Get the auth for the given url from the netrc file.""" + global _netrc_warned try: from netrc import NetrcParseError, netrc except ImportError: @@ -297,7 +303,14 @@ try: authenticator = netrc(os.getenv("NETRC")) - except (NetrcParseError, OSError): + except FileNotFoundError: + return None + except (NetrcParseError, OSError) as e: + if not _netrc_warned: + logger.warning( + "Couldn't parse netrc because of %s: %s", type(e).__name__, e + ) + _netrc_warned = True return None info = authenticator.authenticators(hostname) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/src/unearth/vcs/base.py new/unearth-0.17.2/src/unearth/vcs/base.py --- old/unearth-0.15.5/src/unearth/vcs/base.py 2024-06-25 04:35:28.059207400 +0200 +++ new/unearth-0.17.2/src/unearth/vcs/base.py 2024-09-02 06:27:25.260641800 +0200 @@ -235,7 +235,7 @@ class VcsSupport: def __init__(self) -> None: - self._registry: dict[str, Type[VersionControl]] = {} + self._registry: dict[str, type[VersionControl]] = {} def register(self, vcs: _V) -> _V: self._registry[vcs.name] = vcs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/tests/test_collector.py new/unearth-0.17.2/tests/test_collector.py --- old/unearth-0.15.5/tests/test_collector.py 2024-06-25 04:35:28.063207400 +0200 +++ new/unearth-0.17.2/tests/test_collector.py 2024-09-02 06:27:25.264641800 +0200 @@ -25,22 +25,15 @@ def test_collect_links_from_404_page(pypi_session): - collected = list( - collect_links_from_location( - pypi_session, Link("https://test.pypi.org/simple/not-found") - ) - ) - assert not collected + link = Link("https://test.pypi.org/simple/not-found") + collected = list(collect_links_from_location(pypi_session, link)) + assert collected == [link] def test_skip_non_html_archive(pypi_session, caplog): - collected = list( - collect_links_from_location( - pypi_session, - Link("https://test.pypi.org/files/click-8.1.3-py3-none-any.whl"), - ) - ) - assert not collected + link = Link("https://test.pypi.org/files/click-8.1.3-py3-none-any.whl") + collected = list(collect_links_from_location(pypi_session, link)) + assert collected == [link] assert "Content-Type unsupported" in caplog.records[0].message @@ -52,7 +45,7 @@ ), key=lambda link: link.filename, ) - assert len(collected) == 4 + assert len(collected) == 5 assert all(link.url.startswith("https://test.pypi.org") for link in collected) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unearth-0.15.5/tests/test_utils.py new/unearth-0.17.2/tests/test_utils.py --- old/unearth-0.15.5/tests/test_utils.py 2024-06-25 04:35:28.063207400 +0200 +++ new/unearth-0.17.2/tests/test_utils.py 2024-09-02 06:27:25.264641800 +0200 @@ -1,6 +1,7 @@ +import logging from unittest import mock -from unearth.utils import LazySequence +from unearth.utils import LazySequence, get_netrc_auth def test_lazy_sequence(): @@ -23,3 +24,29 @@ assert len(seq) == 5 assert list(seq) == [0, 1, 2, 3, 4] assert func.call_count == 5 + + +def test_get_netrc_auth_when_unparsable(caplog, monkeypatch, tmp_path): + url = "https://test.invalid/blah" + netrc_path = tmp_path / "netrc" + netrc_path.write_text("invalid netrc entry", encoding="utf8") + monkeypatch.setenv("NETRC", str(netrc_path)) + caplog.set_level(logging.WARNING) + + get_netrc_auth(url) + + msgs = [i.msg for i in caplog.records] + msg = "Couldn't parse netrc because of %s: %s" + assert msg in msgs + + +def test_get_netrc_auth_when_netrc_missing(caplog, monkeypatch, tmp_path): + url = "https://test.invalid/blah" + monkeypatch.setenv("NETRC", str(tmp_path / "bogus")) + caplog.set_level(logging.WARNING) + + get_netrc_auth(url) + + msgs = [i.msg for i in caplog.records] + msg = "Couldn't parse netrc because of %s: %s" + assert msg not in msgs