python / cpython

The Python programming language
https://www.python.org/
Other
61.16k stars 29.52k forks source link

Wrong bytecode generated for 'in' operation #62408

Closed 0f33552e-3426-4ce7-83ad-4a88a6ffc812 closed 11 years ago

0f33552e-3426-4ce7-83ad-4a88a6ffc812 commented 11 years ago
BPO 18208
Nosy @brettcannon, @birkenfeld, @amauryfa, @ncoghlan, @benjaminp, @phmc

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields: ```python assignee = None closed_at = created_at = labels = ['interpreter-core', 'invalid'] title = "Wrong bytecode generated for 'in' operation" updated_at = user = 'https://github.com/phmc' ``` bugs.python.org fields: ```python activity = actor = 'pconnell' assignee = 'none' closed = True closed_date = closer = 'pconnell' components = ['Interpreter Core'] creation = creator = 'pconnell' dependencies = [] files = [] hgrepos = [] issue_num = 18208 keywords = [] message_count = 3.0 messages = ['191108', '191112', '191134'] nosy_count = 7.0 nosy_names = ['brett.cannon', 'georg.brandl', 'amaury.forgeotdarc', 'ncoghlan', 'benjamin.peterson', 'pconnell', 'isoschiz'] pr_nums = [] priority = 'normal' resolution = 'not a bug' stage = None status = 'closed' superseder = None type = None url = 'https://bugs.python.org/issue18208' versions = [] ```

0f33552e-3426-4ce7-83ad-4a88a6ffc812 commented 11 years ago

The following two expressions should have the same value:

Python 3.4.0a0 (default:fae92309c3be, Jun 14 2013, 09:29:54) 
[GCC 4.8.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 in [2] == False
False
>>> (1 in [2]) == False
True

It looks like this is a compiler issue - there shouldn't be a jump if the 'in' expression is false:

>>> dis.dis("1 in [2] == False")
  1           0 LOAD_CONST               0 (1)
              3 LOAD_CONST               1 (2)
              6 BUILD_LIST               1
              9 DUP_TOP             
             10 ROT_THREE           
             11 COMPARE_OP               6 (in)
             14 JUMP_IF_FALSE_OR_POP    24
             17 LOAD_CONST               2 (False)
             20 COMPARE_OP               2 (==)
             23 RETURN_VALUE        
        >>   24 ROT_TWO             
             25 POP_TOP             
             26 RETURN_VALUE        
>>>
amauryfa commented 11 years ago

This is one case of chained comparisons: http://docs.python.org/3/reference/expressions.html#not-in

"x \<= y \<= z" is equivalent to "(x \<= y) and (y \<= z)" "x in y == z" is equivalent to "(x in y) and (y == z)"

There is a jump if the 'in' expression is false, because 'and' should short-circuit the second comparison.

0f33552e-3426-4ce7-83ad-4a88a6ffc812 commented 11 years ago

Thanks Amaury. That's quite surprising, but I wouldn't advocate changing such long standing behaviour.

I'm closing the issue.