mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-06-05 15:23:48 -04:00
- Converted MAGICCOOKIE=object() to a little symbol implementation to ease object inspection and debugging
This commit is contained in:
@@ -448,7 +448,7 @@ class _AssociationList(object):
|
||||
def __hash__(self):
|
||||
raise TypeError("%s objects are unhashable" % type(self).__name__)
|
||||
|
||||
_NotProvided = object()
|
||||
_NotProvided = util.symbol('_NotProvided')
|
||||
class _AssociationDict(object):
|
||||
"""Generic proxying list which proxies dict operations to a another dict,
|
||||
converting association objects to and from a simplified value.
|
||||
|
||||
@@ -12,10 +12,10 @@ from sqlalchemy.orm import interfaces, collections
|
||||
from sqlalchemy.orm.util import identity_equal
|
||||
from sqlalchemy import exceptions
|
||||
|
||||
PASSIVE_NORESULT = object()
|
||||
ATTR_WAS_SET = object()
|
||||
NO_VALUE = object()
|
||||
NEVER_SET = object()
|
||||
PASSIVE_NORESULT = util.symbol('PASSIVE_NORESULT')
|
||||
ATTR_WAS_SET = util.symbol('ATTR_WAS_SET')
|
||||
NO_VALUE = util.symbol('NO_VALUE')
|
||||
NEVER_SET = util.symbol('NEVER_SET')
|
||||
|
||||
class InstrumentedAttribute(interfaces.PropComparator):
|
||||
"""public-facing instrumented attribute, placed in the
|
||||
|
||||
@@ -1011,7 +1011,7 @@ def _dict_decorators():
|
||||
setattr(fn, '_sa_instrumented', True)
|
||||
fn.__doc__ = getattr(getattr(dict, fn.__name__), '__doc__')
|
||||
|
||||
Unspecified=object()
|
||||
Unspecified=sautil.symbol('Unspecified')
|
||||
|
||||
def __setitem__(fn):
|
||||
def __setitem__(self, key, value, _sa_initiator=None):
|
||||
@@ -1107,7 +1107,7 @@ def _set_decorators():
|
||||
setattr(fn, '_sa_instrumented', True)
|
||||
fn.__doc__ = getattr(getattr(Set, fn.__name__), '__doc__')
|
||||
|
||||
Unspecified=object()
|
||||
Unspecified=sautil.symbol('Unspecified')
|
||||
|
||||
def add(fn):
|
||||
def add(self, value, _sa_initiator=None):
|
||||
|
||||
@@ -14,7 +14,7 @@ ORM.
|
||||
"""
|
||||
|
||||
from itertools import chain
|
||||
from sqlalchemy import exceptions, logging
|
||||
from sqlalchemy import exceptions, logging, util
|
||||
from sqlalchemy.sql import expression
|
||||
class_mapper = None
|
||||
|
||||
@@ -24,8 +24,8 @@ __all__ = ['EXT_CONTINUE', 'EXT_STOP', 'EXT_PASS', 'MapperExtension',
|
||||
'ExtensionOption', 'PropertyOption',
|
||||
'AttributeExtension', 'StrategizedOption', 'LoaderStrategy' ]
|
||||
|
||||
EXT_CONTINUE = EXT_PASS = object()
|
||||
EXT_STOP = object()
|
||||
EXT_CONTINUE = EXT_PASS = util.symbol('EXT_CONTINUE')
|
||||
EXT_STOP = util.symbol('EXT_STOP')
|
||||
|
||||
class MapperExtension(object):
|
||||
"""Base implementation for customizing Mapper behavior.
|
||||
|
||||
@@ -30,7 +30,7 @@ global_extensions = []
|
||||
# a constant returned by _get_attr_by_column to indicate
|
||||
# this mapper is not handling an attribute for a particular
|
||||
# column
|
||||
NO_ATTRIBUTE = object()
|
||||
NO_ATTRIBUTE = util.symbol('NO_ATTRIBUTE')
|
||||
|
||||
# lock used to synchronize the "mapper compile" step
|
||||
_COMPILE_MUTEX = util.threading.Lock()
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
from operator import and_, or_, inv, add, mul, sub, div, mod, truediv, \
|
||||
lt, le, ne, gt, ge, eq
|
||||
|
||||
from sqlalchemy.util import Set
|
||||
from sqlalchemy.util import Set, symbol
|
||||
|
||||
def from_():
|
||||
raise NotImplementedError()
|
||||
@@ -74,9 +73,9 @@ def asc_op(a):
|
||||
_commutative = Set([eq, ne, add, mul])
|
||||
def is_commutative(op):
|
||||
return op in _commutative
|
||||
|
||||
_smallest = object()
|
||||
_largest = object()
|
||||
|
||||
_smallest = symbol('_smallest')
|
||||
_largest = symbol('_largest')
|
||||
|
||||
_PRECEDENCE = {
|
||||
from_:15,
|
||||
|
||||
@@ -952,6 +952,42 @@ class ScopedRegistry(object):
|
||||
def _get_key(self):
|
||||
return self.scopefunc()
|
||||
|
||||
class symbol(object):
|
||||
"""A constant symbol.
|
||||
|
||||
>>> symbol('foo') is symbol('foo')
|
||||
True
|
||||
>>> symbol('foo')
|
||||
<symbol 'foo>
|
||||
|
||||
A slight refinement of the MAGICCOOKIE=object() pattern. The primary
|
||||
advantage of symbol() is its repr(). They are also singletons.
|
||||
"""
|
||||
|
||||
symbols = {}
|
||||
_lock = threading.Lock()
|
||||
|
||||
def __new__(cls, name):
|
||||
try:
|
||||
symbol._lock.acquire()
|
||||
sym = cls.symbols.get(name)
|
||||
if sym is None:
|
||||
cls.symbols[name] = sym = object.__new__(cls, name)
|
||||
return sym
|
||||
finally:
|
||||
symbol._lock.release()
|
||||
|
||||
def __init__(self, name):
|
||||
"""Construct a new named symbol.
|
||||
|
||||
Repeated calls of symbol('name') will all return the same instance.
|
||||
"""
|
||||
|
||||
assert isinstance(name, str)
|
||||
self.name = name
|
||||
def __repr__(self):
|
||||
return "<symbol '%s>" % self.name
|
||||
|
||||
def warn(msg):
|
||||
if isinstance(msg, basestring):
|
||||
warnings.warn(msg, exceptions.SAWarning, stacklevel=3)
|
||||
|
||||
Reference in New Issue
Block a user