File: PKG-INFO

package info (click to toggle)
python-libarchive-c 5.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 908 kB
  • sloc: python: 1,552; makefile: 7
file content (147 lines) | stat: -rw-r--r-- 5,308 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
Metadata-Version: 2.1
Name: libarchive-c
Version: 5.1
Summary: Python interface to libarchive
Home-page: https://github.com/Changaco/python-libarchive-c
Author: Changaco
Author-email: changaco@changaco.oy.lc
License: CC0
Keywords: archive libarchive 7z tar bz2 zip gz
Description-Content-Type: text/x-rst
License-File: LICENSE.md

A Python interface to libarchive. It uses the standard ctypes_ module to
dynamically load and access the C library.

.. _ctypes: https://docs.python.org/3/library/ctypes.html

Installation
============

    pip install libarchive-c

Compatibility
=============

python
------

python-libarchive-c is currently tested with python 3.8, 3.9, 3.10 and 3.11.

If you find an incompatibility with older versions you can send us a small patch,
but we won't accept big changes.

libarchive
----------

python-libarchive-c may not work properly with obsolete versions of libarchive such as the ones included in MacOS. In that case you can install a recent version of libarchive (e.g. with ``brew install libarchive`` on MacOS) and use the ``LIBARCHIVE`` environment variable to point python-libarchive-c to it::

    export LIBARCHIVE=/usr/local/Cellar/libarchive/3.3.3/lib/libarchive.13.dylib

Usage
=====

Import::

    import libarchive

Extracting archives
-------------------

To extract an archive, use the ``extract_file`` function::

    os.chdir('/path/to/target/directory')
    libarchive.extract_file('test.zip')

Alternatively, the ``extract_memory`` function can be used to extract from a buffer,
and ``extract_fd`` from a file descriptor.

The ``extract_*`` functions all have an integer ``flags`` argument which is passed
directly to the C function ``archive_write_disk_set_options()``. You can import
the ``EXTRACT_*`` constants from the ``libarchive.extract`` module and see the
official description of each flag in the ``archive_write_disk(3)`` man page.

By default, when the ``flags`` argument is ``None``, the ``SECURE_NODOTDOT``,
``SECURE_NOABSOLUTEPATHS`` and ``SECURE_SYMLINKS`` flags are passed to
libarchive, unless the current directory is the root (``/``).

Reading archives
----------------

To read an archive, use the ``file_reader`` function::

    with libarchive.file_reader('test.7z') as archive:
        for entry in archive:
            for block in entry.get_blocks():
                ...

Alternatively, the ``memory_reader`` function can be used to read from a buffer,
``fd_reader`` from a file descriptor, ``stream_reader`` from a stream object
(which must support the standard ``readinto`` method), and ``custom_reader``
from anywhere using callbacks.

To learn about the attributes of the ``entry`` object, see the ``libarchive/entry.py``
source code or run ``help(libarchive.entry.ArchiveEntry)`` in a Python shell.

Displaying progress
~~~~~~~~~~~~~~~~~~~

If your program processes large archives, you can keep track of its progress
with the ``bytes_read`` attribute. Here's an example of a progress bar using
`tqdm <https://pypi.org/project/tqdm/>`_::

    with tqdm(total=os.stat(archive_path).st_size, unit='bytes') as pbar, \
         libarchive.file_reader(archive_path) as archive:
        for entry in archive:
            ...
            pbar.update(archive.bytes_read - pbar.n)

Creating archives
-----------------

To create an archive, use the ``file_writer`` function::

    from libarchive.entry import FileType

    with libarchive.file_writer('test.tar.gz', 'ustar', 'gzip') as archive:
        # Add the `libarchive/` directory and everything in it (recursively),
        # then the `README.rst` file.
        archive.add_files('libarchive/', 'README.rst')
        # Add a regular file defined from scratch.
        data = b'foobar'
        archive.add_file_from_memory('../escape-test', len(data), data)
        # Add a directory defined from scratch.
        early_epoch = (42, 42)  # 1970-01-01 00:00:42.000000042
        archive.add_file_from_memory(
            'metadata-test', 0, b'',
            filetype=FileType.DIRECTORY, permission=0o755, uid=4242, gid=4242,
            atime=early_epoch, mtime=early_epoch, ctime=early_epoch, birthtime=early_epoch,
        )

Alternatively, the ``memory_writer`` function can be used to write to a memory buffer,
``fd_writer`` to a file descriptor, and ``custom_writer`` to a callback function.

For each of those functions, the mandatory second argument is the archive format,
and the optional third argument is the compression format (called “filter” in
libarchive). The acceptable values are listed in ``libarchive.ffi.WRITE_FORMATS``
and ``libarchive.ffi.WRITE_FILTERS``.

File metadata codecs
--------------------

By default, UTF-8 is used to read and write file attributes from and to archives.
A different codec can be specified through the ``header_codec`` arguments of the
``*_reader`` and ``*_writer`` functions. Example::

    with libarchive.file_writer('test.tar', 'ustar', header_codec='cp037') as archive:
        ...
    with file_reader('test.tar', header_codec='cp037') as archive:
        ...

In addition to file paths (``pathname`` and ``linkpath``), the specified codec is
used to encode and decode user and group names (``uname`` and ``gname``).

License
=======

`CC0 Public Domain Dedication <http://creativecommons.org/publicdomain/zero/1.0/>`_