is parameter an iterable?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Rick Wotnaz

    #31
    Re: is parameter an iterable?

    Steven D'Aprano <steve@REMOVETH IScyber.com.au> wrote in
    news:pan.2005.1 1.15.22.57.58.8 55137@REMOVETHI Scyber.com.au:
    [color=blue]
    > def foo(inputVal):
    > try:
    > for val in inputVal:
    > # do stuff
    > except TypeError, msg:
    > if msg == "iteration over non-sequence":
    > # handle non-iterable case
    > else:
    > # some other TypeError is a bug, so re-raise the
    > exception raise[/color]

    Does this in fact work on your system? On mine (2.4.1 (#65, Mar 30
    2005, 09:13:57) [MSC v.1310 32 bit (Intel)]), it doesn't seem to. I
    tried
    if msg.find("itera tion over non-sequence") >= 0:
    .... but I got a traceback, and
    AttributeError: TypeError instance has no attribute 'find'
    .... which leads me to belive that 'msg' is not type(str). It can be
    coerced (str(msg).find works as expected). But what exactly is msg?
    It appears to be of <type 'instance'>, and does not test equal to a
    string. This is not the least surprise to me.

    --
    rzed

    Comment

    • Rick Wotnaz

      #32
      Re: is parameter an iterable?

      Steven D'Aprano <steve@REMOVETH IScyber.com.au> wrote in
      news:pan.2005.1 1.15.22.57.58.8 55137@REMOVETHI Scyber.com.au:
      [color=blue]
      > def foo(inputVal):
      > try:
      > for val in inputVal:
      > # do stuff
      > except TypeError, msg:
      > if msg == "iteration over non-sequence":
      > # handle non-iterable case
      > else:
      > # some other TypeError is a bug, so re-raise the
      > exception raise[/color]

      Does this in fact work on your system? On mine (2.4.1 (#65, Mar 30
      2005, 09:13:57) [MSC v.1310 32 bit (Intel)]), it doesn't seem to. I
      tried
      if msg.find("itera tion over non-sequence") >= 0:
      .... but I got a traceback, and
      AttributeError: TypeError instance has no attribute 'find'
      .... which leads me to belive that 'msg' is not type(str). It can be
      coerced (str(msg).find works as expected). But what exactly is msg?
      It appears to be of <type 'instance'>, and does not test equal to a
      string. This is not the least surprise to me.

      --
      rzed

      Comment

      • Roy Smith

        #33
        Re: is parameter an iterable?

        In article <Xns97105D1B0A5 05reederz@63.22 3.7.253>,
        Rick Wotnaz <desparn@wtf.co m> wrote:
        [color=blue]
        > Steven D'Aprano <steve@REMOVETH IScyber.com.au> wrote in
        > news:pan.2005.1 1.15.22.57.58.8 55137@REMOVETHI Scyber.com.au:
        >[color=green]
        > > def foo(inputVal):
        > > try:
        > > for val in inputVal:
        > > # do stuff
        > > except TypeError, msg:
        > > if msg == "iteration over non-sequence":
        > > # handle non-iterable case
        > > else:
        > > # some other TypeError is a bug, so re-raise the
        > > exception raise[/color]
        >
        > Does this in fact work on your system? On mine (2.4.1 (#65, Mar 30
        > 2005, 09:13:57) [MSC v.1310 32 bit (Intel)]), it doesn't seem to. I
        > tried
        > if msg.find("itera tion over non-sequence") >= 0:
        > ... but I got a traceback, and
        > AttributeError: TypeError instance has no attribute 'find'
        > ... which leads me to belive that 'msg' is not type(str). It can be
        > coerced (str(msg).find works as expected). But what exactly is msg?
        > It appears to be of <type 'instance'>, and does not test equal to a
        > string. This is not the least surprise to me.[/color]

        It's an easy experiment to do:

        -------------------
        Roy-Smiths-Computer:play$ cat ex.py
        #!/usr/bin/env python

        try:
        1 + "foo"
        except TypeError, msg:
        print type(msg)
        print msg
        print repr(msg)
        print dir(msg)
        Roy-Smiths-Computer:play$ py ex.py
        <type 'instance'>
        unsupported operand type(s) for +: 'int' and 'str'
        <exceptions.Typ eError instance at 0x36d968>
        ['__doc__', '__getitem__', '__init__', '__module__', '__str__', 'args']
        ---------------------

        Comment

        • Roy Smith

          #34
          Re: is parameter an iterable?

          In article <Xns97105D1B0A5 05reederz@63.22 3.7.253>,
          Rick Wotnaz <desparn@wtf.co m> wrote:
          [color=blue]
          > Steven D'Aprano <steve@REMOVETH IScyber.com.au> wrote in
          > news:pan.2005.1 1.15.22.57.58.8 55137@REMOVETHI Scyber.com.au:
          >[color=green]
          > > def foo(inputVal):
          > > try:
          > > for val in inputVal:
          > > # do stuff
          > > except TypeError, msg:
          > > if msg == "iteration over non-sequence":
          > > # handle non-iterable case
          > > else:
          > > # some other TypeError is a bug, so re-raise the
          > > exception raise[/color]
          >
          > Does this in fact work on your system? On mine (2.4.1 (#65, Mar 30
          > 2005, 09:13:57) [MSC v.1310 32 bit (Intel)]), it doesn't seem to. I
          > tried
          > if msg.find("itera tion over non-sequence") >= 0:
          > ... but I got a traceback, and
          > AttributeError: TypeError instance has no attribute 'find'
          > ... which leads me to belive that 'msg' is not type(str). It can be
          > coerced (str(msg).find works as expected). But what exactly is msg?
          > It appears to be of <type 'instance'>, and does not test equal to a
          > string. This is not the least surprise to me.[/color]

          It's an easy experiment to do:

          -------------------
          Roy-Smiths-Computer:play$ cat ex.py
          #!/usr/bin/env python

          try:
          1 + "foo"
          except TypeError, msg:
          print type(msg)
          print msg
          print repr(msg)
          print dir(msg)
          Roy-Smiths-Computer:play$ py ex.py
          <type 'instance'>
          unsupported operand type(s) for +: 'int' and 'str'
          <exceptions.Typ eError instance at 0x36d968>
          ['__doc__', '__getitem__', '__init__', '__module__', '__str__', 'args']
          ---------------------

          Comment

          • Fredrik Lundh

            #35
            Re: is parameter an iterable?

            Rick Wotnaz wrote.
            [color=blue]
            > ... which leads me to belive that 'msg' is not type(str). It can be
            > coerced (str(msg).find works as expected). But what exactly is msg?
            > It appears to be of <type 'instance'>, and does not test equal to a
            > string.[/color]

            it's an instance of the exception type, of course.

            :::

            if you do

            raise SomeError, value

            Python will actually do

            raise SomeError(value )

            (that is, create a SomeError exception and pass the value as its
            first argument).

            you can use either form in your code (I prefer the latter myself).

            :::

            as for catching the exceptions, if you do

            try:
            ...
            except SomeError, v:
            ...

            Python will treat this as

            try:
            ...
            except:
            # some exception occurred
            typ = sys.exc_type
            exc = sys.exc_value
            if issubclass(typ, SomeError):
            v = exc
            ...
            else:
            raise # propagate!

            (where typ and exc are internal variables)

            </F>



            Comment

            • Fredrik Lundh

              #36
              Re: is parameter an iterable?

              Rick Wotnaz wrote.
              [color=blue]
              > ... which leads me to belive that 'msg' is not type(str). It can be
              > coerced (str(msg).find works as expected). But what exactly is msg?
              > It appears to be of <type 'instance'>, and does not test equal to a
              > string.[/color]

              it's an instance of the exception type, of course.

              :::

              if you do

              raise SomeError, value

              Python will actually do

              raise SomeError(value )

              (that is, create a SomeError exception and pass the value as its
              first argument).

              you can use either form in your code (I prefer the latter myself).

              :::

              as for catching the exceptions, if you do

              try:
              ...
              except SomeError, v:
              ...

              Python will treat this as

              try:
              ...
              except:
              # some exception occurred
              typ = sys.exc_type
              exc = sys.exc_value
              if issubclass(typ, SomeError):
              v = exc
              ...
              else:
              raise # propagate!

              (where typ and exc are internal variables)

              </F>



              Comment

              • Rick Wotnaz

                #37
                Re: is parameter an iterable?

                "Fredrik Lundh" <fredrik@python ware.com> wrote in
                news:mailman.75 0.1132159667.18 701.python-list@python.org :
                [color=blue]
                > Rick Wotnaz wrote.
                >[color=green]
                >> ... which leads me to belive that 'msg' is not type(str). It
                >> can be coerced (str(msg).find works as expected). But what
                >> exactly is msg? It appears to be of <type 'instance'>, and does
                >> not test equal to a string.[/color]
                >
                > it's an instance of the exception type, of course.
                >
                >:::
                >
                > if you do
                >
                > raise SomeError, value
                >
                > Python will actually do
                >
                > raise SomeError(value )
                >
                > (that is, create a SomeError exception and pass the value as its
                > first argument).
                >
                > you can use either form in your code (I prefer the latter
                > myself).
                >
                >:::
                >
                > as for catching the exceptions, if you do
                >
                > try:
                > ...
                > except SomeError, v:
                > ...
                >
                > Python will treat this as
                >
                > try:
                > ...
                > except:
                > # some exception occurred
                > typ = sys.exc_type
                > exc = sys.exc_value
                > if issubclass(typ, SomeError):
                > v = exc
                > ...
                > else:
                > raise # propagate!
                >
                > (where typ and exc are internal variables)
                >[/color]

                Thank you (and Roy Smith) for helping to clarify this. I see that
                my mental image of an Exception (which, I admit, was not based on
                extensive R'ing of TFM) was way off. Judging by Steven D'Aprano's
                code sample, I'm not the only one who was mistaken about the nature
                of v in your example. I'd always assumed it was the human-
                readable string associated with the TypeError. Wrong, I see.

                --
                rzed

                Comment

                • Rick Wotnaz

                  #38
                  Re: is parameter an iterable?

                  "Fredrik Lundh" <fredrik@python ware.com> wrote in
                  news:mailman.75 0.1132159667.18 701.python-list@python.org :
                  [color=blue]
                  > Rick Wotnaz wrote.
                  >[color=green]
                  >> ... which leads me to belive that 'msg' is not type(str). It
                  >> can be coerced (str(msg).find works as expected). But what
                  >> exactly is msg? It appears to be of <type 'instance'>, and does
                  >> not test equal to a string.[/color]
                  >
                  > it's an instance of the exception type, of course.
                  >
                  >:::
                  >
                  > if you do
                  >
                  > raise SomeError, value
                  >
                  > Python will actually do
                  >
                  > raise SomeError(value )
                  >
                  > (that is, create a SomeError exception and pass the value as its
                  > first argument).
                  >
                  > you can use either form in your code (I prefer the latter
                  > myself).
                  >
                  >:::
                  >
                  > as for catching the exceptions, if you do
                  >
                  > try:
                  > ...
                  > except SomeError, v:
                  > ...
                  >
                  > Python will treat this as
                  >
                  > try:
                  > ...
                  > except:
                  > # some exception occurred
                  > typ = sys.exc_type
                  > exc = sys.exc_value
                  > if issubclass(typ, SomeError):
                  > v = exc
                  > ...
                  > else:
                  > raise # propagate!
                  >
                  > (where typ and exc are internal variables)
                  >[/color]

                  Thank you (and Roy Smith) for helping to clarify this. I see that
                  my mental image of an Exception (which, I admit, was not based on
                  extensive R'ing of TFM) was way off. Judging by Steven D'Aprano's
                  code sample, I'm not the only one who was mistaken about the nature
                  of v in your example. I'd always assumed it was the human-
                  readable string associated with the TypeError. Wrong, I see.

                  --
                  rzed

                  Comment

                  • Steven D'Aprano

                    #39
                    Re: is parameter an iterable?

                    On Wed, 16 Nov 2005 09:06:01 -0500, Rick Wotnaz wrote:

                    [cutting to the important bit][color=blue][color=green]
                    >> except TypeError, msg:
                    >> if msg == "iteration over non-sequence":
                    >> # handle non-iterable case[/color][/color]
                    [color=blue]
                    > Does this in fact work on your system? On mine (2.4.1 (#65, Mar 30
                    > 2005, 09:13:57) [MSC v.1310 32 bit (Intel)]), it doesn't seem to.[/color]

                    Dammit, that will teach me not to test my code before posting.

                    No it doesn't: msg is an object of type exceptions.Type Error.

                    The easy fix is to just coerce it to a string:

                    if str(msg) == "iteration over non-sequence":

                    which *does* work on my system. But perhaps a better way is to do this:


                    # Create an instance of the exception you expect:
                    try:
                    for i in 0:
                    pass
                    except TypeError, ITER_OVER_NON_S EQ:
                    pass
                    # Now run your code...
                    try:
                    ...blah blah blah...
                    except TypeError, msg
                    if str(msg) == str(ITER_OVER_N ON_SEQ):
                    ...blah blah blah...

                    This means we're no longer assuming what the error message will be,
                    which makes our code a lot more future-proof and implementation-proof: if
                    some version of Python changes the error string from "iteration over
                    non-sequence" to something else, the code should continue to work
                    correctly.


                    --
                    Steven.

                    Comment

                    • Steven D'Aprano

                      #40
                      Re: is parameter an iterable?

                      On Wed, 16 Nov 2005 09:06:01 -0500, Rick Wotnaz wrote:

                      [cutting to the important bit][color=blue][color=green]
                      >> except TypeError, msg:
                      >> if msg == "iteration over non-sequence":
                      >> # handle non-iterable case[/color][/color]
                      [color=blue]
                      > Does this in fact work on your system? On mine (2.4.1 (#65, Mar 30
                      > 2005, 09:13:57) [MSC v.1310 32 bit (Intel)]), it doesn't seem to.[/color]

                      Dammit, that will teach me not to test my code before posting.

                      No it doesn't: msg is an object of type exceptions.Type Error.

                      The easy fix is to just coerce it to a string:

                      if str(msg) == "iteration over non-sequence":

                      which *does* work on my system. But perhaps a better way is to do this:


                      # Create an instance of the exception you expect:
                      try:
                      for i in 0:
                      pass
                      except TypeError, ITER_OVER_NON_S EQ:
                      pass
                      # Now run your code...
                      try:
                      ...blah blah blah...
                      except TypeError, msg
                      if str(msg) == str(ITER_OVER_N ON_SEQ):
                      ...blah blah blah...

                      This means we're no longer assuming what the error message will be,
                      which makes our code a lot more future-proof and implementation-proof: if
                      some version of Python changes the error string from "iteration over
                      non-sequence" to something else, the code should continue to work
                      correctly.


                      --
                      Steven.

                      Comment

                      • Fredrik Lundh

                        #41
                        Re: is parameter an iterable?

                        Steven D'Aprano wrote:
                        [color=blue]
                        > This means we're no longer assuming what the error message will be,
                        > which makes our code a lot more future-proof and implementation-proof: if
                        > some version of Python changes the error string from "iteration over
                        > non-sequence" to something else, the code should continue to work
                        > correctly.[/color]

                        Alex has already posted the right way to do this. can you please stop

                        </F>



                        Comment

                        • Fredrik Lundh

                          #42
                          Re: is parameter an iterable?

                          Steven D'Aprano wrote:
                          [color=blue]
                          > This means we're no longer assuming what the error message will be,
                          > which makes our code a lot more future-proof and implementation-proof: if
                          > some version of Python changes the error string from "iteration over
                          > non-sequence" to something else, the code should continue to work
                          > correctly.[/color]

                          Alex has already posted the right way to do this. can you please stop

                          </F>



                          Comment

                          • Fredrik Lundh

                            #43
                            Re: is parameter an iterable?

                            > Alex has already posted the right way to do this. can you please stop

                            posting crappy non-solutions to a problem that has a very simple solution (split
                            things up), that should be obvious to anyone who didn't sleep through exceptions
                            101.

                            </F>



                            Comment

                            • Fredrik Lundh

                              #44
                              Re: is parameter an iterable?

                              > Alex has already posted the right way to do this. can you please stop

                              posting crappy non-solutions to a problem that has a very simple solution (split
                              things up), that should be obvious to anyone who didn't sleep through exceptions
                              101.

                              </F>



                              Comment

                              • Bengt Richter

                                #45
                                Re: is parameter an iterable?

                                On Wed, 16 Nov 2005 17:39:57 +0100, "Fredrik Lundh" <fredrik@python ware.com> wrote:
                                [color=blue]
                                >Rick Wotnaz wrote.
                                >[color=green]
                                >> ... which leads me to belive that 'msg' is not type(str). It can be
                                >> coerced (str(msg).find works as expected). But what exactly is msg?
                                >> It appears to be of <type 'instance'>, and does not test equal to a
                                >> string.[/color]
                                >
                                >it's an instance of the exception type, of course.
                                >
                                >:::
                                >
                                >if you do
                                >
                                > raise SomeError, value
                                >
                                >Python will actually do
                                >
                                > raise SomeError(value )[/color]

                                Depending on what you mean by "actually" I guess ...
                                (I'm sure you know this and more ;-)
                                [color=blue][color=green][color=darkred]
                                >>> dis.dis(compile ('raise SomeError, value','','exec '))[/color][/color][/color]
                                1 0 LOAD_NAME 0 (SomeError)
                                3 LOAD_NAME 1 (value)
                                6 RAISE_VARARGS 2
                                9 LOAD_CONST 0 (None)
                                12 RETURN_VALUE[color=blue][color=green][color=darkred]
                                >>> dis.dis(compile ('raise SomeError(value )','','exec'))[/color][/color][/color]
                                1 0 LOAD_NAME 0 (SomeError)
                                3 LOAD_NAME 1 (value)
                                6 CALL_FUNCTION 1
                                9 RAISE_VARARGS 1
                                12 LOAD_CONST 0 (None)
                                15 RETURN_VALUE

                                I guess that comes from the grammar of the raise statement, i.e.,

                                raise_stmt: 'raise' [test [',' test [',' test]]]

                                which allows up to three arguments for raise, apparently all general
                                expressions, but with some specific run-time requirements for what
                                combinations of argument expression values are allowable.

                                I.e., it seems (I haven't looked in ceval.c(?)) that RAISE_VARARGS must
                                look at the first item in its count of args on the stack, and in the
                                SomeError, value case find an exception class, and decide to instantiate it
                                and throw the instance, but if it finds the instance ready made, as in
                                SomeError(value ), it must skip the instantiation (and disallow further args BTW).
                                [color=blue][color=green][color=darkred]
                                >>> raise Exception, 'arg'[/color][/color][/color]
                                Traceback (most recent call last):
                                File "<stdin>", line 1, in ?
                                Exception: arg[color=blue][color=green][color=darkred]
                                >>> raise Exception('arg' )[/color][/color][/color]
                                Traceback (most recent call last):
                                File "<stdin>", line 1, in ?
                                Exception: arg

                                Those looks the same, but sensitivity to the type of the first arg is revealed by
                                [color=blue][color=green][color=darkred]
                                >>> raise Exception('arg' ), 'what now?'[/color][/color][/color]
                                Traceback (most recent call last):
                                File "<stdin>", line 1, in ?
                                TypeError: instance exception may not have a separate value
                                [color=blue][color=green][color=darkred]
                                >>> raise Exception('arg' , 'what now?')[/color][/color][/color]
                                Traceback (most recent call last):
                                File "<stdin>", line 1, in ?
                                Exception: ('arg', 'what now?')

                                [color=blue]
                                >
                                >(that is, create a SomeError exception and pass the value as its
                                >first argument).
                                >
                                >you can use either form in your code (I prefer the latter myself).
                                >[/color]
                                Just to drive home the general expression allowability in raise,
                                and instance vs class as the first arg:
                                [color=blue][color=green][color=darkred]
                                >>> extab = [StopIteration(' stop stop ;-)'), ValueError('wro ng value')][/color][/color][/color]
                                [color=blue][color=green][color=darkred]
                                >>> raise extab[1][/color][/color][/color]
                                Traceback (most recent call last):
                                File "<stdin>", line 1, in ?
                                ValueError: wrong value
                                [color=blue][color=green][color=darkred]
                                >>> raise extab[0][/color][/color][/color]
                                Traceback (most recent call last):
                                File "<stdin>", line 1, in ?
                                StopIteration: stop stop ;-)
                                [color=blue][color=green][color=darkred]
                                >>> extab = [StopIteration, 'stop stop ;-)', ValueError, 'wrong value'][/color][/color][/color]
                                [color=blue][color=green][color=darkred]
                                >>> raise extab[2], extab[3][/color][/color][/color]
                                Traceback (most recent call last):
                                File "<stdin>", line 1, in ?
                                ValueError: wrong value
                                [color=blue][color=green][color=darkred]
                                >>> raise extab[0], extab[1][/color][/color][/color]
                                Traceback (most recent call last):
                                File "<stdin>", line 1, in ?
                                StopIteration: stop stop ;-)

                                Ok, I'll stop ;-)

                                Regards,
                                Bengt Richter

                                Comment

                                Working...