Spec-Zone.ru › Python 3.14

tarfile — Чтение и запись файлов архивов tar

Исходный код: Lib/tarfile.py

Модуль tarfile позволяет читать и записывать архивы tar, в том числе использующие сжатие gzip, bz2 и lzma. Используйте модуль zipfile для чтения или записи файлов .zip или высокоуровневые функции из shutil.

Некоторые факты и цифры:

  • читает и записывает архивы со сжатием gzip, bz2, compression.zstd и lzma, если соответствующие модули доступны.

    Если в вашей копии CPython отсутствует какой-либо из этих необязательных модулей, обратитесь к документации вашего дистрибутива (то есть того, кто предоставил вам Python). Если вы являетесь дистрибьютором, см. раздел Требования к необязательным модулям.

  • поддерживает чтение и запись в формате POSIX.1-1988 (ustar).
  • поддерживает чтение и запись в формате GNU tar, включая расширения longname и longlink, а также только чтение всех вариантов расширения sparse, в том числе восстановление разреженных файлов.
  • поддерживает чтение и запись в формате POSIX.1-2001 (pax).
  • обрабатывает каталоги, обычные файлы, жёсткие ссылки, символические ссылки, FIFO, символьные устройства и блочные устройства, а также может получать и восстанавливать сведения о файлах, например временные метки, права доступа и владельца.

Изменено в версии 3.3: Добавлена поддержка сжатия lzma.

Изменено в версии 3.12: Архивы извлекаются с использованием фильтра, который позволяет либо ограничить неожиданные или опасные возможности, либо явно указать, что они ожидаемы и архиву можно полностью доверять.

Изменено в версии 3.14: Фильтр извлечения по умолчанию установлен в значение data, который запрещает некоторые опасные возможности, например ссылки на абсолютные пути или пути за пределами целевого каталога. Ранее использовалась стратегия фильтрации, эквивалентная fully_trusted.

Изменено в версии 3.14: Добавлена поддержка сжатия Zstandard с помощью compression.zstd.

tarfile.open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)

Возвращает объект TarFile для пути name. Подробные сведения об объектах TarFile и допустимых именованных аргументах см. в разделе Объекты TarFile.

mode должен быть строкой формата 'filemode[:compression]'; по умолчанию используется 'r'. Полный список сочетаний режимов:

режим

действие

'r' или 'r:*'

Открыть для чтения с автоматическим определением сжатия (рекомендуется).

'r:'

Открыть только для чтения без сжатия.

'r:gz'

Открыть для чтения со сжатием gzip.

'r:bz2'

Открыть для чтения со сжатием bzip2.

'r:xz'

Открыть для чтения со сжатием lzma.

'r:zst'

Открыть для чтения со сжатием Zstandard.

'x' или 'x:'

Создать архив tar без сжатия в монопольном режиме. Если он уже существует, вызвать исключение FileExistsError.

'x:gz'

Создать архив tar со сжатием gzip. Если он уже существует, вызвать исключение FileExistsError.

'x:bz2'

Создать архив tar со сжатием bzip2. Если он уже существует, вызвать исключение FileExistsError.

'x:xz'

Создать архив tar со сжатием lzma. Если он уже существует, вызвать исключение FileExistsError.

'x:zst'

Создать архив tar со сжатием Zstandard. Если он уже существует, вызвать исключение FileExistsError.

'a' или 'a:'

Открыть для добавления без сжатия. Если файл не существует, он будет создан.

'w' или 'w:'

Открыть для записи без сжатия.

'w:gz'

Открыть для записи со сжатием gzip.

'w:bz2'

Открыть для записи со сжатием bzip2.

'w:xz'

Открыть для записи со сжатием lzma.

'w:zst'

Открыть для записи со сжатием Zstandard.

Обратите внимание, что использовать 'a:gz', 'a:bz2' или 'a:xz' невозможно. Если mode не подходит для чтения определённого (сжатого) файла, вызывается исключение ReadError. Чтобы избежать этого, используйте режим mode 'r'. Если метод сжатия не поддерживается, вызывается исключение CompressionError.

Если указан fileobj, он используется вместо файлового объекта, открытого в бинарном режиме для name. Предполагается, что он находится в позиции 0.

Для режимов 'w:gz', 'x:gz', 'w|gz', 'w:bz2', 'x:bz2', 'w|bz2', tarfile.open() принимает именованный аргумент compresslevel (по умолчанию 9), задающий уровень сжатия файла.

Для режимов 'w:xz', 'x:xz' и 'w|xz', tarfile.open() принимает именованный аргумент preset, задающий уровень сжатия файла.

Для режимов 'w:zst', 'x:zst' и 'w|zst', tarfile.open() принимает именованный аргумент level, задающий уровень сжатия файла. Также можно передать именованный аргумент options, задающий расширенные параметры сжатия Zstandard, описанные в CompressionParameter. Именованный аргумент zstd_dict можно передать для указания объекта ZstdDict — словаря Zstandard, который улучшает сжатие небольших объёмов данных.

Для специальных целей предусмотрен второй формат mode: 'filemode|[compression]'. tarfile.open() возвращает объект TarFile, обрабатывающий данные как поток блоков. Произвольный поиск по файлу не выполняется. Если указан fileobj, им может быть любой объект с методом read() или write() (в зависимости от mode), работающим с байтами. Параметр bufsize задаёт размер блока; значение по умолчанию — 20 * 512 байт. Используйте этот вариант, например, с sys.stdin.buffer, файловым объектом сокета или ленточным устройством. Однако такой объект TarFile имеет ограничение: произвольный доступ невозможен; см. Примеры. Возможны следующие режимы:

Режим

Действие

'r|*'

Открыть поток блоков tar для чтения с автоматическим определением сжатия.

'r|'

Открыть поток несжатых блоков tar для чтения.

'r|gz'

