From 71af58a9871a9a1cdc4f1e00d89a65f8d0dc0ffb Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 28 Apr 2021 05:06:48 +0800 Subject: [PATCH 01/26] positional mismatch on 4.4 --- montydb/engine/project.py | 19 +++++++++++++++++-- .../test_projection_positional.py | 14 +++++++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/montydb/engine/project.py b/montydb/engine/project.py index ad140d9..9912978 100644 --- a/montydb/engine/project.py +++ b/montydb/engine/project.py @@ -304,8 +304,12 @@ def _positional(fieldwalker): % field, code=2) - if (int(matched_index) >= elem_count and - self.matched.full_path.startswith(node.full_path)): + if _positional_mismatch( + int(matched_index), + elem_count, + self.matched.full_path, + node.full_path + ): raise OperationFailure( "Executor error during find command " ":: caused by :: errmsg: " @@ -318,6 +322,17 @@ def _positional(fieldwalker): return _positional +def _positional_mismatch_(matched, elem_count, matched_path, node_path): + return matched >= elem_count and matched_path.startswith(node_path) + + +def _positional_mismatch_v44(matched, elem_count, matched_path, node_path): + return matched >= elem_count + + +_positional_mismatch = _positional_mismatch_v44 + + def inclusion(fieldwalker, positioned, located_match, init_doc): _doc_type = fieldwalker.doc_type diff --git a/tests/test_engine/test_projection/test_projection_positional.py b/tests/test_engine/test_projection/test_projection_positional.py index 3de6735..9753f89 100644 --- a/tests/test_engine/test_projection/test_projection_positional.py +++ b/tests/test_engine/test_projection/test_projection_positional.py @@ -78,7 +78,7 @@ def test_projection_positional_4(monty_proj, mongo_proj): assert next(mongo_c) == next(monty_c) -def test_projection_positional_5(monty_proj, mongo_proj): +def test_projection_positional_5(monty_proj, mongo_proj, mongo_version): docs = [ {"a": {"b": [1, 2, 3], "c": [4, 5, 6]}}, {"a": {"b": [1, 2, 3], "c": [4]}}, @@ -91,8 +91,16 @@ def test_projection_positional_5(monty_proj, mongo_proj): assert count_documents(mongo_c, spec) == 2 assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) - for i in range(2): - assert next(mongo_c) == next(monty_c) + + if mongo_version[:2] >= [4, 4]: + with pytest.raises(mongo_op_fail) as mongo_err: + next(mongo_c) + + with pytest.raises(monty_op_fail) as monty_err: + next(monty_c) + else: + for i in range(1): + assert next(mongo_c) == next(monty_c) def test_projection_positional_6(monty_proj, mongo_proj): From 991072a013068bbd17403ed42d80bb61c3c52bd9 Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 28 Apr 2021 05:08:19 +0800 Subject: [PATCH 02/26] positional non located match on 4.4 --- montydb/engine/project.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/montydb/engine/project.py b/montydb/engine/project.py index 9912978..4ab168b 100644 --- a/montydb/engine/project.py +++ b/montydb/engine/project.py @@ -109,13 +109,9 @@ def __call__(self, fieldwalker): fieldwalker.go(path).get() if self.include_flag: - located_match = None - if self.matched is not None: - located_match = self.matched.located - projected = inclusion(fieldwalker, positioned, - located_match, + self.matched, init_doc) else: projected = exclusion(fieldwalker, init_doc) @@ -333,8 +329,9 @@ def _positional_mismatch_v44(matched, elem_count, matched_path, node_path): _positional_mismatch = _positional_mismatch_v44 -def inclusion(fieldwalker, positioned, located_match, init_doc): +def inclusion(fieldwalker, positioned, matched, init_doc): _doc_type = fieldwalker.doc_type + located_match = matched.located if matched else False def _inclusion(node, init_doc=None): doc = node.value @@ -368,7 +365,10 @@ def _inclusion(node, init_doc=None): if isinstance(child.value, _doc_type): new_doc.append(child.value) else: - new_doc.append(child.value) + if _include_positional_non_located_match(matched, node): + new_doc.append(child.value) + else: + new_doc.append(_doc_type()) return new_doc or _no_val @@ -406,6 +406,18 @@ def _inclusion(node, init_doc=None): return _inclusion(fieldwalker.tree.root, init_doc) +def _include_positional_non_located_match_(matched, node): + return True + + +def _include_positional_non_located_match_v44(matched, node): + return matched.full_path.startswith(node.full_path) + + +_include_positional_non_located_match = \ + _include_positional_non_located_match_v44 + + def exclusion(fieldwalker, init_doc): _doc_type = fieldwalker.doc_type From c947bbaa46d5ea5860a42004d479b8144e45e8e5 Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 28 Apr 2021 13:10:50 +0800 Subject: [PATCH 03/26] fix deprecation warnings --- montydb/base.py | 9 +++++---- montydb/client.py | 4 ++-- montydb/engine/queries.py | 5 ++++- montydb/engine/weighted.py | 5 ++++- montydb/utils/io.py | 2 +- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/montydb/base.py b/montydb/base.py index a10009b..c8737ac 100644 --- a/montydb/base.py +++ b/montydb/base.py @@ -18,11 +18,12 @@ # Assembling crucial classes and functions form pymongo module, # some of them may modified by needs. +try: + from collections.abc import MutableMapping +except ImportError: + from collections import MutableMapping -from collections import ( - OrderedDict, - MutableMapping, -) +from collections import OrderedDict from .types import ( abc, iteritems, diff --git a/montydb/client.py b/montydb/client.py index fceb812..3d3d898 100644 --- a/montydb/client.py +++ b/montydb/client.py @@ -128,9 +128,9 @@ def get_database(self, name): """ # verify database name if platform.system() == "Windows": - is_invaild = set('/\. "$*<>:|?').intersection(set(name)) + is_invaild = set(r'/\. "$*<>:|?').intersection(set(name)) else: - is_invaild = set('/\. "$').intersection(set(name)) + is_invaild = set(r'/\. "$').intersection(set(name)) if is_invaild or not name: raise errors.OperationFailure("Invaild database name.") diff --git a/montydb/engine/queries.py b/montydb/engine/queries.py index c209118..9aff0a5 100644 --- a/montydb/engine/queries.py +++ b/montydb/engine/queries.py @@ -2,7 +2,10 @@ import re from copy import deepcopy from datetime import datetime -from collections import Mapping +try: + from collections.abc import MutableMapping +except ImportError: + from collections import MutableMapping from ..errors import OperationFailure diff --git a/montydb/engine/weighted.py b/montydb/engine/weighted.py index bfed83f..68e8a7e 100644 --- a/montydb/engine/weighted.py +++ b/montydb/engine/weighted.py @@ -1,6 +1,9 @@ from datetime import datetime -from collections import Mapping +try: + from collections.abc import Mapping +except ImportError: + from collections import Mapping from ..types import ( integer_types, diff --git a/montydb/utils/io.py b/montydb/utils/io.py index f218b88..9d5731d 100644 --- a/montydb/utils/io.py +++ b/montydb/utils/io.py @@ -210,7 +210,7 @@ class MongoQueryRecorder(object): def __init__(self, mongodb, namespace=None, user=None): self._mongodb = mongodb - self._namespace = namespace or {"$regex": mongodb.name + "\..*"} + self._namespace = namespace or {"$regex": mongodb.name + r"\..*"} self._user = user self._epoch = datetime(1970, 1, 1) From 084b0f933794e45093e1cb7b5006099b03ba1c68 Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 28 Apr 2021 13:18:29 +0800 Subject: [PATCH 04/26] set 4.4 as compat version --- montydb/configure.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/montydb/configure.py b/montydb/configure.py index cd8dd8a..52e8587 100644 --- a/montydb/configure.py +++ b/montydb/configure.py @@ -18,7 +18,7 @@ URI_SCHEME_PREFIX = "montydb://" -MONGO_COMPAT_VERSIONS = ("3.6", "4.0", "4.2") +MONGO_COMPAT_VERSIONS = ("3.6", "4.0", "4.2", "4.4") _pinned_repository = {"_": None} @@ -199,7 +199,7 @@ def set_storage(repository=None, storage = storage or DEFAULT_STORAGE - valid_versions = list(MONGO_COMPAT_VERSIONS) + ["4.4"] + valid_versions = list(MONGO_COMPAT_VERSIONS) if mongo_version and mongo_version not in valid_versions: raise ConfigurationError( "Unknown mongodb version: %s, currently supported versions are: %s" From 7ba6a9c25608d284d10e9a7f16b8df7ba6d4754e Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 28 Apr 2021 13:19:25 +0800 Subject: [PATCH 05/26] check positional key position --- montydb/engine/project.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/montydb/engine/project.py b/montydb/engine/project.py index 4ab168b..3ed8d7a 100644 --- a/montydb/engine/project.py +++ b/montydb/engine/project.py @@ -61,6 +61,11 @@ def _perr_doc(val): return "{ " + ", ".join(v_lis) + " }" +_check_positional_key_ = False +_check_positional_key_v44 = True +_check_positional_key = _check_positional_key_v44 + + class Projector(object): """ """ @@ -182,6 +187,10 @@ def parser(self, spec, qfilter): elif key == "_id" and not _is_include(val): self.proj_with_id = False + elif _check_positional_key and key.startswith("$."): + raise OperationFailure( + "FieldPath field names may not start with '$'.") + else: # Normal field options, include or exclude. flag = _is_include(val) @@ -216,6 +225,15 @@ def parser(self, spec, qfilter): "Positional projection '{}' contains the positional " "operator more than once.".format(key)) + if _check_positional_key and ".$." in key: + raise OperationFailure( + "As of 4.4, it's illegal to specify positional " + "operator in the middle of a path.Positional " + "projection may only be used at the end, for example: " + "a.b.$. If the query previously used a form like " + "a.b.$.d, remove the parts following the '$' and the " + "results will be equivalent.", code=31394) + path = key.split(".$", 1)[0] conditions = qfilter.conditions match_query = _is_positional_match(conditions, path) From 39c3ba1a9d3e5d37240ad3615cd1d653bfd450d1 Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 28 Apr 2021 13:19:51 +0800 Subject: [PATCH 06/26] update compat attributes --- montydb/configure.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/montydb/configure.py b/montydb/configure.py index 52e8587..4aeeb79 100644 --- a/montydb/configure.py +++ b/montydb/configure.py @@ -277,7 +277,7 @@ def _bson_init(use_bson): def _mongo_compat(version): - from .engine import queries + from .engine import queries, project if version.startswith("3"): v3 = getattr(queries, "_is_comparable_ver3") @@ -293,3 +293,18 @@ def _mongo_compat(version): else: setattr(queries, "_regex_options_check", getattr(queries, "_regex_options_")) + + if version == "4.4": + setattr(project, "_positional_mismatch", + getattr(project, "_positional_mismatch_v44")) + setattr(project, "_check_positional_key", + getattr(project, "_check_positional_key_v44")) + setattr(project, "_include_positional_non_located_match", + getattr(project, "_include_positional_non_located_match_v44")) + else: + setattr(project, "_positional_mismatch", + getattr(project, "_positional_mismatch_")) + setattr(project, "_check_positional_key", + getattr(project, "_check_positional_key_")) + setattr(project, "_include_positional_non_located_match", + getattr(project, "_include_positional_non_located_match_")) From 03f5061d9ef7c6cfc3ce6ca3de42bf70f05b0f86 Mon Sep 17 00:00:00 2001 From: David Lai Date: Wed, 28 Apr 2021 13:37:01 +0800 Subject: [PATCH 07/26] check field not end with "." --- montydb/engine/project.py | 6 ++-- .../test_projection_positional.py | 28 ++++++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/montydb/engine/project.py b/montydb/engine/project.py index 3ed8d7a..b697330 100644 --- a/montydb/engine/project.py +++ b/montydb/engine/project.py @@ -188,8 +188,10 @@ def parser(self, spec, qfilter): self.proj_with_id = False elif _check_positional_key and key.startswith("$."): - raise OperationFailure( - "FieldPath field names may not start with '$'.") + raise OperationFailure("FieldPath field names may not start " + "with '$'.") + elif _check_positional_key and key.endswith("."): + raise OperationFailure("FieldPath must not end with a '.'.") else: # Normal field options, include or exclude. diff --git a/tests/test_engine/test_projection/test_projection_positional.py b/tests/test_engine/test_projection/test_projection_positional.py index 9753f89..e7c47f8 100644 --- a/tests/test_engine/test_projection/test_projection_positional.py +++ b/tests/test_engine/test_projection/test_projection_positional.py @@ -245,7 +245,7 @@ def run(spec, proj): run(spec, proj) -def test_projection_positional_12(monty_proj, mongo_proj): +def test_projection_positional_12(monty_proj, mongo_proj, mongo_version): docs = [ {"a": [{"b": [{"c": 1}, {"x": 1}]}, {"b": [{"c": 1}, {"x": 1}]}]}, @@ -263,6 +263,16 @@ def run(proj): for i in range(2): assert next(mongo_c) == next(monty_c) + def fail(proj): + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + with pytest.raises(mongo_op_fail) as mongo_err: + next(mongo_c) + + with pytest.raises(monty_op_fail) as monty_err: + next(monty_c) + for ie in range(2): proj = {"a.b.5": ie} run(proj) @@ -280,13 +290,13 @@ def run(proj): run(proj) proj = {"a.b.c.": ie} # Redundant dot - run(proj) + run(proj) if mongo_version[:2] < [4, 4] else fail(proj) proj = {"a.b.c": ie} run(proj) -def test_projection_positional_13(monty_proj, mongo_proj): +def test_projection_positional_13(monty_proj, mongo_proj, mongo_version): docs = [ {"a": [{"b": [1, 5]}, {"b": 2}, {"b": [3, 10, 4]}], "c": [{"b": [1]}, {"b": 2}, {"b": [3, 5]}]}, @@ -301,11 +311,21 @@ def run(proj): assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) assert next(mongo_c) == next(monty_c) + def fail(proj): + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + with pytest.raises(mongo_op_fail) as mongo_err: + next(mongo_c) + + with pytest.raises(monty_op_fail) as monty_err: + next(monty_c) + proj = {"a.b.$": 1} run(proj) proj = {"a.$.b": 1} - run(proj) + run(proj) if mongo_version[:2] < [4, 4] else fail(proj) def test_projection_positional_14(monty_proj, mongo_proj): From fe7fe318aa9971b4e6ac27678762680ebf56add2 Mon Sep 17 00:00:00 2001 From: David Lai Date: Thu, 29 Apr 2021 02:55:45 +0800 Subject: [PATCH 08/26] fix typo from c947bbaa --- montydb/engine/queries.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/montydb/engine/queries.py b/montydb/engine/queries.py index 9aff0a5..9a6af61 100644 --- a/montydb/engine/queries.py +++ b/montydb/engine/queries.py @@ -3,9 +3,9 @@ from copy import deepcopy from datetime import datetime try: - from collections.abc import MutableMapping + from collections.abc import Mapping except ImportError: - from collections import MutableMapping + from collections import Mapping from ..errors import OperationFailure From 5a7b9a6b5ed844a92cb392ca2dd56c24a8419c6f Mon Sep 17 00:00:00 2001 From: David Lai Date: Sat, 29 May 2021 19:37:08 +0800 Subject: [PATCH 09/26] testing mongodb 4.4 --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 3945b04..d77c2cf 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -14,7 +14,7 @@ jobs: fail-fast: false matrix: python-version: [ 2.7, 3.7, 3.8, 3.9 ] - mongodb-version: [ "3.6", "4.0", "4.2" ] + mongodb-version: [ "3.6", "4.0", "4.2", "4.4" ] monty-storage: [ memory, flatfile, sqlite ] experimental: [ false ] include: From 894e92a0b46cd7f3f2558a3e424f8c6e2c7d32f2 Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Sun, 20 Jun 2021 17:22:19 +0800 Subject: [PATCH 10/26] flake8: bump max-complexity ./montydb/engine/project.py:121:5: C901 'Projector.parser' is too complex (29) --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 2085674..d8e4064 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -47,7 +47,7 @@ jobs: - name: Lint with flake8 run: | # Ideally max-complexity should be set to 10 - flake8 . --count --ignore=F841,W503 --max-complexity=26 --max-line-length=88 --statistics + flake8 . --count --ignore=F841,W503 --max-complexity=29 --max-line-length=88 --statistics - name: Find typos with codespell run: codespell --ignore-words-list=nd,nin From 18fa3993c0373531cd0f1b1dd987de0966153add Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Sun, 20 Jun 2021 19:13:45 +0800 Subject: [PATCH 11/26] project: fix regression --- montydb/engine/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/montydb/engine/project.py b/montydb/engine/project.py index 135d65e..0f54496 100644 --- a/montydb/engine/project.py +++ b/montydb/engine/project.py @@ -358,7 +358,7 @@ def _positional_mismatch_v44(matched, elem_count, matched_path, node_path): def inclusion(fieldwalker, positioned, matched, init_doc): _doc_type = fieldwalker.doc_type - located_match = matched.located if matched else False + located_match = False if matched is None else matched.located def _inclusion(node, init_doc=None): doc = node.value From 151c90e4f0b4792cb63d1d065440ca13af722763 Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Sun, 20 Jun 2021 22:21:20 +0800 Subject: [PATCH 12/26] tests: update projection test specific for 4.4 --- .../test_projection_positional.py | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/tests/test_engine/test_projection/test_projection_positional.py b/tests/test_engine/test_projection/test_projection_positional.py index c67e6e6..cd5aada 100644 --- a/tests/test_engine/test_projection/test_projection_positional.py +++ b/tests/test_engine/test_projection/test_projection_positional.py @@ -179,38 +179,60 @@ def test_projection_positional_10(monty_proj, mongo_proj): assert next(mongo_c) == next(monty_c) -def test_projection_positional_11(monty_proj, mongo_proj): +def test_projection_positional_11(monty_proj, mongo_proj, mongo_version): docs = [ - {"a": [{"b": [0, 1, 2]}, {"b": [3, 2, 4]}]}, + {"a": [{"b": [0, 1, 2], "c": {"d": "eek", "e": "arr"}}, + {"b": [3, 2, 4], "c": {"d": "foo", "e": "bar"}}]}, ] - def run(spec, proj): + def run(spec, proj, debug=None): monty_c = monty_proj(docs, spec, proj) mongo_c = mongo_proj(docs, spec, proj) assert count_documents(mongo_c, spec) == 1 assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) - assert next(mongo_c) == next(monty_c) + mongo_doc = next(mongo_c) + monty_doc = next(monty_c) + if debug: + print(debug, mongo_doc) + print(debug, monty_doc) + assert monty_doc == mongo_doc spec = {"a.b.2": 4} proj = {"a.b.$": 1} run(spec, proj) + spec = {"a.b.2": 4} + proj = {"a.c.d.$": 1} + run(spec, proj) + spec = {"a.b": 2} proj = {"a.b.$": 1} run(spec, proj) spec = {"a.b": 2} proj = {"a.$.b": 1} - run(spec, proj) + if mongo_version[:2] >= [4, 4]: + with pytest.raises(mongo_op_fail) as mongo_err: + run(spec, proj) + else: + run(spec, proj) spec = {"a.b": 2} proj = {"$.a.b": 1} - run(spec, proj) + if mongo_version[:2] >= [4, 4]: + with pytest.raises(mongo_op_fail) as mongo_err: + run(spec, proj) + else: + run(spec, proj) spec = {"a.b": 2} proj = {"a": 1, "$.a.b": 1} - run(spec, proj) + if mongo_version[:2] >= [4, 4]: + with pytest.raises(mongo_op_fail) as mongo_err: + run(spec, proj) + else: + run(spec, proj) for ie in range(2): spec = {"a.b": 2} @@ -229,12 +251,12 @@ def run(spec, proj): proj = {"a.b.0.1.x.$": 1} run(spec, proj) - for ie in range(2): + for ie in range(2): # exclude/include spec = {"a.b": 2} proj = {"a.b.0.1.x": ie} run(spec, proj) - for ie in range(2): + for ie in range(2): # exclude/include spec = {} proj = {"a.0.b.x": ie} run(spec, proj) From ce6a36cf17c1aeaf27ac52952c6a4cd1ac455757 Mon Sep 17 00:00:00 2001 From: David Lai Date: Thu, 8 Jul 2021 04:09:01 +0800 Subject: [PATCH 13/26] add projection path collision check --- montydb/configure.py | 4 ++ montydb/engine/project.py | 27 +++++++ .../test_projection_positional.py | 12 +++- .../test_projection_regular.py | 72 +++++++++++++++++++ 4 files changed, 113 insertions(+), 2 deletions(-) diff --git a/montydb/configure.py b/montydb/configure.py index 92e7303..bafe502 100644 --- a/montydb/configure.py +++ b/montydb/configure.py @@ -310,6 +310,8 @@ def _mongo_compat(version): getattr(project, "_positional_mismatch_v44")) setattr(project, "_check_positional_key", getattr(project, "_check_positional_key_v44")) + setattr(project, "_check_path_collision", + getattr(project, "_check_path_collision_v44")) setattr(project, "_include_positional_non_located_match", getattr(project, "_include_positional_non_located_match_v44")) else: @@ -317,5 +319,7 @@ def _mongo_compat(version): getattr(project, "_positional_mismatch_")) setattr(project, "_check_positional_key", getattr(project, "_check_positional_key_")) + setattr(project, "_check_path_collision", + getattr(project, "_check_path_collision_")) setattr(project, "_include_positional_non_located_match", getattr(project, "_include_positional_non_located_match_")) diff --git a/montydb/engine/project.py b/montydb/engine/project.py index 18b5668..c8e32ee 100644 --- a/montydb/engine/project.py +++ b/montydb/engine/project.py @@ -35,6 +35,15 @@ def _is_positional_match(conditions, match_field): return None +def _has_path_collision(path, parsed_paths): + path = path.split(".$")[0] + for parsed in parsed_paths: + if path == parsed \ + or path.startswith(parsed + ".") \ + or parsed.startswith(path + "."): + return parsed + + def _perr_doc(val): """ For pretty error msg, same as Mongo @@ -62,6 +71,10 @@ def _perr_doc(val): _check_positional_key_v44 = True _check_positional_key = _check_positional_key_v44 +_check_path_collision_ = False +_check_path_collision_v44 = True +_check_path_collision = _check_path_collision_v44 + class Projector(object): """ """ @@ -123,6 +136,20 @@ def parser(self, spec, qfilter): self.array_op_type = self.ARRAY_OP_NORMAL for key, val in spec.items(): + # check path collision (mongo-4.4+) + if _check_path_collision: + collision = _has_path_collision(key, self.regular_field) \ + or _has_path_collision(key, self.array_field.keys()) + if collision: + remaining = key[len(collision + "."):] + if remaining: + raise OperationFailure( + "Path collision at %s remaining portion %s" + % (collision, remaining) + ) + else: + raise OperationFailure("Path collision at %s" % key) + # Parsing options if is_duckument_type(val): if not len(val) == 1: diff --git a/tests/test_engine/test_projection/test_projection_positional.py b/tests/test_engine/test_projection/test_projection_positional.py index cd5aada..fae6a3e 100644 --- a/tests/test_engine/test_projection/test_projection_positional.py +++ b/tests/test_engine/test_projection/test_projection_positional.py @@ -370,7 +370,7 @@ def run(proj): run(proj) -def test_projection_positional_15(monty_proj, mongo_proj): +def test_projection_positional_15(monty_proj, mongo_proj, mongo_version): docs = [ {"a": [{"b": [0, 1, {"c": 5}]}, {"b": [3, 2, {"x": 5}]}]}, ] @@ -382,7 +382,15 @@ def test_projection_positional_15(monty_proj, mongo_proj): assert count_documents(mongo_c, spec) == 1 assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) - assert next(mongo_c) == next(monty_c) + + if mongo_version[:2] < [4, 4]: + assert next(mongo_c) == next(monty_c) + else: + # Path collision at a.b.x remaining portion b.x + with pytest.raises(mongo_op_fail): + next(mongo_c) + with pytest.raises(monty_op_fail): + next(monty_c) def test_projection_positional_err_2(monty_proj, mongo_proj): diff --git a/tests/test_engine/test_projection/test_projection_regular.py b/tests/test_engine/test_projection/test_projection_regular.py index b523a5d..7818e38 100644 --- a/tests/test_engine/test_projection/test_projection_regular.py +++ b/tests/test_engine/test_projection/test_projection_regular.py @@ -1,4 +1,10 @@ +import pytest + +from pymongo.errors import OperationFailure as mongo_op_fail +from montydb.errors import OperationFailure as monty_op_fail + + def count_documents(cursor, spec=None): return cursor.collection.count_documents(spec or {}) @@ -50,3 +56,69 @@ def test_projection_regular_3(monty_proj, mongo_proj): assert count_documents(mongo_c, spec) == 1 assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) assert next(mongo_c) == next(monty_c) + + +def test_projection_path_collision_1(monty_proj, mongo_proj, mongo_version): + if mongo_version[:2] < [4, 4]: + return + + docs = [ + {"size": {"h": 10, "w": 5, "uom": "cm"}} + ] + spec = {"size.h": 10} + proj = {"size": 1, "size.uom": 1} + + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + assert count_documents(mongo_c, spec) == 1 + assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) + + with pytest.raises(mongo_op_fail) as mongo_err: + next(mongo_c) + # OperationFailure: "Path collision at size.uom remaining portion uom" + with pytest.raises(monty_op_fail) as monty_err: + next(monty_c) + + +def test_projection_path_collision_2(monty_proj, mongo_proj, mongo_version): + if mongo_version[:2] < [4, 4]: + return + + docs = [ + {"size": {"h": 10, "w": 5, "uom": "cm"}} + ] + spec = {"size.h": 10} + proj = {"size.uom": 1, "size": 1} + + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + assert count_documents(mongo_c, spec) == 1 + assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) + + with pytest.raises(mongo_op_fail) as mongo_err: + next(mongo_c) + # OperationFailure: "Path collision at size" + with pytest.raises(monty_op_fail) as monty_err: + next(monty_c) + + +def test_projection_path_collision_3(monty_proj, mongo_proj, mongo_version): + if mongo_version[:2] < [4, 4]: + return + + docs = [ + {"a": [{"b": [0, 1, {"c": 5}]}, {"b": [3, 2, {"x": 5}]}]}, + ] + spec = {"a.b.1": 1} + proj = {"a.b.$": 1, "a.b": 1} + + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + with pytest.raises(mongo_op_fail) as mongo_err: + next(mongo_c) + # OperationFailure: "Path collision at a.b" + with pytest.raises(monty_op_fail) as monty_err: + next(monty_c) From 2a99bdd8a850bb686e5c2dd1c5382fc74914d31f Mon Sep 17 00:00:00 2001 From: David Lai Date: Thu, 8 Jul 2021 04:21:38 +0800 Subject: [PATCH 14/26] add $mod remainder check --- montydb/configure.py | 6 ++++++ montydb/engine/queries.py | 7 +++++++ .../test_queries/test_queryop_evaluation_mod.py | 17 ++++++++++++++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/montydb/configure.py b/montydb/configure.py index bafe502..5185fca 100644 --- a/montydb/configure.py +++ b/montydb/configure.py @@ -306,6 +306,10 @@ def _mongo_compat(version): setattr(queries, "_regex_options_check", getattr(queries, "_regex_options_")) if version == "4.4": + # $mod checking remainder is starting from mongo-4.3.1 but since 4.3 is not + # a stable release so we match this behavior in 4.4 + setattr(queries, "_mod_check_numeric_remainder", + getattr(queries, "_mod_check_numeric_remainder_v431_")) setattr(project, "_positional_mismatch", getattr(project, "_positional_mismatch_v44")) setattr(project, "_check_positional_key", @@ -315,6 +319,8 @@ def _mongo_compat(version): setattr(project, "_include_positional_non_located_match", getattr(project, "_include_positional_non_located_match_v44")) else: + setattr(queries, "_mod_check_numeric_remainder", + getattr(queries, "_mod_check_numeric_remainder_")) setattr(project, "_positional_mismatch", getattr(project, "_positional_mismatch_")) setattr(project, "_check_positional_key", diff --git a/montydb/engine/queries.py b/montydb/engine/queries.py index b141e67..9c0413d 100644 --- a/montydb/engine/queries.py +++ b/montydb/engine/queries.py @@ -900,6 +900,11 @@ def _regex(fieldwalker): return _regex +_mod_check_numeric_remainder_ = False +_mod_check_numeric_remainder_v431_ = True +_mod_check_numeric_remainder = _mod_check_numeric_remainder_v431_ + + def parse_mod(query): if not isinstance(query, list): raise OperationFailure("malformed mod, needs to be an array") @@ -916,6 +921,8 @@ def parse_mod(query): if not isinstance(divisor, num_types): raise OperationFailure("malformed mod, divisor not a number") if not isinstance(remainder, num_types): + if _mod_check_numeric_remainder: + raise OperationFailure("malformed mod, remainder not a number") remainder = 0 if isinstance(divisor, bson.Decimal128): diff --git a/tests/test_engine/test_queries/test_queryop_evaluation_mod.py b/tests/test_engine/test_queries/test_queryop_evaluation_mod.py index 6b8586e..b254238 100644 --- a/tests/test_engine/test_queries/test_queryop_evaluation_mod.py +++ b/tests/test_engine/test_queries/test_queryop_evaluation_mod.py @@ -1,4 +1,7 @@ +import pytest +from pymongo.errors import OperationFailure as mongo_op_fail +from montydb.errors import OperationFailure as monty_op_fail from montydb.types import bson from ...conftest import skip_if_no_bson @@ -102,7 +105,7 @@ def test_qop_mod_7(monty_find, mongo_find): assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) -def test_qop_mod_8(monty_find, mongo_find): +def test_qop_mod_8(monty_find, mongo_find, mongo_version): docs = [ {"a": 8} ] @@ -111,8 +114,16 @@ def test_qop_mod_8(monty_find, mongo_find): monty_c = monty_find(docs, spec) mongo_c = mongo_find(docs, spec) - assert count_documents(mongo_c, spec) == 1 - assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) + if mongo_version < [4, 3, 1]: + assert count_documents(mongo_c, spec) == 1 + assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) + else: + # error raise if remainder is not a number, starting MongoDB 4.3.1 + # https://jira.mongodb.org/browse/SERVER-23664 + with pytest.raises(mongo_op_fail) as mongo_err: + next(mongo_c) + with pytest.raises(monty_op_fail) as monty_err: + next(monty_c) @skip_if_no_bson From c7a32614f648613a7f71cf09c328e9dc7e4fd256 Mon Sep 17 00:00:00 2001 From: David Lai Date: Thu, 8 Jul 2021 04:29:01 +0800 Subject: [PATCH 15/26] flake8: bump max-complexity, again ./montydb/engine/project.py:134:5: C901 'Projector.parser' is too complex (32) :( --- .github/workflows/python-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 4256ef5..141a228 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -50,7 +50,7 @@ jobs: - name: Lint with flake8 run: | # Ideally max-complexity should be set to 10 - flake8 . --count --ignore=F841,W503 --max-complexity=29 --max-line-length=88 --statistics + flake8 . --count --ignore=F841,W503 --max-complexity=32 --max-line-length=88 --statistics - name: Find typos with codespell run: codespell --ignore-words-list=nd,nin From 7cdc5003edd5f623f987877ed7f8e749be4e6be7 Mon Sep 17 00:00:00 2001 From: David Lai Date: Thu, 8 Jul 2021 04:30:38 +0800 Subject: [PATCH 16/26] flake8: fix indent (E126) --- montydb/engine/project.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/montydb/engine/project.py b/montydb/engine/project.py index c8e32ee..cc261be 100644 --- a/montydb/engine/project.py +++ b/montydb/engine/project.py @@ -138,8 +138,10 @@ def parser(self, spec, qfilter): for key, val in spec.items(): # check path collision (mongo-4.4+) if _check_path_collision: - collision = _has_path_collision(key, self.regular_field) \ - or _has_path_collision(key, self.array_field.keys()) + collision = ( + _has_path_collision(key, self.regular_field) + or _has_path_collision(key, self.array_field.keys()) + ) if collision: remaining = key[len(collision + "."):] if remaining: From c3a2faaed676fdeb212fd68c2217fee916f0f798 Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Sun, 22 Jan 2023 02:59:12 +0800 Subject: [PATCH 17/26] Cleanup after master merged --- Makefile | 2 +- montydb/configure.py | 73 ++++++++----------- montydb/engine/queries.py | 17 +---- .../test_queryop_evaluation_mod.py | 3 - 4 files changed, 35 insertions(+), 60 deletions(-) diff --git a/Makefile b/Makefile index 7b28ee9..1950b2b 100644 --- a/Makefile +++ b/Makefile @@ -25,7 +25,7 @@ lint: ## Run linting with flake8 poetry run flake8 . \ --count \ --ignore=F841,W503 \ - --max-complexity=26 \ + --max-complexity=32 \ --max-line-length=88 \ --statistics \ --exclude .venv diff --git a/montydb/configure.py b/montydb/configure.py index ce52c06..c8192c0 100644 --- a/montydb/configure.py +++ b/montydb/configure.py @@ -292,50 +292,41 @@ def _bson_init(use_bson): def _mongo_compat(version): from .engine import queries, project - def patch(mod, func, ver_func): - setattr(mod, func, getattr(mod, ver_func)) + def patch(mod, attr, ver): + setattr(mod, attr, getattr(mod, attr + ver)) if version.startswith("3"): - patch(queries, "_is_comparable", "_is_comparable_ver3") - patch(queries, "_regex_options_check", "_regex_options_") - patch(queries, "_mod_remainder_not_num", "_mod_remainder_not_num_") + patch(queries, "_is_comparable", "_ver3") + patch(queries, "_regex_options", "_") + patch(queries, "_mod_check_numeric_remainder", "_") + patch(project, "_positional_mismatch", "_") + patch(project, "_check_positional_key", "_") + patch(project, "_check_path_collision", "_") + patch(project, "_include_positional_non_located_match", "_") elif version == "4.0": - patch(queries, "_is_comparable", "_is_comparable_ver4") - patch(queries, "_regex_options_check", "_regex_options_") - patch(queries, "_mod_remainder_not_num", "_mod_remainder_not_num_") + patch(queries, "_is_comparable", "_ver4") + patch(queries, "_regex_options", "_") + patch(queries, "_mod_check_numeric_remainder", "_") + patch(project, "_positional_mismatch", "_") + patch(project, "_check_positional_key", "_") + patch(project, "_check_path_collision", "_") + patch(project, "_include_positional_non_located_match", "_") elif version == "4.2": - patch(queries, "_is_comparable", "_is_comparable_ver4") - patch(queries, "_regex_options_check", "_regex_options_v42") - patch(queries, "_mod_remainder_not_num", "_mod_remainder_not_num_") - - else: - patch(queries, "_is_comparable", "_is_comparable_ver4") - patch(queries, "_regex_options_check", "_regex_options_") - patch(queries, "_mod_remainder_not_num", "_mod_remainder_not_num_v44") - - if version == "4.4": - # $mod checking remainder is starting from mongo-4.3.1 but since 4.3 is not - # a stable release so we match this behavior in 4.4 - setattr(queries, "_mod_check_numeric_remainder", - getattr(queries, "_mod_check_numeric_remainder_v431_")) - setattr(project, "_positional_mismatch", - getattr(project, "_positional_mismatch_v44")) - setattr(project, "_check_positional_key", - getattr(project, "_check_positional_key_v44")) - setattr(project, "_check_path_collision", - getattr(project, "_check_path_collision_v44")) - setattr(project, "_include_positional_non_located_match", - getattr(project, "_include_positional_non_located_match_v44")) - else: - setattr(queries, "_mod_check_numeric_remainder", - getattr(queries, "_mod_check_numeric_remainder_")) - setattr(project, "_positional_mismatch", - getattr(project, "_positional_mismatch_")) - setattr(project, "_check_positional_key", - getattr(project, "_check_positional_key_")) - setattr(project, "_check_path_collision", - getattr(project, "_check_path_collision_")) - setattr(project, "_include_positional_non_located_match", - getattr(project, "_include_positional_non_located_match_")) + patch(queries, "_is_comparable", "_ver4") + patch(queries, "_regex_options", "_v42") + patch(queries, "_mod_check_numeric_remainder", "_") + patch(project, "_positional_mismatch", "_") + patch(project, "_check_positional_key", "_") + patch(project, "_check_path_collision", "_") + patch(project, "_include_positional_non_located_match", "_") + + else: # 4.4+ (default) + patch(queries, "_is_comparable", "_ver4") + patch(queries, "_regex_options", "_") + patch(queries, "_mod_check_numeric_remainder", "_v431_") + patch(project, "_positional_mismatch", "_v44") + patch(project, "_check_positional_key", "_v44") + patch(project, "_check_path_collision", "_v44") + patch(project, "_include_positional_non_located_match", "_v44") diff --git a/montydb/engine/queries.py b/montydb/engine/queries.py index c1b07c2..6d21392 100644 --- a/montydb/engine/queries.py +++ b/montydb/engine/queries.py @@ -421,7 +421,7 @@ def _regex_options_v42(regex_flag, opt_flag): raise OperationFailure("options set in both $regex and $options") -_regex_options_check = _regex_options_v42 +_regex_options = _regex_options_v42 def _modify_regex_optins(sub_spec): @@ -451,7 +451,7 @@ def _modify_regex_optins(sub_spec): _re = sub_spec["$regex"] sub_spec["$regex"] = None - _regex_options_check(regex_flags, opt_flags) + _regex_options(regex_flags, opt_flags) new_sub_spec = deepcopy(sub_spec) new_sub_spec["$regex"] = { @@ -897,18 +897,6 @@ def _regex(fieldwalker): return _regex -def _mod_remainder_not_num_(): - pass - - -def _mod_remainder_not_num_v44(): - # https://jira.mongodb.org/browse/SERVER-23664 - raise OperationFailure("malformed mod, remainder not a number") - - -_mod_remainder_not_num = _mod_remainder_not_num_v44 - - _mod_check_numeric_remainder_ = False _mod_check_numeric_remainder_v431_ = True _mod_check_numeric_remainder = _mod_check_numeric_remainder_v431_ @@ -930,7 +918,6 @@ def parse_mod(query): if not isinstance(divisor, num_types): raise OperationFailure("malformed mod, divisor not a number") if not isinstance(remainder, num_types): - # _mod_remainder_not_num() if _mod_check_numeric_remainder: raise OperationFailure("malformed mod, remainder not a number") remainder = 0 diff --git a/tests/test_engine/test_queries/test_queryop_evaluation_mod.py b/tests/test_engine/test_queries/test_queryop_evaluation_mod.py index 4ed6a69..a99dd08 100644 --- a/tests/test_engine/test_queries/test_queryop_evaluation_mod.py +++ b/tests/test_engine/test_queries/test_queryop_evaluation_mod.py @@ -4,9 +4,6 @@ from montydb.errors import OperationFailure as monty_op_fail from montydb.types import bson -from pymongo.errors import OperationFailure as MongoOpFail -from montydb.errors import OperationFailure as MontyOpFail - from ...conftest import skip_if_no_bson From 55224a2b1983c9f5ad8f6f0929b9414cf01de34e Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Sun, 22 Jan 2023 18:35:02 +0800 Subject: [PATCH 18/26] Add mongodb 5.0, 6.0 --- montydb/configure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/montydb/configure.py b/montydb/configure.py index c8192c0..48cb794 100644 --- a/montydb/configure.py +++ b/montydb/configure.py @@ -18,7 +18,7 @@ URI_SCHEME_PREFIX = "montydb://" -MONGO_COMPAT_VERSIONS = ("3.6", "4.0", "4.2", "4.4") # 4.4 is experimenting +MONGO_COMPAT_VERSIONS = ("3.6", "4.0", "4.2", "4.4", "5.0", "6.0") _pinned_repository = {"_": None} From 0735ebf9e9feca23c17a1d4de8d46e33809931d7 Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Sun, 22 Jan 2023 18:39:41 +0800 Subject: [PATCH 19/26] Add mongoengine to test; Drop Python 3.6 --- README.md | 2 +- pyproject.toml | 4 ++-- setup.cfg | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c1ac0b9..01f0b18 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Most of the CRUD operators have been implemented. You can visit [issue #14](http This project is tested against: - MongoDB: 3.6, 4.0, 4.2 (4.4 on the way💦) -- Python: 3.6, 3.7, 3.8, 3.9, 3.10, 3.11 +- Python: 3.7, 3.8, 3.9, 3.10, 3.11 ## Install diff --git a/pyproject.toml b/pyproject.toml index 5040385..6b4722a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,6 @@ classifiers = [ "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", @@ -27,13 +26,14 @@ include=[ ] [tool.poetry.dependencies] -python = ">=3.6, <3.12" +python = ">=3.7, <3.12" [tool.poetry.dev-dependencies] pytest = "^6.2.4" pytest-cov = "^2.12.1" pymongo = "=3.11.3" lmdb = "^1.2.1" +mongoengine = "^0.26.0" flake8 = "^3.9.2" codespell = "^2.1.0" black = {version = "^21.11b1", python =">=3.6.2", allow-prereleases = true} diff --git a/setup.cfg b/setup.cfg index 1715467..16a4619 100644 --- a/setup.cfg +++ b/setup.cfg @@ -19,7 +19,6 @@ classifiers = License :: OSI Approved :: BSD License Operating System :: OS Independent Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 @@ -38,12 +37,13 @@ project_urls = zip_safe = true packages = find: include_package_data = true -python_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.* +python_requires = >=3.7 install_requires = tests_require = pytest-cov pymongo lmdb + mongoengine [options.packages.find] exclude = From fcaa6889b931dd9008a9a32b1b33a14b698fe0ca Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Sun, 22 Jan 2023 18:48:28 +0800 Subject: [PATCH 20/26] Update poetry.lock --- poetry.lock | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3cacc17..19fce9c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -62,7 +62,6 @@ files = [ [package.dependencies] click = ">=7.1.2" -dataclasses = {version = ">=0.6", markers = "python_version < \"3.7\""} mypy-extensions = ">=0.4.3" pathspec = ">=0.9.0,<1" platformdirs = ">=2" @@ -184,18 +183,6 @@ files = [ [package.extras] toml = ["tomli"] -[[package]] -name = "dataclasses" -version = "0.8" -description = "A backport of the dataclasses module for Python 3.6" -category = "dev" -optional = false -python-versions = ">=3.6, <3.7" -files = [ - {file = "dataclasses-0.8-py3-none-any.whl", hash = "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf"}, - {file = "dataclasses-0.8.tar.gz", hash = "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97"}, -] - [[package]] name = "flake8" version = "3.9.2" @@ -329,6 +316,21 @@ files = [ {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] +[[package]] +name = "mongoengine" +version = "0.26.0" +description = "MongoEngine is a Python Object-Document Mapper for working with MongoDB." +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mongoengine-0.26.0-py3-none-any.whl", hash = "sha256:020a0779d1830affc649f2760d8c408e998981f18898e425eb041915181d3a53"}, + {file = "mongoengine-0.26.0.tar.gz", hash = "sha256:3f284bdcbe8d1a3a9b8ab7d3c3ed672d10b8fd2e545447cd1d75e40d6e978332"}, +] + +[package.dependencies] +pymongo = ">=3.4,<5.0" + [[package]] name = "mypy-extensions" version = "0.4.3" @@ -761,5 +763,5 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black ( [metadata] lock-version = "2.0" -python-versions = ">=3.6, <3.11" -content-hash = "79285620c197e903c3dc15753de90ee618db06683b8281d3b0f94b9d2b1d156f" +python-versions = ">=3.7, <3.12" +content-hash = "acf8cd5f5d8835f8bd68cd1a30113791464eea8c9d19a2b6a59965257a126635" From 0c3862dde05180acf20fff1f42f9dd01523eb096 Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Sun, 22 Jan 2023 18:57:32 +0800 Subject: [PATCH 21/26] Update poetry.lock --- poetry.lock | 259 ++++++++++++++++++++++++++-------------------------- 1 file changed, 127 insertions(+), 132 deletions(-) diff --git a/poetry.lock b/poetry.lock index 19fce9c..3253bce 100644 --- a/poetry.lock +++ b/poetry.lock @@ -32,14 +32,14 @@ tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy [[package]] name = "bandit" -version = "1.7.1" +version = "1.7.4" description = "Security oriented static analyser for python code." category = "dev" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" files = [ - {file = "bandit-1.7.1-py3-none-any.whl", hash = "sha256:f5acd838e59c038a159b5c621cf0f8270b279e884eadd7b782d7491c02add0d4"}, - {file = "bandit-1.7.1.tar.gz", hash = "sha256:a81b00b5436e6880fa8ad6799bc830e02032047713cbb143a12939ac67eb756c"}, + {file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"}, + {file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"}, ] [package.dependencies] @@ -48,6 +48,11 @@ GitPython = ">=1.0.1" PyYAML = ">=5.3.1" stevedore = ">=1.20.0" +[package.extras] +test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml"] +toml = ["toml"] +yaml = ["PyYAML"] + [[package]] name = "black" version = "21.12b0" @@ -81,14 +86,14 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "click" -version = "8.0.4" +version = "8.1.3" description = "Composable command line interface toolkit" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "click-8.0.4-py3-none-any.whl", hash = "sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1"}, - {file = "click-8.0.4.tar.gz", hash = "sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"}, + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] [package.dependencies] @@ -97,87 +102,92 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "codespell" -version = "2.2.1" +version = "2.2.2" description = "Codespell" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "codespell-2.2.1-py3-none-any.whl", hash = "sha256:0c53a70f466952706407383d87142a78f319a0e18602802c4aadd3d93158bfc6"}, - {file = "codespell-2.2.1.tar.gz", hash = "sha256:569b67e5e5c3ade02a1e23f6bbc56c64b608a3ab48ddd943ece0a03e6c346ed1"}, + {file = "codespell-2.2.2-py3-none-any.whl", hash = "sha256:87dfcd9bdc9b3cb8b067b37f0af22044d7a84e28174adfc8eaa203056b7f9ecc"}, + {file = "codespell-2.2.2.tar.gz", hash = "sha256:c4d00c02b5a2a55661f00d5b4b3b5a710fa803ced9a9d7e45438268b099c319c"}, ] [package.extras] -dev = ["check-manifest", "flake8", "pytest", "pytest-cov", "pytest-dependency"] +dev = ["check-manifest", "flake8", "pytest", "pytest-cov", "pytest-dependency", "tomli"] hard-encoding-detection = ["chardet"] +toml = ["tomli"] [[package]] name = "colorama" -version = "0.4.5" +version = "0.4.6" description = "Cross-platform colored terminal text." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] [[package]] name = "coverage" -version = "6.2" +version = "7.0.5" description = "Code coverage measurement for Python" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "coverage-6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da"}, - {file = "coverage-6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971"}, - {file = "coverage-6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840"}, - {file = "coverage-6.2-cp310-cp310-win32.whl", hash = "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c"}, - {file = "coverage-6.2-cp310-cp310-win_amd64.whl", hash = "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f"}, - {file = "coverage-6.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76"}, - {file = "coverage-6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47"}, - {file = "coverage-6.2-cp311-cp311-win_amd64.whl", hash = "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64"}, - {file = "coverage-6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48"}, - {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17"}, - {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781"}, - {file = "coverage-6.2-cp36-cp36m-win32.whl", hash = "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a"}, - {file = "coverage-6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0"}, - {file = "coverage-6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884"}, - {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617"}, - {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8"}, - {file = "coverage-6.2-cp37-cp37m-win32.whl", hash = "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4"}, - {file = "coverage-6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74"}, - {file = "coverage-6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc"}, - {file = "coverage-6.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475"}, - {file = "coverage-6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57"}, - {file = "coverage-6.2-cp38-cp38-win32.whl", hash = "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c"}, - {file = "coverage-6.2-cp38-cp38-win_amd64.whl", hash = "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2"}, - {file = "coverage-6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c"}, - {file = "coverage-6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3"}, - {file = "coverage-6.2-cp39-cp39-win32.whl", hash = "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282"}, - {file = "coverage-6.2-cp39-cp39-win_amd64.whl", hash = "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644"}, - {file = "coverage-6.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de"}, - {file = "coverage-6.2.tar.gz", hash = "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8"}, + {file = "coverage-7.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2a7f23bbaeb2a87f90f607730b45564076d870f1fb07b9318d0c21f36871932b"}, + {file = "coverage-7.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c18d47f314b950dbf24a41787ced1474e01ca816011925976d90a88b27c22b89"}, + {file = "coverage-7.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef14d75d86f104f03dea66c13188487151760ef25dd6b2dbd541885185f05f40"}, + {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66e50680e888840c0995f2ad766e726ce71ca682e3c5f4eee82272c7671d38a2"}, + {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9fed35ca8c6e946e877893bbac022e8563b94404a605af1d1e6accc7eb73289"}, + {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d8d04e755934195bdc1db45ba9e040b8d20d046d04d6d77e71b3b34a8cc002d0"}, + {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e109f1c9a3ece676597831874126555997c48f62bddbcace6ed17be3e372de8"}, + {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0a1890fca2962c4f1ad16551d660b46ea77291fba2cc21c024cd527b9d9c8809"}, + {file = "coverage-7.0.5-cp310-cp310-win32.whl", hash = "sha256:be9fcf32c010da0ba40bf4ee01889d6c737658f4ddff160bd7eb9cac8f094b21"}, + {file = "coverage-7.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:cbfcba14a3225b055a28b3199c3d81cd0ab37d2353ffd7f6fd64844cebab31ad"}, + {file = "coverage-7.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:30b5fec1d34cc932c1bc04017b538ce16bf84e239378b8f75220478645d11fca"}, + {file = "coverage-7.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1caed2367b32cc80a2b7f58a9f46658218a19c6cfe5bc234021966dc3daa01f0"}, + {file = "coverage-7.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d254666d29540a72d17cc0175746cfb03d5123db33e67d1020e42dae611dc196"}, + {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19245c249aa711d954623d94f23cc94c0fd65865661f20b7781210cb97c471c0"}, + {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b05ed4b35bf6ee790832f68932baf1f00caa32283d66cc4d455c9e9d115aafc"}, + {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:29de916ba1099ba2aab76aca101580006adfac5646de9b7c010a0f13867cba45"}, + {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e057e74e53db78122a3979f908973e171909a58ac20df05c33998d52e6d35757"}, + {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:411d4ff9d041be08fdfc02adf62e89c735b9468f6d8f6427f8a14b6bb0a85095"}, + {file = "coverage-7.0.5-cp311-cp311-win32.whl", hash = "sha256:52ab14b9e09ce052237dfe12d6892dd39b0401690856bcfe75d5baba4bfe2831"}, + {file = "coverage-7.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:1f66862d3a41674ebd8d1a7b6f5387fe5ce353f8719040a986551a545d7d83ea"}, + {file = "coverage-7.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b69522b168a6b64edf0c33ba53eac491c0a8f5cc94fa4337f9c6f4c8f2f5296c"}, + {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436e103950d05b7d7f55e39beeb4d5be298ca3e119e0589c0227e6d0b01ee8c7"}, + {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c56bec53d6e3154eaff6ea941226e7bd7cc0d99f9b3756c2520fc7a94e6d96"}, + {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a38362528a9115a4e276e65eeabf67dcfaf57698e17ae388599568a78dcb029"}, + {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f67472c09a0c7486e27f3275f617c964d25e35727af952869dd496b9b5b7f6a3"}, + {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:220e3fa77d14c8a507b2d951e463b57a1f7810a6443a26f9b7591ef39047b1b2"}, + {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ecb0f73954892f98611e183f50acdc9e21a4653f294dfbe079da73c6378a6f47"}, + {file = "coverage-7.0.5-cp37-cp37m-win32.whl", hash = "sha256:d8f3e2e0a1d6777e58e834fd5a04657f66affa615dae61dd67c35d1568c38882"}, + {file = "coverage-7.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9e662e6fc4f513b79da5d10a23edd2b87685815b337b1a30cd11307a6679148d"}, + {file = "coverage-7.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:790e4433962c9f454e213b21b0fd4b42310ade9c077e8edcb5113db0818450cb"}, + {file = "coverage-7.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49640bda9bda35b057b0e65b7c43ba706fa2335c9a9896652aebe0fa399e80e6"}, + {file = "coverage-7.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d66187792bfe56f8c18ba986a0e4ae44856b1c645336bd2c776e3386da91e1dd"}, + {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:276f4cd0001cd83b00817c8db76730938b1ee40f4993b6a905f40a7278103b3a"}, + {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95304068686545aa368b35dfda1cdfbbdbe2f6fe43de4a2e9baa8ebd71be46e2"}, + {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:17e01dd8666c445025c29684d4aabf5a90dc6ef1ab25328aa52bedaa95b65ad7"}, + {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea76dbcad0b7b0deb265d8c36e0801abcddf6cc1395940a24e3595288b405ca0"}, + {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:50a6adc2be8edd7ee67d1abc3cd20678987c7b9d79cd265de55941e3d0d56499"}, + {file = "coverage-7.0.5-cp38-cp38-win32.whl", hash = "sha256:e4ce984133b888cc3a46867c8b4372c7dee9cee300335e2925e197bcd45b9e16"}, + {file = "coverage-7.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:4a950f83fd3f9bca23b77442f3a2b2ea4ac900944d8af9993743774c4fdc57af"}, + {file = "coverage-7.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c2155943896ac78b9b0fd910fb381186d0c345911f5333ee46ac44c8f0e43ab"}, + {file = "coverage-7.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54f7e9705e14b2c9f6abdeb127c390f679f6dbe64ba732788d3015f7f76ef637"}, + {file = "coverage-7.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ee30375b409d9a7ea0f30c50645d436b6f5dfee254edffd27e45a980ad2c7f4"}, + {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b78729038abea6a5df0d2708dce21e82073463b2d79d10884d7d591e0f385ded"}, + {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13250b1f0bd023e0c9f11838bdeb60214dd5b6aaf8e8d2f110c7e232a1bff83b"}, + {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2c407b1950b2d2ffa091f4e225ca19a66a9bd81222f27c56bd12658fc5ca1209"}, + {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c76a3075e96b9c9ff00df8b5f7f560f5634dffd1658bafb79eb2682867e94f78"}, + {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f26648e1b3b03b6022b48a9b910d0ae209e2d51f50441db5dce5b530fad6d9b1"}, + {file = "coverage-7.0.5-cp39-cp39-win32.whl", hash = "sha256:ba3027deb7abf02859aca49c865ece538aee56dcb4871b4cced23ba4d5088904"}, + {file = "coverage-7.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:949844af60ee96a376aac1ded2a27e134b8c8d35cc006a52903fc06c24a3296f"}, + {file = "coverage-7.0.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:b9727ac4f5cf2cbf87880a63870b5b9730a8ae3a4a360241a0fdaa2f71240ff0"}, + {file = "coverage-7.0.5.tar.gz", hash = "sha256:051afcbd6d2ac39298d62d340f94dbb6a1f31de06dfaf6fcef7b759dd3860c45"}, ] [package.extras] @@ -203,14 +213,14 @@ pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "gitdb" -version = "4.0.9" +version = "4.0.10" description = "Git Object Database" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, - {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, + {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, + {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, ] [package.dependencies] @@ -218,30 +228,30 @@ smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.18" -description = "Python Git Library" +version = "3.1.30" +description = "GitPython is a python library used to interact with Git repositories" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "GitPython-3.1.18-py3-none-any.whl", hash = "sha256:fce760879cd2aebd2991b3542876dc5c4a909b30c9d69dfc488e504a8db37ee8"}, - {file = "GitPython-3.1.18.tar.gz", hash = "sha256:b838a895977b45ab6f0cc926a9045c8d1c44e2b653c1fcc39fe91f42c6e8f05b"}, + {file = "GitPython-3.1.30-py3-none-any.whl", hash = "sha256:cd455b0000615c60e286208ba540271af9fe531fa6a87cc590a7298785ab2882"}, + {file = "GitPython-3.1.30.tar.gz", hash = "sha256:769c2d83e13f5d938b7688479da374c4e3d49f71549aaf462b646db9602ea6f8"}, ] [package.dependencies] gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.0", markers = "python_version < \"3.8\""} +typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} [[package]] name = "importlib-metadata" -version = "4.8.3" +version = "6.0.0" description = "Read metadata from Python packages" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "importlib_metadata-4.8.3-py3-none-any.whl", hash = "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e"}, - {file = "importlib_metadata-4.8.3.tar.gz", hash = "sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668"}, + {file = "importlib_metadata-6.0.0-py3-none-any.whl", hash = "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad"}, + {file = "importlib_metadata-6.0.0.tar.gz", hash = "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"}, ] [package.dependencies] @@ -249,20 +259,20 @@ typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pep517", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy", "pytest-perf (>=0.9.2)"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" files = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] [[package]] @@ -345,29 +355,26 @@ files = [ [[package]] name = "packaging" -version = "21.3" +version = "23.0" description = "Core utilities for Python packages" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, + {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, + {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, ] -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" - [[package]] name = "pathspec" -version = "0.9.0" +version = "0.10.3" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.7" files = [ - {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, - {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, + {file = "pathspec-0.10.3-py3-none-any.whl", hash = "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6"}, + {file = "pathspec-0.10.3.tar.gz", hash = "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"}, ] [[package]] @@ -384,19 +391,22 @@ files = [ [[package]] name = "platformdirs" -version = "2.4.0" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "2.6.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "platformdirs-2.4.0-py3-none-any.whl", hash = "sha256:8868bbe3c3c80d42f20156f22e7131d2fb321f5bc86a2a345375c6481a67021d"}, - {file = "platformdirs-2.4.0.tar.gz", hash = "sha256:367a5e80b3d04d2428ffa76d33f124cf11e8fff2acdaa9b43d545f5c7d661ef2"}, + {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, + {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.4", markers = "python_version < \"3.8\""} + [package.extras] -docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] -test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -536,21 +546,6 @@ srv = ["dnspython (>=1.16.0,<1.17.0)"] tls = ["ipaddress"] zstd = ["zstandard"] -[[package]] -name = "pyparsing" -version = "3.0.7" -description = "Python parsing module" -category = "dev" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, - {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, -] - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - [[package]] name = "pytest" version = "6.2.5" @@ -735,33 +730,33 @@ files = [ [[package]] name = "typing-extensions" -version = "4.1.1" -description = "Backported and Experimental Type Hints for Python 3.6+" +version = "4.4.0" +description = "Backported and Experimental Type Hints for Python 3.7+" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, - {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, + {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, + {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, ] [[package]] name = "zipp" -version = "3.6.0" +version = "3.11.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "zipp-3.6.0-py3-none-any.whl", hash = "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc"}, - {file = "zipp-3.6.0.tar.gz", hash = "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832"}, + {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, + {file = "zipp-3.11.0.tar.gz", hash = "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"}, ] [package.extras] -docs = ["jaraco.packaging (>=8.2)", "rst.linker (>=1.9)", "sphinx"] -testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "2.0" python-versions = ">=3.7, <3.12" -content-hash = "acf8cd5f5d8835f8bd68cd1a30113791464eea8c9d19a2b6a59965257a126635" +content-hash = "4ca8ed597387fa38f68214f18dc85288106fb8199fb420bc00a8845e25c51171" From 0ba3d5dbdba50f9f3f9b4136f21be44b51966ca0 Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Fri, 3 Feb 2023 18:29:42 +0800 Subject: [PATCH 22/26] Fix query mod regression --- montydb/configure.py | 4 ++-- montydb/engine/queries.py | 4 ++-- tests/test_engine/test_queries/test_queryop_evaluation_mod.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/montydb/configure.py b/montydb/configure.py index fb77ca3..6a1c0f3 100644 --- a/montydb/configure.py +++ b/montydb/configure.py @@ -322,7 +322,7 @@ def patch(mod, attr, ver): elif version == "4.2": patch(queries, "_is_comparable", "_ver4") patch(queries, "_regex_options", "_v42") - patch(queries, "_mod_check_numeric_remainder", "_") + patch(queries, "_mod_check_numeric_remainder", "_v42_") patch(project, "_positional_mismatch", "_") patch(project, "_check_positional_key", "_") patch(project, "_check_path_collision", "_") @@ -331,7 +331,7 @@ def patch(mod, attr, ver): else: # 4.4+ (default) patch(queries, "_is_comparable", "_ver4") patch(queries, "_regex_options", "_") - patch(queries, "_mod_check_numeric_remainder", "_v431_") + patch(queries, "_mod_check_numeric_remainder", "_v42_") patch(project, "_positional_mismatch", "_v44") patch(project, "_check_positional_key", "_v44") patch(project, "_check_path_collision", "_v44") diff --git a/montydb/engine/queries.py b/montydb/engine/queries.py index ee91872..e45bc93 100644 --- a/montydb/engine/queries.py +++ b/montydb/engine/queries.py @@ -898,8 +898,8 @@ def _regex(fieldwalker): _mod_check_numeric_remainder_ = False -_mod_check_numeric_remainder_v431_ = True -_mod_check_numeric_remainder = _mod_check_numeric_remainder_v431_ +_mod_check_numeric_remainder_v42_ = True +_mod_check_numeric_remainder = _mod_check_numeric_remainder_v42_ # mongo-4.2.19+ # https://jira.mongodb.org/browse/SERVER-23664 diff --git a/tests/test_engine/test_queries/test_queryop_evaluation_mod.py b/tests/test_engine/test_queries/test_queryop_evaluation_mod.py index a99dd08..f9030c4 100644 --- a/tests/test_engine/test_queries/test_queryop_evaluation_mod.py +++ b/tests/test_engine/test_queries/test_queryop_evaluation_mod.py @@ -115,7 +115,7 @@ def test_qop_mod_8(monty_find, mongo_find, mongo_version): monty_c = monty_find(docs, spec) mongo_c = mongo_find(docs, spec) - if mongo_version < [4, 3, 1]: + if mongo_version < [4, 2]: assert count_documents(mongo_c, spec) == 1 assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) else: From aef4af721c5193e2781995c014ea711e903fdf22 Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Fri, 3 Feb 2023 18:39:09 +0800 Subject: [PATCH 23/26] Exclude poetry-version from matrix --- .github/workflows/python-package.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index a671b1d..afaf261 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -21,7 +21,7 @@ jobs: monty-storage: [ memory, flatfile, sqlite ] mongodb-version: [ "3.6", "4.0", "4.2", "4.4", "5.0", "6.0" ] python-version: [ "3.7", "3.8", "3.9", "3.10", "3.11" ] - poetry-version: [ "1.3" ] + include: # run lmdb tests as experimental due to the seg fault in GitHub # action is not reproducible on my Windows and Mac. @@ -29,7 +29,6 @@ jobs: monty-storage: lightning mongodb-version: "4.0" python-version: "3.7" - poetry-version: "1.3" steps: - uses: actions/checkout@v3 @@ -44,10 +43,10 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Setup Poetry ${{ matrix.poetry-version }} + - name: Setup Poetry 1.3 uses: abatilo/actions-poetry@v2 with: - poetry-version: ${{ matrix.poetry-version }} + poetry-version: "1.3" - name: Install dependencies via poetry run: make install From e83e863a0595c13f6bc38343d023fc2fc47279af Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Fri, 3 Feb 2023 19:14:24 +0800 Subject: [PATCH 24/26] Add test cases For #67, thanks to @thasler --- .../test_projection_regular.py | 14 ++++ .../test_projection/test_projection_slice.py | 80 +++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/tests/test_engine/test_projection/test_projection_regular.py b/tests/test_engine/test_projection/test_projection_regular.py index 7818e38..c83a050 100644 --- a/tests/test_engine/test_projection/test_projection_regular.py +++ b/tests/test_engine/test_projection/test_projection_regular.py @@ -58,6 +58,20 @@ def test_projection_regular_3(monty_proj, mongo_proj): assert next(mongo_c) == next(monty_c) +def test_projection_regular_err_mix_include_exclude(monty_proj, mongo_proj): + docs = [ + {"a": "foo", "b": "bar"}, + ] + spec = {} + proj = {"a": 0, "b": 1} + + with pytest.raises(mongo_op_fail) as mongo_err: + next(mongo_proj(docs, spec, proj)) + + with pytest.raises(monty_op_fail) as monty_err: + next(monty_proj(docs, spec, proj)) + + def test_projection_path_collision_1(monty_proj, mongo_proj, mongo_version): if mongo_version[:2] < [4, 4]: return diff --git a/tests/test_engine/test_projection/test_projection_slice.py b/tests/test_engine/test_projection/test_projection_slice.py index 8325f26..ea4753c 100644 --- a/tests/test_engine/test_projection/test_projection_slice.py +++ b/tests/test_engine/test_projection/test_projection_slice.py @@ -103,3 +103,83 @@ def run(proj): proj = {"a": {"$slice": [-5, 4]}, "x": 0} run(proj) + + +def test_projection_slice_fields(monty_proj, mongo_proj): + docs = [ + {"a": [0, 1, 2], "b": 7, "c": 9} + ] + spec = {} + proj = {"a": {"$slice": 1}} + + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + assert count_documents(mongo_c, spec) == 1 + assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) + assert next(mongo_c) == next(monty_c) + + +def test_projection_slice_fields_with_regular_exclusion(monty_proj, mongo_proj): + docs = [ + {"a": [0, 1, 2], "b": 7, "c": 9} + ] + spec = {} + proj = {"a": {"$slice": 1}, "b": 0} + + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + assert count_documents(mongo_c, spec) == 1 + assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) + assert next(mongo_c) == next(monty_c) + + +def test_projection_slice_fields_with_regular_inclusion(monty_proj, mongo_proj): + docs = [ + {"a": [0, 1, 2], "b": 7, "c": 9} + ] + spec = {} + proj = {"a": {"$slice": 1}, "b": 1} + + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + assert count_documents(mongo_c, spec) == 1 + assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) + res = next(mongo_c) + print(res) + assert res == next(monty_c) + + +def test_projection_slice_fields_with_id_exclusion(monty_proj, mongo_proj): + docs = [ + {"a": [0, 1, 2], "b": 7, "c": 9} + ] + spec = {} + proj = {"a": {"$slice": 1}, "_id": 0} + + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + assert count_documents(mongo_c, spec) == 1 + assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) + assert next(mongo_c) == next(monty_c) + + +def test_projection_slice_mongo_44_example(monty_proj, mongo_proj): + docs = [ + {"item": "socks", + "qty": 100, + "details": {"colors": ["blue", "red"], + "sizes": ["S", "M", "L"]}} + ] + spec = {} + proj = {"qty": 1, "details.colors": {"$slice": 1}} + + monty_c = monty_proj(docs, spec, proj) + mongo_c = mongo_proj(docs, spec, proj) + + assert count_documents(mongo_c, spec) == 1 + assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) + assert next(mongo_c) == next(monty_c) From 016b62a1a24a8875a684c03b1b37783207b563a5 Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Fri, 3 Feb 2023 19:18:28 +0800 Subject: [PATCH 25/26] Cleanup --- tests/test_engine/test_projection/test_projection_slice.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_engine/test_projection/test_projection_slice.py b/tests/test_engine/test_projection/test_projection_slice.py index ea4753c..a723b11 100644 --- a/tests/test_engine/test_projection/test_projection_slice.py +++ b/tests/test_engine/test_projection/test_projection_slice.py @@ -147,9 +147,7 @@ def test_projection_slice_fields_with_regular_inclusion(monty_proj, mongo_proj): assert count_documents(mongo_c, spec) == 1 assert count_documents(monty_c, spec) == count_documents(mongo_c, spec) - res = next(mongo_c) - print(res) - assert res == next(monty_c) + assert next(mongo_c) == next(monty_c) def test_projection_slice_fields_with_id_exclusion(monty_proj, mongo_proj): From 71f8283d35c2b1ff01c9e4132e4851f6ad8757a4 Mon Sep 17 00:00:00 2001 From: davidlatwe Date: Sun, 5 Feb 2023 15:56:44 +0800 Subject: [PATCH 26/26] Fix warnings in test --- pyproject.toml | 5 +++++ tests/test_mongoengine.py | 9 ++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3a08c13..6cb09b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,6 +40,11 @@ codespell = "^2" black = {version = "*", python =">=3.6.2", allow-prereleases = true} bandit = "^1" +[tool.pytest.ini_options] +filterwarnings = [ + "ignore::pytest.PytestUnraisableExceptionWarning", +] + [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" diff --git a/tests/test_mongoengine.py b/tests/test_mongoengine.py index 498b423..791e765 100644 --- a/tests/test_mongoengine.py +++ b/tests/test_mongoengine.py @@ -3,9 +3,12 @@ def test_mongoengine_basic(monty_database): - mongoengine.connect(db="test_db", - mongo_client_class=montydb.MontyClient, - repository=":memory:") + mongoengine.connect( + db="test_db", + mongo_client_class=montydb.MontyClient, + repository=":memory:", + uuidRepresentation="standard", # so mongoengine don't raise DeprecationWarning + ) class BlogPost(mongoengine.Document): title = mongoengine.StringField(required=True, max_length=200)