This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: typing: get_type_hints on stringified lone ClassVar raises TypeError
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: AlexWaygood, GBeauregard, JelleZijlstra, eric.smith, gvanrossum, kj, sobolevn
Priority: normal Keywords: patch

Created on 2022-01-27 20:50 by GBeauregard, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 30983 merged GBeauregard, 2022-01-28 08:46
Messages (11)
msg411923 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-01-27 20:50
```
class C:
    a: "ClassVar"

get_type_hints(C, globals())  # TypeError: Plain typing.ClassVar is not valid as type argument
```

A stringified lone ClassVar raises at runtime, but this pattern is tested for in dataclasses unit tests and used in the wild. The PEP is not clear that it should or should not be used with arguments, and it works fine when not stringified.

The fix for this is trivial and I can submit a patch if there's agreement.
msg411924 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-01-27 20:53
I think this is needed for moving dataclasses to using typing.py introspection tools to be viable.
msg411927 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2022-01-27 21:17
dataclasses is no doubt too lenient. But it's just trying to accept valid strings that look like ClassVar. Way back when this was initially implemented, we decided that calling get_type_hints would be too expensive for every dataclass, and would also neccesitate importing typing, which we didn't want to require.

I think someone needs to do an analysis of how expensive it would be for dataclasses to import typing and to call get_type_hints. Perhaps we'd make a different decision today.
msg411928 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-01-27 21:20
I'm drafting an implementation for the purpose of investigating performance right now; I will share when ready.
msg411934 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2022-01-27 22:43
It seems acceptable to mypy.

I'm not sure I like the agenda of "moving dataclasses to using typing.py introspection tools".
msg411943 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-01-28 00:03
It's acceptable to mypy, and pyright added support a few months ago when I made an issue and Eric Traut discovered this pattern in the wild too.

Some of the other type checkers (pyre) still error I believe. My feeling is that since this has apparently become used in practice we should fix the runtime error for when it's stringified, but we don't necessarily need to prescribe that it's a legal type annotation for type checkers (?). If I was prescribing how to use ClassVar in a vacuum, I don't see any good typing reason we should prohibit this.

re: moving dataclasses: I'm not sure either! I'm trying to look into the issues it brings up in practice to weigh against the difficulties of maintaining the existing bespoke introspection implementation and the problems it has (dealing with stringified annotations, supporting renaming the Annotated symbol).

I made an implementation that fully moves dataclasses over to using `get_type_hints` (and got all the tests to pass), but my feeling right now is that a few issues are too serious for it to be viable:

1) the namespaces are a mess, and issues like https://github.com/python/typing/issues/508 don't have a solution at the moment
2) get_type_hints paints a wide brush on the entire class when it raises for errors, so it's not very viable to deal with non-typing non-Annotated[] annotations as a one-off

There's also nontechnical issues, like the potential politics of making dataclasses always import typing. I'll be updating bpo-46511 later with thoughts.
msg411955 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2022-01-28 01:09
Please just don't go there. I beg you. It's not worth it.
msg411959 - (view) Author: Gregory Beauregard (GBeauregard) * Date: 2022-01-28 02:01
I think I miscommunicated my intent with sentence placement. I already posted the thoughts I referred to; they're just my concluding opinion on the technical merit of using get_type_hints in dataclasses to solve the Annotated problem: https://bugs.python.org/msg411945

In any case, I apologize for the faux pas and I'll be careful in the future.

I dug up the issue where pyright was changed (to allow bare ClassVar) that has an argument for not allowing it to be bare: https://github.com/microsoft/pyright/issues/2377
msg411972 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2022-01-28 03:54
I
To be clear: I am okay with this patch, just not with making dataclasses
import typing.
-- 
--Guido (mobile)
msg412015 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2022-01-28 16:58
New changeset 5445e173e76ec792358082caf660fbdc846c64b2 by Gregory Beauregard in branch 'main':
bpo-46553: allow bare typing.ClassVar annotations (#30983)
https://github.com/python/cpython/commit/5445e173e76ec792358082caf660fbdc846c64b2
msg415413 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2022-03-17 14:31
Is there any reason to keep this issue open? The PR was merged.
History
Date User Action Args
2022-04-11 14:59:55adminsetgithub: 90711
2022-03-17 14:34:07JelleZijlstrasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2022-03-17 14:31:21eric.smithsetmessages: + msg415413
2022-01-28 16:58:45gvanrossumsetmessages: + msg412015
2022-01-28 08:46:04GBeauregardsetkeywords: + patch
stage: patch review
pull_requests: + pull_request29162
2022-01-28 03:54:54gvanrossumsetmessages: + msg411972
2022-01-28 02:01:54GBeauregardsetmessages: + msg411959
2022-01-28 01:09:35gvanrossumsetmessages: + msg411955
2022-01-28 00:03:43GBeauregardsetmessages: + msg411943
2022-01-27 22:43:02gvanrossumsetmessages: + msg411934
2022-01-27 21:20:25GBeauregardsetmessages: + msg411928
2022-01-27 21:17:04eric.smithsetmessages: + msg411927
2022-01-27 21:01:24GBeauregardsetnosy: + GBeauregard
2022-01-27 21:00:09GBeauregardsettype: behavior
2022-01-27 21:00:04GBeauregardsetnosy: + sobolevn, AlexWaygood, - GBeauregard
2022-01-27 20:53:20GBeauregardsetmessages: + msg411924
2022-01-27 20:50:13GBeauregardcreate