commit:     50031116133a3a8b300f0473196e7703b374f8f9
Author:     Eli Schwartz <eschwartz93 <AT> gmail <DOT> com>
AuthorDate: Tue Jun 11 14:08:25 2024 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Jun 11 14:25:47 2024 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=50031116

dev-python/setuptools-rust: backport upstream patch to unbreak complex merge

When rebuilding world with python 3.12 it's very easy to end up with a
merge order that results in building setuptools-rust's dependencies for
3.12 only, but not yet merging setuptools-rust. This then breaks all
other packages relying on setuptools, due to plugin autoloading.

Fix this by making setuptools-rust only depend on other packages when it
is actually used, but not in the APIs invoked by the plugin autoloading.
This means that the package only has to be fully merged in time for
other packages that have an explicit BDEPEND on it, which is fine as
that is already the case.

Bug: https://github.com/PyO3/setuptools-rust/pull/437
Closes: https://bugs.gentoo.org/933553
Signed-off-by: Eli Schwartz <eschwartz93 <AT> gmail.com>
Signed-off-by: Sam James <sam <AT> gentoo.org>

 ...tools-rust-1.9.0-delay-non-stdlib-imports.patch | 156 ++++++++++++++++
 .../setuptools-rust-1.9.0-r1.ebuild                | 198 +++++++++++++++++++++
 2 files changed, 354 insertions(+)

diff --git 
a/dev-python/setuptools-rust/files/setuptools-rust-1.9.0-delay-non-stdlib-imports.patch
 
