New submission from Jack DeVries <jdevries3...@gmail.com>:

Consider the following code:

class A:
    a = 'a'

# runs without error
match {'a': 1}:
    case {'a': 1, A.a: 1}:
        pass

# raises ValueError
match {'a': 1, 'b': 1}:
    case {'a': 1, A.a: 1}:
        pass

In both cases, the mapping pattern is the same (and both are not valid due to 
duplicate key values). However, the pattern is only evaluated in the second 
case. This is because a key-length optimization provides a shortcut around 
pattern evaluation. The docs gives users a hint that things like this might 
happen, which is a good thing:

> Users should generally never rely on a pattern being evaluated. Depending on 
> > implementation, the interpreter may cache values or use other optimizations 
> > which skip repeated evaluations. 

> https://docs.python.org/3.10/reference/compound_stmts.html#overview

However, I can't help but think that these ergonomics are strange. Consider if 
some other code is mutating the value of `A.a`. This could create some very 
strange and flaky bugs where the state of `A.a` can change and make the pattern 
invalid, but nonetheless not cause an exception until much later, or not at all.

There is mapping pattern validation code in the `match_keys` function in 
ceval.c. I haven't looked, but I assume there is some other runtime validation 
for other match case types. I propose factoring Exception-raising validation 
into a separate procedure that is called before any optimization jumps occur.

This trades speed for consistent behavior, and I'm interested to hear what 
others think!

----------
components: Interpreter Core
messages: 397662
nosy: jack__d
priority: normal
severity: normal
status: open
title: No ValueError for duplicate key value in mapping patern when lengths do 
not match
type: behavior
versions: Python 3.10, Python 3.11

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue44658>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to