From: =?utf-8?q?Miro_Hron=C4=8Dok?= <miro@hroncok.cz>
Date: Mon, 17 Jun 2024 14:24:55 +0200
Subject: Allow InstancePropertyHelper to accept properties with names on
 Python 3.13+

Fixes https://github.com/Pylons/pyramid/issues/3761

Origin: other, https://github.com/Pylons/pyramid/pull/3762/commits/1079613eb07e2a67454378e1fc28815dfd64bb82
Bug: https://github.com/Pylons/pyramid/issues/3761
Bug-Debian: https://bugs.debian.org/1082259
Last-Update: 2024-12-08
---
 src/pyramid/util.py |  3 ++-
 tests/test_util.py  | 28 ++++++++++++++++++++++------
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/pyramid/util.py b/src/pyramid/util.py
index 191768e..d7b441b 100644
--- a/src/pyramid/util.py
+++ b/src/pyramid/util.py
@@ -110,7 +110,8 @@ class InstancePropertyHelper:
         if name is None:
             if not hasattr(callable, '__name__'):
                 raise ValueError(
-                    'missing __name__, must specify "name" for property'
+                    'missing __name__, must specify "name" for property '
+                    'on Python < 3.13'
                 )
             name = callable.__name__
         name = get_callable_name(name)
diff --git a/tests/test_util.py b/tests/test_util.py
index bf4c089..ae31384 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -67,13 +67,21 @@ class Test_InstancePropertyHelper(unittest.TestCase):
 
     def test_property_without_name(self):
         def worker(obj):  # pragma: no cover
-            pass
+            return obj.bar
 
         foo = Dummy()
         helper = self._getTargetClass()
-        self.assertRaises(
-            ValueError, helper.set_property, foo, property(worker)
-        )
+        if sys.version_info < (3, 13):
+            self.assertRaises(
+                ValueError, helper.set_property, foo, property(worker)
+            )
+        else:
+            # Since Python 3.13, the name of the property is automatic
+            helper.set_property(foo, property(worker))
+            foo.bar = 1
+            self.assertEqual(1, foo.worker)
+            foo.bar = 2
+            self.assertEqual(2, foo.worker)
 
     def test_property_with_name(self):
         def worker(obj):
@@ -272,10 +280,18 @@ class Test_InstancePropertyMixin(unittest.TestCase):
 
     def test_property_without_name(self):
         def worker(obj):  # pragma: no cover
-            pass
+            return obj.bar
 
         foo = self._makeOne()
-        self.assertRaises(ValueError, foo.set_property, property(worker))
+        if sys.version_info < (3, 13):
+            self.assertRaises(ValueError, foo.set_property, property(worker))
+        else:
+            # Since Python 3.13, the name of the property is automatic
+            foo.set_property(property(worker))
+            foo.bar = 1
+            self.assertEqual(1, foo.worker)
+            foo.bar = 2
+            self.assertEqual(2, foo.worker)
 
     def test_property_with_name(self):
         def worker(obj):
