Skip to content

Commit

Permalink
No longer support 'util.class_or_instance_method' propagating on the …
Browse files Browse the repository at this point in the history
…descriptor protocol
  • Loading branch information
friedkeenan committed Jan 3, 2025
1 parent 44e030d commit 93ce50f
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 21 deletions.
19 changes: 13 additions & 6 deletions pak/util/decorators.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Custom decorators."""

import functools
import types

from collections.abc import Hashable

__all__ = [
Expand Down Expand Up @@ -139,12 +141,17 @@ def __set_name__(self, owner, name):
raise TypeError(f"{type(self).__qualname__} '{owner.__qualname__}.{name}' must have an instance method")

def __get__(self, instance, owner=None):
# 'classmethod' in fact propagates the '__get__' call instead of
# just returning a bound method. This allows users to create
# "class properties" by combining 'classmethod' and 'property'.
# We support the same here.
# From Python 3.9 to Python 3.12, 'classmethod'
# in fact propagates the '__get__' call instead
# of just returning a bound method. This allows
# users to create "class properties" by combining
# 'classmethod' and 'property'.
#
# We do not model the same, as it was decided that
# that design was unsound and was deprecated in
# Python 3.11 and then removed in Python 3.13.

if instance is None:
return self._class_method.__get__(owner, owner)
return types.MethodType(self._class_method, owner)

return self._instance_method.__get__(instance, owner)
return types.MethodType(self._instance_method, instance)
15 changes: 0 additions & 15 deletions tests/test_utils/test_decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,21 +74,6 @@ class MissingInstanceMethod:
def method(cls):
pass

def test_class_or_instance_method_descriptor_propagate():
class Test:
@pak.util.class_or_instance_method
@property
def attr(cls):
return "class"

@attr.instance_method
@property
def attr(self):
return "instance"

assert Test.attr == "class"
assert Test().attr == "instance"

def test_class_or_instance_method_copy():
class Test:
@pak.util.class_or_instance_method
Expand Down

0 comments on commit 93ce50f

Please sign in to comment.