V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
ClericPy
V2EX  ›  Python

终于等到你, 单文件解释器: pyoxy?

  •  
  •   ClericPy ·
    ClericPy · 73 天前 · 2513 次点击
    这是一个创建于 73 天前的主题,其中的信息可能已经有所发展或是发生改变。

    源自半个多月前周报里看到的帖子 https://gregoryszorc.com/blog/2022/05/10/announcing-the-pyoxy-python-runner/

    1. 什么时候能出 Windows release, 不确定靠谱不靠谱, 等了半个月了都没 release 出来
    2. 这种单文件可执行文件该不会跟 pyinstaller 和 nuitka 那个一样打包后是单个 exe, 结果运行时先解压缩到临时目录一大堆东西吧... 解压缩不反对, 但经常遇到没自动清理很烦
    3. 稍微期待一下, 不求性能多好, 只求兼容性靠谱一点
    4. 里面也提到了 zipapp 和 shiv, 暂时没仔细看文档, 不知道会不会把源码都编译保护起来
    5. 没啥人讨论么? 抽时间我去 HN 看看有没有人讨论

    看作者的意思, 有了绿色版 Python 解释器, 打包发布时候对环境要求就更低了, 比如打个 docker 镜像也不用提前安装 Python 了

    9 条回复    2022-05-30 12:16:43 +08:00
    ysc3839
        1
    ysc3839  
       72 天前 via Android
    CPython 本身就可以实现真单文件,C/C++部分静态链接,Python 部分代码打包成 zip 然后塞进可执行文件里。
    不能单文件的是 native module ,因为用的是系统级的 DLL/so/dylib 机制进行加载,目前似乎没有哪个系统支持从内存中加载 DLL 的。
    Node.js 的 Electron 和 pkg 也会把 native module 解压出来的。
    codehz
        2
    codehz  
       72 天前
    @ysc3839 系统不能做不代表你不可以自己做(
    只要没禁止 JIT (也就是分配 RWX 内存,无论同时 RWX 还是异步 RW->RX )
    内存加载动态库算是黑产常见使用方式了
    ysc3839
        3
    ysc3839  
       72 天前 via Android
    @codehz 不可移植,意味着不会有官方支持这种做法,意味着所有功能、问题都要自己实现、修复。那既然要自己实现,还不如研究如何把第三方 native module 直接静态链接进可执行文件中。自解压 native module 本来就是为了能直接利用现有的 native module binaries 所做的妥协。
    bybyte
        4
    bybyte  
       72 天前
    @ysc3839 从系统中加载 DLL 是可以的,这种方法经常用来躲过反作弊系统的检测 https://bbs.pediy.com/thread-230147.htm
    weyou
        5
    weyou  
       72 天前 via Android
    @ysc3839 Tcl/Tk 语言的 starkit 打包工具就是利用 VFS ( virtual file system )的内存文件系统做到了只从内存加载动态库( dll 或者 so 都可以)。而且这项技术已经有二三十年了,一直很奇怪 Python 的打包工具为什么没有实现
    ysc3839
        6
    ysc3839  
       72 天前 via Android
    @bybyte @weyou
    是我的表达有误,我不是说原理上不可行,而是没有系统本身提供了这个功能。我很清楚这功能是可以实现的,但因为实现起来过于复杂,稳定性未知,大部分项目才不会采用。如果你们觉得可行的话,欢迎去说服上述几个打包项目,这样能直接解决楼主的问题。
    dant
        7
    dant  
       72 天前   ❤️ 1
    @ysc3839 Linux 可以用 memfd 然后 dlopen("/proc/self/fd/x"),或者 Android linker 直接支持 fd+offset 从 apk 里载入 未压缩的 so 。
    但是 Python 的问题是总有一些库会用 __file__ 拼文件系统路径加载资源,PyInstaller 因此写了不少 hook 。
    ysc3839
        8
    ysc3839  
       72 天前 via Android
    @dant 访问文件反而不是最主要的问题,通过 Python 本身的接口访问的话,总有办法拦截下来的。通过 native module 访问的话,上述几个方案似乎也是不进行处理。
    ClericPy
        9
    ClericPy  
    OP
       72 天前
    @weyou 是这个原因导致 zipapp 不能支持 .so/.pyd 这类导入的么, 所以 shiv 每次都得解压缩了才能用(虽然兼容性更好, 如果能解压缩到内存就好了). 这部分知识不太了解

    至于楼下提到的 __file__ 那是那几个库自己的问题, 正常情况不是 web 那边静态文件靠 pkgutil.get_data 够用

    本来以为就是想问问单文件解释器可用情况, 以及解决不解压的单文件运行方式, 没想到知道了这么多新知识, 活到老学到老
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1321 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:21 · PVG 02:21 · LAX 11:21 · JFK 14:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.