1# sql/types_api.py
2# Copyright (C) 2005-2019 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4#
5# This module is part of SQLAlchemy and is released under
6# the MIT License: http://www.opensource.org/licenses/mit-license.php
7
8"""Base types API.
9
10"""
11
12
13from . import operators
14from .base import SchemaEventTarget
15from .visitors import Visitable
16from .visitors import VisitableType
17from .. import exc
18from .. import util
19
20# these are back-assigned by sqltypes.
21BOOLEANTYPE = None
22INTEGERTYPE = None
23NULLTYPE = None
24STRINGTYPE = None
25MATCHTYPE = None
26INDEXABLE = None
27_resolve_value_to_type = None
28
29
30class TypeEngine(Visitable):
31    """The ultimate base class for all SQL datatypes.
32
33    Common subclasses of :class:`.TypeEngine` include
34    :class:`.String`, :class:`.Integer`, and :class:`.Boolean`.
35
36    For an overview of the SQLAlchemy typing system, see
37    :ref:`types_toplevel`.
38
39    .. seealso::
40
41        :ref:`types_toplevel`
42
43    """
44
45    _sqla_type = True
46    _isnull = False
47
48    class Comparator(operators.ColumnOperators):
49        """Base class for custom comparison operations defined at the
50        type level.  See :attr:`.TypeEngine.comparator_factory`.
51
52
53        """
54
55        __slots__ = "expr", "type"
56
57        default_comparator = None
58
59        def __init__(self, expr):
60            self.expr = expr
61            self.type = expr.type
62
63        @util.dependencies("sqlalchemy.sql.default_comparator")
64        def operate(self, default_comparator, op, *other, **kwargs):
65            o = default_comparator.operator_lookup[op.__name__]
66            return o[0](self.expr, op, *(other + o[1:]), **kwargs)
67
68        @util.dependencies("sqlalchemy.sql.default_comparator")
69        def reverse_operate(self, default_comparator, op, other, **kwargs):
70            o = default_comparator.operator_lookup[op.__name__]
71            return o[0](self.expr, op, other, reverse=True, *o[1:], **kwargs)
72
73        def _adapt_expression(self, op, other_comparator):
74            """evaluate the return type of <self> <op> <othertype>,
75            and apply any adaptations to the given operator.
76
77            This method determines the type of a resulting binary expression
78            given two source types and an operator.   For example, two
79            :class:`.Column` objects, both of the type :class:`.Integer`, will
80            produce a :class:`.BinaryExpression` that also has the type
81            :class:`.Integer` when compared via the addition (``+``) operator.
82            However, using the addition operator with an :class:`.Integer`
83            and a :class:`.Date` object will produce a :class:`.Date`, assuming
84            "days delta" behavior by the database (in reality, most databases
85            other than PostgreSQL don't accept this particular operation).
86
87            The method returns a tuple of the form <operator>, <type>.
88            The resulting operator and type will be those applied to the
89            resulting :class:`.BinaryExpression` as the final operator and the
90            right-hand side of the expression.
91
92            Note that only a subset of operators make usage of
93            :meth:`._adapt_expression`,
94            including math operators and user-defined operators, but not
95            boolean comparison or special SQL keywords like MATCH or BETWEEN.
96
97            """
98
99            return op, self.type
100
101        def __reduce__(self):
102            return _reconstitute_comparator, (self.expr,)
103
104    hashable = True
105    """Flag, if False, means values from this type aren't hashable.
106
107    Used by the ORM when uniquing result lists.
108
109    """
110
111    comparator_factory = Comparator
112    """A :class:`.TypeEngine.Comparator` class which will apply
113    to operations performed by owning :class:`.ColumnElement` objects.
114
115    The :attr:`.comparator_factory` attribute is a hook consulted by
116    the core expression system when column and SQL expression operations
117    are performed.   When a :class:`.TypeEngine.Comparator` class is
118    associated with this attribute, it allows custom re-definition of
119    all existing operators, as well as definition of new operators.
120    Existing operators include those provided by Python operator overloading
121    such as :meth:`.operators.ColumnOperators.__add__` and
122    :meth:`.operators.ColumnOperators.__eq__`,
123    those provided as standard
124    attributes of :class:`.operators.ColumnOperators` such as
125    :meth:`.operators.ColumnOperators.like`
126    and :meth:`.operators.ColumnOperators.in_`.
127
128    Rudimentary usage of this hook is allowed through simple subclassing
129    of existing types, or alternatively by using :class:`.TypeDecorator`.
130    See the documentation section :ref:`types_operators` for examples.
131
132    """
133
134    should_evaluate_none = False
135    """If True, the Python constant ``None`` is considered to be handled
136    explicitly by this type.
137
138    The ORM uses this flag to indicate that a positive value of ``None``
139    is passed to the column in an INSERT statement, rather than omitting
140    the column from the INSERT statement which has the effect of firing
141    off column-level defaults.   It also allows types which have special
142    behavior for Python None, such as a JSON type, to indicate that
143    they'd like to handle the None value explicitly.
144
145    To set this flag on an existing type, use the
146    :meth:`.TypeEngine.evaluates_none` method.
147
148    .. seealso::
149
150        :meth:`.TypeEngine.evaluates_none`
151
152    .. versionadded:: 1.1
153
154
155    """
156
157    def evaluates_none(self):
158        """Return a copy of this type which has the :attr:`.should_evaluate_none`
159        flag set to True.
160
161        E.g.::
162
163                Table(
164                    'some_table', metadata,
165                    Column(
166                        String(50).evaluates_none(),
167                        nullable=True,
168                        server_default='no value')
169                )
170
171        The ORM uses this flag to indicate that a positive value of ``None``
172        is passed to the column in an INSERT statement, rather than omitting
173        the column from the INSERT statement which has the effect of firing
174        off column-level defaults.   It also allows for types which have
175        special behavior associated with the Python None value to indicate
176        that the value doesn't necessarily translate into SQL NULL; a
177        prime example of this is a JSON type which may wish to persist the
178        JSON value ``'null'``.
179
180        In all cases, the actual NULL SQL value can be always be
181        persisted in any column by using
182        the :obj:`~.expression.null` SQL construct in an INSERT statement
183        or associated with an ORM-mapped attribute.
184
185        .. note::
186
187            The "evaluates none" flag does **not** apply to a value
188            of ``None`` passed to :paramref:`.Column.default` or
189            :paramref:`.Column.server_default`; in these cases, ``None``
190            still means "no default".
191
192        .. versionadded:: 1.1
193
194        .. seealso::
195
196            :ref:`session_forcing_null` - in the ORM documentation
197
198            :paramref:`.postgresql.JSON.none_as_null` - PostgreSQL JSON
199            interaction with this flag.
200
201            :attr:`.TypeEngine.should_evaluate_none` - class-level flag
202
203        """
204        typ = self.copy()
205        typ.should_evaluate_none = True
206        return typ
207
208    def copy(self, **kw):
209        return self.adapt(self.__class__)
210
211    def compare_against_backend(self, dialect, conn_type):
212        """Compare this type against the given backend type.
213
214        This function is currently not implemented for SQLAlchemy
215        types, and for all built in types will return ``None``.  However,
216        it can be implemented by a user-defined type
217        where it can be consumed by schema comparison tools such as
218        Alembic autogenerate.
219
220        A future release of SQLAlchemy will potentially implement this method
221        for builtin types as well.
222
223        The function should return True if this type is equivalent to the
224        given type; the type is typically reflected from the database
225        so should be database specific.  The dialect in use is also
226        passed.   It can also return False to assert that the type is
227        not equivalent.
228
229        :param dialect: a :class:`.Dialect` that is involved in the comparison.
230
231        :param conn_type: the type object reflected from the backend.
232
233        .. versionadded:: 1.0.3
234
235        """
236        return None
237
238    def copy_value(self, value):
239        return value
240
241    def literal_processor(self, dialect):
242        """Return a conversion function for processing literal values that are
243        to be rendered directly without using binds.
244
245        This function is used when the compiler makes use of the
246        "literal_binds" flag, typically used in DDL generation as well
247        as in certain scenarios where backends don't accept bound parameters.
248
249        .. versionadded:: 0.9.0
250
251        """
252        return None
253
254    def bind_processor(self, dialect):
255        """Return a conversion function for processing bind values.
256
257        Returns a callable which will receive a bind parameter value
258        as the sole positional argument and will return a value to
259        send to the DB-API.
260
261        If processing is not necessary, the method should return ``None``.
262
263        :param dialect: Dialect instance in use.
264
265        """
266        return None
267
268    def result_processor(self, dialect, coltype):
269        """Return a conversion function for processing result row values.
270
271        Returns a callable which will receive a result row column
272        value as the sole positional argument and will return a value
273        to return to the user.
274
275        If processing is not necessary, the method should return ``None``.
276
277        :param dialect: Dialect instance in use.
278
279        :param coltype: DBAPI coltype argument received in cursor.description.
280
281        """
282        return None
283
284    def column_expression(self, colexpr):
285        """Given a SELECT column expression, return a wrapping SQL expression.
286
287        This is typically a SQL function that wraps a column expression
288        as rendered in the columns clause of a SELECT statement.
289        It is used for special data types that require
290        columns to be wrapped in some special database function in order
291        to coerce the value before being sent back to the application.
292        It is the SQL analogue of the :meth:`.TypeEngine.result_processor`
293        method.
294
295        The method is evaluated at statement compile time, as opposed
296        to statement construction time.
297
298        .. seealso::
299
300            :ref:`types_sql_value_processing`
301
302        """
303
304        return None
305
306    @util.memoized_property
307    def _has_column_expression(self):
308        """memoized boolean, check if column_expression is implemented.
309
310        Allows the method to be skipped for the vast majority of expression
311        types that don't use this feature.
312
313        """
314
315        return (
316            self.__class__.column_expression.__code__
317            is not TypeEngine.column_expression.__code__
318        )
319
320    def bind_expression(self, bindvalue):
321        """"Given a bind value (i.e. a :class:`.BindParameter` instance),
322        return a SQL expression in its place.
323
324        This is typically a SQL function that wraps the existing bound
325        parameter within the statement.  It is used for special data types
326        that require literals being wrapped in some special database function
327        in order to coerce an application-level value into a database-specific
328        format.  It is the SQL analogue of the
329        :meth:`.TypeEngine.bind_processor` method.
330
331        The method is evaluated at statement compile time, as opposed
332        to statement construction time.
333
334        Note that this method, when implemented, should always return
335        the exact same structure, without any conditional logic, as it
336        may be used in an executemany() call against an arbitrary number
337        of bound parameter sets.
338
339        .. seealso::
340
341            :ref:`types_sql_value_processing`
342
343        """
344        return None
345
346    @util.memoized_property
347    def _has_bind_expression(self):
348        """memoized boolean, check if bind_expression is implemented.
349
350        Allows the method to be skipped for the vast majority of expression
351        types that don't use this feature.
352
353        """
354
355        return (
356            self.__class__.bind_expression.__code__
357            is not TypeEngine.bind_expression.__code__
358        )
359
360    @staticmethod
361    def _to_instance(cls_or_self):
362        return to_instance(cls_or_self)
363
364    def compare_values(self, x, y):
365        """Compare two values for equality."""
366
367        return x == y
368
369    def get_dbapi_type(self, dbapi):
370        """Return the corresponding type object from the underlying DB-API, if
371        any.
372
373         This can be useful for calling ``setinputsizes()``, for example.
374
375        """
376        return None
377
378    @property
379    def python_type(self):
380        """Return the Python type object expected to be returned
381        by instances of this type, if known.
382
383        Basically, for those types which enforce a return type,
384        or are known across the board to do such for all common
385        DBAPIs (like ``int`` for example), will return that type.
386
387        If a return type is not defined, raises
388        ``NotImplementedError``.
389
390        Note that any type also accommodates NULL in SQL which
391        means you can also get back ``None`` from any type
392        in practice.
393
394        """
395        raise NotImplementedError()
396
397    def with_variant(self, type_, dialect_name):
398        r"""Produce a new type object that will utilize the given
399        type when applied to the dialect of the given name.
400
401        e.g.::
402
403            from sqlalchemy.types import String
404            from sqlalchemy.dialects import mysql
405
406            s = String()
407
408            s = s.with_variant(mysql.VARCHAR(collation='foo'), 'mysql')
409
410        The construction of :meth:`.TypeEngine.with_variant` is always
411        from the "fallback" type to that which is dialect specific.
412        The returned type is an instance of :class:`.Variant`, which
413        itself provides a :meth:`.Variant.with_variant`
414        that can be called repeatedly.
415
416        :param type\_: a :class:`.TypeEngine` that will be selected
417         as a variant from the originating type, when a dialect
418         of the given name is in use.
419        :param dialect_name: base name of the dialect which uses
420         this type. (i.e. ``'postgresql'``, ``'mysql'``, etc.)
421
422        """
423        return Variant(self, {dialect_name: to_instance(type_)})
424
425    @util.memoized_property
426    def _type_affinity(self):
427        """Return a rudimental 'affinity' value expressing the general class
428        of type."""
429
430        typ = None
431        for t in self.__class__.__mro__:
432            if t in (TypeEngine, UserDefinedType):
433                return typ
434            elif issubclass(t, (TypeEngine, UserDefinedType)):
435                typ = t
436        else:
437            return self.__class__
438
439    def dialect_impl(self, dialect):
440        """Return a dialect-specific implementation for this
441        :class:`.TypeEngine`.
442
443        """
444        try:
445            return dialect._type_memos[self]["impl"]
446        except KeyError:
447            return self._dialect_info(dialect)["impl"]
448
449    def _unwrapped_dialect_impl(self, dialect):
450        """Return the 'unwrapped' dialect impl for this type.
451
452        For a type that applies wrapping logic (e.g. TypeDecorator), give
453        us the real, actual dialect-level type that is used.
454
455        This is used for class-based lookups by dialects.
456
457        """
458        return self.dialect_impl(dialect)
459
460    def _cached_literal_processor(self, dialect):
461        """Return a dialect-specific literal processor for this type."""
462        try:
463            return dialect._type_memos[self]["literal"]
464        except KeyError:
465            d = self._dialect_info(dialect)
466            d["literal"] = lp = d["impl"].literal_processor(dialect)
467            return lp
468
469    def _cached_bind_processor(self, dialect):
470        """Return a dialect-specific bind processor for this type."""
471
472        try:
473            return dialect._type_memos[self]["bind"]
474        except KeyError:
475            d = self._dialect_info(dialect)
476            d["bind"] = bp = d["impl"].bind_processor(dialect)
477            return bp
478
479    def _cached_result_processor(self, dialect, coltype):
480        """Return a dialect-specific result processor for this type."""
481
482        try:
483            return dialect._type_memos[self][coltype]
484        except KeyError:
485            d = self._dialect_info(dialect)
486            # key assumption: DBAPI type codes are
487            # constants.  Else this dictionary would
488            # grow unbounded.
489            d[coltype] = rp = d["impl"].result_processor(dialect, coltype)
490            return rp
491
492    def _cached_custom_processor(self, dialect, key, fn):
493        try:
494            return dialect._type_memos[self][key]
495        except KeyError:
496            d = self._dialect_info(dialect)
497            impl = d["impl"]
498            d[key] = result = fn(impl)
499            return result
500
501    def _dialect_info(self, dialect):
502        """Return a dialect-specific registry which
503        caches a dialect-specific implementation, bind processing
504        function, and one or more result processing functions."""
505
506        if self in dialect._type_memos:
507            return dialect._type_memos[self]
508        else:
509            impl = self._gen_dialect_impl(dialect)
510            if impl is self:
511                impl = self.adapt(type(self))
512            # this can't be self, else we create a cycle
513            assert impl is not self
514            dialect._type_memos[self] = d = {"impl": impl}
515            return d
516
517    def _gen_dialect_impl(self, dialect):
518        return dialect.type_descriptor(self)
519
520    def adapt(self, cls, **kw):
521        """Produce an "adapted" form of this type, given an "impl" class
522        to work with.
523
524        This method is used internally to associate generic
525        types with "implementation" types that are specific to a particular
526        dialect.
527        """
528        return util.constructor_copy(self, cls, **kw)
529
530    def coerce_compared_value(self, op, value):
531        """Suggest a type for a 'coerced' Python value in an expression.
532
533        Given an operator and value, gives the type a chance
534        to return a type which the value should be coerced into.
535
536        The default behavior here is conservative; if the right-hand
537        side is already coerced into a SQL type based on its
538        Python type, it is usually left alone.
539
540        End-user functionality extension here should generally be via
541        :class:`.TypeDecorator`, which provides more liberal behavior in that
542        it defaults to coercing the other side of the expression into this
543        type, thus applying special Python conversions above and beyond those
544        needed by the DBAPI to both ides. It also provides the public method
545        :meth:`.TypeDecorator.coerce_compared_value` which is intended for
546        end-user customization of this behavior.
547
548        """
549        _coerced_type = _resolve_value_to_type(value)
550        if (
551            _coerced_type is NULLTYPE
552            or _coerced_type._type_affinity is self._type_affinity
553        ):
554            return self
555        else:
556            return _coerced_type
557
558    def _compare_type_affinity(self, other):
559        return self._type_affinity is other._type_affinity
560
561    def compile(self, dialect=None):
562        """Produce a string-compiled form of this :class:`.TypeEngine`.
563
564        When called with no arguments, uses a "default" dialect
565        to produce a string result.
566
567        :param dialect: a :class:`.Dialect` instance.
568
569        """
570        # arg, return value is inconsistent with
571        # ClauseElement.compile()....this is a mistake.
572
573        if not dialect:
574            dialect = self._default_dialect()
575
576        return dialect.type_compiler.process(self)
577
578    @util.dependencies("sqlalchemy.engine.default")
579    def _default_dialect(self, default):
580        if self.__class__.__module__.startswith("sqlalchemy.dialects"):
581            tokens = self.__class__.__module__.split(".")[0:3]
582            mod = ".".join(tokens)
583            return getattr(__import__(mod).dialects, tokens[-1]).dialect()
584        else:
585            return default.DefaultDialect()
586
587    def __str__(self):
588        if util.py2k:
589            return unicode(self.compile()).encode(  # noqa
590                "ascii", "backslashreplace"
591            )  # noqa
592        else:
593            return str(self.compile())
594
595    def __repr__(self):
596        return util.generic_repr(self)
597
598
599class VisitableCheckKWArg(util.EnsureKWArgType, VisitableType):
600    pass
601
602
603class UserDefinedType(util.with_metaclass(VisitableCheckKWArg, TypeEngine)):
604    """Base for user defined types.
605
606    This should be the base of new types.  Note that
607    for most cases, :class:`.TypeDecorator` is probably
608    more appropriate::
609
610      import sqlalchemy.types as types
611
612      class MyType(types.UserDefinedType):
613          def __init__(self, precision = 8):
614              self.precision = precision
615
616          def get_col_spec(self, **kw):
617              return "MYTYPE(%s)" % self.precision
618
619          def bind_processor(self, dialect):
620              def process(value):
621                  return value
622              return process
623
624          def result_processor(self, dialect, coltype):
625              def process(value):
626                  return value
627              return process
628
629    Once the type is made, it's immediately usable::
630
631      table = Table('foo', meta,
632          Column('id', Integer, primary_key=True),
633          Column('data', MyType(16))
634          )
635
636    The ``get_col_spec()`` method will in most cases receive a keyword
637    argument ``type_expression`` which refers to the owning expression
638    of the type as being compiled, such as a :class:`.Column` or
639    :func:`.cast` construct.  This keyword is only sent if the method
640    accepts keyword arguments (e.g. ``**kw``) in its argument signature;
641    introspection is used to check for this in order to support legacy
642    forms of this function.
643
644    .. versionadded:: 1.0.0 the owning expression is passed to
645       the ``get_col_spec()`` method via the keyword argument
646       ``type_expression``, if it receives ``**kw`` in its signature.
647
648    """
649
650    __visit_name__ = "user_defined"
651
652    ensure_kwarg = "get_col_spec"
653
654    class Comparator(TypeEngine.Comparator):
655        __slots__ = ()
656
657        def _adapt_expression(self, op, other_comparator):
658            if hasattr(self.type, "adapt_operator"):
659                util.warn_deprecated(
660                    "UserDefinedType.adapt_operator is deprecated.  Create "
661                    "a UserDefinedType.Comparator subclass instead which "
662                    "generates the desired expression constructs, given a "
663                    "particular operator."
664                )
665                return self.type.adapt_operator(op), self.type
666            else:
667                return super(
668                    UserDefinedType.Comparator, self
669                )._adapt_expression(op, other_comparator)
670
671    comparator_factory = Comparator
672
673    def coerce_compared_value(self, op, value):
674        """Suggest a type for a 'coerced' Python value in an expression.
675
676        Default behavior for :class:`.UserDefinedType` is the
677        same as that of :class:`.TypeDecorator`; by default it returns
678        ``self``, assuming the compared value should be coerced into
679        the same type as this one.  See
680        :meth:`.TypeDecorator.coerce_compared_value` for more detail.
681
682        """
683
684        return self
685
686
687class Emulated(object):
688    """Mixin for base types that emulate the behavior of a DB-native type.
689
690    An :class:`.Emulated` type will use an available database type
691    in conjunction with Python-side routines and/or database constraints
692    in order to approximate the behavior of a database type that is provided
693    natively by some backends.  When a native-providing backend is in
694    use, the native version of the type is used.  This native version
695    should include the :class:`.NativeForEmulated` mixin to allow it to be
696    distinguished from :class:`.Emulated`.
697
698    Current examples of :class:`.Emulated` are:  :class:`.Interval`,
699    :class:`.Enum`, :class:`.Boolean`.
700
701    .. versionadded:: 1.2.0b3
702
703    """
704
705    def adapt_to_emulated(self, impltype, **kw):
706        """Given an impl class, adapt this type to the impl assuming "emulated".
707
708        The impl should also be an "emulated" version of this type,
709        most likely the same class as this type itself.
710
711        e.g.: sqltypes.Enum adapts to the Enum class.
712
713        """
714        return super(Emulated, self).adapt(impltype, **kw)
715
716    def adapt(self, impltype, **kw):
717        if hasattr(impltype, "adapt_emulated_to_native"):
718
719            if self.native:
720                # native support requested, dialect gave us a native
721                # implementor, pass control over to it
722                return impltype.adapt_emulated_to_native(self, **kw)
723            else:
724                # impltype adapts to native, and we are not native,
725                # so reject the impltype in favor of "us"
726                impltype = self.__class__
727
728        if issubclass(impltype, self.__class__):
729            return self.adapt_to_emulated(impltype, **kw)
730        else:
731            return super(Emulated, self).adapt(impltype, **kw)
732
733
734class NativeForEmulated(object):
735    """Indicates DB-native types supported by an :class:`.Emulated` type.
736
737    .. versionadded:: 1.2.0b3
738
739    """
740
741    @classmethod
742    def adapt_emulated_to_native(cls, impl, **kw):
743        """Given an impl, adapt this type's class to the impl assuming "native".
744
745        The impl will be an :class:`.Emulated` class but not a
746        :class:`.NativeForEmulated`.
747
748        e.g.: postgresql.ENUM produces a type given an Enum instance.
749
750        """
751        return cls(**kw)
752
753
754class TypeDecorator(SchemaEventTarget, TypeEngine):
755    """Allows the creation of types which add additional functionality
756    to an existing type.
757
758    This method is preferred to direct subclassing of SQLAlchemy's
759    built-in types as it ensures that all required functionality of
760    the underlying type is kept in place.
761
762    Typical usage::
763
764      import sqlalchemy.types as types
765
766      class MyType(types.TypeDecorator):
767          '''Prefixes Unicode values with "PREFIX:" on the way in and
768          strips it off on the way out.
769          '''
770
771          impl = types.Unicode
772
773          def process_bind_param(self, value, dialect):
774              return "PREFIX:" + value
775
776          def process_result_value(self, value, dialect):
777              return value[7:]
778
779          def copy(self, **kw):
780              return MyType(self.impl.length)
781
782    The class-level "impl" attribute is required, and can reference any
783    TypeEngine class.  Alternatively, the load_dialect_impl() method
784    can be used to provide different type classes based on the dialect
785    given; in this case, the "impl" variable can reference
786    ``TypeEngine`` as a placeholder.
787
788    Types that receive a Python type that isn't similar to the ultimate type
789    used may want to define the :meth:`TypeDecorator.coerce_compared_value`
790    method. This is used to give the expression system a hint when coercing
791    Python objects into bind parameters within expressions. Consider this
792    expression::
793
794        mytable.c.somecol + datetime.date(2009, 5, 15)
795
796    Above, if "somecol" is an ``Integer`` variant, it makes sense that
797    we're doing date arithmetic, where above is usually interpreted
798    by databases as adding a number of days to the given date.
799    The expression system does the right thing by not attempting to
800    coerce the "date()" value into an integer-oriented bind parameter.
801
802    However, in the case of ``TypeDecorator``, we are usually changing an
803    incoming Python type to something new - ``TypeDecorator`` by default will
804    "coerce" the non-typed side to be the same type as itself. Such as below,
805    we define an "epoch" type that stores a date value as an integer::
806
807        class MyEpochType(types.TypeDecorator):
808            impl = types.Integer
809
810            epoch = datetime.date(1970, 1, 1)
811
812            def process_bind_param(self, value, dialect):
813                return (value - self.epoch).days
814
815            def process_result_value(self, value, dialect):
816                return self.epoch + timedelta(days=value)
817
818    Our expression of ``somecol + date`` with the above type will coerce the
819    "date" on the right side to also be treated as ``MyEpochType``.
820
821    This behavior can be overridden via the
822    :meth:`~TypeDecorator.coerce_compared_value` method, which returns a type
823    that should be used for the value of the expression. Below we set it such
824    that an integer value will be treated as an ``Integer``, and any other
825    value is assumed to be a date and will be treated as a ``MyEpochType``::
826
827        def coerce_compared_value(self, op, value):
828            if isinstance(value, int):
829                return Integer()
830            else:
831                return self
832
833    .. warning::
834
835       Note that the **behavior of coerce_compared_value is not inherited
836       by default from that of the base type**.
837       If the :class:`.TypeDecorator` is augmenting a
838       type that requires special logic for certain types of operators,
839       this method **must** be overridden.  A key example is when decorating
840       the :class:`.postgresql.JSON` and :class:`.postgresql.JSONB` types;
841       the default rules of :meth:`.TypeEngine.coerce_compared_value` should
842       be used in order to deal with operators like index operations::
843
844            class MyJsonType(TypeDecorator):
845                impl = postgresql.JSON
846
847                def coerce_compared_value(self, op, value):
848                    return self.impl.coerce_compared_value(op, value)
849
850       Without the above step, index operations such as ``mycol['foo']``
851       will cause the index value ``'foo'`` to be JSON encoded.
852
853    """
854
855    __visit_name__ = "type_decorator"
856
857    def __init__(self, *args, **kwargs):
858        """Construct a :class:`.TypeDecorator`.
859
860        Arguments sent here are passed to the constructor
861        of the class assigned to the ``impl`` class level attribute,
862        assuming the ``impl`` is a callable, and the resulting
863        object is assigned to the ``self.impl`` instance attribute
864        (thus overriding the class attribute of the same name).
865
866        If the class level ``impl`` is not a callable (the unusual case),
867        it will be assigned to the same instance attribute 'as-is',
868        ignoring those arguments passed to the constructor.
869
870        Subclasses can override this to customize the generation
871        of ``self.impl`` entirely.
872
873        """
874
875        if not hasattr(self.__class__, "impl"):
876            raise AssertionError(
877                "TypeDecorator implementations "
878                "require a class-level variable "
879                "'impl' which refers to the class of "
880                "type being decorated"
881            )
882        self.impl = to_instance(self.__class__.impl, *args, **kwargs)
883
884    coerce_to_is_types = (util.NoneType,)
885    """Specify those Python types which should be coerced at the expression
886    level to "IS <constant>" when compared using ``==`` (and same for
887    ``IS NOT`` in conjunction with ``!=``.
888
889    For most SQLAlchemy types, this includes ``NoneType``, as well as
890    ``bool``.
891
892    :class:`.TypeDecorator` modifies this list to only include ``NoneType``,
893    as typedecorator implementations that deal with boolean types are common.
894
895    Custom :class:`.TypeDecorator` classes can override this attribute to
896    return an empty tuple, in which case no values will be coerced to
897    constants.
898
899    """
900
901    class Comparator(TypeEngine.Comparator):
902        __slots__ = ()
903
904        def operate(self, op, *other, **kwargs):
905            kwargs["_python_is_types"] = self.expr.type.coerce_to_is_types
906            return super(TypeDecorator.Comparator, self).operate(
907                op, *other, **kwargs
908            )
909
910        def reverse_operate(self, op, other, **kwargs):
911            kwargs["_python_is_types"] = self.expr.type.coerce_to_is_types
912            return super(TypeDecorator.Comparator, self).reverse_operate(
913                op, other, **kwargs
914            )
915
916    @property
917    def comparator_factory(self):
918        if TypeDecorator.Comparator in self.impl.comparator_factory.__mro__:
919            return self.impl.comparator_factory
920        else:
921            return type(
922                "TDComparator",
923                (TypeDecorator.Comparator, self.impl.comparator_factory),
924                {},
925            )
926
927    def _gen_dialect_impl(self, dialect):
928        """
929        #todo
930        """
931        adapted = dialect.type_descriptor(self)
932        if adapted is not self:
933            return adapted
934
935        # otherwise adapt the impl type, link
936        # to a copy of this TypeDecorator and return
937        # that.
938        typedesc = self._unwrapped_dialect_impl(dialect)
939        tt = self.copy()
940        if not isinstance(tt, self.__class__):
941            raise AssertionError(
942                "Type object %s does not properly "
943                "implement the copy() method, it must "
944                "return an object of type %s" % (self, self.__class__)
945            )
946        tt.impl = typedesc
947        return tt
948
949    @property
950    def _type_affinity(self):
951        """
952        #todo
953        """
954        return self.impl._type_affinity
955
956    def _set_parent(self, column):
957        """Support SchemaEventTarget"""
958
959        super(TypeDecorator, self)._set_parent(column)
960
961        if isinstance(self.impl, SchemaEventTarget):
962            self.impl._set_parent(column)
963
964    def _set_parent_with_dispatch(self, parent):
965        """Support SchemaEventTarget"""
966
967        super(TypeDecorator, self)._set_parent_with_dispatch(parent)
968
969        if isinstance(self.impl, SchemaEventTarget):
970            self.impl._set_parent_with_dispatch(parent)
971
972    def type_engine(self, dialect):
973        """Return a dialect-specific :class:`.TypeEngine` instance
974        for this :class:`.TypeDecorator`.
975
976        In most cases this returns a dialect-adapted form of
977        the :class:`.TypeEngine` type represented by ``self.impl``.
978        Makes usage of :meth:`dialect_impl` but also traverses
979        into wrapped :class:`.TypeDecorator` instances.
980        Behavior can be customized here by overriding
981        :meth:`load_dialect_impl`.
982
983        """
984        adapted = dialect.type_descriptor(self)
985        if not isinstance(adapted, type(self)):
986            return adapted
987        elif isinstance(self.impl, TypeDecorator):
988            return self.impl.type_engine(dialect)
989        else:
990            return self.load_dialect_impl(dialect)
991
992    def load_dialect_impl(self, dialect):
993        """Return a :class:`.TypeEngine` object corresponding to a dialect.
994
995        This is an end-user override hook that can be used to provide
996        differing types depending on the given dialect.  It is used
997        by the :class:`.TypeDecorator` implementation of :meth:`type_engine`
998        to help determine what type should ultimately be returned
999        for a given :class:`.TypeDecorator`.
1000
1001        By default returns ``self.impl``.
1002
1003        """
1004        return self.impl
1005
1006    def _unwrapped_dialect_impl(self, dialect):
1007        """Return the 'unwrapped' dialect impl for this type.
1008
1009        For a type that applies wrapping logic (e.g. TypeDecorator), give
1010        us the real, actual dialect-level type that is used.
1011
1012        This is used for class-based lookups by dialects.
1013
1014        """
1015        return self.load_dialect_impl(dialect).dialect_impl(dialect)
1016
1017    def __getattr__(self, key):
1018        """Proxy all other undefined accessors to the underlying
1019        implementation."""
1020        return getattr(self.impl, key)
1021
1022    def process_literal_param(self, value, dialect):
1023        """Receive a literal parameter value to be rendered inline within
1024        a statement.
1025
1026        This method is used when the compiler renders a
1027        literal value without using binds, typically within DDL
1028        such as in the "server default" of a column or an expression
1029        within a CHECK constraint.
1030
1031        The returned string will be rendered into the output string.
1032
1033        .. versionadded:: 0.9.0
1034
1035        """
1036        raise NotImplementedError()
1037
1038    def process_bind_param(self, value, dialect):
1039        """Receive a bound parameter value to be converted.
1040
1041        Subclasses override this method to return the
1042        value that should be passed along to the underlying
1043        :class:`.TypeEngine` object, and from there to the
1044        DBAPI ``execute()`` method.
1045
1046        The operation could be anything desired to perform custom
1047        behavior, such as transforming or serializing data.
1048        This could also be used as a hook for validating logic.
1049
1050        This operation should be designed with the reverse operation
1051        in mind, which would be the process_result_value method of
1052        this class.
1053
1054        :param value: Data to operate upon, of any type expected by
1055         this method in the subclass.  Can be ``None``.
1056        :param dialect: the :class:`.Dialect` in use.
1057
1058        """
1059
1060        raise NotImplementedError()
1061
1062    def process_result_value(self, value, dialect):
1063        """Receive a result-row column value to be converted.
1064
1065        Subclasses should implement this method to operate on data
1066        fetched from the database.
1067
1068        Subclasses override this method to return the
1069        value that should be passed back to the application,
1070        given a value that is already processed by
1071        the underlying :class:`.TypeEngine` object, originally
1072        from the DBAPI cursor method ``fetchone()`` or similar.
1073
1074        The operation could be anything desired to perform custom
1075        behavior, such as transforming or serializing data.
1076        This could also be used as a hook for validating logic.
1077
1078        :param value: Data to operate upon, of any type expected by
1079         this method in the subclass.  Can be ``None``.
1080        :param dialect: the :class:`.Dialect` in use.
1081
1082        This operation should be designed to be reversible by
1083        the "process_bind_param" method of this class.
1084
1085        """
1086
1087        raise NotImplementedError()
1088
1089    @util.memoized_property
1090    def _has_bind_processor(self):
1091        """memoized boolean, check if process_bind_param is implemented.
1092
1093        Allows the base process_bind_param to raise
1094        NotImplementedError without needing to test an expensive
1095        exception throw.
1096
1097        """
1098
1099        return (
1100            self.__class__.process_bind_param.__code__
1101            is not TypeDecorator.process_bind_param.__code__
1102        )
1103
1104    @util.memoized_property
1105    def _has_literal_processor(self):
1106        """memoized boolean, check if process_literal_param is implemented.
1107
1108
1109        """
1110
1111        return (
1112            self.__class__.process_literal_param.__code__
1113            is not TypeDecorator.process_literal_param.__code__
1114        )
1115
1116    def literal_processor(self, dialect):
1117        """Provide a literal processing function for the given
1118        :class:`.Dialect`.
1119
1120        Subclasses here will typically override
1121        :meth:`.TypeDecorator.process_literal_param` instead of this method
1122        directly.
1123
1124        By default, this method makes use of
1125        :meth:`.TypeDecorator.process_bind_param` if that method is
1126        implemented, where :meth:`.TypeDecorator.process_literal_param` is
1127        not.  The rationale here is that :class:`.TypeDecorator` typically
1128        deals with Python conversions of data that are above the layer of
1129        database presentation.  With the value converted by
1130        :meth:`.TypeDecorator.process_bind_param`, the underlying type will
1131        then handle whether it needs to be presented to the DBAPI as a bound
1132        parameter or to the database as an inline SQL value.
1133
1134        .. versionadded:: 0.9.0
1135
1136        """
1137        if self._has_literal_processor:
1138            process_param = self.process_literal_param
1139        elif self._has_bind_processor:
1140            # the bind processor should normally be OK
1141            # for TypeDecorator since it isn't doing DB-level
1142            # handling, the handling here won't be different for bound vs.
1143            # literals.
1144            process_param = self.process_bind_param
1145        else:
1146            process_param = None
1147
1148        if process_param:
1149            impl_processor = self.impl.literal_processor(dialect)
1150            if impl_processor:
1151
1152                def process(value):
1153                    return impl_processor(process_param(value, dialect))
1154
1155            else:
1156
1157                def process(value):
1158                    return process_param(value, dialect)
1159
1160            return process
1161        else:
1162            return self.impl.literal_processor(dialect)
1163
1164    def bind_processor(self, dialect):
1165        """Provide a bound value processing function for the
1166        given :class:`.Dialect`.
1167
1168        This is the method that fulfills the :class:`.TypeEngine`
1169        contract for bound value conversion.   :class:`.TypeDecorator`
1170        will wrap a user-defined implementation of
1171        :meth:`process_bind_param` here.
1172
1173        User-defined code can override this method directly,
1174        though its likely best to use :meth:`process_bind_param` so that
1175        the processing provided by ``self.impl`` is maintained.
1176
1177        :param dialect: Dialect instance in use.
1178
1179        This method is the reverse counterpart to the
1180        :meth:`result_processor` method of this class.
1181
1182        """
1183        if self._has_bind_processor:
1184            process_param = self.process_bind_param
1185            impl_processor = self.impl.bind_processor(dialect)
1186            if impl_processor:
1187
1188                def process(value):
1189                    return impl_processor(process_param(value, dialect))
1190
1191            else:
1192
1193                def process(value):
1194                    return process_param(value, dialect)
1195
1196            return process
1197        else:
1198            return self.impl.bind_processor(dialect)
1199
1200    @util.memoized_property
1201    def _has_result_processor(self):
1202        """memoized boolean, check if process_result_value is implemented.
1203
1204        Allows the base process_result_value to raise
1205        NotImplementedError without needing to test an expensive
1206        exception throw.
1207
1208        """
1209        return (
1210            self.__class__.process_result_value.__code__
1211            is not TypeDecorator.process_result_value.__code__
1212        )
1213
1214    def result_processor(self, dialect, coltype):
1215        """Provide a result value processing function for the given
1216        :class:`.Dialect`.
1217
1218        This is the method that fulfills the :class:`.TypeEngine`
1219        contract for result value conversion.   :class:`.TypeDecorator`
1220        will wrap a user-defined implementation of
1221        :meth:`process_result_value` here.
1222
1223        User-defined code can override this method directly,
1224        though its likely best to use :meth:`process_result_value` so that
1225        the processing provided by ``self.impl`` is maintained.
1226
1227        :param dialect: Dialect instance in use.
1228        :param coltype: A SQLAlchemy data type
1229
1230        This method is the reverse counterpart to the
1231        :meth:`bind_processor` method of this class.
1232
1233        """
1234        if self._has_result_processor:
1235            process_value = self.process_result_value
1236            impl_processor = self.impl.result_processor(dialect, coltype)
1237            if impl_processor:
1238
1239                def process(value):
1240                    return process_value(impl_processor(value), dialect)
1241
1242            else:
1243
1244                def process(value):
1245                    return process_value(value, dialect)
1246
1247            return process
1248        else:
1249            return self.impl.result_processor(dialect, coltype)
1250
1251    def coerce_compared_value(self, op, value):
1252        """Suggest a type for a 'coerced' Python value in an expression.
1253
1254        By default, returns self.   This method is called by
1255        the expression system when an object using this type is
1256        on the left or right side of an expression against a plain Python
1257        object which does not yet have a SQLAlchemy type assigned::
1258
1259            expr = table.c.somecolumn + 35
1260
1261        Where above, if ``somecolumn`` uses this type, this method will
1262        be called with the value ``operator.add``
1263        and ``35``.  The return value is whatever SQLAlchemy type should
1264        be used for ``35`` for this particular operation.
1265
1266        """
1267        return self
1268
1269    def copy(self, **kw):
1270        """Produce a copy of this :class:`.TypeDecorator` instance.
1271
1272        This is a shallow copy and is provided to fulfill part of
1273        the :class:`.TypeEngine` contract.  It usually does not
1274        need to be overridden unless the user-defined :class:`.TypeDecorator`
1275        has local state that should be deep-copied.
1276
1277        """
1278
1279        instance = self.__class__.__new__(self.__class__)
1280        instance.__dict__.update(self.__dict__)
1281        return instance
1282
1283    def get_dbapi_type(self, dbapi):
1284        """Return the DBAPI type object represented by this
1285        :class:`.TypeDecorator`.
1286
1287        By default this calls upon :meth:`.TypeEngine.get_dbapi_type` of the
1288        underlying "impl".
1289        """
1290        return self.impl.get_dbapi_type(dbapi)
1291
1292    def compare_values(self, x, y):
1293        """Given two values, compare them for equality.
1294
1295        By default this calls upon :meth:`.TypeEngine.compare_values`
1296        of the underlying "impl", which in turn usually
1297        uses the Python equals operator ``==``.
1298
1299        This function is used by the ORM to compare
1300        an original-loaded value with an intercepted
1301        "changed" value, to determine if a net change
1302        has occurred.
1303
1304        """
1305        return self.impl.compare_values(x, y)
1306
1307    def __repr__(self):
1308        return util.generic_repr(self, to_inspect=self.impl)
1309
1310
1311class Variant(TypeDecorator):
1312    """A wrapping type that selects among a variety of
1313    implementations based on dialect in use.
1314
1315    The :class:`.Variant` type is typically constructed
1316    using the :meth:`.TypeEngine.with_variant` method.
1317
1318    .. seealso:: :meth:`.TypeEngine.with_variant` for an example of use.
1319
1320    """
1321
1322    def __init__(self, base, mapping):
1323        """Construct a new :class:`.Variant`.
1324
1325        :param base: the base 'fallback' type
1326        :param mapping: dictionary of string dialect names to
1327          :class:`.TypeEngine` instances.
1328
1329        """
1330        self.impl = base
1331        self.mapping = mapping
1332
1333    def coerce_compared_value(self, operator, value):
1334        result = self.impl.coerce_compared_value(operator, value)
1335        if result is self.impl:
1336            return self
1337        else:
1338            return result
1339
1340    def load_dialect_impl(self, dialect):
1341        if dialect.name in self.mapping:
1342            return self.mapping[dialect.name]
1343        else:
1344            return self.impl
1345
1346    def _set_parent(self, column):
1347        """Support SchemaEventTarget"""
1348
1349        if isinstance(self.impl, SchemaEventTarget):
1350            self.impl._set_parent(column)
1351        for impl in self.mapping.values():
1352            if isinstance(impl, SchemaEventTarget):
1353                impl._set_parent(column)
1354
1355    def _set_parent_with_dispatch(self, parent):
1356        """Support SchemaEventTarget"""
1357
1358        if isinstance(self.impl, SchemaEventTarget):
1359            self.impl._set_parent_with_dispatch(parent)
1360        for impl in self.mapping.values():
1361            if isinstance(impl, SchemaEventTarget):
1362                impl._set_parent_with_dispatch(parent)
1363
1364    def with_variant(self, type_, dialect_name):
1365        r"""Return a new :class:`.Variant` which adds the given
1366        type + dialect name to the mapping, in addition to the
1367        mapping present in this :class:`.Variant`.
1368
1369        :param type\_: a :class:`.TypeEngine` that will be selected
1370         as a variant from the originating type, when a dialect
1371         of the given name is in use.
1372        :param dialect_name: base name of the dialect which uses
1373         this type. (i.e. ``'postgresql'``, ``'mysql'``, etc.)
1374
1375        """
1376
1377        if dialect_name in self.mapping:
1378            raise exc.ArgumentError(
1379                "Dialect '%s' is already present in "
1380                "the mapping for this Variant" % dialect_name
1381            )
1382        mapping = self.mapping.copy()
1383        mapping[dialect_name] = type_
1384        return Variant(self.impl, mapping)
1385
1386    @property
1387    def comparator_factory(self):
1388        """express comparison behavior in terms of the base type"""
1389        return self.impl.comparator_factory
1390
1391
1392def _reconstitute_comparator(expression):
1393    return expression.comparator
1394
1395
1396def to_instance(typeobj, *arg, **kw):
1397    if typeobj is None:
1398        return NULLTYPE
1399
1400    if util.callable(typeobj):
1401        return typeobj(*arg, **kw)
1402    else:
1403        return typeobj
1404
1405
1406def adapt_type(typeobj, colspecs):
1407    if isinstance(typeobj, type):
1408        typeobj = typeobj()
1409    for t in typeobj.__class__.__mro__[0:-1]:
1410        try:
1411            impltype = colspecs[t]
1412            break
1413        except KeyError:
1414            pass
1415    else:
1416        # couldn't adapt - so just return the type itself
1417        # (it may be a user-defined type)
1418        return typeobj
1419    # if we adapted the given generic type to a database-specific type,
1420    # but it turns out the originally given "generic" type
1421    # is actually a subclass of our resulting type, then we were already
1422    # given a more specific type than that required; so use that.
1423    if issubclass(typeobj.__class__, impltype):
1424        return typeobj
1425    return typeobj.adapt(impltype)
1426