]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Converted MAGICCOOKIE=object() to a little symbol implementation to ease object...
authorJason Kirtland <jek@discorporate.us>
Fri, 22 Feb 2008 19:03:44 +0000 (19:03 +0000)
committerJason Kirtland <jek@discorporate.us>
Fri, 22 Feb 2008 19:03:44 +0000 (19:03 +0000)
lib/sqlalchemy/ext/associationproxy.py
lib/sqlalchemy/orm/attributes.py
lib/sqlalchemy/orm/collections.py
lib/sqlalchemy/orm/interfaces.py
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/sql/operators.py
lib/sqlalchemy/util.py

index 1e237a857693fcff7b9f875810cfc7ca5c6965e5..bbfb1bcdaee10010911d6ef044ea77058252e024 100644 (file)
@@ -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.
index b0f10c20b55b7b1631a814cc52d0d29470014e36..5cc9cb309121a9907af549502fa399b7a9414eed 100644 (file)
@@ -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
index 8f04fdf7a0e77f257bfb7a793dd7c2e2af127a4d..7b78c240bb9a671c90b764bba33517d3f9e71d9c 100644 (file)
@@ -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):
index f510a3ffaf6b285fffeb1441e7e7e38d6fd567ab..15f752314c52cc8136d8ac2d3db5676dd790e4b9 100644 (file)
@@ -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.
index c0a15c427e46082d9f1c254fe01051e7e371efb6..62067fc358abdfaae8662e2ed9cbd8531c7f033a 100644 (file)
@@ -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()
index 19e0c484cf7161386028fcea6834160899af3f4f..e31d270757b360131cfa87284bbe6103f7c72fab 100644 (file)
@@ -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,
index 14c4c9f554b59ce5456c52531e874dc976b3b86a..4e8a837c9029aa0b2bc50ce72df92ac70df99db3 100644 (file)
@@ -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)