Re: Feature Request: Adding Way to Annotate Class Variables Distinct from Instance Variables

Steve Holden <[email protected]> Wed, 21 Dec 2022 16:48:16 +0000
Newsgroups gmane.comp.python.devel
Message-ID <CAMofdRDk0E_X6ia7agme4GcvLonEMd9Dc3gUHmPvRAi-FW8h4g@mail.gmail.com>
--===============6577186945281464898==
Content-Type: multipart/alternative; boundary="0000000000004e9b2205f0595210"

--0000000000004e9b2205f0595210
Content-Type: text/plain; charset="UTF-8"

Well, the first comment is that this isn't really the best list to ask such
questions on, since it was created for the Python developers to discuss the
development of the language and its implementation. Further, such
discussions nowadays take place on discuss.python.org, and you can find
more information at https://www.python.org/community/lists/.

However, I simplified your program a little, and would observe that the
following program raises no AssertionErrors under Python 3.10  and 3.11.

class Foo:
    variable_both_class_and_instance: str | int = "descriptive string"

    def __init__(self, value: int):
        assert isinstance(self.variable_both_class_and_instance, str)
        self.variable_both_class_and_instance = value
        assert isinstance(self.variable_both_class_and_instance, int)

assert isinstance(Foo.variable_both_class_and_instance, str)
assert isinstance(Foo(42).variable_both_class_and_instance, int)

Union is now outdated, since we can use alternation (|) to offer
alternative types.

It's therefore not obvious to me from your email why ClassVar would need
any modification, or even why it needs to be used in your example. Perhaps
I've missed your point?

Kind regards,
Steve


On Wed, Dec 21, 2022 at 4:15 PM <[email protected]> wrote:

> Hello folks, I am Chihiro, a.k.a. Frodo821, and this is my first post to
> this group.
>
> I searched for a way to annotate both class variables and instance
> variables with different types and concluded that there is currently no way
> to do this.
>
> For example, what I want to:
> ```
> class Foo:
>     variable_both_class_and_instance = Field(desc="descriptive string")
>
>     def __init__(self, value: int):
>         self.variable_both_class_and_instance = value
>
> assert isinstance(Foo.variable_both_class_and_instance, Field)
> assert isinstance(Foo().variable_both_class_and_instance, int)
> ```
>
> In this example, I want to annotate `Foo.variable_both_class_and_instance`
> with `Field` when it is accessed as a class variable. On the other hand, I
> want to annotate `Foo.variable_both_class_and_instance` with `int` when it
> is accessed as an instance variable.
>
> I don't have any smart ideas to accomplish this, but I think
> `typing.ClassVar` could be extended this like:
>
> ```
> class Foo:
>     variable_both_class_and_instance: Union[ClassVar[Field], int] =
> Field(desc="descriptive string")
>
>     def __init__(self, value: int):
>         self.variable_both_class_and_instance = value
>
> assert isinstance(Foo.variable_both_class_and_instance, Field)
> assert isinstance(Foo().variable_both_class_and_instance, int)
> ```
>
> Do you have any ideas or comments about this?
> _______________________________________________
> Python-Dev mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/[email protected]/message/7XFIE6YGRGO3XKCR7MZGDN6CCGUNN6MR/
> Code of Conduct: http://python.org/psf/codeofconduct/
>

--0000000000004e9b2205f0595210
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_default" style=3D"font-size:small">Wel=
l, the first comment is that this isn&#39;t really the best list to ask suc=
h questions on, since it was created for the Python developers to discuss t=
he development of the language and its implementation. Further, such discus=
sions nowadays take place on <a href=3D"http://discuss.python.org">discuss.=
python.org</a>, and you can find more information at=C2=A0<a href=3D"https:=
//www.python.org/community/lists/">https://www.python.org/community/lists/<=
/a>.</div><div class=3D"gmail_default" style=3D"font-size:small"><br></div>=
<div class=3D"gmail_default" style=3D"font-size:small">However, I simplifie=
d your program a little, and would observe that the following program raise=
s no AssertionErrors under Python 3.10=C2=A0 and 3.11.</div><div class=3D"g=
mail_default" style=3D"font-size:small"><br></div><div class=3D"gmail_defau=
lt" style=3D"font-size:small">class Foo:<br>=C2=A0 =C2=A0 variable_both_cla=
ss_and_instance: str | int =3D &quot;descriptive string&quot;<br><br>=C2=A0=
 =C2=A0 def __init__(self, value: int):<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 asse=
