4

When I use the function:

from collections import Counter

Is Counter() sourced using C structures? Is there any convenient way to determine that generally for this and other function?

Give that Python is open sourced generally what should I be looking for in the source code if it is the best way to determine if a given function uses C structures?

oliver
  • 2,467
  • 3
  • 14
  • 29
  • 1
    See for yourself: [Python source code](https://github.com/python/cpython/blob/3.6/Lib/collections/__init__.py). The best way of telling is by looking at the documentation. – tyteen4a03 May 02 '17 at 00:51
  • it looks not :( – oliver May 02 '17 at 00:52
  • having trouble looking at the source code to know what to look for – oliver May 02 '17 at 00:58
  • 2
    Since CPython is a C program, ultimately everything "uses C structures". It is just a question of how far you have to dig before you encounter the underlying C. – John Coleman May 02 '17 at 01:29

1 Answers1

3

There's no direct way to assert this for classes, but there's a way to determine if a function or method was written in C. So any class written in C probably defines at least one explicit or implicit function in C (if not it will be difficult) and you can check with inspect.isbuiltin:

>>> import collections
>>> import inspect
>>> def is_c_class(cls):
...     return any(inspect.isbuiltin(getattr(cls, methname, None)) 
...                for methname in cls.__dict__)

>>> is_c_class(collections.Counter)
False

>>> is_c_class(dict)
True

However that's not all there is to it because collections.Counter calls collections._count_elements which is a C function:

>>> inspect.isbuiltin(collections._count_elements)
True

So you should always check the source code (Pythons repository is on github and also the implementation for Counter) to be sure.


Note that the above mentioned check using isbuiltin has some flaws. For example you could have a class attribute that is a C function:

>>> class Test(object):
...     c_function = all  # builtin all function is a C function

>>> is_c_class(Test)
True

So don't rely on it always giving correct results, treat it as approximation.

MSeifert
  • 145,886
  • 38
  • 333
  • 352
  • 3
    You can actually check a class's `__flags__` to see if it's written in C - a class implemented through the C API won't have Py_TPFLAGS_HEAPTYPE set - but the value of Py_TPFLAGS_HEAPTYPE isn't exposed anywhere at the Python level. (It's currently 1 << 9, but I don't know if that's stable.) – user2357112 May 02 '17 at 01:40
  • @user2357112 Good point, I actually looked at the flags and dismissed them after there values weren't given explicitly. – MSeifert May 02 '17 at 11:16