Grupos de Google ya no admite publicaciones ni suscripciones nuevas de Usenet. El contenido anterior sigue visible.

Python CTypes translation of (pv != NULL)

29 vistas
Ir al primer mensaje no leído

p.la...@ieee.org

no leída,
25 sept 2006, 8:27:08 p.m.25/9/06
para
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

no leída,
26 sept 2006, 1:07:31 a.m.26/9/06
para p.la...@ieee.org,pytho...@python.org
At Monday 25/9/2006 21:27, p.la...@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!
http://www.yahoo.com.ar/respuestas

Thomas Heller

no leída,
26 sept 2006, 5:48:52 a.m.26/9/06
para pytho...@python.org
p.la...@ieee.org schrieb:

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

p.la...@ieee.org

no leída,
26 sept 2006, 3:00:04 p.m.26/9/06
para
> >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.

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.

p.la...@ieee.org

no leída,
26 sept 2006, 3:34:42 p.m.26/9/06
para
> > > > 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?

Gabriel Genellina

no leída,
26 sept 2006, 8:14:07 p.m.26/9/06
para p.la...@ieee.org,pytho...@python.org
At Tuesday 26/9/2006 16:00, p.la...@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_empty_list)==True:

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

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

(do you?)

p.la...@ieee.org

no leída,
27 sept 2006, 12:35:51 p.m.27/9/06
para
> > http://starship.python.net/crew/theller/ctypes/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(Structure):
_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().chars
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!

///

p.la...@ieee.org

no leída,
27 sept 2006, 12:40:38 p.m.27/9/06
para
> 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_empty_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.

Thomas Heller

no leída,
27 sept 2006, 2:22:47 p.m.27/9/06
para pytho...@python.org
p.la...@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_ctype).

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

Gabriel Genellina

no leída,
28 sept 2006, 12:35:32 a.m.28/9/06
para p.la...@ieee.org,pytho...@python.org
At Wednesday 27/9/2006 13:40, p.la...@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

no leída,
28 sept 2006, 12:50:19 a.m.28/9/06
para p.la...@ieee.org,pytho...@python.org
At Wednesday 27/9/2006 13:35, p.la...@ieee.org wrote:

> > > http://starship.python.net/crew/theller/ctypes/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.:

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(Structure):
> _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().chars
>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

p.la...@ieee.org

no leída,
28 sept 2006, 3:06:27 p.m.28/9/06
para
> 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.11592641...@python.org>
http://groups.google.com/group/comp.lang.python/msg/f9f13e731ea3cad7

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.11593814...@python.org>
http://groups.google.com/group/comp.lang.python/msg/6584d964a70b7a2d

p.la...@ieee.org

no leída,
28 sept 2006, 7:47:21 p.m.28/9/06
para
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/theller/moin.cgi/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_ctype).

///

0 mensajes nuevos