Skip to content

Commit

Permalink
black
Browse files Browse the repository at this point in the history
  • Loading branch information
mamico committed Sep 4, 2024
1 parent 15fe7e5 commit 462b86f
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 113 deletions.
1 change: 1 addition & 0 deletions buildout.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ parts =

[versions]
experimental.catalogplan =
packaging = 24.1

[interpreter]
recipe = zc.recipe.egg
Expand Down
100 changes: 50 additions & 50 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
# -*- coding: utf-8 -*-
from setuptools import find_packages, setup

version = '1.0.0a4.dev0'
version = "1.0.0a4.dev0"

setup(name='experimental.catalogplan',
version=version,
description="Experimental ZCatalog plan",
long_description=(open("README.rst").read() + "\n" +
open("CHANGES.rst").read()),
long_description_content_type="text/x-rst",
# Get more strings from
# http://pypi.python.org/pypi?:action=list_classifiers
classifiers=[
'Framework :: Zope2',
'Framework :: Plone',
'Framework :: Plone :: 4.3',
'Framework :: Plone :: 5.0',
'Framework :: Plone :: 5.1',
'Framework :: Plone :: 5.2',
'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
],
keywords='monkeypatch traverse',
author='Mauro Amico',
author_email='mauro.amico@gmail.com',
url='https://github.com/mamico/experimental.catalogplan',
project_urls={
'Issue Tracker': 'https://github.com/mamico/'
'experimental.catalogplan/issues',
'Sources': 'https://github.com/mamico/experimental.catalogplan',
},
license='BSD',
packages=find_packages('src'),
package_dir={'': 'src'},
namespace_packages=['experimental', ],
include_package_data=True,
zip_safe=False,
test_suite="experimental.catalogplan",
install_requires=[
'setuptools',
# -*- Extra requirements: -*-
'Products.ZCatalog>3.0,<6.3',
],
extras_require={
'test': ['Products.CMFPlone[test]']
},
entry_points="""
setup(
name="experimental.catalogplan",
version=version,
description="Experimental ZCatalog plan",
long_description=(open("README.rst").read() + "\n" + open("CHANGES.rst").read()),
long_description_content_type="text/x-rst",
# Get more strings from
# http://pypi.python.org/pypi?:action=list_classifiers
classifiers=[
"Framework :: Zope2",
"Framework :: Plone",
"Framework :: Plone :: 4.3",
"Framework :: Plone :: 5.0",
"Framework :: Plone :: 5.1",
"Framework :: Plone :: 5.2",
"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
"Programming Language :: Python",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
],
keywords="monkeypatch traverse",
author="Mauro Amico",
author_email="mauro.amico@gmail.com",
url="https://github.com/mamico/experimental.catalogplan",
project_urls={
"Issue Tracker": "https://github.com/mamico/" "experimental.catalogplan/issues",
"Sources": "https://github.com/mamico/experimental.catalogplan",
},
license="BSD",
packages=find_packages("src"),
package_dir={"": "src"},
namespace_packages=[
"experimental",
],
include_package_data=True,
zip_safe=False,
test_suite="experimental.catalogplan",
install_requires=[
"setuptools",
# -*- Extra requirements: -*-
"six",
"Products.ZCatalog>3.0",
],
extras_require={"test": ["Products.CMFPlone[test]"]},
entry_points="""
# -*- Entry points: -*-
[z3c.autoinclude.plugin]
target = plone
""",
)
)
3 changes: 2 additions & 1 deletion src/experimental/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
__import__("pkg_resources").declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path

__path__ = extend_path(__path__, __name__)
24 changes: 10 additions & 14 deletions src/experimental/catalogplan/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import logging
import time

from importlib.metadata import version
from Products.PluginIndexes.interfaces import ILimitedResultIndex
from Products.ZCatalog.plan import Benchmark, CatalogPlan, PriorityMap

Expand Down Expand Up @@ -49,27 +49,23 @@ def CatalogPlan_make_key(self, query):
key.append((name, repr(v)))

# --------- >8 ------------------------------------------------
operatorkeys = [
name for name in key
if isinstance(query.get(name), dict)
]
operatorkeys = [name for name in key if isinstance(query.get(name), dict)]
if operatorkeys:
key = [name for name in key if name not in operatorkeys]
key.extend([
(name, tuple(sorted(query[name].keys()))) for name in operatorkeys
])
key.extend([(name, tuple(sorted(query[name].keys()))) for name in operatorkeys])
# --------- 8< ------------------------------------------------

# Workaround: Python 2.x accepted different types as sort key
# for the sorted builtin. Python 3 only sorts on identical types.
tuple_keys = set(key) - set(
[x for x in key if not isinstance(x, tuple)])
tuple_keys = set(key) - set([x for x in key if not isinstance(x, tuple)])
str_keys = set(key) - tuple_keys
return tuple(sorted(str_keys)) + tuple(sorted(tuple_keys))


logger.info("*** CatalogPlan.stop monkey patch ***")
CatalogPlan.stop = CatalogPlan_stop
# if ZCatalog < 6.4
if version("Products.ZCatalog") < "6.4":
logger.info("*** CatalogPlan.stop monkey patch ***")
CatalogPlan.stop = CatalogPlan_stop

logger.info("*** CatalogPlan.make_key monkey patch ***")
CatalogPlan.make_key = CatalogPlan_make_key
logger.info("*** CatalogPlan.make_key monkey patch ***")
CatalogPlan.make_key = CatalogPlan_make_key
75 changes: 27 additions & 48 deletions src/experimental/catalogplan/tests/test_plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ def numbers(self):
return (self.num, self.num + 1)

def getPhysicalPath(self):
return '/{0}'.format(self.num)
return "/{0}".format(self.num)

def start(self):
return '2013-07-{0:02d}'.format(self.num + 1)
return "2013-07-{0:02d}".format(self.num + 1)

def end(self):
return '2013-07-{0:02d}'.format(self.num + 2)
return "2013-07-{0:02d}".format(self.num + 2)


class TestCatalogPlan(cleanup.CleanUp, unittest.TestCase):
Expand All @@ -46,10 +46,11 @@ def assertRegex(self, *args, **kwargs):

def setUp(self):
cleanup.CleanUp.setUp(self)
self.cat = Catalog('catalog')
self.cat = Catalog("catalog")

def _makeOne(self, catalog=None, query=None):
from Products.ZCatalog.plan import CatalogPlan

if catalog is None:
catalog = self.cat
return CatalogPlan(catalog, query=query)
Expand All @@ -61,14 +62,12 @@ def test_getCatalogPlan_partial(self):
class SlowFieldIndex(FieldIndex):
def query_index(self, record, resultset=None):
time.sleep(0.1)
return super(SlowFieldIndex, self).query_index(
record, resultset)
return super(SlowFieldIndex, self).query_index(record, resultset)

class SlowerDateRangeIndex(DateRangeIndex):
def query_index(self, record, resultset=None):
time.sleep(0.2)
return super(SlowerDateRangeIndex, self).query_index(
record, resultset)
return super(SlowerDateRangeIndex, self).query_index(record, resultset)

cat.addIndex("num", SlowFieldIndex("num"))
cat.addIndex("numbers", KeywordIndex("numbers"))
Expand All @@ -85,95 +84,75 @@ def query_index(self, record, resultset=None):

# without a plan index are orderd alphabetically by default
self.assertEqual(zcat._catalog.getCatalogPlan(query1).plan(), None)
self.assertEqual(
cat._sorted_search_indexes(query1),
["date", "num", "numbers"]
)
self.assertEqual(cat._sorted_search_indexes(query1), ["date", "num", "numbers"])

self.assertEqual([b.getPath() for b in zcat.search(query1)], ["2"])
self.assertRegex(
zcat.getCatalogPlan(),
r"(?ms).*'date':\s*\([0-9\.]+, [0-9\.]+, True\)"
zcat.getCatalogPlan(), r"(?ms).*'date':\s*\([0-9\.]+, [0-9\.]+, True\)"
)
self.assertRegex(
zcat.getCatalogPlan(),
r"(?ms).*'num':\s*\([0-9\.]+, [0-9\.]+, True\)"
zcat.getCatalogPlan(), r"(?ms).*'num':\s*\([0-9\.]+, [0-9\.]+, True\)"
)
self.assertRegex(
zcat.getCatalogPlan(),
r"(?ms).*'numbers':\s*\([0-9\.]+, [0-9\.]+, True\)"
zcat.getCatalogPlan(), r"(?ms).*'numbers':\s*\([0-9\.]+, [0-9\.]+, True\)"
)

# after first search field are orderd by speed
self.assertEqual(
cat.getCatalogPlan(query2).plan(), ["numbers", "num", "date"])
self.assertEqual(cat.getCatalogPlan(query2).plan(), ["numbers", "num", "date"])

self.assertEqual([b.getPath() for b in zcat.search(query2)], [])

# `date', `num`, and `numbers` are all involved to filter the
# results(limit flag) despite in the last query search whitin
# `num` and `date` wasn't done
self.assertRegex(
zcat.getCatalogPlan(),
r"(?ms).*'date':\s*\([0-9\.]+, [0-9\.]+, True\)"
zcat.getCatalogPlan(), r"(?ms).*'date':\s*\([0-9\.]+, [0-9\.]+, True\)"
)
self.assertRegex(
zcat.getCatalogPlan(),
r"(?ms).*'num':\s*\([0-9\.]+, [0-9\.]+, True\)"
zcat.getCatalogPlan(), r"(?ms).*'num':\s*\([0-9\.]+, [0-9\.]+, True\)"
)
self.assertRegex(
zcat.getCatalogPlan(),
r"(?ms).*'numbers':\s*\([0-9\.]+, [0-9\.]+, True\)"
)
self.assertEqual(
cat.getCatalogPlan(query2).plan(), ["numbers", "num", "date"]
zcat.getCatalogPlan(), r"(?ms).*'numbers':\s*\([0-9\.]+, [0-9\.]+, True\)"
)
self.assertEqual(cat.getCatalogPlan(query2).plan(), ["numbers", "num", "date"])

# search again doesn't change the index order
self.assertEqual([b.getPath() for b in zcat.search(query1)], ["2"])
self.assertEqual(
cat.getCatalogPlan(query2).plan(), ["numbers", "num", "date"]
)
self.assertEqual(cat.getCatalogPlan(query2).plan(), ["numbers", "num", "date"])

def test_not_query(self):
# not query is generally slower, force this behavior for testing
class SlowNotFieldIndex(FieldIndex):
def query_index(self, record, resultset=None):
if getattr(record, 'not', None):
if getattr(record, "not", None):
time.sleep(0.1)
return super(SlowNotFieldIndex, self).query_index(
record, resultset)
return super(SlowNotFieldIndex, self).query_index(record, resultset)

zcat = ZCatalog("catalog")
cat = zcat._catalog
cat.addIndex(
'num1', SlowNotFieldIndex('num1', extra={"indexed_attrs": "num"}))
cat.addIndex(
'num2', SlowNotFieldIndex('num2', extra={"indexed_attrs": "num"}))
cat.addIndex("num1", SlowNotFieldIndex("num1", extra={"indexed_attrs": "num"}))
cat.addIndex("num2", SlowNotFieldIndex("num2", extra={"indexed_attrs": "num"}))
for i in range(100):
obj = Dummy(i)
zcat.catalog_object(obj, str(i))

query1 = {"num1": {"not": 2}, "num2": 3}
query2 = {"num1": 2, "num2": {'not': 5}}
query2 = {"num1": 2, "num2": {"not": 5}}

# without a plan index are orderd alphabetically by default
for query in [query1, query2]:
self.assertEqual(zcat._catalog.getCatalogPlan(query).plan(), None)
self.assertEqual(
cat._sorted_search_indexes(query),
["num1", "num2"]
)
self.assertEqual(cat._sorted_search_indexes(query), ["num1", "num2"])

self.assertEqual([b.getPath() for b in zcat.search(query1)], ['3'])
self.assertEqual([b.getPath() for b in zcat.search(query2)], ['2'])
self.assertEqual([b.getPath() for b in zcat.search(query1)], ["3"])
self.assertEqual([b.getPath() for b in zcat.search(query2)], ["2"])
# although there are the same fields, the plans are different, and the
# slower `not` query put the field as second in the plan
self.assertEqual(cat.getCatalogPlan(query1).plan(), ["num2", "num1"])
self.assertEqual(cat.getCatalogPlan(query2).plan(), ["num1", "num2"])

# search again doesn't change the order
self.assertEqual([b.getPath() for b in zcat.search(query1)], ['3'])
self.assertEqual([b.getPath() for b in zcat.search(query2)], ['2'])
self.assertEqual([b.getPath() for b in zcat.search(query1)], ["3"])
self.assertEqual([b.getPath() for b in zcat.search(query2)], ["2"])
self.assertEqual(cat.getCatalogPlan(query1).plan(), ["num2", "num1"])
self.assertEqual(cat.getCatalogPlan(query2).plan(), ["num1", "num2"])

0 comments on commit 462b86f

Please sign in to comment.