Python CTypes translation of (pv != NULL)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • p.lavarre@ieee.org

    #1

    Python CTypes translation of (pv != NULL)

    Q: The C idea of (pv != NULL) is said most directly in Python ctypes
    how?

    A: We are of course supposed to write something like:

    def c_not_null(pv):
    return (ctypes.cast(pv , ctypes.c_void_p ).value != None)

    Yes?

    Working from the doc, me the clueless newbie, I was slow to guess such
    relevant truths as:

    ctypes.c_void_p (0).value == None
    ctypes.c_void_p (0) != ctypes.c_void_p (0)

    Curiously yours, thanks in advance, Pat LaVarre

  • Gabriel Genellina

    #2
    Re: Python CTypes translation of (pv != NULL)

    At Monday 25/9/2006 21:27, p.lavarre@ieee. org wrote:
    >Q: The C idea of (pv != NULL) is said most directly in Python ctypes
    >how?
    Perhaps reading the ctypes tutorial? (both in the 2.5 docs and in
    <http://starship.python .net/crew/theller/ctypes/tutorial.html>)



    Gabriel Genellina
    Softlab SRL





    _______________ _______________ _______________ _____
    Preguntá. Respondé. Descubrí.
    Todo lo que querías saber, y lo que ni imaginabas,
    está en Yahoo! Respuestas (Beta).
    ¡Probalo ya!


    Comment

    • Thomas Heller

      #3
      Re: Python CTypes translation of (pv != NULL)

      p.lavarre@ieee. org schrieb:
      Q: The C idea of (pv != NULL) is said most directly in Python ctypes
      how?
      >
      A: We are of course supposed to write something like:
      >
      def c_not_null(pv):
      return (ctypes.cast(pv , ctypes.c_void_p ).value != None)
      >
      Yes?
      >
      Working from the doc, me the clueless newbie, I was slow to guess such
      relevant truths as:
      >
      ctypes.c_void_p (0).value == None
      ctypes.c_void_p (0) != ctypes.c_void_p (0)
      >
      Curiously yours, thanks in advance, Pat LaVarre
      >
      Generally pointer instances have a False boolean value, so

      'if pv: ....'

      should work. Except for c_void_p, c_char_p and c_wchar_p instances.

      Thomas

      Comment

      • p.lavarre@ieee.org

        #4
        Re: Python CTypes translation of (pv != NULL)

        Q: The C idea of (pv != NULL) is said most directly in Python ctypes
        how?
        >
        Perhaps reading the ctypes tutorial? (both in the 2.5 docs and in
        <http://starship.python .net/crew/theller/ctypes/tutorial.html>)
        Actually, no. I see three answers or zero, depending on how you like
        to count.

        Yes that flat edition helps makes this clear, thank you - there I can
        more easily grab an ordered list of all matches of text than in the
        more prominent shadow:


        I see direct discussion only of how to construct null pointers, no
        discussion of how to test for them. Specifically:

        The hint { bool(null_ptr) == False } could be read to mean try ==
        False, in the "Pointers" text.

        The hint { ("values", POINTER(c_int))] ... bar.values = None } could be
        read to say try == None, in the "Calling functions" text.

        The hint { if item.name is None } could be read to say try is None, in
        the "Accessing values exported from dlls" text.

        I'm such a Python newbie that I didn't know is None existed alongside
        == None.

        I guess I'll next dig into that along with the answer below from CTypes
        author Thomas Heller.

        Comment

        • p.lavarre@ieee.org

          #5
          Re: Python CTypes translation of (pv != NULL)

          Q: The C idea of (pv != NULL) ...

          CTypes tutorial ... == False ... == None ... is None ...
          >
          Generally ... 'if pv: ....' ... should work.
          Except for c_void_p, c_char_p and c_wchar_p instances.
          Please can we give me an example of these exceptions?

          Indeed those types are the _p types I use most often. Now here
          'bool(pv)' and 'if pv' tell me that null is False and non-null is True,
          for every kind of null or non-null that I know how to construct.

          Is that mapping somehow not reliable across all instances? Or not
          cross-platform?

          You did mean to say that the Python fragments 'bool(pv)' and 'if pv'
          somehow are not accurate translations of the C fragments 'pv != NULL'
          and 'if pv'? Something other kind of Python is?

          Comment

          • Gabriel Genellina

            #6
            Re: Python CTypes translation of (pv != NULL)

            At Tuesday 26/9/2006 16:00, p.lavarre@ieee. org wrote:
            >Q: The C idea of (pv != NULL) is said most directly in Python ctypes
            >how?
            Perhaps reading the ctypes tutorial? (both in the 2.5 docs and in
            <http://starship.python .net/crew/theller/ctypes/tutorial.html>)
            >
            >Actually, no. I see three answers or zero, depending on how you like
            >to count.
            >
            >Yes that flat edition helps makes this clear, thank you - there I can
            >more easily grab an ordered list of all matches of text than in the
            >more prominent shadow:
            >http://docs.python.org/dev/lib/module-ctypes.html
            >
            >I see direct discussion only of how to construct null pointers, no
            >discussion of how to test for them. Specifically:
            >
            >The hint { bool(null_ptr) == False } could be read to mean try ==
            >False, in the "Pointers" text.
            It says:

            NULL pointers have a False boolean value:
            >>null_ptr = POINTER(c_int)( )
            >>print bool(null_ptr)
            False

            That means that NULL pointers are considered False in a boolean
            expression (and you could assume that non-NULL pointers are True, as
            any other object in general), so you can test a NULL pointer with a
            simple "if ptr: whatever"

            --- cut ---
            from ctypes import *
            null_ptr = POINTER(c_int)( )
            x=c_int(1234)
            other_ptr = pointer(x)

            if null_ptr: print "null_ptr is not NULL"
            else: print "null_ptr is NULL"

            if other_ptr: print "other_ptr is not NULL"
            else: print "other_ptr is NULL"
            --- cut ---

            It's really the same as bool([])==False, bool(any_non_em pty_list)==True :

            L = [1,2,3]
            while L:
            print L.pop()

            You don't say:
            while bool(L)==True:

            (do you?)



            Gabriel Genellina
            Softlab SRL





            _______________ _______________ _______________ _____
            Preguntá. Respondé. Descubrí.
            Todo lo que querías saber, y lo que ni imaginabas,
            está en Yahoo! Respuestas (Beta).
            ¡Probalo ya!


            Comment

            • p.lavarre@ieee.org

              #7
              Re: Python CTypes translation of (pv != NULL)

              http://starship.python.net/crew/thel.../tutorial.html
              ...
              direct discussion only of how to construct null pointers,
              no discussion of how to test for them ...
              ...
              could be read to mean try ... == ... is ... False ... None ...
              CTypes nulls fetched from a struct feel more like None than do CTypes
              nulls fetched from elsewhere, astonishing me the Python newbie, e.g.:

              $ python nulls.py
              True True True None None
              True True True None None
              True False False None c_char_p(None)
              $
              $ cat nulls.py
              from ctypes import *
              class struct_aa(Struc ture):
              _fields_ = [("chars", c_char_p)]
              pv = None
              print not pv, pv == None, pv is None, cast(pv, c_void_p).value , pv
              pv = struct_aa().cha rs
              print not pv, pv == None, pv is None, cast(pv, c_void_p).value , pv
              pv = cast(c_void_p(0 ), c_char_p)
              print not pv, pv == None, pv is None, cast(pv, c_void_p).value , pv
              $

              Possibly relevant, though grabbed at random, is:

              /// PEP 8 -- Style Guide for Python Code
              /// http://www.python.org/dev/peps/pep-0008/

              .... beware of writing "if x" when you really mean "if x is not None" --
              e.g. when testing whether a variable or argument that defaults to None
              was set to some other value. The other value might have a type (such
              as a container) that could be false in a boolean context!

              ///

              Comment

              • p.lavarre@ieee.org

                #8
                Re: Python CTypes translation of (pv != NULL)

                It says:
                >
                NULL pointers have a False boolean value:
                >>null_ptr = POINTER(c_int)( )
                >>print bool(null_ptr)
                False
                Yes.
                That means that NULL pointers are considered False in a boolean
                expression (and you could assume that non-NULL pointers are True, as
                any other object in general),
                I see this now that you show the clueless newbie me, yes thank you.
                Except now by showing me here we have provoked the authority Thomas
                Heller to say:
                Generally pointer instances have a False boolean value, so
                'if pv: ....'
                should work. Except for c_void_p, c_char_p and c_wchar_p instances.
                That English I do not understand. "Except" how?
                so you can test a NULL pointer with a
                simple "if ptr: whatever"
                Apparently, yes, except for the "except" above.
                --- cut ---
                from ctypes import *
                null_ptr = POINTER(c_int)( )
                x=c_int(1234)
                other_ptr = pointer(x)
                >
                if null_ptr: print "null_ptr is not NULL"
                else: print "null_ptr is NULL"
                >
                if other_ptr: print "other_ptr is not NULL"
                else: print "other_ptr is NULL"
                --- cut ---
                Yes.
                It's really the same as bool([])==False, bool(any_non_em pty_list)==True :
                >
                L = [1,2,3]
                while L:
                print L.pop()
                >
                You don't say:
                while bool(L)==True:
                >
                (do you?)
                Oh that's exactly how my newbie innocence led me astray.

                Rather than working first to translate the C 'if pv', I worked first to
                translate the C '(pv != NULL)', and then I got lost (and as yet still
                am lost) in newbie astonishment over some nulls feeling more like None
                than others.

                Comment

                • Thomas Heller

                  #9
                  Re: Python CTypes translation of (pv != NULL)

                  p.lavarre@ieee. org schrieb:
                  >It says:
                  >>
                  >NULL pointers have a False boolean value:
                  > >>null_ptr = POINTER(c_int)( )
                  > >>print bool(null_ptr)
                  >False
                  >
                  Yes.
                  >
                  >That means that NULL pointers are considered False in a boolean
                  >expression (and you could assume that non-NULL pointers are True, as
                  >any other object in general),
                  >
                  I see this now that you show the clueless newbie me, yes thank you.
                  Except now by showing me here we have provoked the authority Thomas
                  Heller to say:
                  >
                  Generally pointer instances have a False boolean value, so
                  'if pv: ....'
                  should work. Except for c_void_p, c_char_p and c_wchar_p instances.
                  >
                  That English I do not understand. "Except" how?
                  Actually I was wrong - there is no exception. To summarize:

                  All ctypes NULL pointers have a False boolean value.
                  So, this C-code:

                  if (pv) { /* or 'if (pv != NULL)' */
                  return *pv; /* whatever */
                  } else {
                  /* handle NULL pointer */
                  }

                  translates to this Python code:

                  if pv:
                  return pv[0] # or whatever
                  else:
                  # pv is a NULL pointer

                  Works for instances of c_char_p, c_void_p, c_wchar_p,
                  and instances of POINTER(some_ct ype).

                  If you want to make the 'if pv:' line more verbose, you could as well
                  write 'if bool(pv):' or 'if bool(pv) == False', but why would
                  you want to do this?

                  Thomas

                  Comment

                  • Gabriel Genellina

                    #10
                    Re: Python CTypes translation of (pv != NULL)

                    At Wednesday 27/9/2006 13:40, p.lavarre@ieee. org wrote:
                    That means that NULL pointers are considered False in a boolean
                    expression (and you could assume that non-NULL pointers are True, as
                    any other object in general),
                    >
                    >I see this now that you show the clueless newbie me, yes thank you.
                    >Except now by showing me here we have provoked the authority Thomas
                    >Heller to say:
                    >
                    Generally pointer instances have a False boolean value, so
                    'if pv: ....'
                    should work. Except for c_void_p, c_char_p and c_wchar_p instances.
                    >
                    >That English I do not understand. "Except" how?
                    Uh? That's wrong. Where did you find that? Should read "Generally
                    NULL pointer instances have..."
                    In short, whenever you see, in C:

                    if (ptr1) { whatever }
                    if (ptr2 != NULL) { whatever }
                    if (ptr3 == NULL) { whatever }

                    that goes into python:

                    if ptr1: ...
                    if ptr2: ...
                    if not ptr3: ...
                    >Oh that's exactly how my newbie innocence led me astray.
                    Don't apologize, it's not easy to learn Python *and* learn to link an
                    external library at the same time...



                    Gabriel Genellina
                    Softlab SRL





                    _______________ _______________ _______________ _____
                    Preguntá. Respondé. Descubrí.
                    Todo lo que querías saber, y lo que ni imaginabas,
                    está en Yahoo! Respuestas (Beta).
                    ¡Probalo ya!


                    Comment

                    • Gabriel Genellina

                      #11
                      Re: Python CTypes translation of (pv != NULL)

                      At Wednesday 27/9/2006 13:35, p.lavarre@ieee. org wrote:
                      ...
                      direct discussion only of how to construct null pointers,
                      no discussion of how to test for them ...
                      ...
                      could be read to mean try ... == ... is ... False ... None ...
                      >
                      >CTypes nulls fetched from a struct feel more like None than do CTypes
                      >nulls fetched from elsewhere, astonishing me the Python newbie, e.g.:
                      No, the difference comes from the kind of pointer type, char* gets
                      converted to string or None. See the table on section 14.14.1.4
                      Fundamental data types
                      >$ python nulls.py
                      >True True True None None
                      >True True True None None
                      >True False False None c_char_p(None)
                      >$
                      >$ cat nulls.py
                      >from ctypes import *
                      >class struct_aa(Struc ture):
                      _fields_ = [("chars", c_char_p)]
                      >pv = None
                      >print not pv, pv == None, pv is None, cast(pv, c_void_p).value , pv
                      >pv = struct_aa().cha rs
                      >print not pv, pv == None, pv is None, cast(pv, c_void_p).value , pv
                      >pv = cast(c_void_p(0 ), c_char_p)
                      >print not pv, pv == None, pv is None, cast(pv, c_void_p).value , pv
                      >$
                      c_char_p is *not* a pointer in Python, since Python does not have pointers.
                      Either the original C pointer was NULL: then the Python value is None
                      Or the original C pointer was not NULL: then the Python value is a string

                      >Possibly relevant, though grabbed at random, is:
                      >
                      >/// PEP 8 -- Style Guide for Python Code
                      >/// http://www.python.org/dev/peps/pep-0008/
                      >
                      >... beware of writing "if x" when you really mean "if x is not None" --
                      >e.g. when testing whether a variable or argument that defaults to None
                      >was set to some other value. The other value might have a type (such
                      >as a container) that could be false in a boolean context!
                      This is exactly the case: None is *not* a pointer (neither any other
                      kind of ctypes object), it's an object -a singleton, i.e., there
                      exist exactly a single one instance of None).
                      If you want to check if some kind of pointer is NULL or not, do *not*
                      check if it is None or not, check its Boolean value, again:
                      if ptr: xxx
                      if not ptr: xxx



                      Gabriel Genellina
                      Softlab SRL





                      _______________ _______________ _______________ _____
                      Preguntá. Respondé. Descubrí.
                      Todo lo que querías saber, y lo que ni imaginabas,
                      está en Yahoo! Respuestas (Beta).
                      ¡Probalo ya!


                      Comment

                      • p.lavarre@ieee.org

                        #12
                        Re: Python CTypes translation of (pv != NULL)

                        Where did you find that?

                        Quoted in full from the gift:

                        Subject: Re: Python CTypes translation of (pv != NULL)
                        Date: Tue, 26 Sep 2006 11:48:52 +0200
                        Message-ID: <mailman.654.11 59264176.10491. python-list@python.org >


                        Cached and pondered just slightly before the gift of a complete
                        disavowal came after:

                        Subject: Re: Python CTypes translation of (pv != NULL)
                        Date: Wed, 27 Sep 2006 20:22:47 +0200
                        Message-ID: <mailman.823.11 59381408.10491. python-list@python.org >


                        Comment

                        • p.lavarre@ieee.org

                          #13
                          Re: Python CTypes translation of (pv != NULL)

                          Future Googlers might like this thread to end with the Thomas Heller's
                          brief conclusive review:

                          /// Copied 2006-09-28 from
                          /// http://starship.python.net/crew/thel...i/CodeSnippets

                          1.2 Check for NULL ctypes pointers

                          The truth value of any NULL ctypes pointer instance is False.

                          So, this C code

                          if (pv == NULL)
                          /* handle NULL pointer */
                          else
                          /* handle non-NULL pointer */

                          translates to this Python code

                          if not pv:
                          # handle NULL pointer
                          else:
                          # handle non-NULL pointer

                          The above is true for instances of c_void_p, c_char_p, c_wchar_p, and
                          POINTER(some_ct ype).

                          ///

                          Comment

                          Working...