简体   繁体   English

Cython:pyximport:在pyximport.install中启用分析

[英]Cython: pyximport: enabling profiling in pyximport.install

My Python 3 projects are using cython a lot. 我的Python 3项目正在使用cython。

In production deployment, I'm using a build script which, amongst other things, disables the profiling: 在生产部署中,我使用的是构建脚本,除其他外,它禁用了分析:

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 development, I'm using pyximport. 在开发中,我正在使用pyximport。 To make the difference between the two contexts, I'm testing if the "production" user is in use in the project's top level __init__.py file. 为了区分这两个上下文,我正在测试项目的顶级__init__.py文件中是否正在使用“生产”用户。 If this is not production, I'm using pyximport; pyximport.install 如果这不是生产,我使用的是pyximport; pyximport.install pyximport; pyximport.install , so that it becomes totally transparent: pyximport; pyximport.install ,使它变得完全透明:

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,
    )

I'm would like to enable the profiling for all cython files while in development environment. 我想在开发环境中为所有cython文件启用分析。 I've tried to add the profile=True argument to the piximport.install statement, but it doesn't works. 我试图将piximport.install profile=True参数添加到piximport.install语句中,但它不起作用。

How can I proceed? 我该怎么办?

Some additional comments: 一些额外的评论:

  • I'd like to avoid pushing Profile=True in all the source codes while in development and removing them before commiting... 我想在开发过程中避免在所有源代码中推送Profile=True并在提交之前将其删除...

  • Using .pyxbld files is not an option for me because I have 46 pyx files and plan to have many more... Unless there's a way to setup only one file to support all the pyx like I did for the build script, but I didn't found how. 使用.pyxbld文件对我来说不是一个选项,因为我有46个pyx文件,并计划有更多...除非有一种方法只设置一个文件来支持所有pyx,就像我为构建脚本所做的那样,但我没有找不到。

Thanks for your help. 谢谢你的帮助。

It requires wrapping one of pyximport's internal functions, but this can be done: 它需要包装pyximport的一个内部函数,但这可以完成:

# 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()

Note that this will not forcibly recompile unchanged modules with the new options; 请注意,这不会使用新选项强制重新编译未更改的模块; you will have to touch those files to trigger a compilation with the new configuration. 您将不得不touch这些文件以使用新配置触发编译。

Here's an apparently undocumented way to pass directives: 这是一种显然没有文档传递指令的方法:

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

I found the cython_directives name in Cython/Distutils/build_ext.py. 我在Cython / Distutils / build_ext.py中找到了cython_directives名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM