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: TopologicalSorter is not Generic at runtime (but is in typeshed)
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.11
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: AlexWaygood, JacobHayes, asvetlov
Priority: normal Keywords: patch

Created on 2021-10-03 22:18 by JacobHayes, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 28714 merged JacobHayes, 2021-10-03 22:22
Messages (7)
msg403115 - (view) Author: Jacob Hayes (JacobHayes) * Date: 2021-10-03 22:18
Reproduction:

```
from graphlib import TopologicalSorter

TopologicalSorter[str]({"a": {}, "b": {"a"}})
```
```
$ mypy /tmp/toposort.py
Success: no issues found in 1 source file
$ python3 /tmp/toposort.py
Traceback (most recent call last):
  File "/tmp/toposort.py", line 3, in <module>
    TopologicalSorter[str]({"a": {}, "b": {"a"}})
TypeError: 'type' object is not subscriptable
```

I opened the issue here (rather than typeshed) because we'd presumably like to support this at runtime too.

Typeshed link: https://github.com/python/mypy/blob/0a830481980bfc554ded61a3eaaaecde384a21e4/mypy/typeshed/stdlib/graphlib.pyi#L6
msg408041 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2021-12-08 18:53
New changeset 3cb9731b7e59b0df9a7a9ab6b7746a669958b693 by Jacob Hayes in branch 'main':
bpo-45359: Support TopologicalSorter type subscript (GH-28714)
https://github.com/python/cpython/commit/3cb9731b7e59b0df9a7a9ab6b7746a669958b693
msg408109 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2021-12-09 11:36
The new feature is applied to Python 3.11 only
msg408110 - (view) Author: Jacob Hayes (JacobHayes) * Date: 2021-12-09 11:53
Thanks for merging!

Should typeshed be updated for <3.11 in the meantime or do you suggest `if TYPE_CHECKING` blocks on user side? Perhaps it's a non-issue if no one else has noticed this. :)
msg408117 - (view) Author: Andrew Svetlov (asvetlov) * (Python committer) Date: 2021-12-09 13:14
`if TYPE_CHECKING:` is a good choice, it works fine just now.
`from __future__ import annotations` is another alternative.

I don't see a reason for REMOVING already existing and correct annotations from typeshed.
msg408177 - (view) Author: Alex Waygood (AlexWaygood) * (Python triager) Date: 2021-12-10 08:54
Another option for code using Python <3.11, that will work without the `from __future__ import annotations` import, is to do something like this:

```
from graphlib import TopologicalSorter
x: 'TopologicalSorter[str]' = TopologicalSorter({"a": {}, "b": {"a"}})
```

By using a string as the annotation, we give mypy the specificity it needs, but the expression will never need to be resolved at runtime.
msg408211 - (view) Author: Jacob Hayes (JacobHayes) * Date: 2021-12-10 14:59
Thanks for the tips! I've been using this patch in my own code in a early imported `__init__.py`:

```
from graphlib import TopologicalSorter
from types import GenericAlias

if not hasattr(TopologicalSorter, "__class_getitem__"):  # pragma: no cover
    TopologicalSorter.__class_getitem__ = classmethod(GenericAlias)  # type: ignore
```

Certainly a bit hacky, but aside from no-op on >=3.11 and satisfying mypy, it supports runtime type inspection via `get_type_hints` before 3.11 (which otherwise still errors for stringized versions). The stringized versions are probably a bit simpler/safer for most folks though :)
History
Date User Action Args
2022-04-11 14:59:50adminsetgithub: 89522
2021-12-10 14:59:57JacobHayessetmessages: + msg408211
2021-12-10 08:54:02AlexWaygoodsettype: behavior -> enhancement

messages: + msg408177
nosy: + AlexWaygood
2021-12-09 13:14:49asvetlovsetmessages: + msg408117
2021-12-09 11:53:54JacobHayessetmessages: + msg408110
2021-12-09 11:36:14asvetlovsetstatus: open -> closed
versions: - Python 3.9, Python 3.10
messages: + msg408109

resolution: fixed
stage: patch review -> resolved
2021-12-08 18:53:08asvetlovsetnosy: + asvetlov
messages: + msg408041
2021-11-01 22:28:28AlexWaygoodsetversions: + Python 3.10, Python 3.11
2021-10-03 22:22:31JacobHayessetkeywords: + patch
stage: patch review
pull_requests: + pull_request27064
2021-10-03 22:18:50JacobHayescreate