Открыть сжатый gzip поток для чтения.

'r|bz2'

Открыть сжатый bzip2 поток для чтения.

'r|xz'

Открыть сжатый lzma поток для чтения.

'r|zst'

Открыть сжатый Zstandard поток для чтения.

'w|'

Открыть несжатый поток для записи.

'w|gz'

Открыть сжатый gzip поток для записи.

'w|bz2'

Открыть сжатый bzip2 поток для записи.

'w|xz'

Открыть сжатый lzma поток для записи.

'w|zst'

Открыть сжатый Zstandard поток для записи.

Изменено в версии 3.5: Добавлен режим 'x' (создание без перезаписи).

Изменено в версии 3.6: Параметр name принимает объект, подобный пути.

Изменено в версии 3.12: Именованный аргумент compresslevel также работает с потоками.

Изменено в версии 3.14: Именованный аргумент preset также работает с потоками.

class tarfile.TarFile

Класс для чтения и записи архивов tar. Не используйте этот класс напрямую: вместо этого используйте tarfile.open(). См. раздел Объекты TarFile.

tarfile.is_tarfile(name)

Возвращает True, если name является файлом архива tar, который может прочитать модуль tarfile. name может быть объектом str, файлом или файловым объектом.

Изменено в версии 3.9: Добавлена поддержка файлов и файловых объектов.

Модуль tarfile определяет следующие исключения:

exception tarfile.TarError

Базовый класс для всех исключений tarfile.

exception tarfile.ReadError

Вызывается при открытии архива tar, который модуль tarfile не может обработать или который каким-либо образом повреждён.

exception tarfile.CompressionError

Вызывается, если метод сжатия не поддерживается или данные не удаётся корректно декодировать.

exception tarfile.StreamError

Вызывается при ограничениях, характерных для потоковых объектов TarFile.

exception tarfile.ExtractError

Вызывается при несерьёзных ошибках во время использования TarFile.extract(), но только если TarFile.errorlevel== 2.

exception tarfile.HeaderError

Вызывается методом TarInfo.frombuf(), если полученный им буфер недействителен.

exception tarfile.FilterError

Базовый класс для элементов, отклонённых фильтрами.

tarinfo

Сведения об элементе, извлечение которого отклонил фильтр, в виде объекта TarInfo.

exception tarfile.AbsolutePathError

Вызывается для запрета извлечения элемента с абсолютным путём.

exception tarfile.OutsideDestinationError

Вызывается для запрета извлечения элемента за пределы целевого каталога.

exception tarfile.SpecialFileError

Вызывается для запрета извлечения специального файла (например, устройства или канала).

exception tarfile.AbsoluteLinkError

Вызывается для запрета извлечения символической ссылки с абсолютным путём.

exception tarfile.LinkOutsideDestinationError

Вызывается для запрета извлечения символической ссылки, указывающей за пределы целевого каталога.

exception tarfile.LinkFallbackError

Вызывается для запрета эмуляции ссылки (жёсткой или символической) путём извлечения другого элемента архива, если этот элемент будет отклонён фильтром по расположению. Исключение, вызвавшее отклонение заменяющего элемента, доступно как BaseException.__context__.

Добавлено в версии 3.14.

На уровне модуля доступны следующие константы:

tarfile.ENCODING

Кодировка символов по умолчанию: 'utf-8' в Windows; в остальных случаях — значение, возвращаемое функцией sys.getfilesystemencoding().

tarfile.REGTYPE
tarfile.AREGTYPE

Тип type обычного файла.

tarfile.LNKTYPE

Тип type ссылки (внутри архива tar).

tarfile.SYMTYPE

Тип type символической ссылки.

tarfile.CHRTYPE

Тип type символьного специального устройства.

tarfile.BLKTYPE

Тип type блочного специального устройства.

tarfile.DIRTYPE

Тип type каталога.

tarfile.FIFOTYPE

Тип type специального устройства FIFO.

tarfile.CONTTYPE

Тип type непрерывного файла.

tarfile.GNUTYPE_LONGNAME

Тип type длинного имени GNU tar.

tarfile.GNUTYPE_LONGLINK

Тип type длинной ссылки GNU tar.

tarfile.GNUTYPE_SPARSE

Тип type разреженного файла GNU tar.

Каждая из следующих констант определяет формат архива tar, который модуль tarfile может создавать. Подробности см. в разделе Поддерживаемые форматы tar.

tarfile.USTAR_FORMAT

Формат POSIX.1-1988 (ustar).

tarfile.GNU_FORMAT

Формат GNU tar.

tarfile.PAX_FORMAT

Формат POSIX.1-2001 (pax).

tarfile.DEFAULT_FORMAT

Формат по умолчанию для создания архивов. В настоящее время это PAX_FORMAT.

Изменено в версии 3.8: Формат по умолчанию для новых архивов изменён с GNU_FORMAT на PAX_FORMAT.

См. также

Module zipfile

Документация стандартного модуля zipfile.

Операции архивирования

Документация по высокоуровневым средствам архивирования, предоставляемым стандартным модулем shutil.

Руководство GNU tar: базовый формат Tar

Документация по файлам архивов tar, включая расширения GNU tar.

Объекты TarFile

Объект TarFile предоставляет интерфейс для работы с архивом tar. Архив tar представляет собой последовательность блоков. Элемент архива (сохранённый файл) состоит из блока заголовка, за которым следуют блоки данных. Файл можно сохранять в архиве tar несколько раз. Каждый элемент архива представлен объектом TarInfo; подробности см. в разделе Объекты TarInfo.

Объект TarFile можно использовать в качестве менеджера контекста в инструкции with. Он будет автоматически закрыт после завершения блока. Обратите внимание: в случае исключения архив, открытый для записи, не будет завершён; будет закрыт только используемый внутри него файловый объект. Пример использования см. в разделе Примеры.

