How do I use both the python version and the C version of a cpython module?

I would like to compare the operation of the python version of bisect.bisect_right to the C version. I can go find Lib/bisect.py and comment out

# Overwrite above definitions with a fast C implementation
try:
    from _bisect import *
except ImportError:
    pass

but I would prefer to load both the python module and the C module so that I can run both in the same program.

Is there a canonical way to do that?

1 Like

Not sure if it’s a canonical way, but the decimal module (Lib/decimal.py) seems to be an adequate example.

Sergey, perhaps you can explain a bit more? I looked through the file including the usage stuff. As best I can tell, you mean that I could run both the C (found in Modules/_decimal/) and the python (found in Lib/_pydecimal.py). I see concretely that it tries to import _decimal and only imports _pydecimal on ImportError.

I wouldn’t know how to run (for example) both the C version of abs() and the python version in the same program.

But then, perhaps I missed your point entirely.

The “official” method is to set the C version of the module to None in the sys.modules cache so that it incurs an ImportError when the Python version tries to import the C version:

import sys
import _bisect as c_bisect
sys.modules['_bisect'] = None
import bisect as py_bisect

print(c_bisect.bisect_right) # <built-in function bisect_right>
print(py_bisect.bisect_right) # <function bisect_right at 0x0000023164AE7C40>

It’s “official” because it’s how the test module does it:

4 Likes

That was awesome. Thank you!

1 Like

Yep, perhaps I should include examples. For the decimal module you can import both C and Python versions:

>>> import _decimal, _pydecimal
>>> import timeit
>>> timeit.timeit('_decimal.Decimal(1)', globals=globals())
0.816780586988898
>>> timeit.timeit('_pydecimal.Decimal(1)', globals=globals())
3.6697204500087537
1 Like

Is there a page somewhere in the documentation with a complete list of correspondences between such modules?

Ah, I see. Thank you for explaining.