# HG changeset patch # User Franz Glasner # Date 1689766255 -7200 # Node ID 5a2fba9967739d648ab2e9f0a0d6c0988a42bbf7 # Parent ef586378f79a4a7c814efc1f97025bbd2d4dbe79 Implement a "forbidden" schema field for dicts diff -r ef586378f79a -r 5a2fba996773 data_schema/__init__.py --- a/data_schema/__init__.py Wed Jul 19 13:26:06 2023 +0200 +++ b/data_schema/__init__.py Wed Jul 19 13:30:55 2023 +0200 @@ -118,6 +118,7 @@ E10056 = NC_("schema-msg", "failing `any-of' item") E10057 = NC_("schema-msg", "`all-of' failed") E10058 = NC_("schema-msg", "failing `all-of' item") + E10059 = NC_("schema-msg", "forbidden key detected") @enum.unique @@ -738,6 +739,14 @@ if not required_keys <= seen_keys: hs = [str(i) for i in required_keys - seen_keys] yield ValidationProblem(code=ERRORS.E10005, hint=sorted(hs), context=context) + # check whether no forbidden keys are seen + try: + forbidden_keys = set(schema.get("forbidden", set())) + except (TypeError, ValueError): + raise SchemaError("`forbidden` must be an iterable") + if forbidden_keys & seen_keys: + hs = [str(i) for i in forbidden_keys & seen_keys] + yield ValidationProblem(code=ERRORS.E10059, hint=sorted(hs), context=context) def validate_list(obj, schema, context): diff -r ef586378f79a -r 5a2fba996773 docs/schema.txt --- a/docs/schema.txt Wed Jul 19 13:26:06 2023 +0200 +++ b/docs/schema.txt Wed Jul 19 13:30:55 2023 +0200 @@ -52,7 +52,7 @@ A callable with an `uri` argument that returns a file-alike and a context manager to be feed into the schema loader. - + - ``schema_loader`` Default: configmix.yaml.load (if available) or ``None`` @@ -118,6 +118,10 @@ Liste von Strings mit Key-Namen, die vorkommen müssen +- ``forbidden`` + + Liste von Strings mit Key-Namen, die **nicht** vorkommen dürfen + - ``max-length`` - ``min-length`` diff -r ef586378f79a -r 5a2fba996773 tests/test_schema.py --- a/tests/test_schema.py Wed Jul 19 13:26:06 2023 +0200 +++ b/tests/test_schema.py Wed Jul 19 13:30:55 2023 +0200 @@ -1607,6 +1607,15 @@ "key-names": {"$type": "int"}})) self.assertEqual(0, len(pr)) + def test_d11_forbidden_keys(self): + pr = list(data_schema.validate( + {"key": 1234, "key-2": 5678}, + {"$type": "dict", + "additional-keys": True, + "forbidden": ["key"]})) + self.assertEqual(1, len(pr)) + self.assertEqual(ERRORS.E10059, pr[0].code) + def test_error_message(self): self.assertEqual("dict expected", data_schema.problem_message(ERRORS.E10000))