How can I find out which index is out of range?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite
1












In the event of an IndexError, is there a way to tell which object on a line is 'out of range'?



Consider this code:



a = [1,2,3]
b = [1,2,3]

x, y = get_values_from_somewhere()

try:
a[x] = b[y]
except IndexError as e:
....


In the event that x or y is too large and IndexError gets caught, I would like to know which of a or b is out of range (so I can perform different actions in the except block).



Clearly I could compare x and y to len(a) and len(b) respectively, but I am curious if there is another way of doing it using IndexError.










share|improve this question

























    up vote
    7
    down vote

    favorite
    1












    In the event of an IndexError, is there a way to tell which object on a line is 'out of range'?



    Consider this code:



    a = [1,2,3]
    b = [1,2,3]

    x, y = get_values_from_somewhere()

    try:
    a[x] = b[y]
    except IndexError as e:
    ....


    In the event that x or y is too large and IndexError gets caught, I would like to know which of a or b is out of range (so I can perform different actions in the except block).



    Clearly I could compare x and y to len(a) and len(b) respectively, but I am curious if there is another way of doing it using IndexError.










    share|improve this question























      up vote
      7
      down vote

      favorite
      1









      up vote
      7
      down vote

      favorite
      1






      1





      In the event of an IndexError, is there a way to tell which object on a line is 'out of range'?



      Consider this code:



      a = [1,2,3]
      b = [1,2,3]

      x, y = get_values_from_somewhere()

      try:
      a[x] = b[y]
      except IndexError as e:
      ....


      In the event that x or y is too large and IndexError gets caught, I would like to know which of a or b is out of range (so I can perform different actions in the except block).



      Clearly I could compare x and y to len(a) and len(b) respectively, but I am curious if there is another way of doing it using IndexError.










      share|improve this question













      In the event of an IndexError, is there a way to tell which object on a line is 'out of range'?



      Consider this code:



      a = [1,2,3]
      b = [1,2,3]

      x, y = get_values_from_somewhere()

      try:
      a[x] = b[y]
      except IndexError as e:
      ....


      In the event that x or y is too large and IndexError gets caught, I would like to know which of a or b is out of range (so I can perform different actions in the except block).



      Clearly I could compare x and y to len(a) and len(b) respectively, but I am curious if there is another way of doing it using IndexError.







      python exception index-error






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 3 hours ago









      David Board

      878




      878






















          5 Answers
          5






          active

          oldest

          votes

















          up vote
          5
          down vote













          There is a way, but I wouldn't consider it as very robust. There is a subtle difference in the error messages:



          a = [1,2,3]
          b = [1,2,3]

          a[2] = b[3]

          ---------------------------------------------------------------------------
          IndexError Traceback (most recent call last)
          <ipython-input-69-8e0d280b609d> in <module>()
          2 b = [1,2,3]
          3
          ----> 4 a[2] = b[3]

          IndexError: list index out of range


          But if the error is on the left hand side:



          a[3] = b[2]

          ---------------------------------------------------------------------------
          IndexError Traceback (most recent call last)
          <ipython-input-68-9d66e07bc70d> in <module>()
          2 b = [1,2,3]
          3
          ----> 4 a[3] = b[2]

          IndexError: list assignment index out of range


          Note the 'assignment' in the message.



          So, you could do something like:



          a = [1,2,3]
          b = [1,2,3]

          try:
          a[3] = b[2]
          except IndexError as e:
          message = e.args[0]
          if 'assignment' in message:
          print("Error on left hand side")
          else:
          print("Error on right hand side")


          Output:



          # Error on left hand side


          Again, I wouldn't trust it too much, it would fail if the message changes in another version of Python.




          I had a look at these parts of the source code, these different messages are really the only difference between the two errors.






          share|improve this answer






















          • that's very good indeed!
            – Jean-François Fabre
            3 hours ago










          • Also, the assignment is never reached in the first. You cannot differentiate the third case where both would raise an error.
            – schwobaseggl
            3 hours ago










          • @schwobaseggl That's right, as the right hand side is evaluated first, it is where the error would be raised.
            – Thierry Lathuille
            3 hours ago










          • good spot! and i totally agree this should not be relied on though as an implementation detail
            – Chris_Rands
            2 hours ago

















          up vote
          2
          down vote













          The IndexError exception does not store information about what raised the exception. Its only data is an error message. You have to craft your code to do so.



          a = [1,2,3]
          b = [1,2,3]

          x, y = get_values_from_somewhere()

          try:
          value = b[y]
          except IndexError as e:
          ...

          try:
          a[x] = value
          except IndexError as e:
          ...


          I want to add I tried to recover the culprit through inspect.frame and was unable to do so. Thus I suspect there really is no robust way.



          Finally, note that this is specific to IndexError as other exceptions may contain the needed information to infer what caused them. By example a KeyError contains the key that raised it.






          share|improve this answer





























            up vote
            1
            down vote













            A more robust approach would be to tap into the traceback object returned by sys.exc_info(), extract the code indicated by the file name and line number from the frame, use ast.parse to parse the line, subclass ast.NodeVisitor to find all the Subscript nodes, unparse (with astunparse) and eval the nodes with the frame's global and local variables to see which of the nodes causes exception, and print the offending expression:



            import sys
            import linecache
            import ast
            import astunparse

            def find_index_error():
            tb = sys.exc_info()[2]
            frame = tb.tb_frame
            lineno = tb.tb_lineno
            filename = frame.f_code.co_filename
            line = linecache.getline(filename, lineno, frame.f_globals)
            node = ast.parse(line.strip(), filename)
            class find_index_error_node(ast.NodeVisitor):
            def visit_Subscript(self, node):
            expr = astunparse.unparse(node).strip()
            try:
            eval(expr, frame.f_globals, frame.f_locals)
            except IndexError:
            print("%s causes IndexError" % expr)
            find_index_error_node().visit(node)

            a = [1,2,3]
            b = [1,2,3]
            x, y = 1, 2
            def f():
            return 3
            try:
            a[f() - 1] = b[f() + y] + a[x + 1] # can you guess which of them causes IndexError?
            except IndexError:
            find_index_error()


            This outputs:



            b[(f() + y)] causes IndexError





            share|improve this answer






















            • Nice. Perhaps you could edit this answer so that everything in the except block is in a function that can be used whenever the developer needs to unpick what caused an IndexError?
              – David Board
              19 mins ago










            • Sure. Edited as suggested then.
              – blhsing
              13 mins ago

















            up vote
            0
            down vote













            No, there is no way of deducing which of the two is out of bounds using the IndexError thrown.






            share|improve this answer



























              up vote
              0
              down vote













              Something like this perhaps?



              a = [1,2,3]
              b = [2,3,4]
              x = 5
              y = 1

              try:
              a[x] = b[y]
              except IndexError:
              try:
              a[x]
              print('b caused indexerror')
              except IndexError:
              print('a caused indexerror')





              share|improve this answer




















                Your Answer





                StackExchange.ifUsing("editor", function ()
                StackExchange.using("externalEditor", function ()
                StackExchange.using("snippets", function ()
                StackExchange.snippets.init();
                );
                );
                , "code-snippets");

                StackExchange.ready(function()
                var channelOptions =
                tags: "".split(" "),
                id: "1"
                ;
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function()
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled)
                StackExchange.using("snippets", function()
                createEditor();
                );

                else
                createEditor();

                );

                function createEditor()
                StackExchange.prepareEditor(
                heartbeatType: 'answer',
                convertImagesToLinks: true,
                noModals: false,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                );



                );













                 

                draft saved


                draft discarded


















                StackExchange.ready(
                function ()
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52332281%2fhow-can-i-find-out-which-index-is-out-of-range%23new-answer', 'question_page');

                );

                Post as a guest






























                5 Answers
                5






                active

                oldest

                votes








                5 Answers
                5






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                5
                down vote













                There is a way, but I wouldn't consider it as very robust. There is a subtle difference in the error messages:



                a = [1,2,3]
                b = [1,2,3]

                a[2] = b[3]

                ---------------------------------------------------------------------------
                IndexError Traceback (most recent call last)
                <ipython-input-69-8e0d280b609d> in <module>()
                2 b = [1,2,3]
                3
                ----> 4 a[2] = b[3]

                IndexError: list index out of range


                But if the error is on the left hand side:



                a[3] = b[2]

                ---------------------------------------------------------------------------
                IndexError Traceback (most recent call last)
                <ipython-input-68-9d66e07bc70d> in <module>()
                2 b = [1,2,3]
                3
                ----> 4 a[3] = b[2]

                IndexError: list assignment index out of range


                Note the 'assignment' in the message.



                So, you could do something like:



                a = [1,2,3]
                b = [1,2,3]

                try:
                a[3] = b[2]
                except IndexError as e:
                message = e.args[0]
                if 'assignment' in message:
                print("Error on left hand side")
                else:
                print("Error on right hand side")


                Output:



                # Error on left hand side


                Again, I wouldn't trust it too much, it would fail if the message changes in another version of Python.




                I had a look at these parts of the source code, these different messages are really the only difference between the two errors.






                share|improve this answer






















                • that's very good indeed!
                  – Jean-François Fabre
                  3 hours ago










                • Also, the assignment is never reached in the first. You cannot differentiate the third case where both would raise an error.
                  – schwobaseggl
                  3 hours ago










                • @schwobaseggl That's right, as the right hand side is evaluated first, it is where the error would be raised.
                  – Thierry Lathuille
                  3 hours ago










                • good spot! and i totally agree this should not be relied on though as an implementation detail
                  – Chris_Rands
                  2 hours ago














                up vote
                5
                down vote













                There is a way, but I wouldn't consider it as very robust. There is a subtle difference in the error messages:



                a = [1,2,3]
                b = [1,2,3]

                a[2] = b[3]

                ---------------------------------------------------------------------------
                IndexError Traceback (most recent call last)
                <ipython-input-69-8e0d280b609d> in <module>()
                2 b = [1,2,3]
                3
                ----> 4 a[2] = b[3]

                IndexError: list index out of range


                But if the error is on the left hand side:



                a[3] = b[2]

                ---------------------------------------------------------------------------
                IndexError Traceback (most recent call last)
                <ipython-input-68-9d66e07bc70d> in <module>()
                2 b = [1,2,3]
                3
                ----> 4 a[3] = b[2]

                IndexError: list assignment index out of range


                Note the 'assignment' in the message.



                So, you could do something like:



                a = [1,2,3]
                b = [1,2,3]

                try:
                a[3] = b[2]
                except IndexError as e:
                message = e.args[0]
                if 'assignment' in message:
                print("Error on left hand side")
                else:
                print("Error on right hand side")


                Output:



                # Error on left hand side


                Again, I wouldn't trust it too much, it would fail if the message changes in another version of Python.




                I had a look at these parts of the source code, these different messages are really the only difference between the two errors.






                share|improve this answer






















                • that's very good indeed!
                  – Jean-François Fabre
                  3 hours ago










                • Also, the assignment is never reached in the first. You cannot differentiate the third case where both would raise an error.
                  – schwobaseggl
                  3 hours ago










                • @schwobaseggl That's right, as the right hand side is evaluated first, it is where the error would be raised.
                  – Thierry Lathuille
                  3 hours ago










                • good spot! and i totally agree this should not be relied on though as an implementation detail
                  – Chris_Rands
                  2 hours ago












                up vote
                5
                down vote










                up vote
                5
                down vote









                There is a way, but I wouldn't consider it as very robust. There is a subtle difference in the error messages:



                a = [1,2,3]
                b = [1,2,3]

                a[2] = b[3]

                ---------------------------------------------------------------------------
                IndexError Traceback (most recent call last)
                <ipython-input-69-8e0d280b609d> in <module>()
                2 b = [1,2,3]
                3
                ----> 4 a[2] = b[3]

                IndexError: list index out of range


                But if the error is on the left hand side:



                a[3] = b[2]

                ---------------------------------------------------------------------------
                IndexError Traceback (most recent call last)
                <ipython-input-68-9d66e07bc70d> in <module>()
                2 b = [1,2,3]
                3
                ----> 4 a[3] = b[2]

                IndexError: list assignment index out of range


                Note the 'assignment' in the message.



                So, you could do something like:



                a = [1,2,3]
                b = [1,2,3]

                try:
                a[3] = b[2]
                except IndexError as e:
                message = e.args[0]
                if 'assignment' in message:
                print("Error on left hand side")
                else:
                print("Error on right hand side")


                Output:



                # Error on left hand side


                Again, I wouldn't trust it too much, it would fail if the message changes in another version of Python.




                I had a look at these parts of the source code, these different messages are really the only difference between the two errors.






                share|improve this answer














                There is a way, but I wouldn't consider it as very robust. There is a subtle difference in the error messages:



                a = [1,2,3]
                b = [1,2,3]

                a[2] = b[3]

                ---------------------------------------------------------------------------
                IndexError Traceback (most recent call last)
                <ipython-input-69-8e0d280b609d> in <module>()
                2 b = [1,2,3]
                3
                ----> 4 a[2] = b[3]

                IndexError: list index out of range


                But if the error is on the left hand side:



                a[3] = b[2]

                ---------------------------------------------------------------------------
                IndexError Traceback (most recent call last)
                <ipython-input-68-9d66e07bc70d> in <module>()
                2 b = [1,2,3]
                3
                ----> 4 a[3] = b[2]

                IndexError: list assignment index out of range


                Note the 'assignment' in the message.



                So, you could do something like:



                a = [1,2,3]
                b = [1,2,3]

                try:
                a[3] = b[2]
                except IndexError as e:
                message = e.args[0]
                if 'assignment' in message:
                print("Error on left hand side")
                else:
                print("Error on right hand side")


                Output:



                # Error on left hand side


                Again, I wouldn't trust it too much, it would fail if the message changes in another version of Python.




                I had a look at these parts of the source code, these different messages are really the only difference between the two errors.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 3 hours ago

























                answered 3 hours ago









                Thierry Lathuille

                6,07982630




                6,07982630











                • that's very good indeed!
                  – Jean-François Fabre
                  3 hours ago










                • Also, the assignment is never reached in the first. You cannot differentiate the third case where both would raise an error.
                  – schwobaseggl
                  3 hours ago










                • @schwobaseggl That's right, as the right hand side is evaluated first, it is where the error would be raised.
                  – Thierry Lathuille
                  3 hours ago










                • good spot! and i totally agree this should not be relied on though as an implementation detail
                  – Chris_Rands
                  2 hours ago
















                • that's very good indeed!
                  – Jean-François Fabre
                  3 hours ago










                • Also, the assignment is never reached in the first. You cannot differentiate the third case where both would raise an error.
                  – schwobaseggl
                  3 hours ago










                • @schwobaseggl That's right, as the right hand side is evaluated first, it is where the error would be raised.
                  – Thierry Lathuille
                  3 hours ago










                • good spot! and i totally agree this should not be relied on though as an implementation detail
                  – Chris_Rands
                  2 hours ago















                that's very good indeed!
                – Jean-François Fabre
                3 hours ago




                that's very good indeed!
                – Jean-François Fabre
                3 hours ago












                Also, the assignment is never reached in the first. You cannot differentiate the third case where both would raise an error.
                – schwobaseggl
                3 hours ago




                Also, the assignment is never reached in the first. You cannot differentiate the third case where both would raise an error.
                – schwobaseggl
                3 hours ago












                @schwobaseggl That's right, as the right hand side is evaluated first, it is where the error would be raised.
                – Thierry Lathuille
                3 hours ago




                @schwobaseggl That's right, as the right hand side is evaluated first, it is where the error would be raised.
                – Thierry Lathuille
                3 hours ago












                good spot! and i totally agree this should not be relied on though as an implementation detail
                – Chris_Rands
                2 hours ago




                good spot! and i totally agree this should not be relied on though as an implementation detail
                – Chris_Rands
                2 hours ago












                up vote
                2
                down vote













                The IndexError exception does not store information about what raised the exception. Its only data is an error message. You have to craft your code to do so.



                a = [1,2,3]
                b = [1,2,3]

                x, y = get_values_from_somewhere()

                try:
                value = b[y]
                except IndexError as e:
                ...

                try:
                a[x] = value
                except IndexError as e:
                ...


                I want to add I tried to recover the culprit through inspect.frame and was unable to do so. Thus I suspect there really is no robust way.



                Finally, note that this is specific to IndexError as other exceptions may contain the needed information to infer what caused them. By example a KeyError contains the key that raised it.






                share|improve this answer


























                  up vote
                  2
                  down vote













                  The IndexError exception does not store information about what raised the exception. Its only data is an error message. You have to craft your code to do so.



                  a = [1,2,3]
                  b = [1,2,3]

                  x, y = get_values_from_somewhere()

                  try:
                  value = b[y]
                  except IndexError as e:
                  ...

                  try:
                  a[x] = value
                  except IndexError as e:
                  ...


                  I want to add I tried to recover the culprit through inspect.frame and was unable to do so. Thus I suspect there really is no robust way.



                  Finally, note that this is specific to IndexError as other exceptions may contain the needed information to infer what caused them. By example a KeyError contains the key that raised it.






                  share|improve this answer
























                    up vote
                    2
                    down vote










                    up vote
                    2
                    down vote









                    The IndexError exception does not store information about what raised the exception. Its only data is an error message. You have to craft your code to do so.



                    a = [1,2,3]
                    b = [1,2,3]

                    x, y = get_values_from_somewhere()

                    try:
                    value = b[y]
                    except IndexError as e:
                    ...

                    try:
                    a[x] = value
                    except IndexError as e:
                    ...


                    I want to add I tried to recover the culprit through inspect.frame and was unable to do so. Thus I suspect there really is no robust way.



                    Finally, note that this is specific to IndexError as other exceptions may contain the needed information to infer what caused them. By example a KeyError contains the key that raised it.






                    share|improve this answer














                    The IndexError exception does not store information about what raised the exception. Its only data is an error message. You have to craft your code to do so.



                    a = [1,2,3]
                    b = [1,2,3]

                    x, y = get_values_from_somewhere()

                    try:
                    value = b[y]
                    except IndexError as e:
                    ...

                    try:
                    a[x] = value
                    except IndexError as e:
                    ...


                    I want to add I tried to recover the culprit through inspect.frame and was unable to do so. Thus I suspect there really is no robust way.



                    Finally, note that this is specific to IndexError as other exceptions may contain the needed information to infer what caused them. By example a KeyError contains the key that raised it.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited 3 hours ago

























                    answered 3 hours ago









                    Olivier Melançon

                    11.5k11436




                    11.5k11436




















                        up vote
                        1
                        down vote













                        A more robust approach would be to tap into the traceback object returned by sys.exc_info(), extract the code indicated by the file name and line number from the frame, use ast.parse to parse the line, subclass ast.NodeVisitor to find all the Subscript nodes, unparse (with astunparse) and eval the nodes with the frame's global and local variables to see which of the nodes causes exception, and print the offending expression:



                        import sys
                        import linecache
                        import ast
                        import astunparse

                        def find_index_error():
                        tb = sys.exc_info()[2]
                        frame = tb.tb_frame
                        lineno = tb.tb_lineno
                        filename = frame.f_code.co_filename
                        line = linecache.getline(filename, lineno, frame.f_globals)
                        node = ast.parse(line.strip(), filename)
                        class find_index_error_node(ast.NodeVisitor):
                        def visit_Subscript(self, node):
                        expr = astunparse.unparse(node).strip()
                        try:
                        eval(expr, frame.f_globals, frame.f_locals)
                        except IndexError:
                        print("%s causes IndexError" % expr)
                        find_index_error_node().visit(node)

                        a = [1,2,3]
                        b = [1,2,3]
                        x, y = 1, 2
                        def f():
                        return 3
                        try:
                        a[f() - 1] = b[f() + y] + a[x + 1] # can you guess which of them causes IndexError?
                        except IndexError:
                        find_index_error()


                        This outputs:



                        b[(f() + y)] causes IndexError





                        share|improve this answer






















                        • Nice. Perhaps you could edit this answer so that everything in the except block is in a function that can be used whenever the developer needs to unpick what caused an IndexError?
                          – David Board
                          19 mins ago










                        • Sure. Edited as suggested then.
                          – blhsing
                          13 mins ago














                        up vote
                        1
                        down vote













                        A more robust approach would be to tap into the traceback object returned by sys.exc_info(), extract the code indicated by the file name and line number from the frame, use ast.parse to parse the line, subclass ast.NodeVisitor to find all the Subscript nodes, unparse (with astunparse) and eval the nodes with the frame's global and local variables to see which of the nodes causes exception, and print the offending expression:



                        import sys
                        import linecache
                        import ast
                        import astunparse

                        def find_index_error():
                        tb = sys.exc_info()[2]
                        frame = tb.tb_frame
                        lineno = tb.tb_lineno
                        filename = frame.f_code.co_filename
                        line = linecache.getline(filename, lineno, frame.f_globals)
                        node = ast.parse(line.strip(), filename)
                        class find_index_error_node(ast.NodeVisitor):
                        def visit_Subscript(self, node):
                        expr = astunparse.unparse(node).strip()
                        try:
                        eval(expr, frame.f_globals, frame.f_locals)
                        except IndexError:
                        print("%s causes IndexError" % expr)
                        find_index_error_node().visit(node)

                        a = [1,2,3]
                        b = [1,2,3]
                        x, y = 1, 2
                        def f():
                        return 3
                        try:
                        a[f() - 1] = b[f() + y] + a[x + 1] # can you guess which of them causes IndexError?
                        except IndexError:
                        find_index_error()


                        This outputs:



                        b[(f() + y)] causes IndexError





                        share|improve this answer






















                        • Nice. Perhaps you could edit this answer so that everything in the except block is in a function that can be used whenever the developer needs to unpick what caused an IndexError?
                          – David Board
                          19 mins ago










                        • Sure. Edited as suggested then.
                          – blhsing
                          13 mins ago












                        up vote
                        1
                        down vote










                        up vote
                        1
                        down vote









                        A more robust approach would be to tap into the traceback object returned by sys.exc_info(), extract the code indicated by the file name and line number from the frame, use ast.parse to parse the line, subclass ast.NodeVisitor to find all the Subscript nodes, unparse (with astunparse) and eval the nodes with the frame's global and local variables to see which of the nodes causes exception, and print the offending expression:



                        import sys
                        import linecache
                        import ast
                        import astunparse

                        def find_index_error():
                        tb = sys.exc_info()[2]
                        frame = tb.tb_frame
                        lineno = tb.tb_lineno
                        filename = frame.f_code.co_filename
                        line = linecache.getline(filename, lineno, frame.f_globals)
                        node = ast.parse(line.strip(), filename)
                        class find_index_error_node(ast.NodeVisitor):
                        def visit_Subscript(self, node):
                        expr = astunparse.unparse(node).strip()
                        try:
                        eval(expr, frame.f_globals, frame.f_locals)
                        except IndexError:
                        print("%s causes IndexError" % expr)
                        find_index_error_node().visit(node)

                        a = [1,2,3]
                        b = [1,2,3]
                        x, y = 1, 2
                        def f():
                        return 3
                        try:
                        a[f() - 1] = b[f() + y] + a[x + 1] # can you guess which of them causes IndexError?
                        except IndexError:
                        find_index_error()


                        This outputs:



                        b[(f() + y)] causes IndexError





                        share|improve this answer














                        A more robust approach would be to tap into the traceback object returned by sys.exc_info(), extract the code indicated by the file name and line number from the frame, use ast.parse to parse the line, subclass ast.NodeVisitor to find all the Subscript nodes, unparse (with astunparse) and eval the nodes with the frame's global and local variables to see which of the nodes causes exception, and print the offending expression:



                        import sys
                        import linecache
                        import ast
                        import astunparse

                        def find_index_error():
                        tb = sys.exc_info()[2]
                        frame = tb.tb_frame
                        lineno = tb.tb_lineno
                        filename = frame.f_code.co_filename
                        line = linecache.getline(filename, lineno, frame.f_globals)
                        node = ast.parse(line.strip(), filename)
                        class find_index_error_node(ast.NodeVisitor):
                        def visit_Subscript(self, node):
                        expr = astunparse.unparse(node).strip()
                        try:
                        eval(expr, frame.f_globals, frame.f_locals)
                        except IndexError:
                        print("%s causes IndexError" % expr)
                        find_index_error_node().visit(node)

                        a = [1,2,3]
                        b = [1,2,3]
                        x, y = 1, 2
                        def f():
                        return 3
                        try:
                        a[f() - 1] = b[f() + y] + a[x + 1] # can you guess which of them causes IndexError?
                        except IndexError:
                        find_index_error()


                        This outputs:



                        b[(f() + y)] causes IndexError






                        share|improve this answer














                        share|improve this answer



                        share|improve this answer








                        edited 13 mins ago

























                        answered 50 mins ago









                        blhsing

                        14.5k2630




                        14.5k2630











                        • Nice. Perhaps you could edit this answer so that everything in the except block is in a function that can be used whenever the developer needs to unpick what caused an IndexError?
                          – David Board
                          19 mins ago










                        • Sure. Edited as suggested then.
                          – blhsing
                          13 mins ago
















                        • Nice. Perhaps you could edit this answer so that everything in the except block is in a function that can be used whenever the developer needs to unpick what caused an IndexError?
                          – David Board
                          19 mins ago










                        • Sure. Edited as suggested then.
                          – blhsing
                          13 mins ago















                        Nice. Perhaps you could edit this answer so that everything in the except block is in a function that can be used whenever the developer needs to unpick what caused an IndexError?
                        – David Board
                        19 mins ago




                        Nice. Perhaps you could edit this answer so that everything in the except block is in a function that can be used whenever the developer needs to unpick what caused an IndexError?
                        – David Board
                        19 mins ago












                        Sure. Edited as suggested then.
                        – blhsing
                        13 mins ago




                        Sure. Edited as suggested then.
                        – blhsing
                        13 mins ago










                        up vote
                        0
                        down vote













                        No, there is no way of deducing which of the two is out of bounds using the IndexError thrown.






                        share|improve this answer
























                          up vote
                          0
                          down vote













                          No, there is no way of deducing which of the two is out of bounds using the IndexError thrown.






                          share|improve this answer






















                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            No, there is no way of deducing which of the two is out of bounds using the IndexError thrown.






                            share|improve this answer












                            No, there is no way of deducing which of the two is out of bounds using the IndexError thrown.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered 3 hours ago









                            Chirila Alexandru

                            1,12431736




                            1,12431736




















                                up vote
                                0
                                down vote













                                Something like this perhaps?



                                a = [1,2,3]
                                b = [2,3,4]
                                x = 5
                                y = 1

                                try:
                                a[x] = b[y]
                                except IndexError:
                                try:
                                a[x]
                                print('b caused indexerror')
                                except IndexError:
                                print('a caused indexerror')





                                share|improve this answer
























                                  up vote
                                  0
                                  down vote













                                  Something like this perhaps?



                                  a = [1,2,3]
                                  b = [2,3,4]
                                  x = 5
                                  y = 1

                                  try:
                                  a[x] = b[y]
                                  except IndexError:
                                  try:
                                  a[x]
                                  print('b caused indexerror')
                                  except IndexError:
                                  print('a caused indexerror')





                                  share|improve this answer






















                                    up vote
                                    0
                                    down vote










                                    up vote
                                    0
                                    down vote









                                    Something like this perhaps?



                                    a = [1,2,3]
                                    b = [2,3,4]
                                    x = 5
                                    y = 1

                                    try:
                                    a[x] = b[y]
                                    except IndexError:
                                    try:
                                    a[x]
                                    print('b caused indexerror')
                                    except IndexError:
                                    print('a caused indexerror')





                                    share|improve this answer












                                    Something like this perhaps?



                                    a = [1,2,3]
                                    b = [2,3,4]
                                    x = 5
                                    y = 1

                                    try:
                                    a[x] = b[y]
                                    except IndexError:
                                    try:
                                    a[x]
                                    print('b caused indexerror')
                                    except IndexError:
                                    print('a caused indexerror')






                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered 3 hours ago









                                    Xnkr

                                    178211




                                    178211



























                                         

                                        draft saved


                                        draft discarded















































                                         


                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function ()
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52332281%2fhow-can-i-find-out-which-index-is-out-of-range%23new-answer', 'question_page');

                                        );

                                        Post as a guest













































































                                        Comments

                                        Popular posts from this blog

                                        Long meetings (6-7 hours a day): Being “babysat” by supervisor

                                        Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

                                        Confectionery