2015-05-04 6 views
5

Meine Python 3-Projekte verwenden Cython sehr.Cython: pyximport: Aktivieren der Profilerstellung in pyximport.install

In Produktionsbereitstellung, ich bin ein Build-Skript, die unter anderem die Profilierung deaktiviert:

from distutils.core import setup 
from Cython.Build import cythonize 
import os 

compiler_directives = { 
    'language_level': 3, 
    'optimize.use_switch': True, 
    'profile': True, 
} 

setup(
    packages=["XXXXXX"], 
    ext_modules=cythonize(
     module_list="**/*.pyx", 
     compiler_directives=compiler_directives, 
    ) 
) 

In Entwicklung, ich bin mit pyximport. Um den Unterschied zwischen den beiden Kontexten zu machen, teste ich, ob der "production" -Benutzer in der obersten __init__.py Datei des Projekts verwendet wird. Ist dies nicht der Produktion ist, verwende ich pyximport; pyximport.install, so dass es völlig transparent wird:

if getpass.getuser != PRODUCTION_USER_NAME: 
    import pyximport 
    pyximport.install(
     pyximport=True, 
     pyimport=False, 
     build_dir=None, 
     build_in_temp=True, 
     setup_args={}, 
     reload_support=False, 
     load_py_module_on_import_failure=False, 
     inplace=False, 
     language_level=3, 
    ) 

Ich möchte die Profilierung für alle cython Dateien ermöglichen, während in Entwicklungsumgebung. Ich habe versucht, das profile=True Argument zur piximport.install Aussage hinzuzufügen, aber es funktioniert nicht.

Wie kann ich fortfahren?

Einige zusätzliche Bemerkungen:

  • ich möchte und sie vor commiting ...

  • Mit .pyxbld Dateien ist keine Entfernung vermeiden Profile=True in allen Quellcodes, während in der Entwicklung drängen Option für mich, weil ich 46 Pyx-Dateien habe und plane, viel mehr zu haben ... Es sei denn, es gibt eine Möglichkeit, nur eine Datei zu installieren, um alle Pyx wie das Build-Skript zu unterstützen, aber ich habe nicht gefunden, wie.

Danke für Ihre Hilfe.

Antwort

2

Es erfordert Umwickeln eines pyximport internen Funktionen, aber dies getan werden kann:

# Allow .pyx files to be seamlessly integrated via cython/pyximport with 
# default compiler directives. 
import functools 
import pyximport.pyximport 

# Hack pyximport to have default options for profiling and embedding signatures 
# in docstrings. 
# Anytime pyximport needs to build a file, it ends up calling 
# pyximport.pyximport.get_distutils_extension. This function returns an object 
# which has a cython_directives attribute that may be set to a dictionary of 
# compiler directives for cython. 
_old_get_distutils_extension = pyximport.pyximport.get_distutils_extension 
@functools.wraps(_old_get_distutils_extension) 
def _get_distutils_extension_new(*args, **kwargs): 
    extension_mod, setup_args = _old_get_distutils_extension(*args, **kwargs) 

    if not hasattr(extension_mod, 'cython_directives'): 
     extension_mod.cython_directives = {} 
    extension_mod.cython_directives.setdefault('embedsignature', True) 
    extension_mod.cython_directives.setdefault('profile', True) 
    return extension_mod, setup_args 
pyximport.pyximport.get_distutils_extension = _get_distutils_extension_new 
pyximport.install() 

Beachten Sie, dass dies nicht zwangsläufig unverändert Module mit den neuen Optionen neu kompilieren; Sie müssen diese Dateien touch haben, um eine Kompilierung mit der neuen Konfiguration auszulösen.

2

Hier ist ein scheinbar nicht dokumentierte Weg Richtlinien weitergeben müssen:

pyximport.install(setup_args={ 
    'options': { 
     'build_ext': { 
      'cython_directives': { 
       'language_level': 3, 
       'optimize.use_switch': True, 
       'profile': True, 
      } 
     } 
    } 
}) 

ich den cython_directives Namen in Cython/Distutils/build_ext.py gefunden.