Py_None value

It is clear to me that None used to indicate the absence of a value. But since everything should have a basic value during implementation, I want to see what value was used to indicate the absence of a value with respect to CPython .

I understand, based on the documentation , that NoneObject is single-line. Since my skills are rusty, my best amateur hunch is that the value None will be a pointer to the memory allocated for the Py_None object; since it is a singleton, it would guarantee uniqueness. Or is it assigned c NULL , which is 0x0000 based on the second answer in this question ?

In addition, the documentation also indicates:

Note that PyTypeObject for None is not directly displayed in the Python / C API.

I assume that you cannot find it through the source. (What I did, not knowing where to look, object.c naively believing that I could understand something)

But I am not sure of my opinion on this matter, so I asked.

What is the c level value for a Py_None object in CPython ?

+5
source share
3 answers

Py_None - macro definition in Include/object.h . This is an alias for _Py_NoneStruct in object.c , which is a static (as in the repository) global variable of type PyObject (which is a structure). It is set in terms of Python to NoneType (defined directly above it in object.c and is used only once for _Py_NoneStruct ).

So this is not NULL or any other special value in C, it is a single-screen PyObject instance of _PyNone_Type . Regarding the _PyNone_Type PyTypeObject , which are not displayed, I believe that they refer to the static (i.e. internal binding), which means that PyTypeObject is only available in object.c and is used only once to determine of PyNone .

Just add a little to this, whenever the documentation says that PyNone not of type, this should not be taken literally. It has a special type of type NoneType , which you can access through the singleton None , but you cannot create new instances or do any other actions that you can do with the regular type. There seems to be a hard-coded restriction for not creating new instances, and although I cannot pinpoint where it is 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 selected from typeobject.c when the tp_new field is NULL. Surprisingly, _PyNone_Type seems to be defined using non-NULL tp_new (points to static none_new in object.c ). At some point, it may be set to NULL, but this is just an implementation detail and does not really affect the scope of your question.

+5
source

Py_None is equal to Py_None , and must be incremented and returned from the function during normal operation if no other value is to be returned. NULL returned only if the exception is to be passed to the virtual machine and the actual exception object is created / assigned separately .

+1
source

Py_None is the value of the address of the _Py_NoneStruct structure _Py_NoneStruct .

See code :

 /* _Py_NoneStruct is an object of undefined type which can be used in contexts where NULL (nil) is not suitable (since NULL often means 'error'). Don't forget to apply Py_INCREF() when returning this value!!! */ PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */ #define Py_None (&_Py_NoneStruct) 
+1
source

Source: https://habr.com/ru/post/1233687/


All Articles