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/

Reply via email to