size of the many per-column objects we're hitting, but somehow the overall memory is
hardly being reduced at all in initial testing
class _JoinedDispatchDescriptor(object):
+ __slots__ = 'name',
+
def __init__(self, name):
self.name = name
class _JoinedListener(_CompoundListener):
_exec_once = False
+ __slots__ = 'parent', 'name', 'local', 'parent_listeners'
+
def __init__(self, parent, name, local):
self.parent = parent
self.name = name
class _JoinedDispatcher(object):
"""Represent a connection between two _Dispatch objects."""
+ __slots__ = 'local', 'parent', '_parent_cls'
+
def __init__(self, local, parent):
self.local = local
self.parent = parent
"""Represent :func:`.listen` arguments.
"""
+ __slots__ = (
+ 'target', 'identifier', 'fn', 'fn_key', 'fn_wrap', 'dispatch_target'
+ )
+
def __init__(self, target, identifier,
fn, dispatch_target, _fn_wrap=None):
self.target = target
.. versionadded:: 0.9.0
- """
-
- impl = None
- """The :class:`.AttributeImpl` which is the current event initiator.
- """
+ :var impl: The :class:`.AttributeImpl` which is the current event
+ initiator.
- op = None
- """The symbol :attr:`.OP_APPEND`, :attr:`.OP_REMOVE` or :attr:`.OP_REPLACE`,
- indicating the source operation.
+ :var op: The symbol :attr:`.OP_APPEND`, :attr:`.OP_REMOVE` or
+ :attr:`.OP_REPLACE`, indicating the source operation.
"""
+ __slots__ = 'impl', 'op', 'parent_token'
+
def __init__(self, attribute_impl, op):
self.impl = attribute_impl
self.op = op
self.expire_missing = expire_missing
+ __slots__ = (
+ 'class_', 'key', 'callable_', 'dispatch', 'trackparent',
+ 'parent_token', 'send_modified_events', 'is_equal', 'expire_missing'
+ )
+
def __str__(self):
return "%s.%s" % (self.class_.__name__, self.key)
supports_population = True
collection = False
+ __slots__ = '_replace_token', '_append_token', '_remove_token'
+
+ def __init__(self, *arg, **kw):
+ super(ScalarAttributeImpl, self).__init__(*arg, **kw)
+ self._replace_token = self._append_token = None
+ self._remove_token = None
+
+ def _init_append_token(self):
+ self._replace_token = self._append_token = Event(self, OP_REPLACE)
+ return self._replace_token
+
+ _init_append_or_replace_token = _init_append_token
+
+ def _init_remove_token(self):
+ self._remove_token = Event(self, OP_REMOVE)
+ return self._remove_token
+
def delete(self, state, dict_):
# TODO: catch key errors, convert to attributeerror?
state._modified_event(dict_, self, old)
dict_[self.key] = value
- @util.memoized_property
- def _replace_token(self):
- return Event(self, OP_REPLACE)
-
- @util.memoized_property
- def _append_token(self):
- return Event(self, OP_REPLACE)
-
- @util.memoized_property
- def _remove_token(self):
- return Event(self, OP_REMOVE)
-
def fire_replace_event(self, state, dict_, value, previous, initiator):
for fn in self.dispatch.set:
value = fn(
- state, value, previous, initiator or self._replace_token)
+ state, value, previous,
+ initiator or self._replace_token or
+ self._init_append_or_replace_token())
return value
def fire_remove_event(self, state, dict_, value, initiator):
for fn in self.dispatch.remove:
- fn(state, value, initiator or self._remove_token)
+ fn(state, value,
+ initiator or self._remove_token or self._init_remove_token())
@property
def type(self):
supports_population = True
collection = False
+ __slots__ = ()
+
def delete(self, state, dict_):
old = self.get(state, dict_)
- self.fire_remove_event(state, dict_, old, self._remove_token)
+ self.fire_remove_event(
+ state, dict_, old,
+ self._remove_token or self._init_remove_token())
del dict_[self.key]
def get_history(self, state, dict_, passive=PASSIVE_OFF):
self.sethasparent(instance_state(value), state, False)
for fn in self.dispatch.remove:
- fn(state, value, initiator or self._remove_token)
+ fn(state, value, initiator or
+ self._remove_token or self._init_remove_token())
state._modified_event(dict_, self, value)
for fn in self.dispatch.set:
value = fn(
- state, value, previous, initiator or self._replace_token)
+ state, value, previous, initiator or
+ self._replace_token or self._init_append_or_replace_token())
state._modified_event(dict_, self, previous)
supports_population = True
collection = True
+ __slots__ = 'copy', 'collection_factory', '_append_token', '_remove_token'
+
def __init__(self, class_, key, callable_, dispatch,
typecallable=None, trackparent=False, extension=None,
copy_function=None, compare_function=None, **kwargs):
copy_function = self.__copy
self.copy = copy_function
self.collection_factory = typecallable
+ self._append_token = None
+ self._remove_token = None
if getattr(self.collection_factory, "_sa_linker", None):
def unlink(target, collection, collection_adapter):
collection._sa_linker(None)
+ def _init_append_token(self):
+ self._append_token = Event(self, OP_APPEND)
+ return self._append_token
+
+ def _init_remove_token(self):
+ self._remove_token = Event(self, OP_REMOVE)
+ return self._remove_token
+
def __copy(self, item):
return [y for y in collections.collection_adapter(item)]
return [(instance_state(o), o) for o in current]
- @util.memoized_property
- def _append_token(self):
- return Event(self, OP_APPEND)
-
- @util.memoized_property
- def _remove_token(self):
- return Event(self, OP_REMOVE)
-
def fire_append_event(self, state, dict_, value, initiator):
for fn in self.dispatch.append:
- value = fn(state, value, initiator or self._append_token)
+ value = fn(
+ state, value,
+ initiator or self._append_token or self._init_append_token())
state._modified_event(dict_, self, NEVER_SET, True)
self.sethasparent(instance_state(value), state, False)
for fn in self.dispatch.remove:
- fn(state, value, initiator or self._remove_token)
+ fn(state, value,
+ initiator or self._remove_token or self._init_remove_token())
state._modified_event(dict_, self, NEVER_SET, True)
impl.pop(old_state,
old_dict,
state.obj(),
- parent_impl._append_token,
+ parent_impl._append_token or
+ parent_impl._init_append_token(),
passive=PASSIVE_NO_FETCH)
if child is not None:
"""
+ __slots__ = ()
+
is_selectable = False
"""Return True if this object is an instance of :class:`.Selectable`."""
attributes.
"""
+ __slots__ = ()
"""
+ __slots__ = 'prop', 'property', '_parentmapper', '_adapt_to_entity'
+
def __init__(self, prop, parentmapper, adapt_to_entity=None):
self.prop = self.property = prop
self._parentmapper = parentmapper
else:
return self._adapt_to_entity._adapt_element
- @util.memoized_property
+ @property
def info(self):
return self.property.info
:attr:`.TypeEngine.comparator_factory`
"""
+
@util.memoized_instancemethod
def __clause_element__(self):
if self.adapter:
"""
from .. import exc, util
-from . import operators
from . import type_api
+from . import operators
from .elements import BindParameter, True_, False_, BinaryExpression, \
Null, _const_expr, _clause_element_as_expr, \
ClauseList, ColumnElement, TextClause, UnaryExpression, \
from .selectable import SelectBase, Alias, Selectable, ScalarSelect
-class _DefaultColumnComparator(operators.ColumnOperators):
+class _DefaultColumnComparator(object):
"""Defines comparison and math operations.
See :class:`.ColumnOperators` and :class:`.Operators` for descriptions
"""
- @util.memoized_property
- def type(self):
- return self.expr.type
-
- def operate(self, op, *other, **kwargs):
- o = self.operators[op.__name__]
- return o[0](self, self.expr, op, *(other + o[1:]), **kwargs)
-
- def reverse_operate(self, op, other, **kwargs):
- o = self.operators[op.__name__]
- return o[0](self, self.expr, op, other,
- reverse=True, *o[1:], **kwargs)
-
- def _adapt_expression(self, op, other_comparator):
- """evaluate the return type of <self> <op> <othertype>,
- and apply any adaptations to the given operator.
-
- This method determines the type of a resulting binary expression
- given two source types and an operator. For example, two
- :class:`.Column` objects, both of the type :class:`.Integer`, will
- produce a :class:`.BinaryExpression` that also has the type
- :class:`.Integer` when compared via the addition (``+``) operator.
- However, using the addition operator with an :class:`.Integer`
- and a :class:`.Date` object will produce a :class:`.Date`, assuming
- "days delta" behavior by the database (in reality, most databases
- other than Postgresql don't accept this particular operation).
-
- The method returns a tuple of the form <operator>, <type>.
- The resulting operator and type will be those applied to the
- resulting :class:`.BinaryExpression` as the final operator and the
- right-hand side of the expression.
-
- Note that only a subset of operators make usage of
- :meth:`._adapt_expression`,
- including math operators and user-defined operators, but not
- boolean comparison or special SQL keywords like MATCH or BETWEEN.
-
- """
- return op, other_comparator.type
-
def _boolean_compare(self, expr, op, obj, negate=None, reverse=False,
_python_is_types=(util.NoneType, bool),
result_type = None,
return expr._bind_param(operator, other)
else:
return other
+
+the_comparator = _DefaultColumnComparator()
:class:`.ColumnOperators`.
"""
+ __slots__ = ()
def __and__(self, other):
"""Implement the ``&`` operator.
"""
+ __slots__ = ()
+
timetuple = None
"""Hack, allows datetime objects to be compared on the LHS."""
from .type_api import TypeEngine, TypeDecorator, to_instance
from .elements import quoted_name, type_coerce, _defer_name
-from .default_comparator import _DefaultColumnComparator
from .. import exc, util, processors
from .base import _bind_or_error, SchemaEventTarget
from . import operators
type_api.MATCHTYPE = MATCHTYPE
type_api._type_map = _type_map
-# this one, there's all kinds of ways to play it, but at the EOD
-# there's just a giant dependency cycle between the typing system and
-# the expression element system, as you might expect. We can use
-# importlaters or whatnot, but the typing system just necessarily has
-# to have some kind of connection like this. right now we're injecting the
-# _DefaultColumnComparator implementation into the TypeEngine.Comparator
-# interface. Alternatively TypeEngine.Comparator could have an "impl"
-# injected, though just injecting the base is simpler, error free, and more
-# performant.
-
-
-class Comparator(_DefaultColumnComparator):
- BOOLEANTYPE = BOOLEANTYPE
-
-TypeEngine.Comparator.__bases__ = (
- Comparator, ) + TypeEngine.Comparator.__bases__
+TypeEngine.Comparator.BOOLEANTYPE = BOOLEANTYPE
STRINGTYPE = None
MATCHTYPE = None
+
class TypeEngine(Visitable):
"""The ultimate base class for all SQL datatypes.
"""
+ __slots__ = 'expr', 'type'
def __init__(self, expr):
self.expr = expr
+ self.type = expr.type
+
+ @util.dependencies('sqlalchemy.sql.default_comparator')
+ def operate(self, default_comparator, op, *other, **kwargs):
+ comp = default_comparator.the_comparator
+ o = comp.operators[op.__name__]
+ return o[0](comp, self.expr, op, *(other + o[1:]), **kwargs)
+
+ @util.dependencies('sqlalchemy.sql.default_comparator')
+ def reverse_operate(self, default_comparator, op, other, **kwargs):
+ comp = default_comparator.the_comparator
+ o = comp.operators[op.__name__]
+ return o[0](comp, self.expr, op, other,
+ reverse=True, *o[1:], **kwargs)
+
+ def _adapt_expression(self, op, other_comparator):
+ """evaluate the return type of <self> <op> <othertype>,
+ and apply any adaptations to the given operator.
+
+ This method determines the type of a resulting binary expression
+ given two source types and an operator. For example, two
+ :class:`.Column` objects, both of the type :class:`.Integer`, will
+ produce a :class:`.BinaryExpression` that also has the type
+ :class:`.Integer` when compared via the addition (``+``) operator.
+ However, using the addition operator with an :class:`.Integer`
+ and a :class:`.Date` object will produce a :class:`.Date`, assuming
+ "days delta" behavior by the database (in reality, most databases
+ other than Postgresql don't accept this particular operation).
+
+ The method returns a tuple of the form <operator>, <type>.
+ The resulting operator and type will be those applied to the
+ resulting :class:`.BinaryExpression` as the final operator and the
+ right-hand side of the expression.
+
+ Note that only a subset of operators make usage of
+ :meth:`._adapt_expression`,
+ including math operators and user-defined operators, but not
+ boolean comparison or special SQL keywords like MATCH or BETWEEN.
+
+ """
+ return op, other_comparator.type
def __reduce__(self):
return _reconstitute_comparator, (self.expr, )
__visit_name__ = "user_defined"
class Comparator(TypeEngine.Comparator):
+ __slots__ = ()
+
def _adapt_expression(self, op, other_comparator):
if hasattr(self.type, 'adapt_operator'):
util.warn_deprecated(
"""
class Comparator(TypeEngine.Comparator):
+ __slots__ = ()
def operate(self, op, *other, **kwargs):
kwargs['_python_is_types'] = self.expr.type.coerce_to_is_types
class comparator_factory(TypeEngine.Comparator):
def __init__(self, expr):
- self.expr = expr
+ super(MyInteger.comparator_factory, self).__init__(expr)
def __add__(self, other):
return self.expr.op("goofy")(other)
class comparator_factory(TypeDecorator.Comparator):
def __init__(self, expr):
- self.expr = expr
+ super(MyInteger.comparator_factory, self).__init__(expr)
def __add__(self, other):
return self.expr.op("goofy")(other)
class comparator_factory(TypeDecorator.Comparator):
def __init__(self, expr):
- self.expr = expr
+ super(MyIntegerOne.comparator_factory, self).__init__(expr)
def __add__(self, other):
return self.expr.op("goofy")(other)
class comparator_factory(TypeEngine.Comparator):
def __init__(self, expr):
- self.expr = expr
+ super(
+ SomeOtherInteger.comparator_factory,
+ self).__init__(expr)
def __add__(self, other):
return self.expr.op("not goofy")(other)
class comparator_factory(TypeDecorator.Comparator):
def __init__(self, expr):
- self.expr = expr
+ super(MyInteger.comparator_factory, self).__init__(expr)
def __add__(self, other):
return self.expr.op("goofy")(other)
class comparator_factory(TypeEngine.Comparator):
def __init__(self, expr):
- self.expr = expr
+ super(MyInteger.comparator_factory, self).__init__(expr)
def __add__(self, other):
return self.expr.op("goofy")(other)
class comparator_factory(TypeEngine.Comparator):
def __init__(self, expr):
- self.expr = expr
+ super(MyInteger.comparator_factory, self).__init__(expr)
def foob(self, other):
return self.expr.op("foob")(other)