Добавлено в версии 3.2: Добавлена поддержка протокола управления контекстом.

class tarfile.TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=1, stream=False)

Все следующие аргументы необязательны, и к ним также можно обращаться как к атрибутам экземпляра.

name — путь к архиву. name может быть объектом, подобным пути. Его можно не указывать, если задан fileobj. В этом случае используется атрибут name файлового объекта, если он существует.

mode — это либо 'r' для чтения существующего архива, 'a' для добавления данных в существующий файл, 'w' для создания нового файла с перезаписью существующего или 'x' для создания нового файла, только если он ещё не существует.

Если задан fileobj, он используется для чтения или записи данных. Если режим fileobj можно определить, он заменяет значение mode. fileobj будет использоваться начиная с позиции 0.

Примечание

fileobj не закрывается при закрытии TarFile.

format определяет формат архива при записи. Его значением должна быть одна из констант USTAR_FORMAT, GNU_FORMAT или PAX_FORMAT, определённых на уровне модуля. При чтении формат определяется автоматически, даже если в одном архиве представлены разные форматы.

Аргумент tarinfo можно использовать для замены класса TarInfo по умолчанию другим классом.

Если dereference равно False, в архив добавляются символические и жёсткие ссылки. Если оно равно True, в архив добавляется содержимое целевых файлов. Это не действует в системах, не поддерживающих символические ссылки.

Если ignore_zeros равно False, пустой блок считается концом архива. Если оно равно True, пустые (и недопустимые) блоки пропускаются, чтобы извлечь как можно больше элементов. Это полезно только при чтении объединённых или повреждённых архивов.

Для debug можно задать значение от 0 (отладочные сообщения отсутствуют) до 3 (все отладочные сообщения). Сообщения записываются в sys.stderr.

errorlevel определяет способ обработки ошибок извлечения; см. the corresponding attribute.

Аргументы encoding и errors задают кодировку символов, используемую для чтения или записи архива, а также способ обработки ошибок преобразования. Настройки по умолчанию подходят большинству пользователей. Подробности см. в разделе Проблемы с Unicode.

Аргумент pax_headers — необязательный словарь строк, который будет добавлен как глобальный заголовок pax, если format равен PAX_FORMAT.

Если для stream задано значение True, при чтении архива сведения о файлах в архиве не кэшируются, что позволяет экономить память.

Изменено в версии 3.2: В качестве значения по умолчанию для аргумента errors используется 'surrogateescape'.

Изменено в версии 3.5: Добавлен режим 'x' (эксклюзивное создание).

Изменено в версии 3.6: Параметр name принимает объект, подобный пути.

Изменено в версии 3.13: Добавлен параметр stream.

classmethod TarFile.open(...)

Альтернативный конструктор. Функция tarfile.open() фактически является сокращённым вызовом этого метода класса.

TarFile.getmember(name)

Возвращает объект TarInfo для элемента с именем name. Если элемент с именем name не найден в архиве, возникает исключение KeyError.

Примечание

Если элемент встречается в архиве более одного раза, предполагается, что его последнее вхождение является самой актуальной версией.

TarFile.getmembers()

Возвращает элементы архива в виде списка объектов TarInfo. Порядок элементов в списке совпадает с их порядком в архиве.

TarFile.getnames()

Возвращает элементы в виде списка их имён. Порядок имён совпадает с порядком в списке, возвращаемом методом getmembers().

TarFile.list(verbose=True, *, members=None)

Выводит оглавление в sys.stdout. Если verbose равно False, выводятся только имена элементов. Если оно равно True, выводятся данные в формате, похожем на вывод ls -l. Если задан необязательный аргумент members, он должен быть подмножеством списка, возвращаемого методом getmembers().

Изменено в версии 3.5: Добавлен параметр members.

TarFile.next()

Если TarFile открыт для чтения, возвращает следующий элемент архива в виде объекта TarInfo. Если доступных элементов больше нет, возвращает None.

TarFile.extractall(path='.', members=None, *, numeric_owner=False, filter=None)

Извлекает все элементы архива в текущий рабочий каталог или каталог path. Если задан необязательный аргумент members, он должен быть подмножеством списка, возвращаемого методом getmembers(). Сведения о каталоге, такие как владелец, время изменения и разрешения, устанавливаются после извлечения всех элементов. Это позволяет обойти две проблемы: время изменения каталога сбрасывается при каждом создании в нём файла; а извлечение файлов завершится ошибкой, если разрешения каталога не позволяют выполнять запись.

Если numeric_owner равно True, для установки владельца и группы извлечённых файлов используются номера uid и gid из tarfile. В противном случае используются указанные в tarfile имена.

Аргумент filter определяет, как members изменяются или отклоняются перед извлечением. Подробности см. в разделе Фильтры извлечения. Рекомендуется задавать этот аргумент явно только в том случае, если требуются определённые возможности tar, либо как filter='data' для поддержки версий Python с менее безопасными настройками по умолчанию (3.13 и ниже).

Предупреждение

Не извлекайте архивы из ненадёжных источников без предварительной проверки.

Начиная с Python 3.14, значение по умолчанию (data) предотвращает наиболее опасные проблемы безопасности. Однако оно не предотвращает все нежелательные или небезопасные действия. Подробности см. в разделе Фильтры извлечения.

Изменено в версии 3.5: Добавлен параметр numeric_owner.

Изменено в версии 3.6: Параметр path принимает объект, подобный пути.

Изменено в версии 3.12: Добавлен параметр filter.

Изменено в версии 3.14: Теперь значение параметра filter по умолчанию — 'data'.

TarFile.extract(member, path='', set_attrs=True, *, numeric_owner=False, filter=None)

Извлекает элемент архива в текущий рабочий каталог, используя его полное имя. Сведения о файле извлекаются с максимально возможной точностью. Аргумент member может быть именем файла или объектом TarInfo. Другой каталог можно указать с помощью аргумента path. path может быть объектом, подобным пути. Атрибуты файла (владелец, время изменения, режим доступа) устанавливаются, если set_attrs не равно false.

