public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/usd] f45: Backport upstream patch for Python 3.15
@ 2026-09-19 22:03 Benjamin A. Beasley
0 siblings, 0 replies; only message in thread
From: Benjamin A. Beasley @ 2026-09-19 22:03 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/usd
Branch : f45
Commit : 3dd9abd675ec3cc0f8e15fb6f66f93868aa26568
Author : Benjamin A. Beasley <code@musicinmybrain.net>
Date : 2026-09-19T08:01:23+01:00
Stats : +402/-117 in 3 file(s)
URL : https://src.fedoraproject.org/rpms/usd/c/3dd9abd675ec3cc0f8e15fb6f66f93868aa26568?branch=f45
Log:
Backport upstream patch for Python 3.15
---
diff --git a/0001-Replace-PyWeakref_GetObject-with-PyWeakref_GetRef.patch b/0001-Replace-PyWeakref_GetObject-with-PyWeakref_GetRef.patch
deleted file mode 100644
index 97dbab3..0000000
--- a/0001-Replace-PyWeakref_GetObject-with-PyWeakref_GetRef.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From f3e9600db6086e834c0503cdaf30b5ba7ed53ceb Mon Sep 17 00:00:00 2001
-From: Anonymous Coward <nobody@redhat.com>
-Date: Sun, 26 Jul 2026 16:13:18 +0200
-Subject: [PATCH] Replace PyWeakref_GetObject with PyWeakref_GetRef
-
-PyWeakref_GetObject was removed in Python 3.15. Replace all four call
-sites with PyWeakref_GetRef, which returns a strong reference instead
-of a borrowed one, and adjust reference counting accordingly.
-
-In Tf_PyIdHandle::Ptr(), return Py_None when the referent is dead to
-match the original behaviour (previously returned NULL erroneously).
-
-In Tf_PyWeakObject::GetObject(), explicitly return a Python None object
-on failure, matching the original semantics exactly.
-
-Fixes: https://github.com/PixarAnimationStudios/OpenUSD/issues/3966
-
-Assisted-by: Claude Opus 4.6
-Reviewed-by: OpenUSD Maintainers <usd-maintainers@fedoraproject.org>
----
- pxr/base/tf/pyFunction.h | 13 +++++++++----
- pxr/base/tf/pyIdentity.cpp | 10 +++++++++-
- pxr/base/tf/pyWeakObject.cpp | 12 +++++++++---
- 3 files changed, 27 insertions(+), 8 deletions(-)
-
-diff --git a/pxr/base/tf/pyFunction.h b/pxr/base/tf/pyFunction.h
-index 85af943b2..f77b5b71b 100644
---- a/pxr/base/tf/pyFunction.h
-+++ b/pxr/base/tf/pyFunction.h
-@@ -49,11 +49,13 @@ struct TfPyFunctionFromPython<Ret (Args...)>
- using namespace pxr_boost::python;
- // Attempt to get the referenced callable object.
- TfPyLock lock;
-- object callable(handle<>(borrowed(PyWeakref_GetObject(weak.ptr()))));
-- if (TfPyIsNone(callable)) {
-+ PyObject *rawCallable = NULL;
-+ if (PyWeakref_GetRef(weak.ptr(), &rawCallable) <= 0) {
- TF_WARN("Tried to call an expired python callback");
- return Ret();
- }
-+ // PyWeakref_GetRef returns a strong reference; handle<> steals it.
-+ object callable{handle<>(rawCallable)};
- return TfPyCall<Ret>(callable)(args...);
- }
- };
-@@ -68,12 +70,15 @@ struct TfPyFunctionFromPython<Ret (Args...)>
- // Attempt to get the referenced self parameter, then build a new
- // instance method and call it.
- TfPyLock lock;
-- PyObject *self = PyWeakref_GetObject(weakSelf.ptr());
-- if (self == Py_None) {
-+ PyObject *self = NULL;
-+ if (PyWeakref_GetRef(weakSelf.ptr(), &self) <= 0) {
- TF_WARN("Tried to call a method on an expired python instance");
- return Ret();
- }
-+ // PyWeakref_GetRef returns a strong reference to self; PyMethod_New
-+ // takes its own reference, so release ours afterward.
- object method(handle<>(PyMethod_New(func.ptr(), self)));
-+ Py_DECREF(self);
- return TfPyCall<Ret>(method)(args...);
- }
- };
-diff --git a/pxr/base/tf/pyIdentity.cpp b/pxr/base/tf/pyIdentity.cpp
-index 5389d8f25..06b7f9b0c 100644
---- a/pxr/base/tf/pyIdentity.cpp
-+++ b/pxr/base/tf/pyIdentity.cpp
-@@ -136,7 +136,15 @@ PyObject *
- Tf_PyIdHandle::Ptr() const {
- if (_weakRef) {
- TfPyLock lock;
-- return PyWeakref_GetObject(_weakRef);
-+ PyObject *obj = NULL;
-+ if (PyWeakref_GetRef(_weakRef, &obj) > 0) {
-+ // Return a borrowed-style reference: decrement so the caller
-+ // does not need to release. Safe because the GIL is held by
-+ // all callers.
-+ Py_DECREF(obj);
-+ return obj;
-+ }
-+ return Py_None; // dead referent → match original behaviour
- }
- return 0;
- }
-diff --git a/pxr/base/tf/pyWeakObject.cpp b/pxr/base/tf/pyWeakObject.cpp
-index 8cfddc729..ecdd7f705 100644
---- a/pxr/base/tf/pyWeakObject.cpp
-+++ b/pxr/base/tf/pyWeakObject.cpp
-@@ -115,9 +115,15 @@ Tf_PyWeakObject::GetOrCreate(pxr_boost::python::object const &obj)
- pxr_boost::python::object
- Tf_PyWeakObject::GetObject() const
- {
-- return pxr_boost::python::object
-- (pxr_boost::python::handle<>
-- (pxr_boost::python::borrowed(PyWeakref_GetObject(_weakRef.get()))));
-+ PyObject *obj = NULL;
-+ if (PyWeakref_GetRef(_weakRef.get(), &obj) > 0) {
-+ // PyWeakref_GetRef returns a strong reference; handle<> steals it.
-+ return pxr_boost::python::object(
-+ pxr_boost::python::handle<>(obj));
-+ }
-+ // Dead referent: return Py_None explicitly, as the original did.
-+ return pxr_boost::python::object(
-+ pxr_boost::python::handle<>(pxr_boost::python::borrowed(Py_None)));
- }
-
- void
---
-2.55.0
-
diff --git a/cd3b9c9f031fdface3423ff7a89995dadf4b73aa.patch b/cd3b9c9f031fdface3423ff7a89995dadf4b73aa.patch
new file mode 100644
index 0000000..aade728
--- /dev/null
+++ b/cd3b9c9f031fdface3423ff7a89995dadf4b73aa.patch
@@ -0,0 +1,387 @@
+From cd3b9c9f031fdface3423ff7a89995dadf4b73aa Mon Sep 17 00:00:00 2001
+From: gitamohr <gitamohr@users.noreply.github.com>
+Date: Thu, 17 Sep 2026 15:04:37 -0700
+Subject: [PATCH] tf: Python 3.13 simultaneously deprecates PyWeakref_GetObject
+ and introduces its replacement PyWeakref_GetRef. PyWeakref_GetObject will be
+ removed in Python 3.15. Add a Tf_PyWeakrefGetRef shim to pyUtils.h that
+ calls PyWeakRef_GetRef directly on >=3.13, and mimics its behavior on <3.13.
+ Port pxr's PyWeakref_GetObject callers to use Tf_PyWeakrefGetRef.
+
+Fixes #3966
+
+(Internal change: 2428356)
+---
+ pxr/base/tf/pyFunction.h | 12 ++--
+ pxr/base/tf/pyIdentity.cpp | 103 ++++++++++++++++++++++-------------
+ pxr/base/tf/pyUtils.h | 42 ++++++++++++++
+ pxr/base/tf/pyWeakObject.cpp | 24 +++++---
+ pxr/base/tf/pyWeakObject.h | 8 ++-
+ 5 files changed, 135 insertions(+), 54 deletions(-)
+
+diff --git a/pxr/base/tf/pyFunction.h b/pxr/base/tf/pyFunction.h
+index 85af943b2c3..66fc7cb8768 100644
+--- a/pxr/base/tf/pyFunction.h
++++ b/pxr/base/tf/pyFunction.h
+@@ -49,11 +49,12 @@ struct TfPyFunctionFromPython<Ret (Args...)>
+ using namespace pxr_boost::python;
+ // Attempt to get the referenced callable object.
+ TfPyLock lock;
+- object callable(handle<>(borrowed(PyWeakref_GetObject(weak.ptr()))));
+- if (TfPyIsNone(callable)) {
++ PyObject *callablePtr;
++ if (Tf_PyWeakrefGetRef(weak.ptr(), &callablePtr) != 1) {
+ TF_WARN("Tried to call an expired python callback");
+ return Ret();
+ }
++ object callable { handle<> { callablePtr } };
+ return TfPyCall<Ret>(callable)(args...);
+ }
+ };
+@@ -68,12 +69,13 @@ struct TfPyFunctionFromPython<Ret (Args...)>
+ // Attempt to get the referenced self parameter, then build a new
+ // instance method and call it.
+ TfPyLock lock;
+- PyObject *self = PyWeakref_GetObject(weakSelf.ptr());
+- if (self == Py_None) {
++ PyObject *selfPtr;
++ if (Tf_PyWeakrefGetRef(weakSelf.ptr(), &selfPtr) != 1) {
+ TF_WARN("Tried to call a method on an expired python instance");
+ return Ret();
+ }
+- object method(handle<>(PyMethod_New(func.ptr(), self)));
++ object self { handle<> { selfPtr } };
++ object method { handle<> { PyMethod_New(func.ptr(), self.ptr()) } };
+ return TfPyCall<Ret>(method)(args...);
+ }
+ };
+diff --git a/pxr/base/tf/pyIdentity.cpp b/pxr/base/tf/pyIdentity.cpp
+index 5389d8f25e2..73db7e82f36 100644
+--- a/pxr/base/tf/pyIdentity.cpp
++++ b/pxr/base/tf/pyIdentity.cpp
+@@ -10,6 +10,7 @@
+ #include "pxr/base/tf/hash.h"
+ #include "pxr/base/tf/mallocTag.h"
+ #include "pxr/base/tf/pyIdentity.h"
++#include "pxr/base/tf/pyUtils.h"
+ #include "pxr/base/tf/staticData.h"
+ #include "pxr/base/tf/stackTrace.h"
+
+@@ -30,7 +31,7 @@ Tf_PyOwnershipPtrMap::_CacheType Tf_PyOwnershipPtrMap::_cache;
+ struct Tf_PyIdHandle {
+
+ TF_MALLOC_TAG_NEW("Tf", "Tf_PyIdHandle");
+-
++
+ Tf_PyIdHandle();
+ explicit Tf_PyIdHandle(PyObject *obj);
+ Tf_PyIdHandle(Tf_PyIdHandle const &other);
+@@ -39,20 +40,29 @@ struct Tf_PyIdHandle {
+ void CleanUp();
+ void Release() const;
+ void Acquire() const;
+- PyObject *Ptr() const;
+- mutable bool _isAcquired;
++
++ // Return a new reference to the referent, or null if it has expired.
++ PyObject *GetRef() const;
++
++ // Return the referent without owning a reference to it, or null if it has
++ // expired. Only valid for comparison and diagnostics; the result may
++ // expire as soon as the caller drops the GIL.
++ PyObject *PeekPtr() const;
++
++ // The reference acquired by Acquire(), or null when not acquired.
++ mutable PyObject *_acquired;
+ PyObject *_weakRef;
+ };
+
+
+
+ Tf_PyIdHandle::Tf_PyIdHandle() :
+- _isAcquired(false), _weakRef(0)
++ _acquired(nullptr), _weakRef(nullptr)
+ {
+ }
+
+ Tf_PyIdHandle::Tf_PyIdHandle(PyObject *obj) :
+- _isAcquired(false), _weakRef(0)
++ _acquired(nullptr), _weakRef(nullptr)
+ {
+ TfPyLock lock;
+ _weakRef = PyWeakref_NewRef(obj, 0);
+@@ -60,7 +70,7 @@ Tf_PyIdHandle::Tf_PyIdHandle(PyObject *obj) :
+ }
+
+ Tf_PyIdHandle::Tf_PyIdHandle(Tf_PyIdHandle const &other) :
+- _isAcquired(false), _weakRef(0)
++ _acquired(nullptr), _weakRef(nullptr)
+ {
+ *this = other;
+ }
+@@ -73,8 +83,9 @@ Tf_PyIdHandle::operator=(Tf_PyIdHandle const &other)
+ _weakRef = other._weakRef;
+ TfPyLock lock;
+ Py_INCREF(_weakRef);
+- if (other._isAcquired)
++ if (other._acquired) {
+ Acquire();
++ }
+ }
+ return *this;
+ }
+@@ -84,45 +95,36 @@ Tf_PyIdHandle::~Tf_PyIdHandle() {
+ }
+
+ void Tf_PyIdHandle::CleanUp() {
+- if (_isAcquired)
++ if (_acquired) {
+ Release();
++ }
+ TfPyLock lock;
+- Py_XDECREF(_weakRef);
++ Py_CLEAR(_weakRef);
+ }
+
+ void Tf_PyIdHandle::Release() const {
+- if (_weakRef && !_isAcquired) {
++ if (_weakRef && !_acquired) {
+ // CODE_COVERAGE_OFF Can only get here if there's a bug.
+ TF_CODING_ERROR("Releasing while not acquired!");
+ return;
+ // CODE_COVERAGE_ON
+- }
+- if (PyObject *ptr = Ptr()) {
+- _isAcquired = false;
+- TfPyLock lock;
+- Py_DECREF(ptr);
+- } else {
+- // CODE_COVERAGE_OFF Can only get here if there's a bug.
+- TF_CODING_ERROR("Acquiring Python identity with "
+- "expired Python object!");
+- TfLogStackTrace("Acquiring Python identity with "
+- "expired Python object!");
+- // CODE_COVERAGE_ON
+ }
++ // Holding the acquired reference keeps the referent alive, so there is no
++ // need to consult the weak reference to find it.
++ TfPyLock lock;
++ Py_CLEAR(_acquired);
+ }
+
+ void Tf_PyIdHandle::Acquire() const {
+- if (_isAcquired) {
++ if (_acquired) {
+ // CODE_COVERAGE_OFF Can only get here if there's a bug.
+ TF_CODING_ERROR("Acquiring while already acquired!");
+ return;
+ // CODE_COVERAGE_ON
+ }
+- if (PyObject *ptr = Ptr()) {
+- _isAcquired = true;
+- TfPyLock lock;
+- Py_INCREF(ptr);
+- } else {
++ TfPyLock lock;
++ // The reference returned here becomes the acquired reference.
++ if (!(_acquired = GetRef())) {
+ // CODE_COVERAGE_OFF Can only get here if there's a bug.
+ TF_CODING_ERROR("Acquiring Python identity with expired Python "
+ "object!");
+@@ -133,12 +135,30 @@ void Tf_PyIdHandle::Acquire() const {
+ }
+
+ PyObject *
+-Tf_PyIdHandle::Ptr() const {
+- if (_weakRef) {
+- TfPyLock lock;
+- return PyWeakref_GetObject(_weakRef);
++Tf_PyIdHandle::GetRef() const {
++ if (!_weakRef) {
++ return nullptr;
+ }
+- return 0;
++ TfPyLock lock;
++ PyObject *obj;
++ if (Tf_PyWeakrefGetRef(_weakRef, &obj) < 0) {
++ // CODE_COVERAGE_OFF _weakRef always comes from PyWeakref_NewRef, so
++ // this can only happen if there's a bug. Note that obj is unspecified
++ // on this path and must not be read.
++ TF_CODING_ERROR("Expected a Python weak reference");
++ PyErr_Clear();
++ return nullptr;
++ // CODE_COVERAGE_ON
++ }
++ return obj;
++}
++
++PyObject *
++Tf_PyIdHandle::PeekPtr() const {
++ TfPyLock lock;
++ PyObject *obj = GetRef();
++ Py_XDECREF(obj);
++ return obj;
+ }
+
+
+@@ -243,16 +263,21 @@ void Tf_PyIdentityHelper::Set(void const *key, PyObject *obj) {
+ _IdentityMap& _identityMap = _GetIdentityMap();
+ _IdentityMap::iterator i = _identityMap.find(key);
+
+- if (i == _identityMap.end()) {
++ if (i == _identityMap.end()) {
+ _identityMap[key] = Tf_PyIdHandle(obj);
+ _RecordEstablishedIdentityStack(key);
+- } else if (i->second.Ptr() != obj) {
++ } else if (i->second.PeekPtr() != obj) {
+ // CODE_COVERAGE_OFF Can only get here if there's a bug.
++ // Hold a reference to the existing object while we report on it, since
++ // _GetTypeName calls back into Python.
++ pxr_boost::python::handle<> existing {
++ pxr_boost::python::allow_null(i->second.GetRef()) };
+ TF_CODING_ERROR("Multiple Python objects for C++ object %p: "
+ "(Existing python object id %p with type %s, "
+ "new python object id %p with type %s)",
+- key, i->second.Ptr(),
+- _GetTypeName(i->second.Ptr()).c_str(),
++ key, existing.get(),
++ existing ? _GetTypeName(existing.get()).c_str()
++ : "expired",
+ obj, _GetTypeName(obj).c_str());
+ _IssueMultipleIdentityErrorStacks(key);
+ i->second = Tf_PyIdHandle(obj);
+@@ -274,8 +299,8 @@ PyObject *Tf_PyIdentityHelper::Get(void const *key) {
+ return 0;
+ }
+
+- // use pxr_boost::python::xincref here, because it returns the increfed ptr.
+- return pxr_boost::python::xincref(i->second.Ptr());
++ // Returns a new reference, or null if the Python object has expired.
++ return i->second.GetRef();
+ }
+
+
+diff --git a/pxr/base/tf/pyUtils.h b/pxr/base/tf/pyUtils.h
+index 51c18e3cb7c..c751eb59964 100644
+--- a/pxr/base/tf/pyUtils.h
++++ b/pxr/base/tf/pyUtils.h
+@@ -117,6 +117,48 @@ TF_API bool TfPyIsNone(pxr_boost::python::object const &obj);
+ /// Return true iff \a obj is None.
+ TF_API bool TfPyIsNone(pxr_boost::python::handle<> const &obj);
+
++/// Get a strong reference to the object referred to by the weak reference
++/// \a ref.
++///
++/// This behaves exactly like PyWeakref_GetRef, which was added in Python 3.13:
++/// on success, store a new strong reference to the referent in \p *pobj and
++/// return 1; if the reference is dead, store null in \p *pobj and return 0; on
++/// error, raise an exception and return -1. Callers must hold the GIL.
++///
++/// As with PyWeakref_GetRef, \p *pobj is unspecified when this returns -1.
++/// Callers must consult the return value and must not inspect \p *pobj unless
++/// it returned 1 or 0.
++///
++/// PyWeakref_GetRef supersedes PyWeakref_GetObject, which is deprecated in 3.13
++/// and slated for removal in 3.15. This function exists only to provide
++/// PyWeakref_GetRef on Python versions before 3.13. Once the minimum supported
++/// Python is 3.13, every call can be replaced with a direct call to
++/// PyWeakref_GetRef and this function deleted.
++inline int
++Tf_PyWeakrefGetRef(PyObject *ref, PyObject **pobj)
++{
++#if PY_VERSION_HEX >= 0x030D0000
++ return PyWeakref_GetRef(ref, pobj);
++#else
++ PyObject *obj = PyWeakref_GetObject(ref);
++ if (!obj) {
++ // Not a weak reference; PyWeakref_GetObject has set an exception.
++ // Leave *pobj alone: PyWeakref_GetRef does not specify its value on
++ // error, so neither do we.
++ return -1;
++ }
++ if (obj == Py_None) {
++ // The referent has expired. None itself is not weak-referenceable, so
++ // this cannot be a live referent.
++ *pobj = nullptr;
++ return 0;
++ }
++ Py_INCREF(obj);
++ *pobj = obj;
++ return 1;
++#endif
++}
++
+ // Helper for \c TfPyObject().
+ TF_API void Tf_PyObjectError(bool printError);
+
+diff --git a/pxr/base/tf/pyWeakObject.cpp b/pxr/base/tf/pyWeakObject.cpp
+index 8cfddc72956..84a25a52d16 100644
+--- a/pxr/base/tf/pyWeakObject.cpp
++++ b/pxr/base/tf/pyWeakObject.cpp
+@@ -115,32 +115,38 @@ Tf_PyWeakObject::GetOrCreate(pxr_boost::python::object const &obj)
+ pxr_boost::python::object
+ Tf_PyWeakObject::GetObject() const
+ {
+- return pxr_boost::python::object
+- (pxr_boost::python::handle<>
+- (pxr_boost::python::borrowed(PyWeakref_GetObject(_weakRef.get()))));
++ PyObject *obj;
++ if (Tf_PyWeakrefGetRef(_weakRef.get(), &obj) != 1) {
++ // The referent has expired; report it as None.
++ return pxr_boost::python::object();
++ }
++ return pxr_boost::python::object(pxr_boost::python::handle<>(obj));
+ }
+
+ void
+ Tf_PyWeakObject::Delete()
+ {
+- Tf_PyWeakObjectRegistry::GetInstance().Remove(GetObject().ptr());
++ // Use the cached key rather than GetObject(): our weak reference has
++ // already been cleared by the time this callback runs.
++ Tf_PyWeakObjectRegistry::GetInstance().Remove(_refObjKey);
+ delete this;
+ }
+-
++
+ Tf_PyWeakObject::Tf_PyWeakObject(pxr_boost::python::object const &obj)
+ : _weakRef(
+ PyWeakref_NewRef(
+ obj.ptr(), pxr_boost::python::
+ object(Tf_PyWeakObjectDeleter(TfCreateWeakPtr(this))).ptr()))
++ , _refObjKey(obj.ptr())
+ {
+ Tf_PyWeakObjectPtr self(this);
+-
++
+ // Set our python identity, but release it immediately, since we are a weak
+ // reference and will expire as soon as the python object does.
+- Tf_PyReleasePythonIdentity(self, GetObject().ptr());
+-
++ Tf_PyReleasePythonIdentity(self, _refObjKey);
++
+ // Install us in the registry.
+- Tf_PyWeakObjectRegistry::GetInstance().Insert(GetObject().ptr(), self);
++ Tf_PyWeakObjectRegistry::GetInstance().Insert(_refObjKey, self);
+ }
+
+ PXR_NAMESPACE_CLOSE_SCOPE
+diff --git a/pxr/base/tf/pyWeakObject.h b/pxr/base/tf/pyWeakObject.h
+index 283887721c2..4fe2f2675fb 100644
+--- a/pxr/base/tf/pyWeakObject.h
++++ b/pxr/base/tf/pyWeakObject.h
+@@ -38,8 +38,14 @@ struct Tf_PyWeakObject : public TfWeakBase
+
+ private:
+ explicit Tf_PyWeakObject(pxr_boost::python::object const &obj);
+-
++
+ pxr_boost::python::handle<> _weakRef;
++
++ // The address of the referent, cached at construction for use as the
++ // registry key. A weak reference is cleared before its callback runs, so
++ // the referent cannot be recovered from _weakRef by the time Delete() runs.
++ // Used only as a key; never dereferenced.
++ PyObject *_refObjKey;
+ };
+
+ PXR_NAMESPACE_CLOSE_SCOPE
diff --git a/usd.spec b/usd.spec
index f505ea3..94be5ec 100644
--- a/usd.spec
+++ b/usd.spec
@@ -148,13 +148,21 @@ Patch: 0006-Downstream-only-use-the-system-libavif.patch
# https://github.com/PixarAnimationStudios/OpenUSD/pull/3903
Patch: %{forgeurl}/pull/3903.patch
-# Replace PyWeakref_GetObject with PyWeakref_GetRef
-# Fixes RHBZ#2433881. This patch is LLM-generated and needs expert human
-# review, but it at least builds. See discussion in
-# https://bugzilla.redhat.com/show_bug.cgi?id=2433881.
-# Mentioned upstream in
-# https://github.com/PixarAnimationStudios/OpenUSD/issues/3966#issuecomment-5128542913.
-Patch: 0001-Replace-PyWeakref_GetObject-with-PyWeakref_GetRef.patch
+# tf: Python 3.13 simultaneously deprecates PyWeakref_GetObject and introduces
+# its replacement PyWeakref_GetRef. PyWeakref_GetObject will be removed in
+# Python 3.15. Add a Tf_PyWeakrefGetRef shim to pyUtils.h that calls
+# PyWeakRef_GetRef directly on >=3.13, and mimics its behavior on <3.13. Port
+# pxr's PyWeakref_GetObject callers to use Tf_PyWeakrefGetRef.
+#
+# https://github.com/PixarAnimationStudios/OpenUSD/commit/cd3b9c9f031fdface3423ff7a89995dadf4b73aa
+#
+# Fixes:
+#
+# PyWeakref_GetObject removed in Python 3.15
+# https://github.com/PixarAnimationStudios/OpenUSD/issues/3966
+#
+# Fixes RHBZ#2433881.
+Patch: %{forgeurl}/commit/cd3b9c9f031fdface3423ff7a89995dadf4b73aa.patch
# Base
BuildRequires: gcc-c++
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-19 22:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-19 22:03 [rpms/usd] f45: Backport upstream patch for Python 3.15 Benjamin A. Beasley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox