On Sat, Apr 23, 2022 at 7:10 PM Paul Moore <p.f.mo...@gmail.com> wrote:
> On Sat, 23 Apr 2022 at 22:42, Rob Cliffe via Python-Dev > <python-dev@python.org> wrote: > > > > UGH! > > > > I thought there was a general understanding that when typing was added > > to Python, there would be no impact, or at least minimal impact, on > > people who didn't use it. (Raises hand.) > > Now we see an(other) instance of intention creep. > > To be fair, none of this is needed unless you want to add type > annotations to your code. So it's still perfectly possible to ignore > all of this (which is what I am currently doing). > > What I am concerned about is when users of libraries I write start to > claim that I "need" to add this sort of stuff to my code, so that they > can type check their code that uses mine, and/or they can get tooltips > for my APIs in their IDEs. That's where I think the biggest issue with > a proposal like this arises - the *social* pressure on people to adopt > typing, and all the complexities it adds. But again, that's not > something that's specific to this proposal, it's inherent in the whole > question of whether people add type annotations at all. > > So I'm -1 on this proposal, but just because I fear I may be forced to > use it when I don't need to, rather than because I think it's a bad > idea per se. > > Paul > I stand with Paul here - But as a "heavy user" of metaclasses, as far as that is possible. (less in production code or "non toy projects", but a lot in understanding what goes, answering questions and teaching people on how they should best use (or skip using) a metaclass. I'd say this breaks too much of the current working of class creation for, possibly, too little. And - on a second thought: Was not this the kind of thing that PEP 563 was supposed to fix? Pep 563 is accepted now, I think one may just use a forward declaration in any annotation context: it will be lazily evaluated and the target class will have been created. So, while I understand the problem with forward references, which have been historically workaround with the usage of strings (even long before even Python 3.0, in Django's Models) I believe this is not a good approach So first part: ================== I'd be comfortable with the statements and blocks as they are if the "forward class" statement would not mess with the metaclass and class creation at all: just create a place-holder the type checkers could then use to find the class later on the file, or later on the code, and then use that class. Has this been thought of? Is there any reason why that would not work, better than it will put some burden on static-type checkers, as opposed to fundamentally modify the way classes are built so that any library featuring any metaclass will have to be divided in incompatible releases "before this pep" and "after this pep"? (and with the harsh inconvenience of needing to have one a part of the code which is often the most complicated 100% rewritten) Second part: ============= The proposal as it is does not preserve everything that is possible with the current metaclass "__new__", besides complicating things. Moreover, there _are_ similar steps on "breaking metaclass.`__new__` " that would actually be useful in customizing the way classes are created, without sacrificing compatibility (in a sense the custom "metaclass.__new__" would still be called exactly as it is today). If there is any chance this thing will move on, I'd like to detail these ideas (it would be longish, similar in size with the proto-pep text) - and maybe there is a way to reconcile compatibility, without the proposal of splitting "__new__" in two 100% incompatible methods. I will leave the actual amendments to this part of the proposal (which would affect all the inner workings of the metaclasses as exposed) to another message. But I will leave one first, huge, problem here that: ```Python def __new_forward__(metaclass, name, bases, namespace, **kwargs): def __new_continue__(metaclass, cls, **kwargs): ``` These two, as they are, do not allow for some of the things that are possible today: let's supose I want, in a custom metaclass `__new__` method inspect the namespace and creates a "__slots__" declaration based on what already _is_ on the namespace: in "__new_forward__" the namespace is filled in a non deterministic way and should not be inspected , and in "__new_continue__" it had already been processed by (what currently is) "type.__new__" and baked into the proxy-map inside the "cls". I the specific case of creating "__slots__" in a similar way "@dataclass" does, the oportunity is gone. I won't mention the suggestion in the text that "class transformers that would create slots are free to re-create the class object upon its first instantiation" is _rather_ bogus. I can imagine a metaclass "__call__" method that could do that, but then, the classes the instances would be actually using would rather become either have to be kept as an attribute in the class as declared in the code, or kept in a registry in the metaclass: in both cases, calls to "isinstance" and "issubclass" involving this class would have to be customized. There are hooks for that, so it _would_ be possible - but we are talking of 3 lines inside an overriden "__new__" method in a custom metaclass that would necessarily require the creation of a "proxy real class in use managing system", involving the customization of the metaclass "__call__", "__instancecheck__" and "__subclasscheck__". and the creation of a shadow-class for each class. Also note that unless customized for that, no static type-checker would ever know of this shadow class - and it is actually different from the declared class in the code (for example, it has "__slots__" active) So, sorry if the two paragraphs above look like "an extreme inprobable work around", but it is what is implicit, even somewhat explicit, in the PEP with the suggestion of how "@dataclass" should be made to work. Actually, modifying the namespace before having it "baked" into the cls "real namespace" through "super().__new__" call is one of the few things metaclasses customization have any use for nowadays (past the __init_subclass__ creation) The idea of creating a proxy object in the "forward declaration" possibly calling "__prepare__" and keep metaclasses as they are, with the "__new__" method to be called just after the "continue class" block is executed, are _much_ more attractive. (again, If, and only if this is gonna be pursued in anyway - I may be wrong, but I think that PEP 563 makes this a non issue at all) js -><- > > PS To be open here, I do actually like type annotations in > straightforward situations - they have located some bugs in my code > for me, and tooltips in VS code *are* nice. What I don't like is not > being able to stick to simple stuff and not bother annotating the > complicated bits, or being pushed into over-strict annotations because > it's too hard (or verbose) to express dynamic, duck-typed constraints. > > also, yes!
_______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-le...@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/KYQBI6JSNJWRADA6K3EGHTHSRSA2WZAJ/ Code of Conduct: http://python.org/psf/codeofconduct/