Skip to main content

ExternC - Embedding C code in python

Example

import externc

# ExternC modifies builtins, so no `externc.` necessary
fn = c("""
  // remember to properly escape backslashes!
  printf("Hello from C\\n");
  Py_RETURN_NONE;
""")

fn() # "Hello from C"

Benchmark

c.py:

import externc
c(r"""
for(int i = 0; i < 1000000000; i++) {
  if(i % (2 << 16) == 0) {
    printf("%d\n", i);
  }
}
Py_RETURN_NONE;
""")()

python.py:

for i in range(1000000000):
  if(i % (2 << 16) == 0):
    print(i)
$ time python c.py
...

real    0m2.615s
user    0m1.593s
sys     0m0.518s
$ time python python.py
...

real    3m25.695s
user    3m25.423s
sys     0m0.194s

The difference is quite obvious

Use cases

Use ExternC

  • for interfacing with C APIs
  • for working with raw pointers
  • for working with capsules
  • when speed is more important than stability

Do not use ExternC

  • when your code must be version independent
  • when your code must be stable (exception: you have used C a lot before)
  • when your code must be distributable
  • when your code must run anywhere but the PC you wrote and tested it on
  • in production

Technicalities

The C function is registered as METH_VARARGS | METH_KEYWORDS. It is of signature PyObject* (PyObject*, PyObject*, PyObject), which is known in the Python extension environment as PyCFunctionWithKeywords. The arguments have the names self, args and kwargs, while the function is named func and the generated module externc_# where # is a hexadecimal number that is incremented by one with every call to c without an explicit module name. The function name and the module name can be modified by passing the funcname and name keyword arguments to c, respectively. funcname is also used as the name of the function to be exported from the module.

The default compiler used is clang with a few default options. The compilers submodule can be used to configure clang with feature flags, linked files and additional include directories or define another compiler, which can be passed to c via the compiler argument.

Metadata

Release files for externc 1.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for externc 1.1.1
File Size Uploaded
externc-1.1.1.tar.gz 16.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for externc 1.1.1
File Interpreter ABI Platform
externc-1.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 34.0 kB

Release files / externc-1.1.1.tar.gz

Download URL externc-1.1.1.tar.gz
Size 16.8 kB
Tags Source
SHA-256 checksum
How to use checksums
34f9eaae10e8868a819ecef4faa85c0c482d5c1c6947543729ce3cd3b0342a2b
BLAKE2b-256 checksum
How to use checksums
b891a6f1b14cb252c2af63771ea3cc2dcd3fb9ced6956d8f8ff89825cc35320e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.12.0a2+

Release files / externc-1.1.1-py3-none-any.whl

Download URL externc-1.1.1-py3-none-any.whl
Size 17.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9fce4ca37393219b4b3c2e31d75e76d7f065c577e739e1d2a06ebeb1ff7ea8a3
BLAKE2b-256 checksum
How to use checksums
8f41a9a9be3ee232e2d609721f51ef468e84f62a36db680d2d59dd944b0a7db7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.12.0a2+

Release history Release notifications | RSS feed

This release

1.1.1 This release

2 release files

1.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page