explanation of C implementation pythons len function [closed]

2024/10/5 19:27:42

I was reading about implementation of builtin functions of python when I came across this C implementation of len function

static PyObject *
builtin_len(PyObject *module, PyObject *obj)
/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/
{
Py_ssize_t res;res = PyObject_Size(obj);
if (res < 0) {assert(PyErr_Occurred());return NULL;
}
return PyLong_FromSsize_t(res);

I am not able to understand what is going on in this code. I have no idea how C works. Can someone explain what this code is doing?

I got the code from https://github.com/python/cpython/blob/master/Python/bltinmodule.c

Edit: I was just curious how len function is so fast and stumbled across this code. I just want to know why function PyObject_Size is used to check size of object is zero and then PyLong_FromSsize_t to return the actual size.

Answer

There is nothing special with this function. Usually the functions written in C, especially those that do not call Python code, are much faster than ones written in Python.

I am specifically taking the stance here that a reader knows how C works, otherwise the explanation would rather be a book.

The builtin_len is the one that is called when len(foo) is executed in Python code. The PyObject *obj argument to the function references the object given as the argument (foo), and PyObject *self will contain a reference to the containing module of builtin_len.

Each container in Python must have a length between 0 and the maximum value allowed by Py_ssize_t. PyObject_Size(obj); is a function/macro that gets the size of the given object through its obj->ob_type->tp_as_sequence->sq_length or obj->ob_type->tp_as_mapping->mp_length. Upon error an exception is set as raised for the current thread and a number < 0 (-1) is returned.

The return NULL; signifies the caller that an exception has occurred and it must act accordingly - if it is a function call instruction in Python bytecode, it will cause an exception to be raised; if it is C code, then it will behave in a manner similar to this function - returning NULL or invalid value if an exception occurred; or it can clear the exception or replace it with another one.

Otherwise if greater than or equal to 0, the Py_ssize_t res which is of a C integer type, is converted to a Python int object, by either returning an existing int object or constructing a new one. The Python int object is called PyLong in CPython 3 for historical reasons. PyLong_FromSsize_t() is one of many functions - this one is able to convert any value of type Py_ssize_t to a Python int with the same value. The reference to this object, like all other objects, are kept as pointers to the (semi-opaque) PyObject structure, and this is returned.

The assert(PyErr_Occurred()); is an assertion that is in effect in debug builds of Python only. It asserts that upon getting a negative number from PyObject_Size, signifying an exception being thrown, the exception has also been properly set; if not present, it will abort the entire CPython process outright. It isn't in effect in release builds of Python because "asserts never fail".

https://en.xdnf.cn/q/120723.html

Related Q&A

How to compare the attributes start with $ in 2 functions and display match or mismatch

My input file contain attributes if(match($OPTION_EnableDetails, "1") or match($OPTION_EnableDetails_juniper, "1")) {details($juniFileXferStatus,$juniFileXferTimeStamp,$juniFileXfer…

Python comparing elements in two lists

I have two lists:a - dictionary which contains keywords such as ["impeccable", "obvious", "fantastic", "evident"] as elements of the listb - sentences which cont…

Remove all keys that have values of N/A, -, or empty strings [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.Want to improve this question? Update the question so it focuses on one problem only by editing this post.Closed 2…

Sorting algorithms more efficient than bubble sort [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.Want to improve this question? Add details and clarify the problem by editing this post.Closed 7 years ago.Improve…

How can I return the odd numbers of a list, using only recursion in Python? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable…

TypeError: int object is not iterable; Python 2.7

Here is my code:def numbers_in_lists(string):num = int(string)l = list(num)return lstring = 543987When i run it:print numbers_in_lists(string)I have the following error:l = list(num) TypeError: int obj…

Python: Are `hash` values for built-in numeric types, strings standardised?

I came to this question while pondering about the ordering of set, frozenset and dict. Python doesnt guarantee any ordering, and any ordering is coupled to the hash value at some level. But is the hash…

How to create a sample django project?

This doesnt work for me.$ python django-admin.py startproject myprojectI am running a ubuntu virtual m/c on my windows system. By default ubuntu 12.04 comes with python 2.7.3 so I am using that only I …

Why elif statement instead of if statement? [duplicate]

This question already has answers here:Difference between multiple ifs and elifs?(9 answers)Why we use if, else if instead of multiple if block if the body is a return statement(13 answers)Closed 7 ye…

How to understand regular expression with python?

Im new with python. Could anybody help me on how I can create a regular expression given a list of strings like this:test_string = "pero pero CC tan tan RGantigua antiguo AQ0FS0que que CS segn se…