pydantic: Cannot use Literal when I use typing-extension==4.6.0
Initial Checks
- I have searched GitHub for a duplicate issue and I’m sure this is something new
- I have searched Google & StackOverflow for a solution and couldn’t find anything
- I have read and followed the docs and still think this is a bug
- I am confident that the issue is with pydantic (not my code, or another library in the ecosystem like FastAPI or mypy)
Description
I update my typing extention 4.6.0, I face this error
.venv/lib/python3.9/site-packages/ddtrace/internal/module.py:216: in _exec_module
self.loader.exec_module(module)
src/entry.py:3: in <module>
from apis import router as api_router
.venv/lib/python3.9/site-packages/ddtrace/internal/module.py:216: in _exec_module
self.loader.exec_module(module)
src/apis/__init__.py:5: in <module>
from .recsys import router as recsys_router
.venv/lib/python3.9/site-packages/ddtrace/internal/module.py:216: in _exec_module
self.loader.exec_module(module)
src/apis/recsys/__init__.py:3: in <module>
from .course.endpoints import router as course_router
.venv/lib/python3.9/site-packages/ddtrace/internal/module.py:216: in _exec_module
self.loader.exec_module(module)
src/apis/recsys/course/__init__.py:1: in <module>
from . import cell
.venv/lib/python3.9/site-packages/ddtrace/internal/module.py:216: in _exec_module
self.loader.exec_module(module)
src/apis/recsys/course/cell/__init__.py:1: in <module>
from . import container
.venv/lib/python3.9/site-packages/ddtrace/internal/module.py:216: in _exec_module
self.loader.exec_module(module)
src/apis/recsys/course/cell/container.py:4: in <module>
from core.models.feature_store.cell_dtos import CourseCellDTO
.venv/lib/python3.9/site-packages/ddtrace/internal/module.py:216: in _exec_module
self.loader.exec_module(module)
src/core/models/feature_store/cell_dtos.py:14: in <module>
class VocaCellDTO(BaseModel):
pydantic/main.py:197: in pydantic.main.ModelMetaclass.__new__
???
pydantic/fields.py:506: in pydantic.fields.ModelField.infer
???
pydantic/fields.py:436: in pydantic.fields.ModelField.__init__
???
pydantic/fields.py:552: in pydantic.fields.ModelField.prepare
???
pydantic/fields.py:668: in pydantic.fields.ModelField._type_analysis
???
Example Code
from enum import Enum
from typing import Literal
from pydantic import BaseModel
class MyEum(str, Enum):
T1 = "T1"
T2 = "T2"
class MyType(BaseModel):
type: Literal[MyEum.T1] = MyEum.T1
dalc: str
then I meet
Traceback (most recent call last):
File "/Users/project/test.py", line 12, in <module>
class MyType(BaseModel):
File "pydantic/main.py", line 197, in pydantic.main.ModelMetaclass.__new__
File "pydantic/fields.py", line 506, in pydantic.fields.ModelField.infer
File "pydantic/fields.py", line 436, in pydantic.fields.ModelField.__init__
File "pydantic/fields.py", line 552, in pydantic.fields.ModelField.prepare
File "pydantic/fields.py", line 668, in pydantic.fields.ModelField._type_analysis
File "/Users/project/lib/python3.9/typing.py", line 852, in __subclasscheck__
return issubclass(cls, self.__origin__)
TypeError: issubclass() arg 1 must be a class
Python, Pydantic & OS Version
pydantic version: 1.10.7
pydantic compiled: True
python version: 3.9.13 (main, Aug 25 2022, 18:24:45) [Clang 12.0.0 ]
platform: macOS-12.6.1-arm64-arm-64bit
optional deps. installed: ['dotenv', 'typing-extensions']
Affected Components
- Compatibility between releases
- Data validation/parsing
- Data serialization -
.dict()and.json() - JSON Schema
- Dataclasses
- Model Config
- Field Types - adding or changing a particular data type
- Function validation decorator
- Generic Models
- Other Model behaviour -
construct(), pickling, private attributes, ORM mode - Plugins and integration with other tools - mypy, FastAPI, python-devtools, Hypothesis, VS Code, PyCharm, etc.
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 36
- Comments: 17 (9 by maintainers)
Commits related to this issue
- Pin typing_extensions < 4.6.0 The latest release of typing_extensions breaks great expectations. Great expectations is already pinned but hasn't release a new version yet: https://github.com/great-... — committed to dagster-io/dagster by jmsanders a year ago
- Pin typing_extensions < 4.6.0 (#14407) The latest release of typing_extensions breaks great expectations. Great expectations is already pinned but hasn't release a new version yet: https://g... — committed to dagster-io/dagster by jmsanders a year ago
- repo: fix bad typing_extensions interaction Ref: https://github.com/pydantic/pydantic/issues/5821#issuecomment-1559196859 We could also pin typing_extensions to 4.5.0 instead, but those pins have a t... — committed to tigarmo/craft-archives by tigarmo a year ago
- repo: fix bad typing_extensions interaction Ref: https://github.com/pydantic/pydantic/issues/5821#issuecomment-1559196859 We could also pin typing_extensions to 4.5.0 instead, but those pins have a ... — committed to tigarmo/craft-archives by tigarmo a year ago
- Applied typing workaround according to https://github.com/pydantic/pydantic/issues/5821#issuecomment-1558520974 — committed to SamhammerAG/sag_py_fastapi_health by devRoemer a year ago
- repo: fix bad typing_extensions interaction (#78) Ref: https://github.com/pydantic/pydantic/issues/5821#issuecomment-1559196859 We could also pin typing_extensions to 4.5.0 instead, but those pins... — committed to canonical/craft-archives by tigarmo a year ago
- deps: floor pydantic Avoid https://github.com/pydantic/pydantic/issues/5821 — committed to stac-utils/stac-fastapi-pgstac by gadomski a year ago
- NOJIRA: Pin typing extensions to 4.5.0 to workaround bug in pydantic See https://github.com/pydantic/pydantic/issues/5821 for more info. We can remove this when we get a new version of pydantic. — committed to javihernandez/albs-web-server by javihernandez a year ago
- deps: floor pydantic Avoid https://github.com/pydantic/pydantic/issues/5821 — committed to stac-utils/stac-fastapi-pgstac by gadomski a year ago
- Unpin typing_extensions due to pydantic issue The issue https://github.com/pydantic/pydantic/issues/5821 has been closed. This should make pydantic compatible with typing_extensions again. — committed to pinkwah/ert by pinkwah a year ago
- Unpin typing_extensions due to pydantic issue The issue https://github.com/pydantic/pydantic/issues/5821 has been closed. This should make pydantic compatible with typing_extensions again. — committed to equinor/ert by pinkwah a year ago
- Pin typing_extensions < 4.6.0 (#14407) The latest release of typing_extensions breaks great expectations. Great expectations is already pinned but hasn't release a new version yet: https://g... — committed to dagster-io/dagster by jmsanders a year ago
- Resolves issue related to use of Literal (#303) Quick fix to address an error encountered when launching the REST API (related to use of `Literal` with pydantic/fastapi). Relates to https://github.... — committed to ml4ai/skema by myedibleenso a year ago
- Resolves issue related to use of Literal (#303) Quick fix to address an error encountered when launching the REST API (related to use of `Literal` with pydantic/fastapi). Relates to https://github.co... — committed to ml4ai/skema by github-actions[bot] a year ago
List of workarounds:
typing_extensions==4.5.0typing.Literalto refer totyping_extensions.Literal. (Full patch example below.) You only need to do this in the initial module.from typing import Literalwithfrom typing_extensions import Literal.The patch of workaround 3:
Hey all, we’ve just released v1.10.8 to address this. It’s going through CI now and should hopefully be available through PyPI shortly. Please let us know if you run into other issues (with
typing_extensionsor otherwise) and we will address them as promptly as we can.Released.
I’m getting this too. Even on pydantic v2.
As a workaround:
from typing import Literaltofrom typing_extensions import LiteralThe docs for pydantic do say:
But I find that documentation ambiguous. It sounds like the requirement is that typing_extensions merely be installed, and then pydantic will choose it if required. But that doesn’t seem to be the case.
So I think we need clearer documentation.
I think the source of the bug is this line:
https://github.com/pydantic/pydantic/blob/bf6b884563e7c635b9d811e97d2fdb51805398b1/pydantic/typing.py#LL412C57-L412C64
So I think this is a bug in pydantic.
is_literal_typeis comparing only totyping_extensions.Literal, nottyping.Literal.I think a patch looks something like:
Minimal steps to reproduce the issue (typing_extensions==4.6.0, pydantic==1.10.7, Python 3.8.10):
raises:
TypeError: issubclass() arg 1 must be a classCan confirm, the bug appears to occur with
typing-extension==4.6.0.Just as a suggestion for Pydantic, I would recommend to replace any code like
is typing.Xwith something that checks for bothtypingandtyping_extensions. In pyanalyze I have a helper for that: https://github.com/quora/pyanalyze/blob/master/pyanalyze/safe.py#L148 (used e.g. at https://github.com/quora/pyanalyze/blob/27fbd1831c908477baf4f9988f23a8278ce5f64e/pyanalyze/annotations.py#L783). This would be safer against future typing-extensions changes that might bring additional backports.Thanks for reporting, @hramezani will take a look 🙏.
@jnawk @Czaki the reason that 1.10.3 was yanked was because 1.10.4 updated the minimum-allowed-version of typing_extensions. As a result, it was incompatible to use pydantic 1.10.4 with other libraries that had pinned the version of typing_extensions below 4.2.0.
However, the release of pydantic 1.10.8 did not set any new minimum dependency versions (it just fixed the bug). So unless I’m missing something, I don’t think the same reasons for yanking the 1.10.3 pydantic version apply here.
This has also been reported over at typing_extensions FYI: https://github.com/python/typing_extensions/issues/179.
If this analysis is correct (and I haven’t checked, but it looks very plausible), you’d probably want to do something like this, in order to retain compatibility with Python 3.7 (where
typing.Literalisn’t a thing yet):(Not sure under what conditions
Literalcan beNonebtw? Seems like a slight oddity in the code as it’s currently written 😃