Skip to content

Commit

Permalink
Match the Py2 and Py3 behaviour of the rest of the queries
Browse files Browse the repository at this point in the history
Not just the one that we previously had a test for. Add tests for these.
  • Loading branch information
jamadden committed May 9, 2017
1 parent 547f7ed commit 5a42a8a
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 20 deletions.
2 changes: 1 addition & 1 deletion CHANGES.rst
Expand Up @@ -6,7 +6,7 @@
==================

- Add support for Python 3.4, 3.5, 3.6 and PyPy. Note that the
``zopyx.txng3.ext`` stemmer is not available on Python 3.4 or PyPy.
``zopyx.txng3.ext`` stemmer is not available on Python 3.

- Remove test dependency on zope.app.zcmlfiles and zope.app.testing,
among others.
Expand Down
4 changes: 3 additions & 1 deletion setup.py
Expand Up @@ -109,7 +109,9 @@ def read(*rnames):
'zope.app.form',
'zope.browsermenu',
],
'stemmer:platform_python_implementation=="CPython" and python_version=="2.7"': [
'stemmer:python_version=="2.7"': [
# This is only available on Python 2. It compiles
# and runs under both CPython and PyPy.
'zopyx.txng3.ext',
],
'stemmer:python_version >= "3.3"': [
Expand Down
39 changes: 27 additions & 12 deletions src/zc/catalog/index.py
Expand Up @@ -227,18 +227,21 @@ def apply(self, query): # any_of, any, between, none,
[s for s in (values_to_documents.get(v) for v in query)
if s is not None])
except TypeError:
return None
return []
elif query_type == 'any':
if query is None:
res = self.family.IF.Set(self.ids())
else:
assert zc.catalog.interfaces.IExtent.providedBy(query)
res = query & self.family.IF.Set(self.ids())
elif query_type == 'between':
res = self.family.IF.multiunion(
[s for s in (values_to_documents.get(v) for v in
values_to_documents.keys(*query))
if s is not None])
try:
res = self.family.IF.multiunion(
[s for s in (values_to_documents.get(v) for v in
values_to_documents.keys(*query))
if s is not None])
except TypeError:
return []
elif query_type == 'none':
assert zc.catalog.interfaces.IExtent.providedBy(query)
res = query - self.family.IF.Set(self.ids())
Expand Down Expand Up @@ -324,8 +327,11 @@ def apply(self, query): # any_of, any, between, none, all_of
elif query_type == 'any_of':
res = self.family.IF.Bucket()
for v in query:
_, res = self.family.IF.weightedUnion(
res, values_to_documents.get(v))
try:
_, res = self.family.IF.weightedUnion(
res, values_to_documents.get(v))
except TypeError:
continue
elif query_type == 'any':
if query is None:
res = self.family.IF.Set(self.ids())
Expand All @@ -340,18 +346,27 @@ def apply(self, query): # any_of, any, between, none, all_of
res = values_to_documents.get(next(values), empty)
except StopIteration:
res = empty
except TypeError:
return []

while res:
try:
v = next(values)
except StopIteration:
break
res = self.family.IF.intersection(
res, values_to_documents.get(v, empty))
try:
res = self.family.IF.intersection(
res, values_to_documents.get(v, empty))
except TypeError:
return []
elif query_type == 'between':
res = self.family.IF.Bucket()
for v in values_to_documents.keys(*query):
_, res = self.family.IF.weightedUnion(
res, values_to_documents.get(v))
try:
for v in values_to_documents.keys(*query):
_, res = self.family.IF.weightedUnion(
res, values_to_documents.get(v))
except TypeError:
return []
elif query_type == 'none':
assert zc.catalog.interfaces.IExtent.providedBy(query)
res = query - self.family.IF.Set(self.ids())
Expand Down
23 changes: 20 additions & 3 deletions src/zc/catalog/setindex.rst
Expand Up @@ -72,15 +72,22 @@ The index supports five types of query. The first is 'any_of'. It
takes an iterable of values, and returns an iterable of document ids that
contain any of the values. The results are weighted.

>>> list(index.apply({'any_of':('b', '1', '5')}))
>>> list(index.apply({'any_of': ('b', '1', '5')}))
[1, 2, 3, 4, 6, 8]
>>> list(index.apply({'any_of': ('b', '1', '5')}))
[1, 2, 3, 4, 6, 8]
>>> list(index.apply({'any_of':('42',)}))
>>> list(index.apply({'any_of': ('42',)}))
[]
>>> index.apply({'any_of': ('a', '3', '7')}) # doctest: +ELLIPSIS
BTrees...FBucket([(1, 1.0), (2, 3.0), (5, 1.0), (6, 1.0), (9, 2.0)])

Using an invalid (non-comparable on Python 3) argument is ignored:

>>> list(index.apply({'any_of': (1,)}))
[]
>>> list(index.apply({'any_of': (1, '1')}))
[1, 3, 4, 8]

Another query is 'any'. If the key is None, all indexed document ids with any
values are returned. If the key is an extent, the intersection of the extent
and all document ids with any values is returned.
Expand Down Expand Up @@ -111,6 +118,10 @@ weighted.
[1, 2, 9]
>>> list(index.apply({'all_of': ('3', '4')}))
[2, 9]
>>> list(index.apply({'all_of': (3, '4')}))
[]
>>> list(index.apply({'all_of': ('3', 4)}))
[]

These tests illustrate two related reported errors that have been fixed.

Expand All @@ -137,6 +148,12 @@ defaults to False. The results are weighted.
>>> index.apply({'between': ('2', '6')}) # doctest: +ELLIPSIS
BTrees...FBucket([(2, 2.0), (4, 1.0), (6, 2.0), (8, 1.0), (9, 4.0)])

Using invalid (non-comparable on Python 3) arguments produces no results:

>>> list(index.apply({'between': (1, 7)}))
[]


The 'none' argument takes an extent and returns the ids in the extent
that are not indexed; it is intended to be used to return docids that have
no (or empty) values.
Expand All @@ -158,7 +175,7 @@ Using none of them simply returns None.

Invalid query names cause ValueErrors.

>>> index.apply({'foo':()})
>>> index.apply({'foo': ()})
... # doctest: +ELLIPSIS
Traceback (most recent call last):
...
Expand Down
12 changes: 9 additions & 3 deletions src/zc/catalog/valueindex.rst
Expand Up @@ -71,13 +71,13 @@ The index supports four types of query. The first is 'any_of'. It
takes an iterable of values, and returns an iterable of document ids that
contain any of the values. The results are not weighted.

>>> list(index.apply({'any_of':('b', 'c')}))
>>> list(index.apply({'any_of': ('b', 'c')}))
[2, 4, 6, 7, 8, 9]
>>> list(index.apply({'any_of': ('b',)}))
[2, 8]
>>> list(index.apply({'any_of': ('d',)}))
[5]
>>> bool(index.apply({'any_of':(42,)}))
>>> bool(index.apply({'any_of': (42,)}))
False

Another query is 'any', If the key is None, all indexed document ids with any
Expand Down Expand Up @@ -117,6 +117,12 @@ defaults to False. The results are not weighted.
>>> list(index.apply({'between': ('b', 'd', True, True)}))
[4, 6, 7, 9]

Using an invalid (non-comparable on Python 3) argument to between produces
nothing:

>>> list(index.apply({'between': (1, 5)}))
[]

The 'none' argument takes an extent and returns the ids in the extent
that are not indexed; it is intended to be used to return docids that have
no (or empty) values.
Expand All @@ -138,7 +144,7 @@ Using none of them simply returns None.

Invalid query names cause ValueErrors.

>>> index.apply({'foo':()})
>>> index.apply({'foo': ()})
... # doctest: +ELLIPSIS
Traceback (most recent call last):
...
Expand Down

0 comments on commit 5a42a8a

Please sign in to comment.