When etching a class, I get different behavior in python, which in cyton

I have the following file hierarchy:

python/apps/A.py /geometrylib/__init__.py /geometrylib/B.py /geometrylib/geometry.py /geometrylib/goemetry.pyx /geometrylib/goemetry.pyd 

geometry.pyx and geometry.py contain the same Camera class (the cython version defines a class with cdef). Both A.py and B.py import the geometry module.

If I import a version of cython (compiled into geometry.pyd), I can correctly open the camera from B.py in the python / geometrylib folder. But I can not expand Camera from A.py in the python / apps folder, I get the following exception:

pickle.PicklingError: Unable to split: it was not found as geometry.Camera

However, if I remove the .pyd geometry and I import the python version (geometry.py) instead, then I can light the camera with A.py or B.py. Nothing else happens except deleting the .pyd geometry, the same python command line, launched from the same folder in both cases. why is this difference?

Digging a bit, I see that this exception occurs on C: \ Python27 \ Lib \ pickle.py line 742

 try: __import__(module) #line 742 mod = sys.modules[module] klass = getattr(mod, name) except (ImportError, KeyError, AttributeError): raise PicklingError( "Can't pickle %r: it not found as %s.%s" % (obj, module, name)) 

When I import the version of cython (geometry.pyd) into A.py (and I will parse the Camera instance to run expec), the geometry module and __import__(module) raise an exception. When I import the python version (geometry.py) into A.py (and I will parse the camera instance to tempt), the geometrylib.geometry module and __import__(module) correctly import the module.

I solved the problem by adding python / geometrylib to PYTHONPATH, then I can properly expand Camera from both A.py and B.py files using the cython version.

How should this work? I do not like my decision. Does anyone have a better solution?

EDITED add more information.

Also on request, this is setup.py, which I used to create a cython extension.

 from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext import numpy setup( cmdclass = { 'build_ext': build_ext}, ext_modules = [Extension("geometry", ['geometry.pyx'], include_dirs=[numpy.get_include(), "."])]) 
+4
source share
1 answer

You build geometry.pyx as a top-level module, while in fact it is part of the geometrylib package. As a result, the Camera class is assigned the wrong __module__ value ( geometry instead of geometrylib.geometry ), and pickler fails when it tries to find a top-level module named geometry .

You must follow the standard packaging rules, that is, place setup.py in the "Python" folder, next to the top-level module (geometrylib). installation call will look like this:

 setup( cmdclass = {'build_ext': build_ext}, ext_modules = [Extension("geometrylib.geometry", ['geometrylib/geometry.pyx'], include_dirs=[numpy.get_include(), "."])]) 
+4
source

Source: https://habr.com/ru/post/1440381/


All Articles