classification
Title: Setting __init_subclass__ and __class_getitem__ methods are in runtime doesnt make them class method.
Type: enhancement Stage: resolved
Components: Interpreter Core Versions: Python 3.8
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: levkivskyi Nosy List: BTaskaya, inada.naoki, levkivskyi, remi.lapeyre, rhettinger, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2019-02-19 17:19 by BTaskaya, last changed 2019-03-11 10:49 by inada.naoki. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 11943 closed BTaskaya, 2019-02-19 17:24
Messages (6)
msg335985 - (view) Author: Batuhan (BTaskaya) * Date: 2019-02-19 17:19
CPython only makes these methods class method when a class created. If you set __class_getitem__ method after the creation it doesn't work unless you use classmethod decorator manually.

>>> class B:
...     pass
... 
>>> def y(*a, **k):
...     return a, k
... 
>>> B.__class_getitem__ = y 
>>> B[int]
((<class 'int'>,), {})
>>> B.__class_getitem__ = classmethod(y)
>>> B[int]
((<class '__main__.B'>, <class 'int'>), {})
msg336021 - (view) Author: Rémi Lapeyre (remi.lapeyre) * Date: 2019-02-19 22:17
Is this an issue though? Shouldn't methods be defined in the class definition, we don't expect setting a function as an attribute to a class to transform it automatically to a method.

Why would we special case __class_getitem__ and not __init_subclass__?
msg336026 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2019-02-19 23:40
> CPython only makes these methods class method when a class created.
> If you set __class_getitem__ method after the creation it 
> doesn't work unless you use classmethod decorator manually.

Give the intended use case for __class_getitem__ and that it was replacement for metaclass code with the same effect, the current behavior doesn't seem unreasonable.  That said, I don't see any downside to allowing the method to attach after class creation.

Assigning to Ivan to make the call on this one.
msg336058 - (view) Author: Inada Naoki (inada.naoki) * (Python committer) Date: 2019-02-20 10:32
__new__ is special function too.  It is converted as staticmethod when class creation.

Since manually converting to (static|class)method is allowed, I don't think
automatic conversion should be applied when attach after class creation.

$ python3
Python 3.7.2 (default, Feb 12 2019, 08:15:36)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class C:
...   def __new__(cls):
...     pass
...
>>> type(C.__dict__['__new__'])
<class 'staticmethod'>
>>> class D:
...   pass
...
>>> D.__new__ = lambda cls: cls
>>> type(D.__dict__['__new__'])
<class 'function'>
msg336121 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-02-20 17:06
I don't like complicating the code and adding a performance penalty to support such uncommon case.

The documentation for __class_getitem__ precisely describes the current behavior: "when defined in the class body, this method is implicitly a class method". Nothing should be changed here.

The documentation for __init_subclass__ could be rewritten in similar words.
msg336123 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2019-02-20 17:08
I totally agree with Serhiy
History
Date User Action Args
2019-03-11 10:49:36inada.naokisetstatus: open -> closed
resolution: not a bug
stage: patch review -> resolved
2019-02-20 17:08:35levkivskyisetmessages: + msg336123
2019-02-20 17:06:48serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg336121
2019-02-20 10:32:51inada.naokisetnosy: + inada.naoki
messages: + msg336058
2019-02-19 23:40:31rhettingersetassignee: levkivskyi
type: behavior -> enhancement
components: + Interpreter Core
versions: + Python 3.8
nosy: + rhettinger

messages: + msg336026
2019-02-19 22:17:41remi.lapeyresetnosy: + remi.lapeyre
messages: + msg336021
2019-02-19 17:29:59xtreaksetnosy: + levkivskyi
2019-02-19 17:24:01BTaskayasetkeywords: + patch
stage: patch review
pull_requests: + pull_request11967
2019-02-19 17:19:55BTaskayacreate