summaryrefslogtreecommitdiff
path: root/astroid
diff options
context:
space:
mode:
authorDavid Liu <david@cs.toronto.edu>2021-09-16 22:06:19 -0400
committerPierre Sassoulas <pierre.sassoulas@gmail.com>2021-09-17 15:07:19 +0200
commit28411ee8575562b7d7d1d0639d4e61f91ed1586b (patch)
treee878313fc11b309aff968fed259496b8f03ab373 /astroid
parente31db65d4013bab30e8c815638fbaa32575ce8a2 (diff)
downloadastroid-git-28411ee8575562b7d7d1d0639d4e61f91ed1586b.tar.gz
Support dataclass inference for pydantic.dataclasses.
Diffstat (limited to 'astroid')
-rw-r--r--astroid/brain/brain_dataclasses.py13
1 files changed, 6 insertions, 7 deletions
diff --git a/astroid/brain/brain_dataclasses.py b/astroid/brain/brain_dataclasses.py
index b85d13fd..96c38b84 100644
--- a/astroid/brain/brain_dataclasses.py
+++ b/astroid/brain/brain_dataclasses.py
@@ -7,7 +7,7 @@ Support both built-in dataclasses and pydantic.dataclasses. References:
- https://docs.python.org/3/library/dataclasses.html
- https://pydantic-docs.helpmanual.io/usage/dataclasses/
"""
-from typing import Generator, List, Optional, Tuple
+from typing import FrozenSet, Generator, List, Optional, Tuple
from astroid import context, inference_tip
from astroid.builder import parse
@@ -35,7 +35,7 @@ from astroid.util import Uninferable
DATACLASSES_DECORATORS = frozenset(("dataclass",))
FIELD_NAME = "field"
-DATACLASS_MODULE = "dataclasses"
+DATACLASS_MODULES = frozenset(("dataclasses", "pydantic.dataclasses"))
DEFAULT_FACTORY = "_HAS_DEFAULT_FACTORY" # based on typing.py
@@ -255,13 +255,12 @@ def infer_dataclass_field_call(
def _looks_like_dataclass_decorator(
- node: NodeNG, decorator_names: List[str] = DATACLASSES_DECORATORS
+ node: NodeNG, decorator_names: FrozenSet[str] = DATACLASSES_DECORATORS
) -> bool:
"""Return True if node looks like a dataclass decorator.
Uses inference to lookup the value of the node, and if that fails,
- matches against specific names. (Currently inference fails for dataclass import
- from pydantic.)
+ matches against specific names.
"""
if isinstance(node, Call): # decorator with arguments
node = node.func
@@ -281,7 +280,7 @@ def _looks_like_dataclass_decorator(
return (
isinstance(inferred, FunctionDef)
and inferred.name in decorator_names
- and inferred.root().name == DATACLASS_MODULE
+ and inferred.root().name in DATACLASS_MODULES
)
@@ -322,7 +321,7 @@ def _looks_like_dataclass_field_call(node: Call, check_scope: bool = True) -> bo
if not isinstance(inferred, FunctionDef):
return False
- return inferred.name == FIELD_NAME and inferred.root().name == DATACLASS_MODULE
+ return inferred.name == FIELD_NAME and inferred.root().name in DATACLASS_MODULES
def _get_field_default(field_call: Call) -> Tuple[str, Optional[NodeNG]]: