Commit 5e509568 authored by Jérome Perrin's avatar Jérome Perrin

ZSQLCatalog: support dict.keys()/items() as search values

constructs like `portal_catalog(title=d.keys())` were allowed on
python2, we can allow them on python3 as well.
parent 7a0d354c
Pipeline #33327 passed with stage
in 0 seconds
...@@ -132,6 +132,9 @@ else: ...@@ -132,6 +132,9 @@ else:
return wrapper return wrapper
list_type_list = list, tuple, set, frozenset list_type_list = list, tuple, set, frozenset
if six.PY3:
import collections.abc
list_type_list = list_type_list + (collections.abc.MappingView,)
try: try:
from ZPublisher.HTTPRequest import record from ZPublisher.HTTPRequest import record
except ImportError: except ImportError:
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
############################################################################## ##############################################################################
from functools import partial from functools import partial
import collections
import unittest import unittest
from Products.ZSQLCatalog.SQLCatalog import Catalog as SQLCatalog from Products.ZSQLCatalog.SQLCatalog import Catalog as SQLCatalog
from Products.ZSQLCatalog.SQLCatalog import Query from Products.ZSQLCatalog.SQLCatalog import Query
...@@ -40,6 +41,7 @@ from DateTime import DateTime ...@@ -40,6 +41,7 @@ from DateTime import DateTime
from Products.ZSQLCatalog.SQLExpression import MergeConflictError from Products.ZSQLCatalog.SQLExpression import MergeConflictError
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
import six import six
from AccessControl.ZopeGuards import guarded_getattr
class MatchList(list): class MatchList(list):
def __repr__(self): def __repr__(self):
...@@ -323,6 +325,24 @@ class TestSQLCatalog(ERP5TypeTestCase): ...@@ -323,6 +325,24 @@ class TestSQLCatalog(ERP5TypeTestCase):
{column: ['a', 'b']}) {column: ['a', 'b']})
self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=['a', 'b']), operator='and'), self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=['a', 'b']), operator='and'),
{column: ['=a', '=b']}) {column: ['=a', '=b']})
self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=['a', 'b']), operator='and'),
{column: ('a', 'b')})
self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=MatchList((['a', 'b'], ['b', 'a']))), operator='and'),
{column: set('ab')})
self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=MatchList((['a', 'b'], ['b', 'a']))), operator='and'),
{column: {'a': 1, 'b': 2}.keys()})
self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=MatchList((['a', 'b'], ['b', 'a']))), operator='and'),
{column: {1: 'a', 2: 'b'}.values()})
# dict-like are also supported
self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=['a', 'b']), operator='and'),
{column: collections.OrderedDict((('a', 1), ('b', 2))).keys()})
self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=['a', 'b']), operator='and'),
{column: collections.OrderedDict(((1, 'a'), (2, 'b'))).values()})
# restricted versions as well
self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=MatchList((['a', 'b'], ['b', 'a']))), operator='and'),
{column: guarded_getattr({'a': 1, 'b': 2}, 'keys')()})
self.catalog(ReferenceQuery(ReferenceQuery(operator='in', default=MatchList((['a', 'b'], ['b', 'a']))), operator='and'),
{column: guarded_getattr({1: 'a', 2: 'b'}, 'values')()})
def test_DefaultKey(self): def test_DefaultKey(self):
self._testDefaultKey('default') self._testDefaultKey('default')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment