From 91df1bc17be81bb8b2122ee2f19b77a137b7b839 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 7 Apr 2006 00:11:13 +0000 Subject: [PATCH] a little spring cleaning for the util package, etc --- lib/sqlalchemy/mapping/query.py | 6 +++ lib/sqlalchemy/mapping/sync.py | 8 ++++ lib/sqlalchemy/mapping/util.py | 7 ++++ lib/sqlalchemy/schema.py | 4 +- lib/sqlalchemy/sql.py | 5 +-- lib/sqlalchemy/util.py | 67 ++++++--------------------------- 6 files changed, 37 insertions(+), 60 deletions(-) diff --git a/lib/sqlalchemy/mapping/query.py b/lib/sqlalchemy/mapping/query.py index 950c2be42c..72037a347d 100644 --- a/lib/sqlalchemy/mapping/query.py +++ b/lib/sqlalchemy/mapping/query.py @@ -1,3 +1,9 @@ +# mapper/query.py +# Copyright (C) 2005,2006 Michael Bayer mike_mp@zzzcomputing.com +# +# This module is part of SQLAlchemy and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php + import objectstore import sqlalchemy.sql as sql diff --git a/lib/sqlalchemy/mapping/sync.py b/lib/sqlalchemy/mapping/sync.py index e690737ae9..cfce9b6b6b 100644 --- a/lib/sqlalchemy/mapping/sync.py +++ b/lib/sqlalchemy/mapping/sync.py @@ -1,3 +1,11 @@ +# mapper/sync.py +# Copyright (C) 2005,2006 Michael Bayer mike_mp@zzzcomputing.com +# +# This module is part of SQLAlchemy and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php + + + import sqlalchemy.sql as sql import sqlalchemy.schema as schema from sqlalchemy.exceptions import * diff --git a/lib/sqlalchemy/mapping/util.py b/lib/sqlalchemy/mapping/util.py index 18e2ac0538..4d957241b0 100644 --- a/lib/sqlalchemy/mapping/util.py +++ b/lib/sqlalchemy/mapping/util.py @@ -1,3 +1,10 @@ +# mapper/util.py +# Copyright (C) 2005,2006 Michael Bayer mike_mp@zzzcomputing.com +# +# This module is part of SQLAlchemy and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php + + import sqlalchemy.sql as sql class TableFinder(sql.ClauseVisitor): diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index acce555ab2..d54006fc35 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -317,8 +317,8 @@ class Column(sql.ColumnClause, SchemaItem): if len(kwargs): raise ArgumentError("Unknown arguments passed to Column: " + repr(kwargs.keys())) - primary_key = AttrProp('_primary_key') - foreign_key = AttrProp('_foreign_key') + primary_key = SimpleProperty('_primary_key') + foreign_key = SimpleProperty('_foreign_key') original = property(lambda s: s._orig or s) parent = property(lambda s:s._parent or s) engine = property(lambda s: s.table.engine) diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py index 2bc025e9f0..7129781a70 100644 --- a/lib/sqlalchemy/sql.py +++ b/lib/sqlalchemy/sql.py @@ -247,6 +247,7 @@ def is_column(col): return isinstance(col, ColumnElement) class AbstractEngine(object): + """represents a 'thing that can produce Compiler objects an execute them'.""" def execute_compiled(self, compiled, parameters, echo=None, **kwargs): raise NotImplementedError() def compiler(self, statement, parameters, **kwargs): @@ -343,7 +344,7 @@ class Compiled(ClauseVisitor): self.after_compile() def execute(self, *multiparams, **params): - """executes this compiled object using the underlying SQLEngine""" + """executes this compiled object using the AbstractEngine it is bound to.""" if len(multiparams): params = multiparams @@ -1350,8 +1351,6 @@ class Select(SelectBaseMixin, FromClause): else: setattr(self, attribute, condition) - _hash_recursion = util.RecursionStack() - def clear_from(self, from_obj): self._froms[from_obj] = FromClause(from_name = None) diff --git a/lib/sqlalchemy/util.py b/lib/sqlalchemy/util.py index c2fc5e37be..d4d5566997 100644 --- a/lib/sqlalchemy/util.py +++ b/lib/sqlalchemy/util.py @@ -4,7 +4,6 @@ # This module is part of SQLAlchemy and is released under # the MIT License: http://www.opensource.org/licenses/mit-license.php -__all__ = ['OrderedProperties', 'OrderedDict', 'generic_repr', 'HashSet', 'AttrProp'] import thread, threading, weakref, UserList, time, string, inspect, sys from exceptions import * import __builtin__ @@ -36,9 +35,9 @@ def reversed(seq): i -= 1 raise StopIteration() return rev() - -class AttrProp(object): - """a quick way to stick a property accessor on an object""" + +class SimpleProperty(object): + """a "default" property accessor.""" def __init__(self, key): self.key = key def __set__(self, obj, value): @@ -50,20 +49,6 @@ class AttrProp(object): return self else: return getattr(obj, self.key) - -def generic_repr(obj, exclude=None): - L = ['%s=%s' % (a, repr(getattr(obj, a))) for a in dir(obj) if not callable(getattr(obj, a)) and not a.startswith('_') and (exclude is None or not exclude.has_key(a))] - return '%s(%s)' % (obj.__class__.__name__, ','.join(L)) - -def hash_key(obj): - if obj is None: - return 'None' - elif isinstance(obj, list): - return repr([hash_key(o) for o in obj]) - elif hasattr(obj, 'hash_key'): - return obj.hash_key() - else: - return repr(obj) class Logger(object): """defines various forms of logging""" @@ -130,30 +115,6 @@ class OrderedProperties(object): def clear(self): self.__dict__.clear() self.__dict__['_list'] = [] - -class RecursionStack(object): - """a thread-local stack used to detect recursive object traversals.""" - def __init__(self): - self.stacks = {} - def _get_stack(self): - try: - stack = self.stacks[thread.get_ident()] - except KeyError: - stack = {} - self.stacks[thread.get_ident()] = stack - return stack - def push(self, obj): - s = self._get_stack() - if s.has_key(obj): - return True - else: - s[obj] = True - return False - def pop(self, obj): - stack = self._get_stack() - del stack[obj] - if len(stack) == 0: - del self.stacks[thread.get_ident()] class OrderedDict(dict): """A Dictionary that keeps its own internal ordering""" @@ -163,52 +124,40 @@ class OrderedDict(dict): if values is not None: for val in values: self.update(val) - def keys(self): return list(self._list) - def clear(self): self._list = [] dict.clear(self) - def update(self, dict): for key in dict.keys(): self.__setitem__(key, dict[key]) - def setdefault(self, key, value): if not self.has_key(key): self.__setitem__(key, value) return value else: return self.__getitem__(key) - def values(self): return map(lambda key: self[key], self._list) - def __iter__(self): return iter(self._list) - def itervalues(self): return iter([self[key] for key in self._list]) - def iterkeys(self): return self.__iter__() - def iteritems(self): return iter([(key, self[key]) for key in self.keys()]) - def __delitem__(self, key): try: del self._list[self._list.index(key)] except ValueError: raise KeyError(key) dict.__delitem__(self, key) - def __setitem__(self, key, object): if not self.has_key(key): self._list.append(key) dict.__setitem__(self, key, object) - def __getitem__(self, key): return dict.__getitem__(self, key) @@ -230,6 +179,7 @@ class ThreadLocal(object): self._tdict["%d_%s" % (thread.get_ident(), key)] = value class DictDecorator(dict): + """a Dictionary that delegates items not found to a second wrapped dictionary.""" def __init__(self, decorate): self.decorate = decorate def __getitem__(self, key): @@ -239,8 +189,9 @@ class DictDecorator(dict): return self.decorate[key] def __repr__(self): return dict.__repr__(self) + repr(self.decorate) + class HashSet(object): - """implements a Set.""" + """implements a Set, including ordering capability""" def __init__(self, iter=None, ordered=False): if ordered: self.map = OrderedDict() @@ -474,6 +425,12 @@ class ScopedRegistry(object): def constructor_args(instance, **kwargs): + """given an object instance and keyword arguments, inspects the + argument signature of the instance's __init__ method and returns + a tuple of list and keyword arguments, suitable for creating a new + instance of the class. The returned arguments are drawn from the + given keyword dictionary, or if not found are drawn from the + corresponding attributes of the original instance.""" classobj = instance.__class__ argspec = inspect.getargspec(classobj.__init__.im_func) -- 2.47.2