python 3.x C extension module and submodule - python-3.x

How do I make a C extension for python 3.x when a module has sub-modules? For example, I have a file called pet.c:
#include <Python.h>
PyObject* CatMeow(PyObject* self) {
return PyUnicode_FromString( ">*<" );
}
static PyMethodDef CatFunctions[] = {
{(char*) "meow", (PyCFunction) CatMeow, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL}
};
static PyModuleDef CatDef = {
PyModuleDef_HEAD_INIT, "cat", "cat ext", -1, CatFunctions,
NULL, NULL, NULL, NULL
};
PyMODINIT_FUNC PyInit_cat(void) {
return PyModule_Create(&CatDef);
}
static PyModuleDef PetDef = {
PyModuleDef_HEAD_INIT, "pet", "pet ext", -1, NULL,
NULL, NULL, NULL, NULL
};
PyMODINIT_FUNC PyInit_pet(void) {
PyObject* p = PyModule_Create(&PetDef);
PyObject* c = PyInit_cat();
Py_INCREF(c);
PyModule_AddObject( p, "cat", c );
return p;
}
When I build it with the following setup.py:
from distutils.core import setup, Extension
setup(
name='pet',
version='0.0',
ext_modules=[Extension('pet', ['pet.c'])]
)
I can see
>>> import pet
>>> pet.cat.meow()
'>*<'
or
>>> from pet import cat
>>> cat.meow()
'>*<'
which is as intended, but when I try
>>> from pet.cat import meow
I have a ModuleNotFoundError saying ... No module named 'pet.cat'; 'pet' is not a package, and if I try
>>> from pet import cat
>>> from cat import meow
I have a ModuleNotFoundError saying ... No module named 'cat'. But if I check the type of cat
>>> type(cat)
<class 'module'>
which says it is a module.
How do I make this work? Adding a module object to another module used to work well in python 2.7. Is it not supposed to work in python3 due to absolute import style? Or do I have to work with multi-phase initialisation as described in PEP 489?

Regarding the first error which complains about pet not being a package. If pet is there only to provide a parent for cat, there is an easy way to turn it into a package: remove all the pet related code from pet.c and use ext_package in setup.py
from distutils.core import setup, Extension
setup(
name = 'pet',
version = '0.0',
ext_package = 'pet',
ext_modules = [Extension('cat', ['pet.c'])]
)
Running the above will create a directory called 'pet' and a shared library of which name starts with 'cat'. This effectively creates a namespace package -- there are two types of packages, regular and namespace, and the latter is the one without requiring __init__.py (see PEP 420 for details). From outside of pet, you can do
>>> from pet import cat
>>> from pet.cat import meow
>>> meow()
'>*<'
>>> cat.meow()
'>*<'
The reason you can't do from cat import meow is because the fully qualified name of the module is 'pet.cat' not 'cat', which you can confirm it from cat.__name__. If you are running the interpreter inside of the directory pet, then you can do from cat import meow.

Related

Implementing Typescript interfaces in Python