Аргументы numeric_owner и filter совпадают с одноимёнными аргументами метода extractall().

Примечание

Метод extract() не решает ряд проблем, связанных с извлечением. В большинстве случаев следует использовать метод extractall().

Предупреждение

Не извлекайте архивы из ненадёжных источников без предварительной проверки. Подробности см. в предупреждении для метода extractall().

Изменено в версии 3.2: Добавлен параметр set_attrs.

Изменено в версии 3.5: Добавлен параметр numeric_owner.

Изменено в версии 3.6: Параметр path принимает объект, подобный пути.

Изменено в версии 3.12: Добавлен параметр filter.

TarFile.extractfile(member)

Извлекает элемент архива в виде файлового объекта. Аргумент member может быть именем файла или объектом TarInfo. Если member — обычный файл или ссылка, возвращается объект io.BufferedReader. Для всех остальных существующих элементов возвращается None. Если member отсутствует в архиве, возникает исключение KeyError.

Изменено в версии 3.3: Возвращается объект io.BufferedReader.

Изменено в версии 3.13: У возвращаемого объекта io.BufferedReader есть атрибут mode, значение которого всегда равно 'rb'.

TarFile.errorlevel: int

Если errorlevel равно 0, ошибки игнорируются при использовании методов TarFile.extract() и TarFile.extractall(). Тем не менее, если значение debug больше 0, они отображаются в отладочном выводе как сообщения об ошибках. Если значение равно 1 (по умолчанию), все фатальные ошибки вызывают исключения OSError или FilterError. Если значение равно 2, все нефатальные ошибки также вызывают исключения TarError.

Некоторые исключения, например вызванные неверными типами аргументов или повреждением данных, возникают всегда.

Пользовательские фильтры извлечения должны вызывать FilterError для фатальных ошибок и ExtractError для нефатальных ошибок.

Обратите внимание: при возникновении исключения архив может быть извлечён лишь частично. Очистка является обязанностью пользователя.

TarFile.extraction_filter

Добавлено в версии 3.12.

Фильтр извлечения, используемый по умолчанию для аргумента filter методов extract() и extractall().

Значением атрибута может быть None или вызываемый объект. Для этого атрибута нельзя использовать строковые имена, в отличие от аргумента filter метода extract().

Если extraction_filter равно None (по умолчанию), методы извлечения используют по умолчанию фильтр data.

Атрибут можно задавать для экземпляров или переопределять в подклассах. Его также можно установить непосредственно для класса TarFile, чтобы задать глобальное значение по умолчанию. Однако, поскольку это повлияет на все варианты использования tarfile, рекомендуется делать это только в приложениях верхнего уровня или в site configuration. Чтобы задать глобальное значение по умолчанию таким способом, функцию фильтра необходимо обернуть в @staticmethod, чтобы предотвратить передачу аргумента self.

Изменено в версии 3.14: Фильтром по умолчанию назначен data, запрещающий некоторые опасные возможности, например ссылки на абсолютные пути или пути за пределами целевого каталога. Ранее значение по умолчанию соответствовало fully_trusted.

TarFile.add(name, arcname=None, recursive=True, *, filter=None)

Добавляет файл name в архив. name может обозначать файл любого типа (каталог, FIFO, символическую ссылку и т. д.). Если задан аргумент arcname, он определяет альтернативное имя файла в архиве. По умолчанию каталоги добавляются рекурсивно. Это можно отключить, задав для recursive значение False. При рекурсивном добавлении элементы добавляются в отсортированном порядке. Если задан filter, это должна быть функция, принимающая в качестве аргумента объект TarInfo и возвращающая изменённый объект TarInfo. Если вместо этого она возвращает None, объект TarInfo исключается из архива. Пример см. в разделе Примеры.

Изменено в версии 3.2: Добавлен параметр filter.

Изменено в версии 3.7: При рекурсивном добавлении элементы добавляются в отсортированном порядке.

TarFile.addfile(tarinfo, fileobj=None)

Добавляет объект TarInfo tarinfo в архив. Если tarinfo представляет собой обычный файл ненулевого размера, аргумент fileobj должен быть двоичным файлом; из него считываются tarinfo.size байт и добавляются в архив. Объекты TarInfo можно создавать напрямую или с помощью метода gettarinfo().

Изменено в версии 3.13: Для обычных файлов ненулевого размера необходимо задавать fileobj.

TarFile.gettarinfo(name=None, arcname=None, fileobj=None)

Создаёт объект TarInfo на основе результата вызова os.stat() или эквивалентной операции для существующего файла. Файл задаётся либо именем name, либо файловым дескриптором в файловом объекте fileobj. name может быть объектом, подобным пути. Если задан arcname, он определяет альтернативное имя файла в архиве; в противном случае имя берётся из атрибута name объекта fileobj или из аргумента name. Имя должно быть текстовой строкой.

Перед добавлением объекта с помощью метода addfile() можно изменить некоторые атрибуты объекта TarInfo. Если файловый объект не является обычным файловым объектом, расположенным в начале файла, может потребоваться изменить такие атрибуты, как size. Это относится к таким объектам, как GzipFile. Также можно изменить name; в таком случае для arcname можно указать фиктивную строку.

Изменено в версии 3.6: Параметр name принимает объект, подобный пути.

TarFile.close()

Закрывает объект TarFile. В режиме записи в архив добавляются два завершающих нулевых блока.

TarFile.pax_headers: dict

Словарь, содержащий пары ключ-значение глобальных заголовков pax.

Объекты TarInfo

Объект TarInfo представляет один элемент в TarFile. Помимо хранения всех необходимых атрибутов файла (таких как тип файла, размер, время, права доступа, владелец и т. д.), он предоставляет полезные методы для определения его типа. Он не содержит сами данные файла.

