From 1250cebc1faddc93172f7eb4ca3649b18ad6b03b Mon Sep 17 00:00:00 2001 From: Vincent Gao Date: Wed, 24 Jun 2026 10:34:12 +0200 Subject: [PATCH] fix: tuple/list dict keys cross-match due to Or semantics in key validation Schema keys that are tuples or lists were validated through the ITERABLE path which uses Or semantics on elements. When two tuple keys had overlapping elements (e.g. ('a','b') and ('b','b')), the first key would incorrectly match the second data key because Or('a','b') matches all elements of ('b','b'). Fix by using exact comparison for tuple/list schema keys during dict key matching, matching the expectation that dict keys should be compared literally rather than as sets of allowed values. Fixes #312 --- schema/__init__.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/schema/__init__.py b/schema/__init__.py index 10d6e8a..4a6685c 100644 --- a/schema/__init__.py +++ b/schema/__init__.py @@ -471,7 +471,17 @@ def validate(self, data: Any, **kwargs: Dict[str, Any]) -> Any: for skey in sorted_skeys: svalue = s[skey] try: - nkey = Schema(skey, error=e).validate(key, **kwargs) + # For tuple/list schema keys, use exact comparison + # to avoid cross-matching via Or semantics when + # elements overlap (issue #312). + if type(skey) in (tuple, list): + if skey != key: + raise SchemaError( + "%r does not match %r" % (skey, key), None + ) + nkey = key + else: + nkey = Schema(skey, error=e).validate(key, **kwargs) except SchemaError as x: # If the rejecting key schema carries a custom error, # remember it in case this data key is reported as wrong.