diff options
| author | Jason Kirtland <jek@discorporate.us> | 2008-03-19 18:02:47 +0000 |
|---|---|---|
| committer | Jason Kirtland <jek@discorporate.us> | 2008-03-19 18:02:47 +0000 |
| commit | a86dc8cbac51893e400e9e49f5e9d358c9845897 (patch) | |
| tree | 0a1aaf7495f574fef153df58c8a813e0718c3ecd | |
| parent | fb9f459d712a70478d30978b8fe84edc4c072f74 (diff) | |
| download | sqlalchemy-a86dc8cbac51893e400e9e49f5e9d358c9845897.tar.gz | |
- symbols now depickle properly
- fixed some symbol __new__ abuse
| -rw-r--r-- | lib/sqlalchemy/util.py | 30 | ||||
| -rw-r--r-- | test/base/utils.py | 31 |
2 files changed, 47 insertions, 14 deletions
diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py index 9adb3983d..af77d792e 100644 --- a/lib/sqlalchemy/util.py +++ b/lib/sqlalchemy/util.py @@ -981,6 +981,17 @@ class ScopedRegistry(object): def _get_key(self): return self.scopefunc() +class _symbol(object): + def __init__(self, name): + """Construct a new named symbol.""" + assert isinstance(name, str) + self.name = name + def __reduce__(self): + return symbol, (self.name,) + def __repr__(self): + return "<symbol '%s>" % self.name +_symbol.__name__ = 'symbol' + class symbol(object): """A constant symbol. @@ -991,32 +1002,23 @@ class symbol(object): A slight refinement of the MAGICCOOKIE=object() pattern. The primary advantage of symbol() is its repr(). They are also singletons. - """ + Repeated calls of symbol('name') will all return the same instance. + + """ symbols = {} _lock = threading.Lock() def __new__(cls, name): + cls._lock.acquire() try: - symbol._lock.acquire() sym = cls.symbols.get(name) if sym is None: - cls.symbols[name] = sym = object.__new__(cls, name) + cls.symbols[name] = sym = _symbol(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) diff --git a/test/base/utils.py b/test/base/utils.py index 6ab141d6c..fc72cf8e1 100644 --- a/test/base/utils.py +++ b/test/base/utils.py @@ -389,5 +389,36 @@ class ArgInspectionTest(TestBase): test(f3) test(f4) +class SymbolTest(TestBase): + def test_basic(self): + sym1 = util.symbol('foo') + assert sym1.name == 'foo' + sym2 = util.symbol('foo') + + assert sym1 is sym2 + assert sym1 == sym2 + + sym3 = util.symbol('bar') + assert sym1 is not sym3 + assert sym1 != sym3 + + def test_pickle(self): + sym1 = util.symbol('foo') + sym2 = util.symbol('foo') + + assert sym1 is sym2 + + # default + s = util.pickle.dumps(sym1) + sym3 = util.pickle.loads(s) + + for protocol in 0, 1, 2: + print protocol + serial = util.pickle.dumps(sym1) + rt = util.pickle.loads(serial) + assert rt is sym1 + assert rt is sym2 + + if __name__ == "__main__": testenv.main() |
