From: Jason Kirtland Date: Fri, 22 Feb 2008 19:03:44 +0000 (+0000) Subject: - Converted MAGICCOOKIE=object() to a little symbol implementation to ease object... X-Git-Tag: rel_0_4_4~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e203b4dd4e2ce24e18fbeb9db515b2bdbbb56bc5;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Converted MAGICCOOKIE=object() to a little symbol implementation to ease object inspection and debugging --- diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index 1e237a8576..bbfb1bcdae 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -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. diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index b0f10c20b5..5cc9cb3091 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -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 diff --git a/lib/sqlalchemy/orm/collections.py b/lib/sqlalchemy/orm/collections.py index 8f04fdf7a0..7b78c240bb 100644 --- a/lib/sqlalchemy/orm/collections.py +++ b/lib/sqlalchemy/orm/collections.py @@ -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): diff --git a/lib/sqlalchemy/orm/interfaces.py b/lib/sqlalchemy/orm/interfaces.py index f510a3ffaf..15f752314c 100644 --- a/lib/sqlalchemy/orm/interfaces.py +++ b/lib/sqlalchemy/orm/interfaces.py @@ -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. diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index c0a15c427e..62067fc358 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -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() diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index 19e0c484cf..e31d270757 100644 --- a/lib/sqlalchemy/sql/operators.py +++ b/lib/sqlalchemy/sql/operators.py @@ -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, diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py index 14c4c9f554..4e8a837c90 100644 --- a/lib/sqlalchemy/util.py +++ b/lib/sqlalchemy/util.py @@ -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') + + + 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 "" % self.name + def warn(msg): if isinstance(msg, basestring): warnings.warn(msg, exceptions.SAWarning, stacklevel=3)