Объекты TarInfo возвращаются методами TarFile getmember(), getmembers() и gettarinfo().

Изменение объектов, возвращаемых getmember() или getmembers(), повлияет на все последующие операции с архивом. Если этого нежелательно, можно воспользоваться copy.copy() или вызвать метод replace(), чтобы за один шаг создать изменённую копию.

Для некоторых атрибутов можно задать значение None, указывающее, что соответствующие метаданные не используются или неизвестны. Различные методы TarInfo обрабатывают None по-разному:

  • Методы extract() и extractall() проигнорируют соответствующие метаданные, оставив значение по умолчанию.
  • Метод addfile() завершится ошибкой.
  • Метод list() выведет строку-заполнитель.
class tarfile.TarInfo(name='')

Создаёт объект TarInfo.

classmethod TarInfo.frombuf(buf, encoding, errors)

Создаёт и возвращает объект TarInfo из строкового буфера buf.

Если буфер недействителен, вызывает исключение HeaderError.

classmethod TarInfo.fromtarfile(tarfile)

Читает следующий элемент из объекта TarFile tarfile и возвращает его как объект TarInfo.

TarInfo.tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape')

Создаёт строковый буфер из объекта TarInfo. Сведения об аргументах см. в описании конструктора класса TarFile.

Изменено в версии 3.2: В качестве значения по умолчанию для аргумента errors используется 'surrogateescape'.

Объект TarInfo имеет следующие общедоступные атрибуты данных:

TarInfo.name: str

Имя элемента архива.

TarInfo.size: int

Размер в байтах.

TarInfo.mtime: int | float

Время последнего изменения в секундах с момента начала эпохи, как в os.stat_result.st_mtime.

Изменено в версии 3.12: Для методов extract() и extractall() можно задать значение None, чтобы при извлечении этот атрибут не применялся.

TarInfo.mode: int

Биты прав доступа, как для os.chmod().

Изменено в версии 3.12: Для методов extract() и extractall() можно задать значение None, чтобы при извлечении этот атрибут не применялся.

TarInfo.type

Тип файла. type обычно равен одной из следующих констант: REGTYPE, AREGTYPE, LNKTYPE, SYMTYPE, DIRTYPE, FIFOTYPE, CONTTYPE, CHRTYPE, BLKTYPE, GNUTYPE_SPARSE. Чтобы удобнее определить тип объекта TarInfo, используйте методы is*() ниже.

TarInfo.linkname: str

Имя целевого файла, которое указывается только в объектах TarInfo типа LNKTYPE и SYMTYPE.

Для символических ссылок (SYMTYPE) значение linkname задаётся относительно каталога, содержащего ссылку. Для жёстких ссылок (LNKTYPE) значение linkname задаётся относительно корня архива.

TarInfo.uid: int

Идентификатор пользователя, который изначально сохранил этот элемент.

Изменено в версии 3.12: Для методов extract() и extractall() можно задать значение None, чтобы при извлечении этот атрибут не применялся.

TarInfo.gid: int

Идентификатор группы пользователя, который изначально сохранил этот элемент.

Изменено в версии 3.12: Для методов extract() и extractall() можно задать значение None, чтобы при извлечении этот атрибут не применялся.

TarInfo.uname: str

Имя пользователя.

Изменено в версии 3.12: Для методов extract() и extractall() можно задать значение None, чтобы при извлечении этот атрибут не применялся.

TarInfo.gname: str

Имя группы.

Изменено в версии 3.12: Для методов extract() и extractall() можно задать значение None, чтобы при извлечении этот атрибут не применялся.

TarInfo.chksum: int

Контрольная сумма заголовка.

TarInfo.devmajor: int

Старший номер устройства.

TarInfo.devminor: int

Младший номер устройства.

TarInfo.offset: int

Здесь начинается заголовок tar.

TarInfo.offset_data: int

Здесь начинаются данные файла.

TarInfo.sparse

Сведения о разреженном элементе.

TarInfo.pax_headers: dict

Словарь с парами «ключ—значение» соответствующего расширенного заголовка pax.

TarInfo.replace(name=..., mtime=..., mode=..., linkname=..., uid=..., gid=..., uname=..., gname=..., deep=True)

Добавлено в версии 3.12.

Возвращает новую копию объекта TarInfo с изменёнными указанными атрибутами. Например, чтобы вернуть TarInfo с именем группы 'staff', используйте:

new_tarinfo = old_tarinfo.replace(gname='staff')

По умолчанию создаётся глубокая копия. Если deep имеет значение false, копия будет поверхностной, то есть pax_headers и любые пользовательские атрибуты будут общими с исходным объектом TarInfo.

Объект TarInfo также предоставляет несколько удобных методов проверки:

TarInfo.isfile()

Возвращает True, если объект TarInfo является обычным файлом.

TarInfo.isreg()

То же, что и isfile().

TarInfo.isdir()

Возвращает True, если это каталог.

TarInfo.issym()

Возвращает True, если это символическая ссылка.

TarInfo.islnk()

Возвращает True, если это жёсткая ссылка.

TarInfo.ischr()

Возвращает True, если это символьное устройство.

TarInfo.isblk()

Возвращает True, если это блочное устройство.

TarInfo.isfifo()

Возвращает True, если это FIFO.

TarInfo.isdev()

Возвращает True, если это символьное устройство, блочное устройство или FIFO.

Фильтры извлечения

Добавлено в версии 3.12.

Формат tar предназначен для сохранения всех сведений о файловой системе UNIX-подобной операционной системы, что делает его очень гибким. К сожалению, эти возможности позволяют легко создавать tar-файлы, извлечение которых может привести к нежелательным — и потенциально вредоносным — последствиям. Например, извлечение tar-файла может различными способами перезаписать произвольные файлы (например, с помощью абсолютных путей, компонентов пути .. или символических ссылок, влияющих на последующие элементы).

