Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork32.4k
bpo-19072: Make @classmethod support chained decorators#8405
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
bpo-19072: Make @classmethod support chained decorators#8405
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Uh oh!
There was an error while loading.Please reload this page.
Misc/NEWS.d/next/Core and Builtins/2018-07-23-13-09-54.bpo-19072.Gc59GS.rst OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Please provide microbenchmark results.
@@ -183,6 +183,27 @@ def test_refleaks_in___init__(self): | |||
fake_prop.__init__('fget', 'fset', 'fdel', 'doc') | |||
self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) | |||
@unittest.skipIf(sys.flags.optimize >= 2, | |||
"Docstrings are omitted with -O2 and above") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Does sys.flags.optimize really affects this test?
Misc/NEWS.d/next/Core and Builtins/2018-07-23-13-09-54.bpo-19072.Gc59GS.rst OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
bpo-19072 (python#8405) allows `classmethod` to wrap other descriptors, but this doesnot work when the wrapped descriptor mimics classmethod. The current PR fixesthis.In Python 3.8 and before, one could create a callable descriptor such that thisworks as expected (see Lib/test/test_decorators.py for examples):```pythonclass A: @myclassmethod def f1(cls): return cls@classmethod @myclassmethod def f2(cls): return cls```In Python 3.8 and before, `A.f2()` return `A`. Currently in Python 3.9, itreturns `type(A)`. This PR make `A.f2()` return `A` again.As ofpython#8405, classmethod calls `obj.__get__(type)` if `obj` has `__get__`.This allows one to chain `@classmethod` and `@property` together. Whenusing classmethod-like descriptors, it's the second argument to `__get__`--theowner or the type--that is important, but this argument is currently missing.Since it is None, the "owner" argument is assumed to be the type of the firstargument, which, in this case, is wrong (we want `A`, not `type(A)`).This PR updates classmethod to call `obj.__get__(type, type)` if `obj` has`__get__`.
Patch by Erik Welch.bpo-19072 (python#8405) allows `classmethod` to wrap other descriptors, but this doesnot work when the wrapped descriptor mimics classmethod. The current PR fixesthis.In Python 3.8 and before, one could create a callable descriptor such that thisworks as expected (see Lib/test/test_decorators.py for examples):```pythonclass A: @myclassmethod def f1(cls): return cls@classmethod @myclassmethod def f2(cls): return cls```In Python 3.8 and before, `A.f2()` return `A`. Currently in Python 3.9, itreturns `type(A)`. This PR make `A.f2()` return `A` again.As ofpython#8405, classmethod calls `obj.__get__(type)` if `obj` has `__get__`.This allows one to chain `@classmethod` and `@property` together. Whenusing classmethod-like descriptors, it's the second argument to `__get__`--theowner or the type--that is important, but this argument is currently missing.Since it is None, the "owner" argument is assumed to be the type of the firstargument, which, in this case, is wrong (we want `A`, not `type(A)`).This PR updates classmethod to call `obj.__get__(type, type)` if `obj` has`__get__`.Co-authored-by: Erik Welch <erik.n.welch@gmail.com>
…rs (#27115)Patch by Erik Welch.bpo-19072 (#8405) allows `classmethod` to wrap other descriptors, but this doesnot work when the wrapped descriptor mimics classmethod. The current PR fixesthis.In Python 3.8 and before, one could create a callable descriptor such that thisworks as expected (see Lib/test/test_decorators.py for examples):```pythonclass A: @myclassmethod def f1(cls): return cls@classmethod @myclassmethod def f2(cls): return cls```In Python 3.8 and before, `A.f2()` return `A`. Currently in Python 3.9, itreturns `type(A)`. This PR make `A.f2()` return `A` again.As of#8405, classmethod calls `obj.__get__(type)` if `obj` has `__get__`.This allows one to chain `@classmethod` and `@property` together. Whenusing classmethod-like descriptors, it's the second argument to `__get__`--theowner or the type--that is important, but this argument is currently missing.Since it is None, the "owner" argument is assumed to be the type of the firstargument, which, in this case, is wrong (we want `A`, not `type(A)`).This PR updates classmethod to call `obj.__get__(type, type)` if `obj` has`__get__`.Co-authored-by: Erik Welch <erik.n.welch@gmail.com>
…rs (pythonGH-27115)Patch by Erik Welch.bpo-19072 (pythonGH-8405) allows `classmethod` to wrap other descriptors, but this doesnot work when the wrapped descriptor mimics classmethod. The current PR fixesthis.In Python 3.8 and before, one could create a callable descriptor such that thisworks as expected (see Lib/test/test_decorators.py for examples):```pythonclass A: @myclassmethod def f1(cls): return cls@classmethod @myclassmethod def f2(cls): return cls```In Python 3.8 and before, `A.f2()` return `A`. Currently in Python 3.9, itreturns `type(A)`. This PR make `A.f2()` return `A` again.As ofpythonGH-8405, classmethod calls `obj.__get__(type)` if `obj` has `__get__`.This allows one to chain `@classmethod` and `@property` together. Whenusing classmethod-like descriptors, it's the second argument to `__get__`--theowner or the type--that is important, but this argument is currently missing.Since it is None, the "owner" argument is assumed to be the type of the firstargument, which, in this case, is wrong (we want `A`, not `type(A)`).This PR updates classmethod to call `obj.__get__(type, type)` if `obj` has`__get__`.Co-authored-by: Erik Welch <erik.n.welch@gmail.com>(cherry picked from commitb83861f)Co-authored-by: Łukasz Langa <lukasz@langa.pl>
…rs (GH-27115) (GH-27162)Patch by Erik Welch.bpo-19072 (GH-8405) allows `classmethod` to wrap other descriptors, but this doesnot work when the wrapped descriptor mimics classmethod. The current PR fixesthis.In Python 3.8 and before, one could create a callable descriptor such that thisworks as expected (see Lib/test/test_decorators.py for examples):```pythonclass A: @myclassmethod def f1(cls): return cls@classmethod @myclassmethod def f2(cls): return cls```In Python 3.8 and before, `A.f2()` return `A`. Currently in Python 3.9, itreturns `type(A)`. This PR make `A.f2()` return `A` again.As ofGH-8405, classmethod calls `obj.__get__(type)` if `obj` has `__get__`.This allows one to chain `@classmethod` and `@property` together. Whenusing classmethod-like descriptors, it's the second argument to `__get__`--theowner or the type--that is important, but this argument is currently missing.Since it is None, the "owner" argument is assumed to be the type of the firstargument, which, in this case, is wrong (we want `A`, not `type(A)`).This PR updates classmethod to call `obj.__get__(type, type)` if `obj` has`__get__`.Co-authored-by: Erik Welch <erik.n.welch@gmail.com>(cherry picked from commitb83861f)
Uh oh!
There was an error while loading.Please reload this page.
https://bugs.python.org/issue19072