Uncategorized

Is it possible to compile a c extension and a python wrapper of the c extension at the same time?


I was wondering if its possible to have a python wrapper package wrapping a c extension for adding typing support, dataclasses on top of it and solving a bug of type hinting not
working for such compiled c extensions such that calling “from patnetstensor import wrapper” works?

Here’s my current file tree:

├── MANIFEST.in
├── Makefile
├── README.md
├── build
├── pyproject.toml
├── setup.py
├── src
│   ├── c
│   │   ├── Python_Vars.c
│   │   ├── Python_Vars.h
│   │   ├── Tensor_LocalCluster.c
│   │   ├── Tensor_LocalCluster.h
│   │   ├── Tensor_LpRelax.c
│   │   ├── Tensor_LpRelax.h
│   │   ├── Tensor_Main.c
│   │   ├── Tensor_Private.c
│   │   ├── Tensor_Private.h
│   │   ├── Tensor_Python.c
│   │   ├── UtilsOfTensor.c
│   │   ├── UtilsOfTensor.h
│   │   ├── default.c
│   │   ├── default.h
│   │   ├── sort.c
│   │   └── sort.h
│   └── patnetstensor
│       ├── __init__.py
│       └── wrapper.py
├── test
│   └── test.py
└── test_run.sh

setup.py:

from setuptools import Extension, setup, find_packages
import os
from distutils import sysconfig
import subprocess
import sys
from Cython.Distutils import build_ext
from typing import Literal


moduleName = "patnetstensor"
cRelativeDir = f"src{os.sep}c"

sourceFiles = [
    file for file in os.listdir(os.path.join(os.path.dirname(__file__), cRelativeDir)) if file.endswith(".c")
]

# Autofind header files in ./src/c
headerFiles = [
    file for file in os.listdir(os.path.join(os.path.dirname(__file__), cRelativeDir)) if file.endswith(".h")
]

dependencies = [
    "Cython"
]

def setPaths(files: list[str], relativeFolder: str, exclude: list[str] = [], pathType: Literal["absolute", "relative"] = "absolute"):
    return [os.path.join(os.path.dirname(__file__), relativeFolder, file) for file in files if file not in exclude] if pathType == "absolute" else [os.path.join(cRelativeDir, file) for file in sourceFiles if file not in ["Tensor_Main.c"]]

modules = [
    Extension(
        name="Tensor_Python",
        sources=setPaths(sourceFiles, cRelativeDir, ["Tensor_Main.c"], "relative"),
        # headers=sourceAbsFiles(headerFiles, cRelativeDir),
    )
    
]

class NoSuffixBuilder(build_ext):    
    def get_ext_filename(self, ext_name):
        filename = super().get_ext_filename(ext_name)
        suffix = sysconfig.get_config_var('EXT_SUFFIX')
        ext = os.path.splitext(filename)[1]
        return filename.replace(suffix, "") + ext

setup(
    name=moduleName,
    version="1.0",
    description="...",
    ext_modules=modules,
    cmdclass={'build_ext': NoSuffixBuilder},
    packages=[f"src{os.sep}{moduleName}"]
)

There are no previous questions like this on the internet thus this question and I have tried configuring the setup.py with no avail. I have considered utilizing C types but as benchmarked by users in other posts, its more than 250x slower than C extensions and with this project’s c codebase already written for c extension.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *