Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Value of Py_None

Tags:

python

c

cpython

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?

like image 432
Dimitris Fasarakis Hilliard Avatar asked Oct 14 '15 09:10

Dimitris Fasarakis Hilliard


People also ask

What is the object none?

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.

Is none a singleton?

Since None is a singleton, testing for object identity (using == in C) is sufficient. There is no PyNone_Check() function for the same reason.

Is not none in Python?

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).


2 Answers

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.

like image 164
gbs Avatar answered Oct 15 '22 23:10

gbs


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.

like image 32
Ignacio Vazquez-Abrams Avatar answered Oct 15 '22 21:10

Ignacio Vazquez-Abrams