Skip to content

Commit

Permalink
Fix issue with recursion error caused by ParamSpec (#6923)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmontagu committed Jul 28, 2023
1 parent 4de8fa4 commit 991bfe4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
2 changes: 1 addition & 1 deletion pydantic/_internal/_generics.py
Expand Up @@ -359,7 +359,7 @@ def has_instance_in_type(type_: Any, isinstance_target: Any) -> bool:

# Handle special case for typehints that can have lists as arguments.
# `typing.Callable[[int, str], int]` is an example for this.
if isinstance(type_, (List, list)):
if isinstance(type_, (List, list)) and not isinstance(type_, typing_extensions.ParamSpec):
if any(has_instance_in_type(element, isinstance_target) for element in type_):
return True

Expand Down
19 changes: 18 additions & 1 deletion tests/test_generics.py
Expand Up @@ -32,7 +32,7 @@
import pytest
from dirty_equals import HasRepr, IsStr
from pydantic_core import CoreSchema, core_schema
from typing_extensions import Annotated, Literal, OrderedDict, TypeVarTuple, Unpack, get_args
from typing_extensions import Annotated, Literal, OrderedDict, ParamSpec, TypeVarTuple, Unpack, get_args

from pydantic import (
BaseModel,
Expand Down Expand Up @@ -2534,3 +2534,20 @@ class Container(BaseModel, Generic[T]):

assert Container[type(None)](value=None).value is None
assert Container[None](value=None).value is None


@pytest.mark.skipif(platform.python_implementation() == 'PyPy', reason='PyPy does not allow ParamSpec in generics')
def test_paramspec_is_usable():
# This used to cause a recursion error due to `P in P is True`
# This test doesn't actually test that ParamSpec works properly for validation or anything.

P = ParamSpec('P')

class MyGenericParamSpecClass(Generic[P]):
def __init__(self, func: Callable[P, None], *args: P.args, **kwargs: P.kwargs) -> None:
super().__init__()

class ParamSpecGenericModel(BaseModel, Generic[P]):
my_generic: MyGenericParamSpecClass[P]

model_config = dict(arbitrary_types_allowed=True)

0 comments on commit 991bfe4

Please sign in to comment.