rt isinstance(self.variable_both_class_and_instance, str)<br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 self.variable_both_class_and_instance =3D value<br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 assert isinstance(self.variable_both_class_and_instance, =
int)</div><div class=3D"gmail_default" style=3D"font-size:small"><br>assert=
 isinstance(Foo.variable_both_class_and_instance, str)<br>assert isinstance=
(Foo(42).variable_both_class_and_instance, int)<br></div><div class=3D"gmai=
l_default" style=3D"font-size:small"><br></div><div class=3D"gmail_default"=
 style=3D"font-size:small">Union is now outdated, since we can use alternat=
ion (|) to offer alternative types.</div><div class=3D"gmail_default" style=
=3D"font-size:small"><br></div><div class=3D"gmail_default" style=3D"font-s=
ize:small">It&#39;s therefore not obvious=C2=A0to me from your email why Cl=
assVar would need any modification,=C2=A0or even why it needs to be used in=
 your example. Perhaps I&#39;ve missed your point?</div><div class=3D"gmail=
_default" style=3D"font-size:small"><br></div><div><div dir=3D"ltr" class=
=3D"gmail_signature" data-smartmail=3D"gmail_signature"><div dir=3D"ltr"><d=
iv><div dir=3D"ltr">Kind regards,</div><div dir=3D"ltr">Steve<br></div></di=
v></div></div></div><br></div><br><div class=3D"gmail_quote"><div dir=3D"lt=
r" class=3D"gmail_attr">On Wed, Dec 21, 2022 at 4:15 PM &lt;<a href=3D"mail=
to:[email protected]">[email protected]</a>&gt; wrote:<br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex">Hello folks, I am Chihiro, a.k=
.a. Frodo821, and this is my first post to this group.<br>
<br>
I searched for a way to annotate both class variables and instance variable=
s with different types and concluded that there is currently no way to do t=
his.<br>
<br>
For example, what I want to:<br>
```<br>
class Foo:<br>
=C2=A0 =C2=A0 variable_both_class_and_instance =3D Field(desc=3D&quot;descr=
iptive string&quot;)<br>
<br>
=C2=A0 =C2=A0 def __init__(self, value: int):<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.variable_both_class_and_instance =3D value=
<br>
<br>
assert isinstance(Foo.variable_both_class_and_instance, Field)<br>
assert isinstance(Foo().variable_both_class_and_instance, int)<br>
```<br>
<br>
In this example, I want to annotate `Foo.variable_both_class_and_instance` =
with `Field` when it is accessed as a class variable. On the other hand, I =
want to annotate `Foo.variable_both_class_and_instance` with `int` when it =
is accessed as an instance variable.<br>
<br>
I don&#39;t have any smart ideas to accomplish this, but I think `typing.Cl=
assVar` could be extended this like:<br>
<br>
```<br>
class Foo:<br>
=C2=A0 =C2=A0 variable_both_class_and_instance: Union[ClassVar[Field], int]=
 =3D Field(desc=3D&quot;descriptive string&quot;)<br>
<br>
=C2=A0 =C2=A0 def __init__(self, value: int):<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 self.variable_both_class_and_instance =3D value=
<br>
<br>
assert isinstance(Foo.variable_both_class_and_instance, Field)<br>
assert isinstance(Foo().variable_both_class_and_instance, int)<br>
```<br>
<br>
Do you have any ideas or comments about this?<br>
_______________________________________________<br>
Python-Dev mailing list -- <a href=3D"mailto:[email protected]" target=
=3D"_blank">[email protected]</a><br>
To unsubscribe send an email to <a href=3D"mailto:[email protected]=
rg" target=3D"_blank">[email protected]</a><br>
<a href=3D"https://mail.python.org/mailman3/lists/python-dev.python.org/" r=
el=3D"noreferrer" target=3D"_blank">https://mail.python.org/mailman3/lists/=
python-dev.python.org/</a><br>
Message archived at <a href=3D"https://mail.python.org/archives/list/python=
[email protected]/message/7XFIE6YGRGO3XKCR7MZGDN6CCGUNN6MR/" rel=3D"noreferre=
r" target=3D"_blank">https://mail.python.org/archives/list/python-dev@pytho=
n.org/message/7XFIE6YGRGO3XKCR7MZGDN6CCGUNN6MR/</a><br>
Code of Conduct: <a href=3D"http://python.org/psf/codeofconduct/" rel=3D"no=
referrer" target=3D"_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote></div>

--0000000000004e9b2205f0595210--

--===============6577186945281464898==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline