仅打包 cythonized 二进制 python 文件和资源数据,但忽略 python .py 源文件

package only cythonized binary python files and resource data but ignoring python .py source files

我需要混淆我的 python 代码,为了实现它我正在使用 cythonize 扩展,我能够实现它并从 a.py 文件中获取二进制编译的 a.so 文件但在执行 bdist_wheel 之后,.whl 包仅打包 a.so 文件并忽略 resource_folder.

我的项目文件结构是

|main_project
|__,setup.py
|__,main_folder
|____,a.py
|____,__init__.py
|____resource_folder
     |__,a.model
     |__,a.json

我使用以下 links 来制作混淆的 python 轮包,

https://bucharjan.cz/blog/using-cython-to-protect-a-python-codebase.html

https://medium.com/@xpl/protecting-python-sources-using-cython-dcd940bb188e

以下是我的 setup.py

的片段
packages = find_packages(exclude=('tests',))

def get_package_files_in_directory(directory):
    paths = []
    for (path, directories, filenames) in os.walk(directory):
        for filename in filenames:
            paths.append(os.path.join('..', path, filename))
    return paths


setup(
    packages=[],

    ext_modules=cythonize(
        [
           Extension("main_folder.*", ["main_folder/*.py"])

        ],
        build_dir="build",
        compiler_directives=dict(
        always_allow_keywords=True
        )),
package_data={p: package_files + get_package_files_in_directory(os.path.join(here, p, 'resources')) for p in packages},
,....
,...
)

打包我使用以下命令

python setup.py build_ext

python setup.py bdist_wheel


预期结果是包含 a.so 文件和资源文件夹的 .whl 文件

实际结果是 .whl 文件只包含 a.so 个文件。


为了也打包 resource_folder 我使用了 get_package_files_in_directory() 函数,正如 link “( How do you add additional files to a wheel?)” 中所建议的,但这对我也不起作用

基于此 by @hoefling 我能够打包我的 resource_folder 和混淆的二进制 a.so 文件。

setup.py

的食谱
from Cython.Distutils import build_ext
from Cython.Build import cythonize
from setuptools.extension import Extension
from setuptools.command.build_py import build_py as build_py_orig
from pathlib import Path
from setuptools import find_packages, setup, Command
import os
import shutil

here = os.path.abspath(os.path.dirname(__file__))    
packages = find_packages(exclude=('tests',))

def get_package_files_in_directory(directory):
    paths = []
    for (path, directories, filenames) in os.walk(directory):
        for filename in filenames:
            paths.append(os.path.join('..', path, filename))
    return paths
#to copy the __init__.py as specified in above references links

class MyBuildExt(build_ext):
    def run(self):
        build_ext.run(self)

        build_dir = Path(self.build_lib)
        root_dir = Path(__file__).parent

        target_dir = build_dir if not self.inplace else root_dir

        self.copy_file(Path('main_folder') / '__init__.py', root_dir, target_dir)


    def copy_file(self, path, source_dir, destination_dir):
        if not (source_dir / path).exists():
            return

        shutil.copyfile(str(source_dir / path), str(destination_dir / path))

#as specified by @hoefling to ignore .py and not resource_folder
class build_py(build_py_orig):
    def build_packages(self):
        pass

setup(
    packages=find_packages(),  # needed for obfuscation
    ext_modules=cythonize(
        [
           Extension("main_folder.*", ["main_folder/*.py"])

        ],
        build_dir="build",
        compiler_directives=dict(
        always_allow_keywords=True
        )),
    package_data={p: get_package_files_in_directory(os.path.join(here, p, 'resource_folder')) for p in packages}, #package_data as found in another reference
    cmdclass={
        'build_py': build_py
    },
    entry_points={
    },
)

创建混淆的 *.whl 包命令集

python setup.py build_ext  #creates the a.so
python setup.py build_py   #copies the resource_folder excluding .py
python setup.py bdist_wheel # then whl generation