I'm looking for some advice on what's the best way of implementing a set of data value only 'interfaces' in Python that are equivalent to their typescript counterpart (we've got a project where we use both, and want to enforce a consistent interface for their communication, which would be via serialising the python into json to pull into the TS component)
The interfaces will be compositions to keep things modular and simple.
Given a set of TS interfaces defined as:
interface TestOutput {
phantom: string
testDateTime: datetime
author: string
result: boolean
report_summaryFile?: string // the '?' means this field is optional
// ... more values
series: Array<Series>
soloImages: Array<Images>
}
interface Series {
number: number
filter: string
kernel: string
// ... more values
images: Array<TestImage>
}
I was thinking of using dataclasses and doing the following:
from dataclasses import dataclass
from typing import List
import datetime
#dataclass
class TestSeries:
seriesNum: int
modality: str
description: str = ''
#dataclass
class TestOutput:
phantom: str
testDateTime: datetime.datetime
author: str
result: bool
series: List[TestSeries]
soloImages: List[Images]
report_summaryFile: str = ''
Is dataclasses the best approach for this?
pydantic is a good library.
I did something similar, but only for dataclasses - ValidatedDC:
from dataclasses import dataclass
from typing import List
from validated_dc import ValidatedDC
import json
#dataclass
class Series(ValidatedDC):
series_num: int
modality: str
description: str = ''
#dataclass
class Output(ValidatedDC):
phantom: str
date_time: str
author: str
result: bool
series: List[Series]
report_summary_file: str = ''
# For example, by API we got a JSON string:
input_json_string = '''
{
"phantom": "test_phantom",
"date_time": "2020.01.01",
"author": "Peter",
"result": true,
"series": [{
"series_num": 1,
"modality": "test_modality"
}]
}
'''
# Load the string into the dictionary:
input_data = json.loads(input_json_string)
# Then create a dataclass to check the types of values and for the
# convenience of further work with data:
output = Output(**input_data)
# Since valid data were obtained, there are no errors
assert output.get_errors() is None
# Let's say we got data with an error:
input_data['series'][0]['series_num'] = '1' # The string is not an integer!
output = Output(**input_data)
assert output.get_errors()
print(output.get_errors())
# {
# 'series': [
# InstanceValidationError(
# value_repr="{'series_num': '1', 'modal...}",
# value_type=<class 'dict'>,
# annotation=<class '__main__.Series'>, exception=None,
# errors={
# 'series_num': [
# BasicValidationError(
# value_repr='1', value_type=<class 'str'>,
# annotation=<class 'int'>, exception=None
# )
# ]
# }
# ),
# ListValidationError(
# item_index=0, item_repr="{'series_num': '1', 'modal...}",
# item_type=<class 'dict'>, annotation=<class '__main__.Series'>
# )
# ]
# }
See here for more details:
https://github.com/EvgeniyBurdin/validated_dc

How using Vim alphabetically sort JS es6 imports

I use vim as IDE for typescript project.
import { FlightInfo } from './FlightInfo'
import { InfoBlockProps, InfoRowProps, INavigationFlightOfferDataProps } from './interfaces'
import { getDiscountData, formatDataByServicesType, selectAdministrationFee } from './functions'
Also, I use ts-lint rule for check sorting:
...
ordered-imports": [
true,
{
"import-sources-order": "lowercase-first",
"named-imports-order": "lowercase-first"
}
],
...
And get errors:
ERROR: 11:1 ordered-imports Import sources within a group must be alphabetized.
ERROR: 11:10 ordered-imports Named imports must be alphabetized.
ERROR: 12:1 ordered-imports Import sources within a group must be alphabetized.
ERROR: 12:10 ordered-imports Named imports must be alphabetized.
I am searching for a solution or plugin for fix this sorting errors.
In this situation, for me very well works ts-lint --fix -c ./ts-congig.json my-file.ts command.

CX_Freeze : Import error : _ufuncs_cxx

I am currently using Python 3.4 on my windows 10 64x and trying to freeze my application using CX_Freeze. Unfortunetly, I get an error message : "Import error : No module named scipy.special._ufuncs_cxx".
Here is my setup.py :
# -*- coding: Latin-1 -*-
import sys
import scipy
from cx_Freeze import setup, Executable
import PyQt4
packages=['PyQt4.QtCore', 'PyQt4.QtGui', 'sys', 'socket', 'pprint', 'pandas', 'datetime', 'json','numpy', 'scipy']
include_files=['C:/Users/sadid/OneDrive/Documents/Visual Studio 2015/Projects/db/img/lib-ico.ico',
'C:/Users/sadid/OneDrive/Documents/Visual Studio 2015/Projects/Lib/db/img']
if sys.platform == 'win32':
base = 'Win32GUI'
exe = Executable(
script='C:/Users/sadid/OneDrive/Documents/Visual Studio 2015/Projects/Lib/Lib/main.py',
initScript = None,
base=base,
targetName='Lib.exe',
copyDependentFiles = True,
compress = True,
icon='C:/Users/sadid/OneDrive/Documents/Visual Studio 2015/Projects/LibAppCustomer/LibAppCustomer/db/img/lib-ico.ico'
)
setup(
name ='LibApplication',
version = '1.0.0',
description = 'Pricing\'s Application',
author = 'DIKSA',
executables = [exe],
options = {
"build.exe": {
"packages": packages,
'include_files': include_files,
'includes' : ['scipy.special._ufuncs_cxx']
}
}
)
Any help please guys thx
This issue is based on how scipy loads itself and there is a plan in place to have cx_Freeze handle these and other such issues -- but it is still in progress. The comments in this issue, however, can help you workaround the issue for now:
https://bitbucket.org/anthony_tuininga/cx_freeze/issues/43/import-errors-when-using-cx_freeze-with

