Possible to use TypedDict for **kwargs (PEP 692) for python versions < 3.12?

I’m curious if there is any way to use PEP 692 in a python versions < 3.12, e.g. 3.8+.? Obviously this feature was released in 3.12, but I know sometimes new features are made accessible in older versions of python using __future__ or something. I’ve never really understood how this works (which is why I’m asking here), but I’m curious if anything like that is available in this case.

You might want to take a look at https://github.com/python/typing_extensions

When you use def foo(**kwargs: Unpack[Movie]): ..., there is no new syntax that depends on Python 3.12+, and I believe there is no new runtime behavior that depends on Python 3.12+. This means that in order to write this kind of code, you just need to import Unpack from typing_extensions, and use it.

The problem is that, even though you can write this code, you will only get the type-checking benefits it provides if your type checker supports it. For example, according to Enable PEP 692 Support · Issue #14697 · python/mypy (github.com), looks like mypy still hasn’t implemented support for Unpack in this context.

(I wrote this assuming you understand that type hints have little to no runtime behavior, and you need to run a type checker on your code to reap the benefits of static typing. If this is not the case, please say so!)

1 Like

Thanks both, that’s exactly the type of thing I was wondering about. I use PyCharm as my IDE and whatever type checker comes with that. I can check if PyCharm’s type checker support it.

Do type checkers typically give different behaviors depending on whatever python version is in the development environment?

Here is the issue tracker to include typed dict unpacking for Pycharm: https://youtrack.jetbrains.com/issue/PY-55044.

They do acknowledge the Python version:

  • in checks like if sys.version_info >= (3,9): ...; else: ..., they know which branch of the if-else will be executed, and they will mark the other branch as unreachable.
  • they need to understand the language grammar (i.e. type checkers will usually hard-fail if you use syntax that’s not supported by your Python version)
  • they need to know what stdlib features are available, what are the exact typing signatures of the functions, etc (e.g. type checkers will not let you use the zip(strict=True) in Python 3.9)

None of these items mean that you can’t import Unpack from typing_extensions and then use it, even though this use of Unpack has only been standardized recently, and is only present in the stdlib typing since Python 3.11.

@fonini so does PEP 692 actually change anything about Python itself? Or is PEP 692 just a statement to type checkers that they should start interpreting Unpack in type annotations in a certain way?

As far as I understand, yes, PEP 692 doesn’t change much about “Python itself”. Now I’m not sure if there is a reasonable definition of what is “Python itself”, but you may say that PEP 692 doesn’t change much about the CPython interpreter and standard library. Except, of course, for the fact that PEP 692 adds an Unpack object to the typing module, which can be imported, subscripted, and placed in annotations. The main point of PEP 692 is to standardize, as you said, how type checkers should start interpreting this use of the Unpack.

This is usually true of all typing PEPs (at least of those that don’t introduce new syntax to the language) – they usually don’t change runtime semantics of anything, and just standardize the meanings (at type-checking time) of the symbols imported from typing.

1 Like

@fonini thank you, this has helped my understanding of how typing features generally work in python and given me hope that I’ll be able to use this new feature in my library while still supporting older python versions!

1 Like