2017-08-28 1 views
2

Résolu, voir Edition # 3Cython CIMPORT ne peut pas trouver le module .pxd

Supposons un paquet est structuré comme:

Some_Package/ 
    some_package/ 
     __init__.py 
     core/ 
      __init__.py 
      definition.pxd 
     helper/ 
      __init__.py 
      helper.pxd 
      helper.pyx 
    setup.py 

Où en definition.pxd je:

import numpy as np 
cimport numpy as np 
# ... 
ctypedef np.int32_t INT_t 

Et dans helper.pxd J'ai:

cimport some_package.core.definition 
from some_package.core.definition cimport INT_t 
# ... 

En helper.pyx Je n'ai pas cimport quoi que ce soit. Je configuré setup.py comme:

ext_modules=cythonize('./some_package/helper/helper.pyx', include_dirs=['.', './some_package/core']) 

Maintenant, mon problème est avec python setup.py build_ext --inplace je peux construire avec succès dans .so, mais quand j'ai essayé de import some_package.helper.helper je suis arrivé un ImportError:

ImportError: No module named "some_package.helper.helper"

J'ai examiné helper.cpp et trouvé des lignes comme:

__pyx_t_1 = __Pyx_ImportModule("some_package.core.definition"); if (!__pyx_t_1) __PYX_ERR(0, 1, __pyx_L1_error) 

Je suppose que cela peut avoir quelque chose à voir avec le chemin d'importation, mais je ne peux pas voir ce qui n'allait pas. Tous les __init__.py sont vides et j'ai importé absolute_import dans chaque fichier. J'ai également changé le include_dirs, mais ne fonctionne toujours pas.

Edit # 1

Selon le documentation, include_dirs ajoute au chemin de recherche *.pxd. J'ai donc essayé aussi de changer les cimport déclarations helper.pxd comme:

cimport definition 
from definition cimport INT_t 

Cette fois-ci, cython ne peut pas compiler: "definition.pxd" not found. Cependant, il devrait être dans le chemin de recherche.

Edit # 2

Une séance d'entraînement rapide est l'ajout d'un vide definition.pyx dans core/, puis configurer les extensions comme:

extensions = [ 
    Extension("some_package.core.definition", ["some_package/core/definition.pyx"]) 
    Extension("some_package.helper.helper", ["some_package/helper/helper.pyx"]) 
] 

Puis, en setup.py:

ext_modules=cythonize(extensions) 

Maintenant cimport some_package.core.definition est- travaillant dans helper.pxd.

Cependant, ce n'est pas élégant.

Edit 3

J'ai finalement trouvé que je donnent sur quelques lignes comme:

cdef INT_t some_int = 1 

Cependant, dans le fichier .pxd, il ne peut y avoir un code exécutable . Dans ce cas, il semble que Cython traite comme un paquet, ce qui n'est pas le cas en tant que fichier .pyx.

Il pourrait y avoir deux méthodes pour contourner:

  1. cdef extern d'un en-tête C.

  2. Enveloppe aux fonctions en ligne.

+0

Attendez, vous avez appelé votre paquet 'src'? Je recommanderais d'utiliser un nom différent d'abord parce que cela ne fait que cris pour les conflits de noms. – MSeifert

+0

@MSeifert Merci! 'src' est à des fins d'illustration (puisque je l'ai trouvé assez commun). En effet, 'src' est nommé' some_package' et est placé dans un répertoire racine nommé 'Some_Package'. –

+0

Oui, c'est un répertoire pour les fichiers 'src'. À la fin, vous prenez le code à partir de là, mais construisez-le comme une extension dans votre paquet réel. C'est un peu déroutant si les concepts sont modifiés. : -] – MSeifert

Répondre

0

Je négligez que j'avais quelques lignes comme:

cdef INT_t some_int = 1 

Cependant, dans le fichier .pxd, il ne peut y avoir un code exécutable . Dans ce cas, il semble que Cython traite comme un paquet, ce qui n'est pas le cas en tant que fichier .pyx.

Il pourrait y avoir deux méthodes pour contourner:

  1. cdef extern d'un en-tête C.

  2. Enveloppe aux fonctions en ligne.