how to use distutils to create executable .zip file?

2024/10/8 10:58:20

Python 2.6 and beyond has the ability to directly execute a .zip file if the zip file contains a __main__.py file at the top of the zip archive. I'm wanting to leverage this feature to provide preview releases of a tool I'm developing that won't require users to install anything beyond copying the .zip file to their disk. Is there a standard way to create such a zip file? I'm looking for a solution that works with python 2.6 and python 2.7.

Ideally I would like to use distutils, since I already have it working when I want to do a normal install. Is there a canonical way to use (or extend) distutils to create such a .zip file?

distutils provides an sdist command which creates a source distribution that is almost right, but creates a structure that is a little too deep.

For example, my source tree looks like this:

my_package/- setup.py- src/- __main__.py- module1/- module2/- module3/

When I do python setup.py sdist I end up with a .zip file with the following structure:

my_package-0.1.zip- my_package-0.1/- README.txt- PKG_INFO- src/- __main__.py- module1/- module2/- module3/

This isn't executable because __main__.py is not at the top of the distribution. Effectively what I want is a src distribution that doesn't include src, but only the files under src. That, or exactly what sdist gives me, but with an extra __main__.py at the top of the archive.

Answer

Updated: Since the setup.cfg is global, it affects the 'install-lib' setting for all commands, which is not what is desired. Unfortunately there is no way (to my knowledge) to pass a options to a subcommand via the command line, e.g. if you specify bdist --install-lib=/ it will raise an error instead of passing that down to the subcommands.

To customize the install-lib for the install subcommand only when bdist is run, you can subclass the bdist_dumb command and set the path manually after the install subcommand is constructed / reinitialized:

setup.py

from distutils.core import setup
from distutils.command.bdist_dumb import bdist_dumbclass custom_bdist_dumb(bdist_dumb):def reinitialize_command(self, name, **kw):cmd = bdist_dumb.reinitialize_command(self, name, **kw)if name == 'install':cmd.install_lib = '/'return cmdif __name__ == '__main__':setup(# our custom class overridecmdclass = {'bdist_dumb': custom_bdist_dumb},name='my_package',py_modules = ['__main__'],packages = ['module1', 'module2'],package_dir = {'': 'src'})

Running:

% python setup.py bdist --format=zip
% unzip -l dist/my_package-0.0.0.linux-x86_64.zip
Archive:  dist/my_package-0.0.0.linux-x86_64.zipLength      Date    Time    Name
---------  ---------- -----   ----184  2011-05-31 20:34   my_package-0.0.0.egg-info30  2011-05-31 20:34   __main__.py128  2011-05-31 20:34   __main__.pyc107  2011-05-31 20:34   module1/__init__.pyc0  2011-05-31 20:27   module1/__init__.py107  2011-05-31 20:34   module2/__init__.pyc0  2011-05-31 20:27   module2/__init__.py
---------                     -------556                     7 files% python dist/my_package-0.0.0.linux-x86_64.zip
my_package working.
https://en.xdnf.cn/q/70135.html

Related Q&A

Pass nested dictionary location as parameter in Python

If I have a nested dictionary I can get a key by indexing like so: >>> d = {a:{b:c}} >>> d[a][b] cAm I able to pass that indexing as a function parameter? def get_nested_value(d, pat…

Correct way to deprecate parameter alias in click

I want to deprecate a parameter alias in click (say, switch from underscores to dashes). For a while, I want both formulations to be valid, but throw a FutureWarning when the parameter is invoked with …

How to rename a file with non-ASCII character encoding to ASCII

I have the file name, "abc枚.xlsx", containing some kind of non-ASCII character encoding and Id like to remove all non-ASCII characters to rename it to "abc.xlsx".Here is what Ive t…

draw random element in numpy

I have an array of element probabilities, lets say [0.1, 0.2, 0.5, 0.2]. The array sums up to 1.0.Using plain Python or numpy, I want to draw elements proportional to their probability: the first eleme…

Python Gevent Pywsgi server with ssl

Im trying to use gevent.pywsgi.WSGIServer to wrap a Flask app. Everything works fine, however, when I try to add a key and a certificate for ssl, its not even able to accept any clients anymore.This is…

unexpected keyword argument buffering - python client

I am receiving the error as "getresponse() got an unexpected keyword argument buffering". Complete error log is :[INFO ] Kivy v1.8.0 [INFO ] [Logger ] Record lo…

numpy and pandas timedelta error

In Python I have an array of dates generated (or read from a CSV-file) using pandas, and I want to add one year to each date. I can get it working using pandas but not using numpy. What am I doing wron…

Pandas - split large excel file

I have an excel file with about 500,000 rows and I want to split it to several excel file, each with 50,000 rows.I want to do it with pandas so it will be the quickest and easiest.any ideas how to make…

Unable to verify secret hash for client at REFRESH_TOKEN_AUTH

Problem"Unable to verify secret hash for client ..." at REFRESH_TOKEN_AUTH auth flow. {"Error": {"Code": "NotAuthorizedException","Message": "Unab…

save a dependecy graph in python

I am using in python3 the stanford dependency parser to parse a sentence, which returns a dependency graph. import pickle from nltk.parse.stanford import StanfordDependencyParserparser = StanfordDepend…