В большинстве случаев весь этот функционал не нужен. Поэтому tarfile поддерживает фильтры извлечения — механизм ограничения возможностей, позволяющий снизить некоторые риски безопасности.

Предупреждение

Ни один из доступных фильтров не блокирует все опасные возможности архивов. Никогда не извлекайте архивы из ненадёжных источников без предварительной проверки. См. также Рекомендации по дополнительной проверке.

См. также

PEP 706

Содержит дополнительные сведения о мотивации и обосновании принятого решения.

Аргумент filter методов TarFile.extract() и extractall() может принимать следующие значения:

  • строка 'fully_trusted': учитывать все метаданные, указанные в архиве. Следует использовать, только если пользователь полностью доверяет архиву или реализует собственную сложную проверку.
  • строка 'tar': учитывать большинство возможностей, специфичных для tar (то есть возможностей UNIX-подобных файловых систем), но блокировать функции, которые с большой вероятностью могут оказаться неожиданными или вредоносными. Подробности см. в описании tar_filter().
  • строка 'data': игнорировать или блокировать большинство возможностей, специфичных для UNIX-подобных файловых систем. Предназначен для извлечения кроссплатформенных архивов данных. Подробности см. в описании data_filter().
  • None (по умолчанию): использовать TarFile.extraction_filter.

    Если и ему присвоено значение None (по умолчанию), будет использован фильтр 'data'.

    Изменено в версии 3.14: Фильтром по умолчанию стал data. Ранее по умолчанию использовался фильтр, эквивалентный fully_trusted.

  • Вызываемый объект, который будет вызываться для каждого извлекаемого элемента. Ему передаются объект TarInfo с описанием элемента и путь назначения, куда извлекается архив (то есть для всех элементов используется один и тот же путь):

    filter(member: TarInfo, path: str, /) -> TarInfo | None
    

    Вызываемый объект вызывается непосредственно перед извлечением каждого элемента, поэтому он может учитывать текущее состояние диска. Он может:

    • вернуть объект TarInfo, который будет использован вместо метаданных из архива, или
    • вернуть None, и тогда элемент будет пропущен, или
    • вызвать исключение, чтобы прервать операцию или пропустить элемент — в зависимости от значения errorlevel. Учтите, что при прерывании извлечения метод extractall() может оставить архив извлечённым лишь частично. Очистка не выполняется.

Стандартные именованные фильтры

Предопределённые именованные фильтры доступны в виде функций, поэтому их можно повторно использовать в пользовательских фильтрах:

tarfile.fully_trusted_filter(member, path)

Возвращает member без изменений.

Реализует фильтр 'fully_trusted'.

tarfile.tar_filter(member, path)

Реализует фильтр 'tar'.

  • Удаляет начальные косые черты (/ и os.sep) из имён файлов.
  • Отказывается извлекать файлы с абсолютными путями (если имя остаётся абсолютным даже после удаления косых черт, например C:/foo в Windows). В этом случае вызывается исключение AbsolutePathError.
  • Нормализует имена файлов (TarInfo.name), содержащие компоненты .., с помощью os.path.normpath(). Обратите внимание, что при этом удаляются внутренние компоненты .., из-за чего значение имени может измениться, если путь проходит через символические ссылки.
  • Отказывается извлекать файлы, абсолютный путь которых (после перехода по символическим ссылкам) ведёт за пределы каталога назначения. В этом случае вызывается исключение OutsideDestinationError.
  • Сбрасывает старшие биты режима доступа (setuid, setgid, sticky) и биты записи для группы и остальных пользователей (S_IWGRP | S_IWOTH).

Возвращает изменённый элемент TarInfo.

Изменено в версии 3.14.7 (ещё не выпущена): Имена файлов, содержащие компоненты .., теперь нормализуются.

tarfile.data_filter(member, path)

Реализует фильтр 'data'. В дополнение к действиям фильтра tar_filter он выполняет следующее:

  • Нормализует цели ссылок (TarInfo.linkname) с помощью os.path.normpath(). Обратите внимание, что при этом удаляются внутренние компоненты .., из-за чего значение ссылки может измениться, если путь в TarInfo.linkname проходит через символические ссылки.
  • Отказывается извлекать ссылки (жёсткие или символические), ведущие к абсолютным путям или за пределы каталога назначения.

    В этом случае вызывается исключение AbsoluteLinkError или LinkOutsideDestinationError.

    Учтите, что такие файлы не извлекаются даже на платформах, не поддерживающих символические ссылки.

  • Отказывается извлекать файлы устройств (в том числе каналы). В этом случае вызывается исключение SpecialFileError.
  • Для обычных файлов, включая жёсткие ссылки:

    • Устанавливает права на чтение и запись для владельца (S_IRUSR | S_IWUSR).
    • Удаляет права на выполнение для группы и остальных пользователей (S_IXGRP | S_IXOTH), если такие права отсутствуют у владельца (S_IXUSR).
  • Для остальных файлов (каталогов) устанавливает mode в None, чтобы методы извлечения пропускали применение битов прав доступа.
  • Устанавливает сведения о пользователе и группе (uid, gid, uname, gname) в None, чтобы методы извлечения не задавали их.

Возвращает изменённый элемент TarInfo.

Обратите внимание, что этот фильтр не блокирует все опасные возможности архивов. Подробности см. в разделе Рекомендации по дополнительной проверке.

Изменено в версии 3.14: Цели ссылок теперь нормализуются.

Ошибки фильтрации

Если фильтр отказывается извлекать файл, он вызывает соответствующее исключение — подкласс FilterError. Если значение TarFile.errorlevel равно 1 или больше, это прервёт извлечение. При значении errorlevel=0 ошибка будет записана в журнал, элемент будет пропущен, а извлечение продолжится.

