Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

comparison chaining has wrong source positions in most contexts (python 3.11.0rc2) #95921

Closed
Assignees
brandtbucher
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error
@15r10nk

Description

@15r10nk

problem

comparison chaining has wrong source positions in most contexts

>>>cnd=True>>>a=1if1in2==3else0Traceback (mostrecentcalllast):File"example.py",line43,in<module>a=1if1in2==3else0^^^^^^^^^^^^^^^^^^^^^^^TypeError:argumentof type'int'isnotiterable

This bug requires two things to happen:

  1. The comparison chain has to contain more than on comparison the type does not matter (==,in,<=,is,...)
  2. The context has to be something other than an expression

no problem

The following examples work:
only one comparison

Traceback (mostrecentcalllast):File"example.py",line4,in<module>if5<"5":^^^^^TypeError:'<'notsupportedbetweeninstancesof'int'and'str'

inside expression

>>>a=Falseor4<"5"<6Traceback (mostrecentcalllast):File"example.py",line15,in<module>a=Falseor4<"5"<6^^^^^^^TypeError:'<'notsupportedbetweeninstancesof'int'and'str'

reason

The problem seems to be the positions in the compiled bytecode:

script:

importdisdeffoo():if1<2<"no int":return1return0forpindis.get_instructions(foo):print(p.positions,p.opname,p.argval)

output (Python 3.11.0rc2+):

Positions(lineno=4,end_lineno=4,col_offset=0,end_col_offset=0)RESUME0Positions(lineno=5,end_lineno=5,col_offset=7,end_col_offset=8)LOAD_CONST1Positions(lineno=5,end_lineno=5,col_offset=9,end_col_offset=10)LOAD_CONST2Positions(lineno=5,end_lineno=6,col_offset=4,end_col_offset=16)SWAP2Positions(lineno=5,end_lineno=6,col_offset=4,end_col_offset=16)COPY2Positions(lineno=5,end_lineno=6,col_offset=4,end_col_offset=16)COMPARE_OP<# range of the whole ifPositions(lineno=5,end_lineno=6,col_offset=4,end_col_offset=16)POP_JUMP_FORWARD_IF_FALSE30Positions(lineno=5,end_lineno=5,col_offset=11,end_col_offset=19)LOAD_CONSTnointPositions(lineno=5,end_lineno=6,col_offset=4,end_col_offset=16)COMPARE_OP<# range of the whole ifPositions(lineno=5,end_lineno=6,col_offset=4,end_col_offset=16)POP_JUMP_FORWARD_IF_FALSE38Positions(lineno=5,end_lineno=6,col_offset=4,end_col_offset=16)JUMP_FORWARD34Positions(lineno=5,end_lineno=6,col_offset=4,end_col_offset=16)POP_TOPNonePositions(lineno=5,end_lineno=6,col_offset=4,end_col_offset=16)JUMP_FORWARD38Positions(lineno=6,end_lineno=6,col_offset=15,end_col_offset=16)LOAD_CONST1Positions(lineno=6,end_lineno=6,col_offset=15,end_col_offset=16)RETURN_VALUENonePositions(lineno=7,end_lineno=7,col_offset=11,end_col_offset=12)LOAD_CONST0Positions(lineno=7,end_lineno=7,col_offset=11,end_col_offset=12)RETURN_VALUENone

the generated ast looks fine (snippet):

            If(               test=Compare(                  left=Constant(                     value=1,                     lineno=5,                     col_offset=7, # correct                     end_lineno=5,                     end_col_offset=8),                  ops=[                     Lt(),                     Lt()],                  comparators=[                     Constant(                        value=2,                        lineno=5,                        col_offset=9, # correct                        end_lineno=5,                        end_col_offset=10),                     Constant(                        value='no int',                        lineno=5,                        col_offset=11, # correct                        end_lineno=5,                        end_col_offset=19)],                  lineno=5,                  col_offset=7,                  end_lineno=5,                  end_col_offset=19),

other examples

here is a list of all the problems I found so far:

>>>if4<"5"<6:...pass...Traceback (mostrecentcalllast):File"example.py",line20,in<module>if4<"5"<6:TypeError:'<'notsupportedbetweeninstancesof'int'and'str'>>>while4<"5"<6:...pass...Traceback (mostrecentcalllast):File"example.py",line24,in<module>while4<"5"<6:TypeError:'<'notsupportedbetweeninstancesof'int'and'str'>>>assert4<"5"<6Traceback (mostrecentcalllast):File"example.py",line27,in<module>assert4<"5"<6TypeError:'<'notsupportedbetweeninstancesof'int'and'str'>>>a=2+(5if4<"5"<6else3)Traceback (mostrecentcalllast):File"example.py",line29,in<module>a=2+(5if4<"5"<6else3)^^^^^^^^^^^^^^^^^^^TypeError:'<'notsupportedbetweeninstancesof'int'and'str'>>>a=[aforain [1]if4<"5"<a ]Traceback (mostrecentcalllast):File"example.py",line34,in<listcomp>a=[aforain [1]if4<"5"<a ]^^^^^^^^^^^^^^^^^^^^^^^^^^^^TypeError:'<'notsupportedbetweeninstancesof'int'and'str'>>>a={aforain [1]if4<"5"<a }Traceback (mostrecentcalllast):File"example.py",line35,in<setcomp>a={aforain [1]if4<"5"<a }^^^^^^^^^^^^^^^^^^^^^^^^^^^^TypeError:'<'notsupportedbetweeninstancesof'int'and'str'>>>a={a:aforain [1]if4<"5"<a }Traceback (mostrecentcalllast):File"example.py",line36,in<dictcomp>a={a:aforain [1]if4<"5"<a }^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^TypeError:'<'notsupportedbetweeninstancesof'int'and'str'>>>a=list((aforain [1]if4<"5"<a ))Traceback (mostrecentcalllast):File"example.py",line37,in<genexpr>a=list((aforain [1]if4<"5"<a ))^^^^^^^^^^^^^^^^^^^^^^^^^^^^TypeError:'<'notsupportedbetweeninstancesof'int'and'str'>>>cnd=True>>>a=1if1in2==3else0Traceback (mostrecentcalllast):File"example.py",line43,in<module>a=1if1in2==3else0^^^^^^^^^^^^^^^^^^^^^^^TypeError:argumentof type'int'isnotiterable>>>ifTrueand4<"5"<6:...pass...Traceback (mostrecentcalllast):File"example.py",line45,in<module>ifTrueand4<"5"<6:TypeError:'<'notsupportedbetweeninstancesof'int'and'str'

expected result

The positions should always match the ast-node range:

>>>a=list((aforain [1]if4<"5"<a ))Traceback (mostrecentcalllast):File"example.py",line37,in<genexpr>a=list((aforain [1]if4<"5"<a ))^^^^^^^TypeError:'<'notsupportedbetweeninstancesof'int'and'str'

or, even better only the failing comparison:

>>>a=list((aforain [1]if4<"5"<a ))Traceback (mostrecentcalllast):File"example.py",line37,in<genexpr>a=list((aforain [1]if4<"5"<a ))^^^^^TypeError:'<'notsupportedbetweeninstancesof'int'and'str'

Metadata

Metadata

Assignees

Labels

interpreter-core(Objects, Python, Grammar, and Parser dirs)type-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions


    [8]ページ先頭

    ©2009-2025 Movatter.jp