Skip to content

Instantly share code, notes, and snippets.

@zzzeek
Created May 30, 2013 22:00
Show Gist options
  • Select an option

  • Save zzzeek/5681612 to your computer and use it in GitHub Desktop.

Select an option

Save zzzeek/5681612 to your computer and use it in GitHub Desktop.
diff --git a/lib/sqlalchemy/sql/expression.py b/lib/sqlalchemy/sql/expression.py
index 5820cb1..f26ca12 100644
--- a/lib/sqlalchemy/sql/expression.py
+++ b/lib/sqlalchemy/sql/expression.py
@@ -1262,6 +1262,14 @@ def false():
return False_()
+_unhashable = object()
+def _hash(*values):
+
+ if _unhashable in values:
+ return _unhashable
+ else:
+ return hash(values)
+
class _FunctionGenerator(object):
"""Generate :class:`.Function` objects based on getattr calls."""
@@ -1669,6 +1677,7 @@ class ClauseElement(Visitable):
"""
c = self.__class__.__new__(self.__class__)
c.__dict__ = self.__dict__.copy()
+ c.__dict__.pop('_hash', None)
ClauseElement._cloned_set._reset(c)
ColumnElement.comparator._reset(c)
@@ -1681,6 +1690,11 @@ class ClauseElement(Visitable):
return c
+ @util.memoized_property
+ def _hash(self):
+ # not hashable
+ return _unhashable
+
@property
def _constructor(self):
"""return the 'constructor' for this ClauseElement.
@@ -2421,6 +2435,10 @@ class ColumnCollection(util.OrderedProperties):
self._data.update((c.key, c) for c in cols)
self.__dict__['_all_cols'] = util.column_set(self)
+ @util.memoized_property
+ def _hash(self):
+ return _hash(*(c._hash for c in self))
+
def __str__(self):
return repr([str(c) for c in self])
@@ -4432,6 +4450,16 @@ class ColumnClause(Immutable, ColumnElement):
self.type = sqltypes.to_instance(type_)
self.is_literal = is_literal
+ @util.memoized_property
+ def _hash(self):
+ return _hash(
+ hash(self.__class__),
+ hash(self.key),
+ hash(self.table.name),
+ self.type._hash,
+ hash(self.is_literal)
+ )
+
def _compare_name_for_result(self, other):
if self.is_literal or \
self.table is None or \
@@ -4586,6 +4614,14 @@ class TableClause(Immutable, FromClause):
for c in columns:
self.append_column(c)
+ @util.memoized_property
+ def _hash(self):
+ return _hash(
+ self.__class__,
+ hash(self.name),
+ self._columns._hash,
+ )
+
def _init_collections(self):
pass
diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py
index bfff053..16834d1 100644
--- a/lib/sqlalchemy/types.py
+++ b/lib/sqlalchemy/types.py
@@ -59,6 +59,10 @@ class TypeEngine(AbstractType):
def __reduce__(self):
return _reconstitute_comparator, (self.expr, )
+ @property
+ def _hash(self):
+ return id(self)
+
hashable = True
"""Flag, if False, means values from this type aren't hashable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment