diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-05-06 17:07:24 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-05-06 17:07:24 -0400 |
| commit | 1b120563905e29f9769fd6d2ce39922d15cebf7f (patch) | |
| tree | f987041976e8aa32b8f3e554cf1c50ba1fec55b2 /lib/sqlalchemy/util | |
| parent | 5c852409219e18fb3d3b1403bfc872b3fe99f802 (diff) | |
| download | sqlalchemy-1b120563905e29f9769fd6d2ce39922d15cebf7f.tar.gz | |
- Fixed unexpected-use regression where in the odd case that the
primaryjoin of a relationship involved comparison to an unhashable
type such as an HSTORE, lazy loads would fail due to a hash-oriented
check on the statement parameters, modified in 1.0 as a result of
:ticket:`3061` to use hashing and modified in :ticket:`3368`
to occur in cases more common than "load on pending".
The values are now checked for the ``__hash__`` attribute beforehand.
fixes #3416
Diffstat (limited to 'lib/sqlalchemy/util')
| -rw-r--r-- | lib/sqlalchemy/util/__init__.py | 2 | ||||
| -rw-r--r-- | lib/sqlalchemy/util/_collections.py | 13 |
2 files changed, 14 insertions, 1 deletions
diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index d777d2e06..ed968f168 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -19,7 +19,7 @@ from ._collections import KeyedTuple, ImmutableContainer, immutabledict, \ OrderedSet, IdentitySet, OrderedIdentitySet, column_set, \ column_dict, ordered_column_set, populate_column_dict, unique_list, \ UniqueAppender, PopulateDict, EMPTY_SET, to_list, to_set, \ - to_column_set, update_copy, flatten_iterator, \ + to_column_set, update_copy, flatten_iterator, has_intersection, \ LRUCache, ScopedRegistry, ThreadLocalRegistry, WeakSequence, \ coerce_generator_arg, lightweight_named_tuple diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index db2c21949..5c62ebed8 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -800,6 +800,19 @@ def to_list(x, default=None): return list(x) +def has_intersection(set_, iterable): + """return True if any items of set_ are present in iterable. + + Goes through special effort to ensure __hash__ is not called + on items in iterable that don't support it. + + """ + # TODO: optimize, write in C, etc. + return bool( + set_.intersection([i for i in iterable if i.__hash__]) + ) + + def to_set(x): if x is None: return set() |
