Skip to content

Use type for deprecated aliases of typing instead of removing them #106745

Closed
@nineteendo

Description

@nineteendo

Enhancement

This module (typing) defines several deprecated aliases to pre-existing standard library classes. ...
the aliases became redundant in Python 3.9 when the corresponding pre-existing classes were enhanced to support []. ...
The redundant types are deprecated as of Python 3.9 ...
(&) will be removed from the typing module no sooner than the first Python version released 5 years after the release of Python 3.9.0.
-- The typing documentation

Instead of removing these aliases, it would be more appropriate to redefine them using the type keyword added in 3.12 which shouldn't cause unnecessary overhead:

type Dict = dict
type List = list
...

And make type checkers warn users of the compatibility aliases that they are only to be used when aiming for backwards compatibility with Python version 3.5.4 - 3.8.

Pitch

These aliases were the only way to parameterise built-in classes in Python version 3.5.4 - 3.8. Completely removing them would suddenly break backwards compatibility with these versions for no good reason. This is especially relevant to third party modules that backport features from newer Python versions and pure python modules trying to support as many Python versions as possible.

A work-around would be to define a compatibility module, but that isn't a great solution as it adds unnecessary extra code & still requires modifying the code which could be cumbersome for large projects:

"""Typing compatibility module"""
from sys import version_info

__all__: list[str] = ['Dict', 'List', ...]

if version_info >= (3, 9):
   # TypeAlias & type can't even be used here because it they weren't available in 3.9 making this a suboptimal solution
   Dict = dict
   List = list
   ...
else:
   from typing import Dict, List, ...
   

What happens otherwise?

  1. IDE's could give incorrect suggestions
  2. Many older online tutorials become irrelevant.
  3. Abandoned projects would become unusable

Examples:

  • Python 3.5.4 - 3.8:
     from typing import List
     
     lst1: List[int] = [3, 1, 4, 1, 5, ...]
     lst2: list[int] = [3, 1, 4, 1, 5, ...] # TypeError: 'type' object is not subscriptable
  • Python 3.9 - 3.X:
     from typing import List
     
     lst1: List[int] = [3, 1, 4, 1, 5, ...]
     lst2: list[int] = [3, 1, 4, 1, 5, ...]
  • Python 3.Y - ∞:
     lst1: list[int] = [3, 1, 4, 1, 5, ...]
     
     from typing import List # ImportError: cannot import name 'List' from 'typing'
     
     lst2: List[int] = [3, 1, 4, 1, 5, ...]

No notation would be compatible with both 3.5.4 - 3.X & 3.Y - ∞

It's worth pointing out these aliases have been deprecated for quite some time. But as long as no irreversible decisions are made this remains open to discussion.

Previous discussion

Not applicable, this is an enhancement.

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions