cythonautoinstall 0.10
Generates and installs simple Cython modules with specified settings. If you are overwhelmed by the compiler directives and the creation of the setup.py file, this is right for you.
License: MIT
Keywords: cython,compile,automatic


# Generates and installs simple Cython modules with specified settings. If you are overwhelmed by the compiler directives and the creation of the setup.py file, this is right for you. 

## Tested against Windows 10 / Python 3.11 / Anaconda

### pip install cythonautoinstall


This function takes Cython code along with various setup parameters and generates a
Cython module, compiles it, and installs it as a Python package. It handles the
generation of the Cython code, the creation of a setup script, compilation, and
installation. Made for people who write simple scripts and are overwhelmed 
by the compiler directives and the creation of the setup.py file


```python
Parameters:
	cython_code (str): The Cython code to be compiled into a module.
	foldername (str): The name of the folder where the package will be installed.
	setup_name (str): The name of the module to be generated.
	setup_sources (tuple or list): A tuple or list of source file paths.
	setup_include_dirs (tuple or list): A tuple or list of include directory paths.
	setup_py_limited_api (bool, optional): Whether to use Python limited API. Default is False.
	setup_define_macros (tuple or list, optional): Define macros for the compilation. Default is ().
	setup_undef_macros (tuple or list, optional): Undefine macros for the compilation. Default is ().
	setup_library_dirs (tuple or list, optional): Library directories. Default is ().
	setup_libraries (tuple or list, optional): Libraries to link against. Default is ().
	setup_runtime_library_dirs (tuple or list, optional): Runtime library directories. Default is ().
	setup_extra_objects (tuple or list, optional): Extra objects to link with. Default is ().
	setup_extra_compile_args (tuple or list, optional): Extra compilation arguments. Default is ().
	setup_extra_link_args (tuple or list, optional): Extra link arguments. Default is ().
	setup_export_symbols (tuple or list, optional): Exported symbols. Default is ().
	setup_swig_opts (tuple or list, optional): SWIG options. Default is ().
	setup_depends (tuple or list, optional): Dependency files. Default is ().
	setup_language (str, optional): Language for compilation. Default is None.
	setup_optional (tuple or list, optional): Optional components. Default is None.
	extra_directives (str, optional): Additional Cython compiler directives. Default is "".
	distutils_extra_compile_args (str, optional): Additional distutils compilation arguments. Default is "".
	distutils_extra_link_args (str, optional): Additional distutils link arguments. Default is "".
	distutils_language (str, optional): Language for distutils compilation. Default is "".
	distutils_define_macros (str, optional): Define macros for distutils compilation. Default is "NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION".
	cython_binding (bool, optional): Whether to generate Cython bindings. Default is True.
	cython_boundscheck (bool, optional): Enable bounds checking. Default is True.
	cython_wraparound (bool, optional): Enable wraparound checking. Default is True.
	cython_initializedcheck (bool, optional): Enable initialized variable checking. Default is False.
	cython_nonecheck (bool, optional): Enable None checking. Default is False.
	cython_overflowcheck (bool, optional): Enable overflow checking. Default is False.
	cython_overflowcheck_fold (bool, optional): Enable folding of overflow checks. Default is True.
	cython_embedsignature (bool, optional): Embed function signatures. Default is False.
	cython_embedsignature_format (str, optional): Format for embedded signatures. Default is "c".
	cython_cdivision (bool, optional): Enable C division. Default is False.
	cython_cdivision_warnings (bool, optional): Enable C division warnings. Default is False.
	cython_cpow (bool, optional): Enable C pow function. Default is False.
	cython_c_api_binop_methods (bool, optional): Enable C API binary operator methods. Default is False.
	cython_profile (bool, optional): Enable profiling. Default is False.
	cython_linetrace (bool, optional): Enable line tracing. Default is False.
	cython_infer_types (bool, optional): Enable type inference. Default is False.
	cython_language_level (int, optional): Cython language level. Default is 3.
	cython_c_string_type (str, optional): C string type. Default is "bytes".
	cython_c_string_encoding (str, optional): C string encoding. Default is "default".
	cython_type_version_tag (bool, optional): Enable type version tag. Default is True.
	cython_unraisable_tracebacks (bool, optional): Enable unraisable tracebacks. Default is False.
	cython_iterable_coroutine (bool, optional): Enable iterable coroutine support. Default is True.
	cython_annotation_typing (bool, optional): Enable annotation typing. Default is True.
	cython_emit_code_comments (bool, optional): Enable code comments in the generated code. Default is False.
	cython_cpp_locals (bool, optional): Enable C++ local variable support. Default is False.

Returns:
	str: The path to the generated package's __init__.py file.

Note:
	Read https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#compiler-directives

Example:

import numpy as np

cython_code = '''
from cython.parallel cimport prange
cimport cython
import numpy as np
cimport numpy as np
import cython
from collections import defaultdict

cpdef searchforcolor(unsigned char[:] pic, unsigned char[:] colors, int width, int totallengthpic, int totallengthcolor):
	cdef my_dict = defaultdict(list)
	cdef int i, j
	cdef unsigned char r,g,b
	for i in prange(0, totallengthcolor, 3,nogil=True):
		r = colors[i]
		g = colors[i + 1]
		b = colors[i + 2]
		for j in range(0, totallengthpic, 3):
			if (r == pic[j]) and (g == pic[j+1]) and (b == pic[j+2]):
				with gil:
					my_dict[(r,g,b)].append(j )

	for key in my_dict.keys():
		my_dict[key] = np.dstack(np.divmod(np.array(my_dict[key]) // 3, width))[0]
	return my_dict
'''

fx = generate_auto_install(
	cython_code,
	foldername="locatepixelcolcompiledpy",
	setup_py_limited_api=False,
	setup_name="locatepixelcolorcompiled",
	setup_sources=("locatepixelcolorcompiled.pyx",),
	setup_include_dirs=(np.get_include(),),
	setup_define_macros=(),
	setup_undef_macros=(),
	setup_library_dirs=(),
	setup_libraries=(),
	setup_runtime_library_dirs=(),
	setup_extra_objects=(),
	setup_extra_compile_args=(),
	setup_extra_link_args=(),
	setup_export_symbols=(),
	setup_swig_opts=(),
	setup_depends=(),
	setup_language=None,
	setup_optional=None,
	extra_directives="",
	distutils_extra_compile_args="/openmp",
	distutils_extra_link_args="/openmp",
	distutils_language="c",
	distutils_define_macros="NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION",
	cython_binding=False,
	cython_boundscheck=False,
	cython_wraparound=False,
	cython_initializedcheck=False,
	cython_nonecheck=False,
	cython_overflowcheck=True,
	cython_overflowcheck_fold=False,
	cython_embedsignature=False,
	cython_embedsignature_format="c",
	cython_cdivision=True,
	cython_cdivision_warnings=False,
	cython_cpow=True,
	cython_c_api_binop_methods=True,
	cython_profile=False,
	cython_linetrace=False,
	cython_infer_types=False,
	cython_language_level=3,
	cython_c_string_type="bytes",
	cython_c_string_encoding="default",
	cython_type_version_tag=True,
	cython_unraisable_tracebacks=False,
	cython_iterable_coroutine=True,
	cython_annotation_typing=True,
	cython_emit_code_comments=False,
	cython_cpp_locals=True,
)
print(fx)

# create a Python file
r'''
import numpy as np
import cv2
import locatepixelcolcompiledpy

def search_colors(pic,colors):
	if not isinstance(colors, np.ndarray):
		colors = np.array(colors, dtype=np.uint8)
	pipi = pic.ravel()
	cololo = colors.ravel()
	totallengthcolor = cololo.shape[0] - 1
	totallenghtpic = pipi.shape[0]-1
	width = pic.shape[1]
	resus0 = locatepixelcolcompiledpy.locatepixelcolorcompiled.searchforcolor(pipi, cololo,width,totallenghtpic,totallengthcolor)
	return resus0


# 4525 x 6623 x 3 picture https://www.pexels.com/pt-br/foto/foto-da-raposa-sentada-no-chao-2295744/
picx = r"C:\Users\hansc\Downloads\pexels-alex-andrews-2295744.jpg"
pic = cv2.imread(picx)
colors0 = np.array([[255, 255, 255]],dtype=np.uint8)
resus0 = search_colors(pic=pic, colors=colors0)
colors1=np.array([(66,  71,  69),(62,  67,  65),(144, 155, 153),(52,  57,  55),(127, 138, 136),(53,  58,  56),(51,  56,  54),(32,  27,  18),(24,  17,   8),],dtype=np.uint8)
resus1 =  search_colors(pic=pic, colors=colors1)
'''
This is how a generated file looks like (it can be edited after the generation):


	import os
	import subprocess
	import sys

	def _dummyimport():
		import Cython
	try:
		from . import locatepixelcolorcompiled
	except Exception as e:

		cstring = '''# distutils: language=c
	# distutils: extra_compile_args=/openmp
	# distutils: extra_link_args=/openmp
	# distutils: define_macros=NPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION
	# cython: binding=False
	# cython: boundscheck=False
	# cython: wraparound=False
	# cython: initializedcheck=False
	# cython: nonecheck=False
	# cython: overflowcheck=True
	# cython: overflowcheck.fold=False
	# cython: embedsignature=False
	# cython: embedsignature.format=c
	# cython: cdivision=True
	# cython: cdivision_warnings=False
	# cython: cpow=True
	# cython: c_api_binop_methods=True
	# cython: profile=False
	# cython: linetrace=False
	# cython: infer_types=False
	# cython: language_level=3
	# cython: c_string_type=bytes
	# cython: c_string_encoding=default
	# cython: type_version_tag=True
	# cython: unraisable_tracebacks=False
	# cython: iterable_coroutine=True
	# cython: annotation_typing=True
	# cython: emit_code_comments=False
	# cython: cpp_locals=True


	from cython.parallel cimport prange
	cimport cython
	import numpy as np
	cimport numpy as np
	import cython
	from collections import defaultdict

	cpdef searchforcolor(unsigned char[:] pic, unsigned char[:] colors, int width, int totallengthpic, int totallengthcolor):
		cdef my_dict = defaultdict(list)
		cdef int i, j
		cdef unsigned char r,g,b
		for i in prange(0, totallengthcolor, 3,nogil=True):
			r = colors[i]
			g = colors[i + 1]
			b = colors[i + 2]
			for j in range(0, totallengthpic, 3):
				if (r == pic[j]) and (g == pic[j+1]) and (b == pic[j+2]):
					with gil:
						my_dict[(r,g,b)].append(j )

		for key in my_dict.keys():
			my_dict[key] = np.dstack(np.divmod(np.array(my_dict[key]) // 3, width))[0]
		return my_dict'''
		pyxfile = f"locatepixelcolorcompiled.pyx"
		pyxfilesetup = f"locatepixelcolorcompiled_setup.py"

		dirname = os.path.abspath(os.path.dirname(__file__))
		pyxfile_complete_path = os.path.join(dirname, pyxfile)
		pyxfile_setup_complete_path = os.path.join(dirname, pyxfilesetup)

		if os.path.exists(pyxfile_complete_path):
			os.remove(pyxfile_complete_path)
		if os.path.exists(pyxfile_setup_complete_path):
			os.remove(pyxfile_setup_complete_path)
		with open(pyxfile_complete_path, mode="w", encoding="utf-8") as f:
			f.write(cstring)

		compilefile = '''
		from setuptools import Extension, setup
		from Cython.Build import cythonize
		ext_modules = Extension(**{'py_limited_api': False, 'name': 'locatepixelcolorcompiled', 'sources': ['locatepixelcolorcompiled.pyx'], 'include_dirs': ['C:\\Users\\hansc\\.conda\\envs\\dfdir\\Lib\\site-packages\\numpy\\core\\include'], 'define_macros': [], 'undef_macros': [], 'library_dirs': [], 'libraries': [], 'runtime_library_dirs': [], 'extra_objects': [], 'extra_compile_args': [], 'extra_link_args': [], 'export_symbols': [], 'swig_opts': [], 'depends': [], 'language': None, 'optional': None})

		setup(
			name='locatepixelcolorcompiled',
			ext_modules=cythonize(ext_modules),
		)
				'''
		with open(pyxfile_setup_complete_path, mode="w", encoding="utf-8") as f:
			f.write('\n'.join([x.lstrip().replace(os.sep, "/") for x in compilefile.splitlines()]))
		subprocess.run(
			[sys.executable, pyxfile_setup_complete_path, "build_ext", "--inplace"],
			cwd=dirname,
			shell=True,
			env=os.environ.copy(),
		)
		from . import locatepixelcolorcompiled


```