This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: unexpected behavior on first match case _
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.10
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: docs@python Nosy List: docs@python, ojob, steven.daprano
Priority: normal Keywords:

Created on 2021-09-29 15:19 by ojob, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (5)
msg402884 - (view) Author: Joël Bourgault (ojob) Date: 2021-09-29 15:19
While testing the `match...case` construction, I get the following behavior with Docker image Python 3.10 rc2-slim:

```python
>>> match "robert":
...     case x if len(x) > 10:
...         print("long nom")
...     case [0, y]:
...         print("point à x nul")
...     case _:
...         print("nothing interesting")
...
nothing interesting
>>> x  # assigned, since matched, even if 'guarded-out'
'robert'
>>> y  # not assigned, because not matched
Traceback (most recent call last):
...
NameError: name 'y' is not defined
>>> _  # normally not assigned, but we get a value?? 😱
'robert'
>>> del _  # but the variable does not even exist!?!?!? 😱😱😱
Traceback (most recent call last):
...
NameError: name '_' is not defined

```

Moreover, if we continue working in the same session by assigning `_` explicitly and playing with `case _`, we don't get any weird behavior anymore, and `_` behaves as a normal variable.

So it seems to me that there is some weird corner case here, that should be adressed.
msg402887 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-09-29 15:56
If you are working in the interactive interpreter, you may be running into a conflict with the "magic" variable `_` which the interactive interpreter creates to hold the result of the last evaluated statement.

So when you evaluate `x`, and that returns the string "robert", it also gets assigned to `_`. But you can't easily delete `_` because it lives in the builtin namespace, not the global namespace.

This happens with anything, not just match statements:


>>> x = "spam eggs"
>>> x
'spam eggs'
>>> _
'spam eggs'
>>> del _  # Not a global, can't delete it!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '_' is not defined


So I think the weird behaviour with _ that you have stumbled over is a red herring.

However, it does seem to me that *perhaps* the assignment to x shouldn't be occurring at all. So that may be a bug in the match statement?
msg402888 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-09-29 16:06
It is a bit tricky to find the documentation for the magic single underscore, but it is here:

https://docs.python.org/3/reference/lexical_analysis.html#reserved-classes-of-identifiers
msg402940 - (view) Author: Joël Bourgault (ojob) Date: 2021-09-30 08:34
I obtain the reported behaviour using `python -m doctests <presentation>.md` in a Gitlab pipeline, so it is likely that the execution is similar to the Python interpreter.

Therefore, I am satisfied by your answer, so I close this 'bug'; thanks a lot!

Now, about the fact that `x` is assigned when matched even if "guarded-out" afterwards: this is exposed in the tutorial, so I consider this to be the expected behavior; see last sentence of https://www.python.org/dev/peps/pep-0636/#adding-conditions-to-patterns.

Note: I discovered the observed behavior while writing a presentation, sourced in a markdown file and then rendered as a RevealJS presentation, visible here (French): https://poles.pages.forge.kaizen-solutions.net/pole-python/pr-sentations/python-structural-pattern-matching.
msg402943 - (view) Author: Joël Bourgault (ojob) Date: 2021-09-30 10:09
Complement: the Python tutorial presents the "magic _" in the following section, close to its end: https://docs.python.org/3/tutorial/introduction.html#numbers

> In interactive mode, the last printed expression is assigned to the variable _.
History
Date User Action Args
2022-04-11 14:59:50adminsetgithub: 89486
2021-09-30 10:09:27ojobsetmessages: + msg402943
2021-09-30 08:42:17ojobsetassignee: docs@python

components: + Documentation
nosy: + docs@python
2021-09-30 08:34:30ojobsetstatus: open -> closed
resolution: not a bug
messages: + msg402940

stage: resolved
2021-09-29 16:06:07steven.dapranosetmessages: + msg402888
2021-09-29 15:56:10steven.dapranosetnosy: + steven.daprano
messages: + msg402887
2021-09-29 15:19:21ojobcreate