472,135 Members | 1,514 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,135 software developers and data experts.

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

Sep 26 '06 #1
12 9730
At Monday 25/9/2006 21:27, p.*******@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

Sep 26 '06 #2
p.*******@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

Sep 26 '06 #3
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.

Sep 26 '06 #4
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?

Sep 26 '06 #5
At Tuesday 26/9/2006 16:00, p.*******@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?)

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

Sep 27 '06 #6
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(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!

///

Sep 27 '06 #7
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.

Sep 27 '06 #8
p.*******@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

Sep 27 '06 #9
At Wednesday 27/9/2006 13:40, p.*******@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!
http://www.yahoo.com.ar/respuestas

Sep 28 '06 #10
At Wednesday 27/9/2006 13:35, p.*******@ieee.org wrote:
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.:
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

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

Sep 28 '06 #11
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: <ma**************************************@python.o rg>
http://groups.google.com/group/comp....f13e731ea3cad7

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: <ma**************************************@python.o rg>
http://groups.google.com/group/comp....84d964a70b7a2d

Sep 28 '06 #12
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_ctype).

///

Sep 28 '06 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Srijit Kumar Bhadra | last post: by
10 posts views Thread by Python_it | last post: by
18 posts views Thread by Paul Watson | last post: by
1 post views Thread by Gerald Klix | last post: by
4 posts views Thread by rozniy | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.