Рекомендации по дополнительной проверке

Даже при использовании filter='data' модуль tarfile не подходит для извлечения недоверенных файлов без предварительной проверки. Среди прочего, предопределённые фильтры не предотвращают атаки типа «отказ в обслуживании». Пользователям следует выполнять дополнительные проверки.

Ниже приведён неполный список того, что следует учитывать:

  • Извлекайте архив во временный каталог, созданный с помощью new temporary directory, чтобы, например, предотвратить эксплуатацию существующих ссылок и упростить очистку после неудачного извлечения.
  • Запретите символические ссылки, если эта возможность вам не нужна.
  • При работе с недоверенными данными используйте внешние ограничения (например, на уровне ОС) на использование диска, памяти и процессора.
  • Проверяйте имена файлов по списку разрешённых символов (чтобы отфильтровать управляющие символы, похожие символы, разделители путей из других систем и т. д.).
  • Проверяйте, что у файлов ожидаемые расширения (это поможет исключить файлы, которые запускаются при «щелчке по ним», а также файлы без расширения, например специальные имена устройств Windows).
  • Ограничивайте число извлекаемых файлов, общий размер извлечённых данных, длину имён файлов (включая длину имён символических ссылок) и размер отдельных файлов.
  • Проверяйте наличие файлов, имена которых будут конфликтовать в файловых системах, нечувствительных к регистру.

Также учтите следующее:

  • Tar-архивы могут содержать несколько версий одного и того же файла. Предполагается, что более поздние версии заменяют предыдущие. Эта возможность необходима для обновления архивов на магнитной ленте, но может использоваться злоумышленниками.
  • Модуль tarfile не защищает от проблем, связанных с «живыми» данными, например от действий злоумышленника, который изменяет каталог назначения (или источник) во время извлечения (или архивации).

Поддержка старых версий Python

Фильтры извлечения появились в Python 3.12, но могут быть перенесены в более старые версии в рамках обновлений безопасности. Чтобы проверить наличие этой возможности, используйте, например, hasattr(tarfile, 'data_filter'), а не проверку версии Python.

В следующих примерах показано, как поддерживать версии Python с этой возможностью и без неё. Учтите, что настройка extraction_filter повлияет на все последующие операции.

  • Полностью доверенный архив:

    my_tarfile.extraction_filter = (lambda member, path: member)
    my_tarfile.extractall()
    
  • Если доступен фильтр 'data', используйте его, а если эта возможность недоступна — вернитесь к поведению Python 3.11 ('fully_trusted'):

    my_tarfile.extraction_filter = getattr(tarfile, 'data_filter',
                                           (lambda member, path: member))
    my_tarfile.extractall()
    
  • Используйте фильтр 'data'; если он недоступен, завершите работу с ошибкой:

    my_tarfile.extractall(filter=tarfile.data_filter)
    

    или:

    my_tarfile.extraction_filter = tarfile.data_filter
    my_tarfile.extractall()
    
  • Используйте фильтр 'data'; если он недоступен, выведите предупреждение:

    if hasattr(tarfile, 'data_filter'):
        my_tarfile.extractall(filter='data')
    else:
        # remove this when no longer needed
        warn_the_user('Extracting may be unsafe; consider updating Python')
        my_tarfile.extractall()
    

Пример фильтра извлечения с состоянием

Хотя методы извлечения tarfile принимают простой вызываемый объект filter, пользовательские фильтры могут быть более сложными объектами с внутренним состоянием. Иногда такие фильтры удобно реализовать как менеджеры контекста и использовать следующим образом:

with StatefulFilter() as filter_func:
    tar.extractall(path, filter=filter_func)

Например, такой фильтр можно записать следующим образом:

class StatefulFilter:
    def __init__(self):
        self.file_count = 0

    def __enter__(self):
        return self

    def __call__(self, member, path):
        self.file_count += 1
        return member

    def __exit__(self, *exc_info):
        print(f'{self.file_count} files extracted')

Интерфейс командной строки

Добавлено в версии 3.4.

Модуль tarfile предоставляет простой интерфейс командной строки для работы с tar-архивами.

Чтобы создать новый tar-архив, укажите его имя после параметра -c, а затем перечислите имена файлов, которые нужно включить:

$ python -m tarfile -c monty.tar  spam.txt eggs.txt

Также можно указать каталог:

$ python -m tarfile -c monty.tar life-of-brian_1979/

Чтобы извлечь tar-архив в текущий каталог, используйте параметр -e:

$ python -m tarfile -e monty.tar

Вы также можете извлечь tar-архив в другой каталог, указав его имя:

$ python -m tarfile -e monty.tar  other-dir/

Чтобы получить список файлов в tar-архиве, используйте параметр -l:

$ python -m tarfile -l monty.tar

Параметры командной строки

-l <tarfile>
--list <tarfile>

Вывести список файлов в tar-архиве.

-c <tarfile> <source1> ... <sourceN>
--create <tarfile> <source1> ... <sourceN>

Создать tar-архив из исходных файлов.

-e <tarfile> [<output_dir>]
--extract <tarfile> [<output_dir>]

Извлечь tar-архив в текущий каталог, если output_dir не указан.

-t <tarfile>
--test <tarfile>

Проверить, является ли tar-архив допустимым.

-v, --verbose

Подробный вывод.

--filter <filtername>

Задаёт фильтр для --extract. Подробности см. в разделе Фильтры извлечения. Допускаются только строковые имена (то есть fully_trusted, tar и data).

Примеры

Примеры чтения

Как извлечь весь tar-архив в текущий рабочий каталог:

import tarfile
tar = tarfile.open("sample.tar.gz")
tar.extractall(filter='data')
tar.close()

Как извлечь часть tar-архива с помощью TarFile.extractall(), используя функцию-генератор вместо списка:

import os
import tarfile

