It is clear to me that None
is used to signify the lack of a value. But since everything must have an underlying value during implementation, I'm looking to see what value has been used in order to signify the absence of a value, regarding CPython
.
I understand, based on the documentation, that NoneObject
is a singleton. Since my c
skills are rusty, my best, amateur guess, would be that the value of None
would be the pointer to the memory allocated for the Py_None
object; since it is a singleton this would guarantee uniqueness. Or is it assigned to c
's NULL
which has a value of 0x0000
based on the second answer in this question?
Additionally, the documentation also points out:
Note that the PyTypeObject for None is not directly exposed in the Python/C API.
Which I'm guessing means you cannot find it searching through source. (Which I did, not knowing where to look, for object.c
naively believing I could understand anything)
But I'm not certain about my opinion on this so I asked.
What is the c
level value for the Py_None
object in CPython
?
None is used to define a null value or Null object in Python. It is not the same as an empty string, False, or a zero. It is a data type of the class NoneType object.
Since None is a singleton, testing for object identity (using == in C) is sufficient. There is no PyNone_Check() function for the same reason.
Use the is not operator to check if a variable is not None in Python, e.g. if my_var is not None: . The is not operator returns True if the values on the left-hand and right-hand sides don't point to the same object (same location in memory).
Py_None
is a macro definition in Include/object.h
. It is a an alias for _Py_NoneStruct
in object.c
which is a static (as in storage) global variable of PyObject
type (which is a struct). It is assigned in Python terms to be of NoneType
(defined right above it in object.c
and only used once for _Py_NoneStruct
).
So it's not NULL or any other special value in C, it's a singleton PyObject
instance of _PyNone_Type
. As for the _PyNone_Type
PyTypeObject
not being exposed, I suppose they refer to the static
keyword (i.e. internal linkage) which means that the PyTypeObject
is only accessible within object.c
and is only used once for the definition of PyNone
.
Just to add to this a bit, whenever the documentation says that PyNone
has no type, it should not be taken literally. It has a special kind of type, NoneType
, which you can still access through the None
singleton but you can't create new instances or do any other thing you can do with a normal type. There seems to be a hard-coded limitation for not creating new instances, and although I can't find exactly where it's defined in the CPython source you can see its effect when trying to create a new instance:
>>> type(None)
<type 'NoneType'>
>>> type(None)()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create 'NoneType' instances
EDIT: It seems that the error is thrown from typeobject.c
when the tp_new
field is NULL. Surprisingly though _PyNone_Type
seems to be defined with a non-NULL tp_new
(points to the static none_new
in object.c
). It might be set to NULL afterwards at some point, but it's just an implementation detail and doesn't really make a difference for the scope of your question.
Py_None
is Py_None
, and must be increfed and returned from a function during normal operation if no other value is to be returned. NULL
is only returned if an exception is to be signaled to the VM, with the actual exception object created/assigned separately.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With