b/dev-python/setuptools-rust/files/setuptools-rust-1.9.0-delay-non-stdlib-imports.patch
new file mode 100644
index 000000000000..ea36c235beea
--- /dev/null
+++ 
b/dev-python/setuptools-rust/files/setuptools-rust-1.9.0-delay-non-stdlib-imports.patch
@@ -0,0 +1,156 @@
+From 06d236045b6a69c94c68f255dc683219ec833c83 Mon Sep 17 00:00:00 2001
+From: Eli Schwartz <[email protected]>
+Date: Fri, 7 Jun 2024 00:15:26 -0400
+Subject: [PATCH 1/2] Delay imports of non-stdlib dependencies until time of
+ use
+
+This is a bit of a hack, but we do this to ensure that when setuptools
+loads entrypoint based hooks it cannot (will not?) crash.
+
+The issue is that setuptools plugins are autoloaded, whether any given
+project uses them at all or not. So if setuptools-rust is installed,
+setuptools always tries to use it, and crashes if setuptools-rust is
+broken.
+
+Of course, setuptools-rust can't be broken, because it's a wonderful
+project.
+
+BUT.
+
+As it happens, third-party vendors providing setuptools-rust can get
+into a situation where multiple packages need to be installed, including
+setuptools-rust, and also build yet other packages from source. In the
+middle of this, setuptools-rust itself could be installed but in
+"half-configured" state, i.e. its dependencies were queued for
+afterwards due to complicated dependency graph magic.
+
+In such a scenario, it should be nominally all right to have an inert
+package installed, since if nothing actually uses setuptools-rust it
+doesn't need to *work* yet. And in fact, it is all right, as long as
+setuptools can import the autoloaded plugin hooks (and do nothing with
+them).
+
+Bug: https://bugs.gentoo.org/933553
+Signed-off-by: Eli Schwartz <[email protected]>
+---
+ setuptools_rust/extension.py  | 7 ++++++-
+ setuptools_rust/rustc_info.py | 8 ++++++--
+ 2 files changed, 12 insertions(+), 3 deletions(-)
+
+diff --git a/setuptools_rust/extension.py b/setuptools_rust/extension.py
+index 2d6e5aa..9ba1cf5 100644
+--- a/setuptools_rust/extension.py
++++ b/setuptools_rust/extension.py
+@@ -1,3 +1,5 @@
++from __future__ import annotations
++
+ import json
+ import os
+ import re
+@@ -14,11 +16,13 @@ from typing import (
+     NewType,
+     Optional,
+     Sequence,
++    TYPE_CHECKING,
+     Union,
+     cast,
+ )
+ 
+-from semantic_version import SimpleSpec
++if TYPE_CHECKING:
++    from semantic_version import SimpleSpec
+ 
+ from ._utils import format_called_process_error
+ 
+@@ -185,6 +189,7 @@ class RustExtension:
+         if self.rust_version is None:
+             return None
+         try:
++            from semantic_version import SimpleSpec
+             return SimpleSpec(self.rust_version)
+         except ValueError:
+             raise SetupError(
+diff --git a/setuptools_rust/rustc_info.py b/setuptools_rust/rustc_info.py
+index 070be0c..d1d4748 100644
+--- a/setuptools_rust/rustc_info.py
++++ b/setuptools_rust/rustc_info.py
+@@ -1,15 +1,19 @@
++from __future__ import annotations
++
+ import subprocess
+ from setuptools.errors import PlatformError
+ from functools import lru_cache
+-from typing import Dict, List, NewType, Optional
++from typing import Dict, List, NewType, Optional, TYPE_CHECKING
+ 
+-from semantic_version import Version
++if TYPE_CHECKING:
++    from semantic_version import Version
+ 
+ 
+ def get_rust_version() -> Optional[Version]:  # type: 
ignore[no-any-unimported]
+     try:
+         # first line of rustc -Vv is something like
+         # rustc 1.61.0 (fe5b13d68 2022-05-18)
++        from semantic_version import Version
+         return Version(_rust_version().split(" ")[1])
+     except (subprocess.CalledProcessError, OSError):
+         return None
+-- 
+2.44.2
+
+
+From a98e8a8d31d30c5d304e9ee7b48ba739946dea6f Mon Sep 17 00:00:00 2001
+From: Eli Schwartz <[email protected]>
+Date: Fri, 7 Jun 2024 00:34:59 -0400
+Subject: [PATCH 2/2] Try extra hard to pick up an existing tomli library from
+ setuptools
+
+Since setuptools-rust already depends on setuptools, it is reasonable to
+assume that even if tomli isn't installed, setuptools is. And setuptools
+includes a vendored copy of tomli.
+
+If the copy in setuptools has been devendored, it will be available via
+"tomli". If it isn't devendored, it will be available via
+"setuptools.extern.tomli" unless setuptools changes their vendoring
+approach which has lasted many years so far. Either way, we are sure to
+have a fallback tomli without explicitly depending on one, which means
+one less dependency to install in the common case.
+
+Signed-off-by: Eli Schwartz <[email protected]>
+---
+ pyproject.toml                    | 1 -
+ setuptools_rust/setuptools_ext.py | 5 ++++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/pyproject.toml b/pyproject.toml
+index cae0536..148d85b 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -26,7 +26,6 @@ classifiers = [
+ dependencies = [
+     "setuptools>=62.4",
+     "semantic_version>=2.8.2,<3",
+-    'tomli>=1.2.1; python_version<"3.11"'
+ ]
+ 
+ [project.entry-points."distutils.commands"]
+diff --git a/setuptools_rust/setuptools_ext.py 
b/setuptools_rust/setuptools_ext.py
+index d4a0204..0ea6f58 100644
+--- a/setuptools_rust/setuptools_ext.py
++++ b/setuptools_rust/setuptools_ext.py
+@@ -26,7 +26,10 @@ except ImportError:
+ if sys.version_info[:2] >= (3, 11):
+     from tomllib import load as toml_load
+ else:
+-    from tomli import load as toml_load
++    try:
++        from tomli import load as toml_load
++    except ImportError:
++        from setuptools.extern.tomli import load as toml_load
+ 
+ 
+ logger = logging.getLogger(__name__)
+-- 
+2.44.2
+

diff --git a/dev-python/setuptools-rust/setuptools-rust-1.9.0-r1.ebuild 
b/dev-python/setuptools-rust/setuptools-rust-1.9.0-r1.ebuild
new file mode 100644
index 000000000000..82babde79723
--- /dev/null
+++ b/dev-python/setuptools-rust/setuptools-rust-1.9.0-r1.ebuild
@@ -0,0 +1,198 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+CARGO_OPTIONAL=yes
+DISTUTILS_USE_PEP517=setuptools
+PYTHON_COMPAT=( python3_{10..13} pypy3 )
+
+CRATES="
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]+wasi-snapshot-preview1
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+       [email protected]
+"
+
+inherit distutils-r1 cargo
+
+DESCRIPTION="A plugin for setuptools to build Rust Python extensions"
+HOMEPAGE="
+       https://github.com/PyO3/setuptools-rust/
+       https://pypi.org/project/setuptools-rust/
+"
+SRC_URI="
+       https://github.com/PyO3/setuptools-rust/archive/v${PV}.tar.gz
+               -> ${P}.gh.tar.gz
+       test? ( ${CARGO_CRATE_URIS} )
+"
+
+# crates are used at test time only, update via pycargoebuild -L -i ...
+LICENSE="MIT"
+SLOT="0"
+KEYWORDS="~amd64 ~arm ~arm64 ~loong ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86"
+IUSE="test"
+RESTRICT="!test? ( test )"
+
+RDEPEND="
+       virtual/rust
+       <dev-python/semantic-version-3[${PYTHON_USEDEP}]
+       >=dev-python/semantic-version-2.8.2[${PYTHON_USEDEP}]
+       >=dev-python/setuptools-62.4[${PYTHON_USEDEP}]
+"
+BDEPEND="
+       >=dev-python/setuptools-62.4[${PYTHON_USEDEP}]
+       test? (
+               ${RDEPEND}
+               dev-python/beautifulsoup4[${PYTHON_USEDEP}]
+               $(python_gen_cond_dep '
+                       dev-python/cffi[${PYTHON_USEDEP}]
+               ' 'python*')
+               dev-python/lxml[${PYTHON_USEDEP}]
+               dev-python/pytest[${PYTHON_USEDEP}]
+       )
+"
+
+PATCHES=(
+       "${FILESDIR}"/${P}-delay-non-stdlib-imports.patch
+)
+
+src_unpack() {
+       cargo_src_unpack
+}
+
+python_test() {
+       local -x UNSAFE_PYO3_SKIP_VERSION_CHECK=1
+
+       local examples=(
+               html-py-ever
+               namespace_package
+               rust_with_cffi
+       )
+       for example_dir in ${examples[@]}; do
+               pushd examples/${example_dir} >/dev/null || die
+               einfo "Running ${example_dir} test"
+               esetup.py build --build-lib=build/lib
+
+               case ${example_dir} in
+                       html-py-ever)
+                               pushd tests >/dev/null || die
+                               local -x PYTHONPATH=../build/lib
+                               ${EPYTHON} run_all.py || die "Tests failed with 
${EPYTHON}"
+                               popd >/dev/null || die
+                               ;;
+                       *)
+                               pushd build/lib >/dev/null || die
+                               epytest ../../tests
+                               popd >/dev/null || die
+                               ;;
+               esac
+
+               rm -rf build || die
+               popd >/dev/null || die
+       done
+}

Reply via email to