summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2023-01-30 15:12:52 -0500
committermike bayer <mike_mp@zzzcomputing.com>2023-01-31 19:13:16 +0000
commita21c715b7a89b0619db0d2d5b31617d17b25a27a (patch)
tree01971eece9c687570137dd6e5d8e86b6040b697c /lib/sqlalchemy/sql
parent6d6a17240815b9090a2972607657f93d347167d6 (diff)
downloadsqlalchemy-a21c715b7a89b0619db0d2d5b31617d17b25a27a.tar.gz
support NewType in type_annotation_map
Added support for :pep:`484` ``NewType`` to be used in the :paramref:`_orm.registry.type_annotation_map` as well as within :class:`.Mapped` constructs. These types will behave in the same way as custom subclasses of types right now; they must appear explicitly within the :paramref:`_orm.registry.type_annotation_map` to be mapped. Within this change, the lookup between decl_api._resolve_type and TypeEngine._resolve_for_python_type is streamlined to not inspect the given type multiple times, instead passing in from decl_api to TypeEngine the already "flattened" version of a Generic or NewType type. Fixes: #9175 Change-Id: I227cf84b4b88e4567fa2d1d7da0c05b54e00c562
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/sqltypes.py8
-rw-r--r--lib/sqlalchemy/sql/type_api.py11
2 files changed, 11 insertions, 8 deletions
diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py
index b5c79b4b9..717e6c0b2 100644
--- a/lib/sqlalchemy/sql/sqltypes.py
+++ b/lib/sqlalchemy/sql/sqltypes.py
@@ -59,7 +59,6 @@ from .. import util
from ..engine import processors
from ..util import langhelpers
from ..util import OrderedDict
-from ..util.typing import GenericProtocol
from ..util.typing import Literal
if TYPE_CHECKING:
@@ -69,6 +68,7 @@ if TYPE_CHECKING:
from .schema import MetaData
from .type_api import _BindProcessorType
from .type_api import _ComparatorFactory
+ from .type_api import _MatchedOnType
from .type_api import _ResultProcessorType
from ..engine.interfaces import Dialect
@@ -1493,14 +1493,16 @@ class Enum(String, SchemaType, Emulated, TypeEngine[Union[str, enum.Enum]]):
return enums, enums
def _resolve_for_literal(self, value: Any) -> Enum:
- typ = self._resolve_for_python_type(type(value), type(value))
+ tv = type(value)
+ typ = self._resolve_for_python_type(tv, tv, tv)
assert typ is not None
return typ
def _resolve_for_python_type(
self,
python_type: Type[Any],
- matched_on: Union[GenericProtocol[Any], Type[Any]],
+ matched_on: _MatchedOnType,
+ matched_on_flattened: Type[Any],
) -> Optional[Enum]:
if not issubclass(python_type, enum.Enum):
return None
diff --git a/lib/sqlalchemy/sql/type_api.py b/lib/sqlalchemy/sql/type_api.py
index 79c889763..fefbf4997 100644
--- a/lib/sqlalchemy/sql/type_api.py
+++ b/lib/sqlalchemy/sql/type_api.py
@@ -19,6 +19,7 @@ from typing import cast
from typing import Dict
from typing import Generic
from typing import Mapping
+from typing import NewType
from typing import Optional
from typing import overload
from typing import Sequence
@@ -35,7 +36,6 @@ from .operators import ColumnOperators
from .visitors import Visitable
from .. import exc
from .. import util
-from ..util.typing import flatten_generic
from ..util.typing import Protocol
from ..util.typing import TypedDict
from ..util.typing import TypeGuard
@@ -65,6 +65,8 @@ _O = TypeVar("_O", bound=object)
_TE = TypeVar("_TE", bound="TypeEngine[Any]")
_CT = TypeVar("_CT", bound=Any)
+_MatchedOnType = Union["GenericProtocol[Any]", NewType, Type[Any]]
+
# replace with pep-673 when applicable
SelfTypeEngine = typing.TypeVar("SelfTypeEngine", bound="TypeEngine[Any]")
@@ -731,7 +733,8 @@ class TypeEngine(Visitable, Generic[_T]):
def _resolve_for_python_type(
self: SelfTypeEngine,
python_type: Type[Any],
- matched_on: Union[GenericProtocol[Any], Type[Any]],
+ matched_on: _MatchedOnType,
+ matched_on_flattened: Type[Any],
) -> Optional[SelfTypeEngine]:
"""given a Python type (e.g. ``int``, ``str``, etc. ) return an
instance of this :class:`.TypeEngine` that's appropriate for this type.
@@ -772,9 +775,7 @@ class TypeEngine(Visitable, Generic[_T]):
"""
- matched_on = flatten_generic(matched_on)
-
- if python_type is not matched_on:
+ if python_type is not matched_on_flattened:
return None
return self