[Python-Dev] Request for Pronouncement: PEP 441 - Improving Python ZIP Application Support
Paul Moore
p.f.moore at gmail.com
Wed Feb 25 20:33:19 CET 2015
On 25 February 2015 at 17:06, Paul Moore <p.f.moore at gmail.com> wrote:
>> Is the difference between create and copy important? e.g., is there
>> anything wrong with
>>
>> create_archive(old_archive, output=new_archive) working as well as
>> create_archive(directory, archive)?
>
> Probably not, now. The semantics have converged enough that this might
> be reasonable. It's how the command line interface works, after all.
> It would mean that the behaviour would be different depending on the
> value of the source argument (supplying the main argument and omitting
> the target are only valid for create), but again that's how the
> command line works.
>
> I'll have a go at implementing this change this evening and see how it
> plays out.
That worked out pretty well, IMO. The resulting API is a lot cleaner
(internally, there's not much change, I still have a copy_archive
function but it's now private). I've included the resulting API
documentation below. It looks pretty good to me.
Does anyone have any further suggestions or comments, or does this
look ready to go back to Guido for a second review?
Paul
Python API
----------
The module defines two convenience functions:
.. function:: create_archive(directory, target=None, interpreter=None,
main=None)
Create an application archive from *source*. The source can be any
of the following:
* The name of a directory, in which case a new application archive
will be created from the content of that directory.
* The name of an existing application archive file, in which case the
file is copied to the target. The file name should include the
``.pyz`` extension, if required.
* A file object open for reading in bytes mode. The content of the
file should be an application archive, and the file object is
assumed to be positioned at the start of the archive.
The *target* argument determines where the resulting archive will be
written:
* If it is the name of a file, the archive will be written to that
file.
* If it is an open file object, the archive will be written to that
file object, which must be open for writing in bytes mode.
* If the target is omitted (or None), the source must be a directory
and the target will be a file with the same name as the source, with
a ``.pyz`` extension added.
The *interpreter* argument specifies the name of the Python
interpreter with which the archive will be executed. It is written as
a "shebang" line at the start of the archive. On POSIX, this will be
interpreted by the OS, and on Windows it will be handled by the Python
launcher. Omitting the *interpreter* results in no shebang line being
written. If an interpreter is specified, and the target is a
filename, the executable bit of the target file will be set.
The *main* argument specifies the name of a callable which will be
used as the main program for the archive. It can only be specified if
the source is a directory, and the source does not already contain a
``__main__.py`` file. The *main* argument should take the form
"pkg.module:callable" and the archive will be run by importing
"pkg.module" and executing the given callable with no arguments. It
is an error to omit *main* if the source is a directory and does not
contain a ``__main__.py`` file, as otherwise the resulting archive
would not be executable.
If a file object is specified for *source* or *target*, it is the
caller's responsibility to close it after calling create_archive.
When copying an existing archive, file objects supplied only need
``read`` and ``readline``, or ``write`` methods. When creating an
archive from a directory, if the target is a file object it will be
passed to the ``zipfile.ZipFile`` class, and must supply the methods
needed by that class.
.. function:: get_interpreter(archive)
Return the interpreter specified in the ``#!`` line at the start of the
archive. If there is no ``#!`` line, return :const:`None`.
The *archive* argument can be a filename or a file-like object open
for reading in bytes mode. It is assumed to be at the start of the archive.
More information about the Python-Dev
mailing list