def py_files(members):
    for tarinfo in members:
        if os.path.splitext(tarinfo.name)[1] == ".py":
            yield tarinfo

tar = tarfile.open("sample.tar.gz")
tar.extractall(members=py_files(tar))
tar.close()

Как прочитать tar-архив, сжатый с помощью gzip, и вывести сведения о некоторых его элементах:

import tarfile
tar = tarfile.open("sample.tar.gz", "r:gz")
for tarinfo in tar:
    print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="")
    if tarinfo.isreg():
        print("a regular file.")
    elif tarinfo.isdir():
        print("a directory.")
    else:
        print("something else.")
tar.close()

Примеры записи

Как создать несжатый tar-архив из списка имён файлов:

import tarfile
tar = tarfile.open("sample.tar", "w")
for name in ["foo", "bar", "quux"]:
    tar.add(name)
tar.close()

Тот же пример с использованием инструкции with:

import tarfile
with tarfile.open("sample.tar", "w") as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

Как создать архив и записать его в stdout, используя sys.stdout.buffer в параметре fileobj метода TarFile.add():

import sys
import tarfile
with tarfile.open("sample.tar.gz", "w|gz", fileobj=sys.stdout.buffer) as tar:
    for name in ["foo", "bar", "quux"]:
        tar.add(name)

Как создать архив и сбросить сведения о пользователе, используя параметр filter метода TarFile.add():

import tarfile
def reset(tarinfo):
    tarinfo.uid = tarinfo.gid = 0
    tarinfo.uname = tarinfo.gname = "root"
    return tarinfo
tar = tarfile.open("sample.tar.gz", "w:gz")
tar.add("foo", filter=reset)
tar.close()

Поддерживаемые форматы tar

Модуль tarfile позволяет создавать tar-архивы в трёх форматах:

  • Формат POSIX.1-1988 ustar (USTAR_FORMAT). Он поддерживает имена файлов длиной до 256 символов и имена ссылок длиной до 100 символов. Максимальный размер файла — 8 ГиБ. Это старый и ограниченный, но широко поддерживаемый формат.
  • Формат GNU tar (GNU_FORMAT). Он поддерживает длинные имена файлов и ссылок, файлы размером более 8 ГиБ и разреженные файлы. Это фактический стандарт в системах GNU/Linux. tarfile полностью поддерживает расширения GNU tar для длинных имён; поддержка разреженных файлов доступна только для чтения.
  • Формат POSIX.1-2001 pax (PAX_FORMAT). Это наиболее гибкий формат, практически не имеющий ограничений. Он поддерживает длинные имена файлов и ссылок, большие файлы и хранит пути в переносимом виде. Современные реализации tar, включая GNU tar, bsdtar/libarchive и star, полностью поддерживают расширенные возможности pax; некоторые старые или неподдерживаемые библиотеки могут их не поддерживать, но должны обрабатывать архивы pax так, как если бы они были в повсеместно поддерживаемом формате ustar. Это текущий формат по умолчанию для новых архивов.

    Он расширяет существующий формат ustar, добавляя дополнительные заголовки для информации, которую иначе сохранить невозможно. Существует два типа заголовков pax: расширенные заголовки влияют только на следующий заголовок файла, а глобальные заголовки действуют для всего архива и влияют на все последующие файлы. Для обеспечения переносимости все данные в заголовке pax кодируются в UTF-8.

Существуют и другие варианты формата tar, которые можно читать, но нельзя создавать:

  • Старинный формат V7. Это первый формат tar из Unix Seventh Edition, поддерживающий только обычные файлы и каталоги. Длина имён не должна превышать 100 символов; сведения об имени пользователя/группы отсутствуют. В некоторых архивах контрольные суммы заголовков вычислены неверно, если поля содержат символы, не относящиеся к ASCII.
  • Расширенный формат tar SunOS. Этот формат является вариантом формата POSIX.1-2001 pax, но несовместим с ним.

Проблемы Unicode

Изначально формат tar был разработан для создания резервных копий на ленточных накопителях, главным образом с целью сохранения сведений о файловой системе. В наши дни tar-архивы обычно используются для распространения файлов и обмена архивами по сети. Одна из проблем исходного формата (который лежит в основе всех остальных форматов) состоит в том, что в нём не предусмотрена поддержка различных кодировок символов. Например, обычный tar-архив, созданный в системе с кодировкой UTF-8, нельзя корректно прочитать в системе с кодировкой Latin-1, если он содержит символы, не относящиеся к ASCII. Текстовые метаданные (например, имена файлов, имена ссылок, имена пользователей/групп) будут отображаться некорректно. К сожалению, определить кодировку архива автоматически невозможно. Формат pax был разработан для решения этой проблемы. Он хранит метаданные, не относящиеся к ASCII, используя универсальную кодировку символов UTF-8.

Особенности преобразования символов в tarfile задаются именованными аргументами encoding и errors класса TarFile.

encoding определяет кодировку символов, используемую для метаданных в архиве. Значение по умолчанию — sys.getfilesystemencoding() или 'ascii' в качестве резервного значения. В зависимости от того, читается архив или записывается, метаданные необходимо декодировать или кодировать. Если значение encoding выбрано неправильно, это преобразование может завершиться ошибкой.

Аргумент errors определяет, как обрабатываются символы, которые невозможно преобразовать. Возможные значения перечислены в разделе Обработчики ошибок. По умолчанию используется схема 'surrogateescape', которую Python также применяет при вызовах файловой системы; см. раздел Имена файлов, аргументы командной строки и переменные окружения.

Для архивов PAX_FORMAT (формат по умолчанию) аргумент encoding обычно не нужен, поскольку все метаданные хранятся в кодировке UTF-8. Аргумент encoding используется только в редких случаях, когда декодируются двоичные заголовки pax или сохраняются строки с суррогатными символами.

© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/tarfile.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API