python: ImportError: dynamic module does not define module export function

im trying to install my function written in c (with python3 setup.py install) but python raise ImportError: dynamic module does not define module export function (PyInit_costFunction)
error!
costFunction.c:
static PyObject *costFunction(PyObject *self, PyObject *args)
{
return Py_BuildValue("d", 0); // or anything!
}
static PyMethodDef costFunction_methods[] = {
{"costFunction", (PyCFunction)costFunction, METH_VARARGS, "cost function"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef costFunctionmodule = {
PyModuleDef_HEAD_INIT,"costFunction", NULL, -1, costFunction_methods
};
PyMODINIT_FUNC PyInit_costFunction(void)
{
return PyModule_Create(&costFunctionmodule);
}
setup.py:
from distutils.core import setup, Extension
setup(name='costFunction', version='1.0', \
ext_modules=[Extension('costFunction', ['costFunction.c'],include_dirs=['include'])])
external library: tinyexpr
i'm using linux mint 18 with python 3.5.2
EDIT:
python3-dev version is 3.5.1-3
finally i used an dirty trick!
compiled c code(without python.h and any python datatype in C) with:
gcc -fPIC -Wall -O3 costFunction.c -o costFunction.so -shared -fopenmp
and used python ctypes module to load and use it:
dll = ctypes.CDLL("./costFunction.so")
costFunction = dll.cost_function
costFunction.restype = ctypes.c_double
costFunction.argtypes = [ctypes.POINTER(ctypes.c_double), ctypes.c_int]

Using cx_freeze in PyQt5, can't find PyQt5

I want to build a standalone binary file for windowz(xp, 7, ...) from my python3(+ PyQt5) script and I inevitably use cx_freeze because other freezing apps do not work with python3 (like py2exe, pyinstaller).
I read the cx_freeze docs and lots of stackoverflow asks ans use this config for setup.py‍‍‍ file :
import sys
from cx_Freeze import setup, Executable
path_platforms = ( "C:\Python33\Lib\site-packages\PyQt5\plugins\platforms\qwindows.dll", "platforms\qwindows.dll" )
includes = ["atexit","PyQt5.QtCore","PyQt5.QtGui", "PyQt5.QtWidgets"]
includefiles = [path_platforms]
excludes = [
'_gtkagg', '_tkagg', 'bsddb', 'curses', 'email', 'pywin.debugger',
'pywin.debugger.dbgcon', 'pywin.dialogs', 'tcl',
'Tkconstants', 'Tkinter'
]
packages = ["os"]
path = []
# Dependencies are automatically detected, but it might need fine tuning.
build_exe_options = {
"includes": includes,
"include_files": includefiles,
"excludes": excludes,
"packages": packages,
"path": path
}
# GUI applications require a different base on Windows (the default is for a
# console application).
base = None
exe = None
if sys.platform == "win32":
exe = Executable(
script="D:\\imi\\aptanaWorKPCworkspace\\azhtel\\tel.py",
initScript = None,
base="Win32GUI",
targetDir = r"dist",
targetName="tel.exe",
compress = True,
copyDependentFiles = True,
appendScriptToExe = False,
appendScriptToLibrary = False,
icon = None
)
setup(
name = "telll",
version = "0.1",
author = 'me',
description = "My GUI application!",
options = {"build_exe": build_exe_options},
executables = [exe]
)
run with:
python D:\imi\aptanaWorKPCworkspace\azhtel\setup.py build
This is my library that I used:
from PyQt5 import QtGui, QtCore, QtWidgets
import sys
from telGui import Ui_MainWindow
import mysql
import mysql.connector
from mysql.connector import errorcode
and this is my files in workspace:
But this error happened (or another kind of errors).
Why this happened and what config for setup.py is good for pyqt5 app ??
Thanks.
Python3.3, PyQt5, Mysqlconnector.
I solved this problem with find another directory near the dist directory called build and all library files are in there, i delete targetDir = r"dist" part of setup.py and everythings is alright !
Try pyinstaller. It's much better than cxfreeze.

Resources