Author: Amaury Forgeot d'Arc <amaur...@gmail.com> Branch: py3.3 Changeset: r75171:db1b4ba4d7e5 Date: 2014-12-30 19:48 +0100 http://bitbucket.org/pypy/pypy/changeset/db1b4ba4d7e5/
Log: Kill the interp-level version of the _lzma module, and import the one from lzmaffi on PyPI. diff --git a/lib_pypy/_lzma.py b/lib_pypy/_lzma.py new file mode 100644 --- /dev/null +++ b/lib_pypy/_lzma.py @@ -0,0 +1,920 @@ +# This file was copied from lzmaffi version 0.3.0. +# It is an almost exact copy of lzmaffi/_lzmamodule2.py. + +# PyPy changes: +# - added __getstate__() methods that raise TypeError on pickling. + +from cffi import FFI +import threading +import functools +import collections +import weakref +import sys +import io + +SUPPORTED_STREAM_FLAGS_VERSION = 0 + +__all__ = ['CHECK_CRC32', + 'CHECK_CRC64', + 'CHECK_ID_MAX', + 'CHECK_NONE', + 'CHECK_SHA256', + 'CHECK_UNKNOWN', + 'FILTER_ARM', + 'FILTER_ARMTHUMB', + 'FILTER_DELTA', + 'FILTER_IA64', + 'FILTER_LZMA1', + 'FILTER_LZMA2', + 'FILTER_POWERPC', + 'FILTER_SPARC', + 'FILTER_X86', + 'FORMAT_ALONE', + 'FORMAT_AUTO', + 'FORMAT_RAW', + 'FORMAT_XZ', + 'FORMAT_BLOCK', + 'LZMACompressor', + 'LZMADecompressor', + 'LZMAError', + 'MF_BT2', + 'MF_BT3', + 'MF_BT4', + 'MF_HC3', + 'MF_HC4', + 'MODE_FAST', + 'MODE_NORMAL', + 'PRESET_DEFAULT', + 'PRESET_EXTREME', + 'STREAM_HEADER_SIZE', + 'decode_block_header_size', + 'decode_stream_header', + 'decode_stream_footer', + 'decode_index', + '_decode_filter_properties', + '_encode_filter_properties', + 'is_check_supported'] + +_owns = weakref.WeakKeyDictionary() + +ffi = FFI() +ffi.cdef(""" +#define UINT64_MAX ... +#define LZMA_CONCATENATED ... +#define LZMA_CHECK_NONE ... +#define LZMA_CHECK_CRC32 ... +#define LZMA_CHECK_CRC64 ... +#define LZMA_CHECK_SHA256 ... +#define LZMA_CHECK_ID_MAX ... +#define LZMA_DELTA_TYPE_BYTE ... +#define LZMA_TELL_ANY_CHECK ... +#define LZMA_TELL_NO_CHECK ... +#define LZMA_VLI_UNKNOWN ... +#define LZMA_FILTER_LZMA1 ... +#define LZMA_FILTER_LZMA2 ... +#define LZMA_FILTER_DELTA ... +#define LZMA_FILTER_X86 ... +#define LZMA_FILTER_IA64 ... +#define LZMA_FILTER_ARM ... +#define LZMA_FILTER_ARMTHUMB ... +#define LZMA_FILTER_SPARC ... +#define LZMA_FILTER_POWERPC ... +#define LZMA_FILTERS_MAX ... +#define LZMA_STREAM_HEADER_SIZE ... +#define LZMA_MF_HC3 ... +#define LZMA_MF_HC4 ... +#define LZMA_MF_BT2 ... +#define LZMA_MF_BT3 ... +#define LZMA_MF_BT4 ... +#define LZMA_MODE_FAST ... +#define LZMA_MODE_NORMAL ... +#define LZMA_PRESET_DEFAULT ... +#define LZMA_PRESET_EXTREME ... + +enum lzma_ret { LZMA_OK, LZMA_STREAM_END, LZMA_NO_CHECK, + LZMA_UNSUPPORTED_CHECK, LZMA_GET_CHECK, + LZMA_MEM_ERROR, LZMA_MEMLIMIT_ERROR, + LZMA_FORMAT_ERROR, LZMA_OPTIONS_ERROR, + LZMA_DATA_ERROR, LZMA_BUF_ERROR, + LZMA_PROG_ERROR, ... }; + +enum lzma_action { LZMA_RUN, LZMA_FINISH, ...}; + +enum lzma_check { ... }; + +typedef uint64_t lzma_vli; + +typedef struct { + void* (*alloc)(void*, size_t, size_t); + void (*free)(void*, void*); + void* opaque; + ...; +} lzma_allocator; + +typedef struct { + const uint8_t *next_in; + size_t avail_in; + uint64_t total_in; + + uint8_t *next_out; + size_t avail_out; + uint64_t total_out; + lzma_allocator *allocator; + ...; +} lzma_stream; + +typedef struct { + int type; + uint32_t dist; + ...; +} lzma_options_delta; + +typedef struct { + uint32_t start_offset; + ...; +} lzma_options_bcj; + +typedef struct { + uint32_t dict_size; + uint32_t lc; + uint32_t lp; + uint32_t pb; + int mode; + uint32_t nice_len; + int mf; + uint32_t depth; + ...; +} lzma_options_lzma; + +typedef struct { + lzma_vli id; + void *options; + ...; +} lzma_filter; + +typedef struct { + uint32_t version; + lzma_vli backward_size; + int check; + ...; +} lzma_stream_flags; + +typedef ... lzma_index; + +typedef struct { + uint32_t version; + uint32_t header_size; + int check; + lzma_vli compressed_size; + lzma_filter* filters; + ...; +} lzma_block; + +bool lzma_check_is_supported(int check); + +// Encoder/Decoder +int lzma_auto_decoder(lzma_stream *strm, uint64_t memlimit, uint32_t flags); +int lzma_stream_decoder(lzma_stream *strm, uint64_t memlimit, uint32_t flags); +int lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit); +int lzma_raw_decoder(lzma_stream *strm, const lzma_filter *filters); +int lzma_block_decoder(lzma_stream *strm, lzma_block *block); + +int lzma_easy_encoder(lzma_stream *strm, uint32_t preset, int check); +int lzma_alone_encoder(lzma_stream *strm, lzma_options_lzma* options); +int lzma_raw_encoder(lzma_stream *strm, const lzma_filter *filters); + +int lzma_get_check(const lzma_stream *strm); + +int lzma_code(lzma_stream *strm, int action); + +void lzma_end(lzma_stream *strm); + +// Extras +int lzma_stream_header_decode(lzma_stream_flags *options, const uint8_t *in); +int lzma_stream_footer_decode(lzma_stream_flags *options, const uint8_t *in); +int lzma_stream_flags_compare(const lzma_stream_flags *a, + const lzma_stream_flags *b); + +enum lzma_index_iter_mode { LZMA_INDEX_ITER_ANY, LZMA_INDEX_ITER_STREAM, + LZMA_INDEX_ITER_BLOCK, LZMA_INDEX_ITER_NONEMPTY_BLOCK, ... }; + +// Indexes +lzma_index* lzma_index_init(lzma_allocator *al); +void lzma_index_end(lzma_index *i, lzma_allocator *al); +int lzma_index_stream_padding(lzma_index *i, lzma_vli stream_padding); +lzma_index* lzma_index_dup(const lzma_index *i, lzma_allocator *al); +int lzma_index_cat(lzma_index *dest, lzma_index *src, lzma_allocator *al); +int lzma_index_buffer_decode(lzma_index **i, uint64_t *memlimit, + lzma_allocator *allocator, const uint8_t *in, size_t *in_pos, + size_t in_size); +lzma_vli lzma_index_block_count(const lzma_index *i); +lzma_vli lzma_index_stream_size(const lzma_index *i); +lzma_vli lzma_index_uncompressed_size(const lzma_index *i); +lzma_vli lzma_index_size(const lzma_index *i); +lzma_vli lzma_index_total_size(const lzma_index *i); + +// Blocks +int lzma_block_header_decode(lzma_block *block, lzma_allocator *al, + const uint8_t *in); +int lzma_block_compressed_size(lzma_block *block, lzma_vli unpadded_size); + +typedef struct { + // cffi doesn't support partial anonymous structs + // so we write the definition in full + struct { + const lzma_stream_flags *flags; + const void *reserved_ptr1; + const void *reserved_ptr2; + const void *reserved_ptr3; + lzma_vli number; + lzma_vli block_count; + lzma_vli compressed_offset; + lzma_vli uncompressed_offset; + lzma_vli compressed_size; + lzma_vli uncompressed_size; + lzma_vli padding; + lzma_vli reserved_vli1; + lzma_vli reserved_vli2; + lzma_vli reserved_vli3; + lzma_vli reserved_vli4; + } stream; + struct { + lzma_vli number_in_file; + lzma_vli compressed_file_offset; + lzma_vli uncompressed_file_offset; + lzma_vli number_in_stream; + lzma_vli compressed_stream_offset; + lzma_vli uncompressed_stream_offset; + lzma_vli uncompressed_size; + lzma_vli unpadded_size; + lzma_vli total_size; + lzma_vli reserved_vli1; + lzma_vli reserved_vli2; + lzma_vli reserved_vli3; + lzma_vli reserved_vli4; + const void *reserved_ptr1; + const void *reserved_ptr2; + const void *reserved_ptr3; + const void *reserved_ptr4; + } block; + ...; +} lzma_index_iter; + +void lzma_index_iter_init(lzma_index_iter *iter, const lzma_index *i); +int lzma_index_iter_next(lzma_index_iter *iter, int mode); +int lzma_index_iter_locate(lzma_index_iter *iter, lzma_vli target); + +// Properties +int lzma_properties_size(uint32_t *size, const lzma_filter *filter); +int lzma_properties_encode(const lzma_filter *filter, uint8_t *props); +int lzma_properties_decode(lzma_filter *filter, lzma_allocator *allocator, + const uint8_t *props, size_t props_size); +int lzma_lzma_preset(lzma_options_lzma* options, uint32_t preset); + +// Special functions +void _pylzma_stream_init(lzma_stream *strm); +void _pylzma_block_header_size_decode(uint32_t b); + +void *malloc(size_t size); +void free(void *ptr); +void *realloc(void *ptr, size_t size); +""") + +m = ffi.verify(""" +#include <lzma.h> +#include <stdlib.h> +void _pylzma_stream_init(lzma_stream *strm) { + lzma_stream tmp = LZMA_STREAM_INIT; // macro from lzma.h + *strm = tmp; +} + +uint32_t _pylzma_block_header_size_decode(uint32_t b) { + return lzma_block_header_size_decode(b); // macro from lzma.h +} +""", + libraries=['lzma'], + include_dirs=['/opt/local/include', '/usr/local/include'], + library_dirs=['/opt/local/include', '/usr/local/include'], + ext_package='_lzmaffi_mods', + modulename='_compiled_module') + +def _new_lzma_stream(): + ret = ffi.new('lzma_stream*') + m._pylzma_stream_init(ret) + return ffi.gc(ret, m.lzma_end) + +def add_constant(c): + globals()[c] = getattr(m, 'LZMA_' + c) + +if sys.version_info >= (2,7): + def to_bytes(data): + return memoryview(data).tobytes() +else: + def to_bytes(data): + if not isinstance(data, basestring): + raise TypeError("lzma: must be str/unicode, got %s" % (type(data),)) + return bytes(data) + +if sys.version_info >= (3,0): + long = int + +for c in ['CHECK_CRC32', 'CHECK_CRC64', 'CHECK_ID_MAX', 'CHECK_NONE', 'CHECK_SHA256', 'FILTER_ARM', 'FILTER_ARMTHUMB', 'FILTER_DELTA', 'FILTER_IA64', 'FILTER_LZMA1', 'FILTER_LZMA2', 'FILTER_POWERPC', 'FILTER_SPARC', 'FILTER_X86', 'MF_BT2', 'MF_BT3', 'MF_BT4', 'MF_HC3', 'MF_HC4', 'MODE_FAST', 'MODE_NORMAL', 'PRESET_DEFAULT', 'PRESET_EXTREME', 'STREAM_HEADER_SIZE']: + add_constant(c) + +def _parse_format(format): + if isinstance(format, (int, long)): + return format + else: + raise TypeError + +CHECK_UNKNOWN = CHECK_ID_MAX + 1 +FORMAT_AUTO, FORMAT_XZ, FORMAT_ALONE, FORMAT_RAW, FORMAT_BLOCK = range(5) + +BCJ_FILTERS = (m.LZMA_FILTER_X86, + m.LZMA_FILTER_POWERPC, + m.LZMA_FILTER_IA64, + m.LZMA_FILTER_ARM, + m.LZMA_FILTER_ARMTHUMB, + m.LZMA_FILTER_SPARC) + +class LZMAError(Exception): + """Call to liblzma failed.""" + +def is_check_supported(check): + """is_check_supported(check_id) -> bool + + Test whether the given integrity check is supported. + + Always returns True for CHECK_NONE and CHECK_CRC32.""" + return bool(m.lzma_check_is_supported(check)) + +def catch_lzma_error(fun, *args): + try: + lzret = fun(*args) + except: + raise + if lzret in (m.LZMA_OK, m.LZMA_GET_CHECK, m.LZMA_NO_CHECK, m.LZMA_STREAM_END): + return lzret + elif lzret == m.LZMA_DATA_ERROR: + raise LZMAError("Corrupt input data") + elif lzret == m.LZMA_UNSUPPORTED_CHECK: + raise LZMAError("Unsupported integrity check") + elif lzret == m.LZMA_FORMAT_ERROR: + raise LZMAError("Input format not supported by decoder") + elif lzret == m.LZMA_OPTIONS_ERROR: + raise LZMAError("Invalid or unsupported options") + elif lzret == m.LZMA_BUF_ERROR: + raise LZMAError("Insufficient buffer space") + elif lzret == m.LZMA_PROG_ERROR: + raise LZMAError("Internal error") + elif lzret == m.LZMA_MEM_ERROR: + raise MemoryError + else: + raise LZMAError("Unrecognised error from liblzma: %d" % lzret) + +def parse_filter_spec_delta(id, dist=1): + ret = ffi.new('lzma_options_delta*') + ret.type = m.LZMA_DELTA_TYPE_BYTE + ret.dist = dist + return ret + +def parse_filter_spec_bcj(id, start_offset=0): + ret = ffi.new('lzma_options_bcj*') + ret.start_offset = start_offset + return ret + +def parse_filter_spec_lzma(id, preset=m.LZMA_PRESET_DEFAULT, **kwargs): + ret = ffi.new('lzma_options_lzma*') + if m.lzma_lzma_preset(ret, preset): + raise LZMAError("Invalid...") + for arg, val in kwargs.items(): + if arg in ('dict_size', 'lc', 'lp', 'pb', 'nice_len', 'depth'): + setattr(ret, arg, val) + elif arg in ('mf', 'mode'): + setattr(ret, arg, int(val)) + else: + raise ValueError("Invalid...") + return ret + +def parse_filter_spec(spec): + if not isinstance(spec, collections.Mapping): + raise TypeError("Filter...") + ret = ffi.new('lzma_filter*') + try: + ret.id = spec['id'] + except KeyError: + raise ValueError("Filter...") + if ret.id in (m.LZMA_FILTER_LZMA1, m.LZMA_FILTER_LZMA2): + try: + options = parse_filter_spec_lzma(**spec) + except TypeError: + raise ValueError("Invalid...") + elif ret.id == m.LZMA_FILTER_DELTA: + try: + options = parse_filter_spec_delta(**spec) + except TypeError: + raise ValueError("Invalid...") + elif ret.id in BCJ_FILTERS: + try: + options = parse_filter_spec_bcj(**spec) + except TypeError: + raise ValueError("Invalid...") + else: + raise ValueError("Invalid %d" % (ret.id,)) + + ret.options = options + _owns[ret] = options + return ret + +def _encode_filter_properties(filterspec): + """_encode_filter_properties(filter) -> bytes + + Return a bytes object encoding the options (properties) of the filter + specified by *filter* (a dict). + + The result does not include the filter ID itself, only the options.""" + filter = parse_filter_spec(filterspec) + size = ffi.new("uint32_t*") + catch_lzma_error(m.lzma_properties_size, size, filter) + result = ffi.new('char[]', size[0]) + catch_lzma_error(m.lzma_properties_encode, filter, result) + return ffi.buffer(result)[:] + +def parse_filter_chain_spec(filterspecs): + if len(filterspecs) > m.LZMA_FILTERS_MAX: + raise ValueError("Too...") + filters = ffi.new('lzma_filter[]', m.LZMA_FILTERS_MAX+1) + _owns[filters] = children = [] + for i in range(m.LZMA_FILTERS_MAX+1): + try: + filterspec = filterspecs[i] + except KeyError: + raise TypeError + except IndexError: + filters[i].id = m.LZMA_VLI_UNKNOWN + else: + filter = parse_filter_spec(filterspecs[i]) + children.append(filter) + filters[i].id = filter.id + filters[i].options = filter.options + return filters + +def build_filter_spec(filter): + spec = {'id': filter.id} + def add_opts(options_type, *opts): + options = ffi.cast('%s*' % (options_type,), filter.options) + for v in opts: + spec[v] = getattr(options, v) + if filter.id == m.LZMA_FILTER_LZMA1: + add_opts('lzma_options_lzma', 'lc', 'lp', 'pb', 'dict_size') + elif filter.id == m.LZMA_FILTER_LZMA2: + add_opts('lzma_options_lzma', 'dict_size') + elif filter.id == m.LZMA_FILTER_DELTA: + add_opts('lzma_options_delta', 'dist') + elif filter.id in BCJ_FILTERS: + add_opts('lzma_options_bcj', 'start_offset') + else: + raise ValueError("Invalid...") + return spec + +def _decode_filter_properties(filter_id, encoded_props): + """_decode_filter_properties(filter_id, encoded_props) -> dict + + Return a dict describing a filter with ID *filter_id*, and options + (properties) decoded from the bytes object *encoded_props*.""" + filter = ffi.new('lzma_filter*') + filter.id = filter_id + catch_lzma_error(m.lzma_properties_decode, + filter, ffi.NULL, encoded_props, len(encoded_props)) + try: + return build_filter_spec(filter) + finally: + # TODO do we need this, the only use of m.free? + m.free(filter.options) + +def _decode_stream_header_or_footer(decode_f, in_bytes): + footer_o = ffi.new('char[]', to_bytes(in_bytes)) + stream_flags = ffi.new('lzma_stream_flags*') + catch_lzma_error(decode_f, stream_flags, footer_o) + return StreamFlags(stream_flags) + +decode_stream_footer = functools.partial(_decode_stream_header_or_footer, + m.lzma_stream_footer_decode) + +decode_stream_header = functools.partial(_decode_stream_header_or_footer, + m.lzma_stream_header_decode) + +def decode_block_header_size(in_byte): + # lzma_block_header_size_decode(b) (((uint32_t)(b) + 1) * 4) + return (ord(in_byte) + 1) * 4 + +def decode_index(s, stream_padding=0): + indexp = ffi.new('lzma_index**') + memlimit = ffi.new('uint64_t*') + memlimit[0] = m.UINT64_MAX + allocator = ffi.NULL + in_buf = ffi.new('char[]', to_bytes(s)) + in_pos = ffi.new('size_t*') + in_pos[0] = 0 + catch_lzma_error(m.lzma_index_buffer_decode, indexp, + memlimit, allocator, in_buf, in_pos, len(s)) + return Index(indexp[0], allocator, stream_padding) + +class Index(object): + def __init__(self, i, allocator, stream_padding=0): + self.i = i + self.allocator = allocator + m.lzma_index_stream_padding(i, stream_padding) + + @property + def uncompressed_size(self): + return m.lzma_index_uncompressed_size(self.i) + + @property + def block_count(self): + return m.lzma_index_block_count(self.i) + + @property + def index_size(self): + return m.lzma_index_size(self.i) + + @property + def blocks_size(self): + return m.lzma_index_total_size(self.i) + + def __iter__(self): + return self.iterator() + + def iterator(self, type=m.LZMA_INDEX_ITER_BLOCK): + iterator = ffi.new('lzma_index_iter*') + m.lzma_index_iter_init(iterator, self.i) + while not m.lzma_index_iter_next(iterator, type): + yield (IndexStreamData(iterator.stream), IndexBlockData(iterator.block)) + + def find(self, offset): + iterator = ffi.new('lzma_index_iter*') + m.lzma_index_iter_init(iterator, self.i) + if m.lzma_index_iter_locate(iterator, offset): + # offset too high + return None + return (IndexStreamData(iterator.stream), IndexBlockData(iterator.block)) + + def __del__(self): + m.lzma_index_end(self.i, self.allocator) + + def copy(self): + new_i = m.lzma_index_dup(self.i, self.allocator) + return Index(new_i, self.allocator) + + deepcopy = copy + + def append(self, other_index): + # m.lzma_index_cat frees its second parameter so we + # must copy it first + other_index_i = m.lzma_index_dup(other_index.i, self.allocator) + catch_lzma_error(m.lzma_index_cat, self.i, + other_index_i, self.allocator) + +class _StructToPy(object): + __slots__ = () + def __init__(self, struct_obj): + # TODO make PyPy-fast + for attr in self.__slots__: + setattr(self, attr, getattr(struct_obj, attr)) + def __repr__(self): + descriptions = ('%s=%r' % (attr, getattr(self, attr)) for attr in self.__slots__) + return "<%s %s>" % (type(self).__name__, ' '.join(descriptions)) + +class IndexStreamData(_StructToPy): + __slots__ = ('number', 'block_count', 'compressed_offset', 'uncompressed_offset', + 'compressed_size', 'uncompressed_size') + +class IndexBlockData(_StructToPy): + __slots__ = ('number_in_file', 'compressed_file_offset', 'uncompressed_file_offset', + 'compressed_stream_offset', 'uncompressed_stream_offset', + 'uncompressed_size', 'unpadded_size', 'total_size') + +class StreamFlags(object): + def __init__(self, i): + self.i = i + + version = property(lambda self: self.i.version) + check = property(lambda self: self.i.check) + backward_size = property(lambda self: self.i.backward_size) + + @property + def supported(self): + return self.version > SUPPORTED_STREAM_FLAGS_VERSION + + def check_supported(self): + if not self.supported: + raise LZMAError("Stream is too new for liblzma version") + + def matches(self, other): + return m.lzma_stream_flags_compare(self.i, other.i) == m.LZMA_OK + + def copy(self): + other_i = ffi.new('lzma_stream_flags*', self.i) + return StreamFlags(other_i) + +class Allocator(object): + def __init__(self): + self.owns = {} + self.lzma_allocator = ffi.new('lzma_allocator*') + alloc = self.owns['a'] = ffi.callback("void*(void*, size_t, size_t)", self.__alloc) + free = self.owns['b'] = ffi.callback("void(void*, void*)", self.__free) + self.lzma_allocator.alloc = alloc + self.lzma_allocator.free = free + self.lzma_allocator.opaque = ffi.NULL + def __alloc(self, _opaque, _nmemb, size): + new_mem = ffi.new('char[]', size) + self.owns[self._addr(new_mem)] = new_mem + return new_mem + def _addr(self, ptr): + return long(ffi.cast('uintptr_t', ptr)) + def __free(self, _opaque, ptr): + if self._addr(ptr) == 0: return + del self.owns[self._addr(ptr)] + +class LZMADecompressor(object): + """ + LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None) + + Create a decompressor object for decompressing data incrementally. + + format specifies the container format of the input stream. If this is + FORMAT_AUTO (the default), the decompressor will automatically detect + whether the input is FORMAT_XZ or FORMAT_ALONE. Streams created with + FORMAT_RAW cannot be autodetected. + + memlimit can be specified to limit the amount of memory used by the + decompressor. This will cause decompression to fail if the input + cannot be decompressed within the given limit. + + filters specifies a custom filter chain. This argument is required for + FORMAT_RAW, and not accepted with any other format. When provided, + this should be a sequence of dicts, each indicating the ID and options + for a single filter. + + For one-shot decompression, use the decompress() function instead. + """ + def __init__(self, format=FORMAT_AUTO, memlimit=None, filters=None, header=None, check=None, unpadded_size=None): + decoder_flags = m.LZMA_TELL_ANY_CHECK | m.LZMA_TELL_NO_CHECK + #decoder_flags = 0 + if memlimit is not None: + if format == FORMAT_RAW: + raise ValueError("Cannot sp...") + #memlimit = long(memlimit) + else: + memlimit = m.UINT64_MAX + + if format == FORMAT_RAW and filters is None: + raise ValueError("Must...") + elif format != FORMAT_RAW and filters is not None: + raise ValueError("Cannot...") + + if format == FORMAT_BLOCK and (header is None or unpadded_size is None or check is None): + raise ValueError("Must...") + elif format != FORMAT_BLOCK and (header is not None or unpadded_size is not None or check is not None): + raise ValueError("Cannot...") + + format = _parse_format(format) + self.lock = threading.Lock() + self.check = CHECK_UNKNOWN + self.unused_data = b'' + self.eof = False + self.lzs = _new_lzma_stream() + self._bufsiz = max(8192, io.DEFAULT_BUFFER_SIZE) + + if format == FORMAT_AUTO: + catch_lzma_error(m.lzma_auto_decoder, self.lzs, memlimit, decoder_flags) + elif format == FORMAT_XZ: + catch_lzma_error(m.lzma_stream_decoder, self.lzs, memlimit, decoder_flags) + elif format == FORMAT_ALONE: + self.check = CHECK_NONE + catch_lzma_error(m.lzma_alone_decoder, self.lzs, memlimit) + elif format == FORMAT_RAW: + self.check = CHECK_NONE + filters = parse_filter_chain_spec(filters) + catch_lzma_error(m.lzma_raw_decoder, self.lzs, + filters) + elif format == FORMAT_BLOCK: + self.__block = block = ffi.new('lzma_block*') + block.version = 0 + block.check = check + block.header_size = len(header) + block.filters = self.__filters = ffi.new('lzma_filter[]', m.LZMA_FILTERS_MAX+1) + header_b = ffi.new('char[]', to_bytes(header)) + catch_lzma_error(m.lzma_block_header_decode, block, self.lzs.allocator, header_b) + if unpadded_size is not None: + catch_lzma_error(m.lzma_block_compressed_size, block, unpadded_size) + self.expected_size = block.compressed_size + catch_lzma_error(m.lzma_block_decoder, self.lzs, block) + else: + raise ValueError("invalid...") + + def decompress(self, data): + """ + decompress(data) -> bytes + + Provide data to the decompressor object. Returns a chunk of + decompressed data if possible, or b"" otherwise. + + Attempting to decompress data after the end of the stream is + reached raises an EOFError. Any data found after the end of the + stream is ignored, and saved in the unused_data attribute. + """ + with self.lock: + if self.eof: + raise EOFError("Already...") + return self._decompress(data) + + def _decompress(self, data): + lzs = self.lzs + + # we need in_ so that lzs.next_in doesn't get garbage collected until + # in_ goes out of scope + data = to_bytes(data) + lzs.next_in = in_ = ffi.new('char[]', data) + lzs.avail_in = len(data) + + bufsiz = self._bufsiz + + lzs.next_out = orig_out = m.malloc(bufsiz) + if orig_out == ffi.NULL: + raise MemoryError + + lzs.avail_out = bufsiz + + data_size = 0 + + try: + while True: + ret = catch_lzma_error(m.lzma_code, lzs, m.LZMA_RUN) + data_size = int(ffi.cast('uintptr_t', lzs.next_out)) - int(ffi.cast('uintptr_t', orig_out)) + # data_size is the amount lzma_code has already outputted + + if ret in (m.LZMA_NO_CHECK, m.LZMA_GET_CHECK): + self.check = m.lzma_get_check(lzs) + + if ret == m.LZMA_STREAM_END: + self.eof = True + if lzs.avail_in > 0: + self.unused_data = ffi.buffer(lzs.next_in, lzs.avail_in)[:] + break + elif lzs.avail_in == 0: + # it ate everything + break + elif lzs.avail_out == 0: + # ran out of space in the output buffer, let's grow it + bufsiz += (bufsiz >> 3) + 6 + next_out = m.realloc(orig_out, bufsiz) + if next_out == ffi.NULL: + # realloc unsuccessful + m.free(orig_out) + orig_out = ffi.NULL + raise MemoryError + + orig_out = next_out + + lzs.next_out = orig_out + data_size + lzs.avail_out = bufsiz - data_size + + result = ffi.buffer(orig_out, data_size)[:] + finally: + m.free(orig_out) + + return result + + def __getstate__(self): + raise TypeError("cannot serialize '%s' object" % + self.__class__.__name__) + +class LZMACompressor(object): + """ + LZMACompressor(format=FORMAT_XZ, check=-1, preset=None, filters=None) + + Create a compressor object for compressing data incrementally. + + format specifies the container format to use for the output. This can + be FORMAT_XZ (default), FORMAT_ALONE, or FORMAT_RAW. + + check specifies the integrity check to use. For FORMAT_XZ, the default + is CHECK_CRC64. FORMAT_ALONE and FORMAT_RAW do not suport integrity + checks; for these formats, check must be omitted, or be CHECK_NONE. + + The settings used by the compressor can be specified either as a + preset compression level (with the 'preset' argument), or in detail + as a custom filter chain (with the 'filters' argument). For FORMAT_XZ + and FORMAT_ALONE, the default is to use the PRESET_DEFAULT preset + level. For FORMAT_RAW, the caller must always specify a filter chain; + the raw compressor does not support preset compression levels. + + preset (if provided) should be an integer in the range 0-9, optionally + OR-ed with the constant PRESET_EXTREME. + + filters (if provided) should be a sequence of dicts. Each dict should + have an entry for "id" indicating the ID of the filter, plus + additional entries for options to the filter. + + For one-shot compression, use the compress() function instead. + """ + def __init__(self, format=FORMAT_XZ, check=-1, preset=None, filters=None): + if format != FORMAT_XZ and check not in (-1, m.LZMA_CHECK_NONE): + raise ValueError("Integrity...") + if preset is not None and filters is not None: + raise ValueError("Cannot...") + if preset is None: + preset = m.LZMA_PRESET_DEFAULT + format = _parse_format(format) + self.lock = threading.Lock() + self.flushed = 0 + self.lzs = _new_lzma_stream() + if format == FORMAT_XZ: + if filters is None: + if check == -1: + check = m.LZMA_CHECK_CRC64 + catch_lzma_error(m.lzma_easy_encoder, self.lzs, + preset, check) + else: + filters = parse_filter_chain_spec(filters) + catch_lzma_error(m.lzma_stream_encoder, self.lzs, + filters, check) + elif format == FORMAT_ALONE: + if filters is None: + options = ffi.new('lzma_options_lzma*') + if m.lzma_lzma_preset(options, preset): + raise LZMAError("Invalid...") + catch_lzma_error(m.lzma_alone_encoder, self.lzs, + options) + else: + raise NotImplementedError + elif format == FORMAT_RAW: + if filters is None: + raise ValueError("Must...") + filters = parse_filter_chain_spec(filters) + catch_lzma_error(m.lzma_raw_encoder, self.lzs, + filters) + else: + raise ValueError("Invalid...") + + def compress(self, data): + """ + compress(data) -> bytes + + Provide data to the compressor object. Returns a chunk of + compressed data if possible, or b"" otherwise. + + When you have finished providing data to the compressor, call the + flush() method to finish the conversion process. + """ + with self.lock: + if self.flushed: + raise ValueError("Compressor...") + return self._compress(data) + + def _compress(self, data, action=m.LZMA_RUN): + # TODO use realloc like in LZMADecompressor + BUFSIZ = 8192 + + lzs = self.lzs + + lzs.next_in = input_ = ffi.new('char[]', to_bytes(data)) + lzs.avail_in = len(data) + outs = [ffi.new('char[]', BUFSIZ)] + lzs.next_out, = outs + lzs.avail_out = BUFSIZ + + siz = BUFSIZ + + while True: + next_out_pos = int(ffi.cast('intptr_t', lzs.next_out)) + ret = catch_lzma_error(m.lzma_code, lzs, action) + data_size = int(ffi.cast('intptr_t', lzs.next_out)) - next_out_pos + if (action == m.LZMA_RUN and lzs.avail_in == 0) or \ + (action == m.LZMA_FINISH and ret == m.LZMA_STREAM_END): + break + elif lzs.avail_out == 0: + # ran out of space in the output buffer + #siz = (BUFSIZ << 1) + 6 + siz = 512 + outs.append(ffi.new('char[]', siz)) + lzs.next_out = outs[-1] + lzs.avail_out = siz + last_out = outs.pop() + last_out_len = siz - lzs.avail_out + last_out_piece = ffi.buffer(last_out[0:last_out_len], last_out_len)[:] + + return b''.join(ffi.buffer(nn)[:] for nn in outs) + last_out_piece + + def flush(self): + with self.lock: + if self.flushed: + raise ValueError("Repeated...") + self.flushed = 1 + return self._compress(b'', action=m.LZMA_FINISH) + + def __getstate__(self): + raise TypeError("cannot serialize '%s' object" % + self.__class__.__name__) + diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -37,7 +37,7 @@ "binascii", "_multiprocessing", '_warnings', "_collections", "_multibytecodec", "_continuation", "_cffi_backend", "_csv", "_pypyjson", "_posixsubprocess", # "cppyy", "micronumpy" - "faulthandler", "_lzma", + "faulthandler", ]) translation_modules = default_modules.copy() diff --git a/pypy/doc/config/objspace.usemodules._lzma.txt b/pypy/doc/config/objspace.usemodules._lzma.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.usemodules._lzma.txt +++ /dev/null @@ -1,2 +0,0 @@ -Use the '_lzma' module. -This module is expected to be working and is included by default. diff --git a/pypy/module/_lzma/__init__.py b/pypy/module/_lzma/__init__.py deleted file mode 100644 --- a/pypy/module/_lzma/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -from pypy.interpreter.mixedmodule import MixedModule - -class Module(MixedModule): - # The private part of the lzma module. - - applevel_name = '_lzma' - - interpleveldefs = { - 'LZMACompressor': 'interp_lzma.W_LZMACompressor', - 'LZMADecompressor': 'interp_lzma.W_LZMADecompressor', - 'LZMAError': 'interp_lzma.W_LZMAError', - '_encode_filter_properties': 'interp_lzma.encode_filter_properties', - '_decode_filter_properties': 'interp_lzma.decode_filter_properties', - } - - for name in 'AUTO XZ ALONE RAW'.split(): - interpleveldefs['FORMAT_%s' % name] = ( - 'space.wrap(interp_lzma.FORMAT_%s)' % name) - for name in 'DEFAULT EXTREME'.split(): - interpleveldefs['PRESET_%s' % name] = ( - 'space.wrap(interp_lzma.LZMA_PRESET_%s)' % name) - for name in 'LZMA1 LZMA2 DELTA X86 IA64 ARM ARMTHUMB SPARC POWERPC'.split(): - interpleveldefs['FILTER_%s' % name] = ( - 'space.wrap(interp_lzma.LZMA_FILTER_%s)' % name) - - appleveldefs = { - } diff --git a/pypy/module/_lzma/interp_lzma.py b/pypy/module/_lzma/interp_lzma.py deleted file mode 100644 --- a/pypy/module/_lzma/interp_lzma.py +++ /dev/null @@ -1,371 +0,0 @@ -from pypy.interpreter.baseobjspace import W_Root -from pypy.interpreter.typedef import ( - TypeDef, interp_attrproperty_bytes, interp_attrproperty) -from pypy.interpreter.error import oefmt -from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault -from pypy.module.exceptions.interp_exceptions import _new_exception, W_Exception -from pypy.module.thread.os_lock import Lock -from rpython.rlib.objectmodel import specialize -from rpython.rlib.rarithmetic import LONGLONG_MASK, r_ulonglong -from rpython.rtyper.tool import rffi_platform as platform -from rpython.rtyper.lltypesystem import rffi -from rpython.rtyper.lltypesystem import lltype -from rpython.translator.tool.cbuild import ExternalCompilationInfo - - -FORMAT_AUTO, FORMAT_XZ, FORMAT_ALONE, FORMAT_RAW = range(4) -R_LONGLONG_MASK = r_ulonglong(LONGLONG_MASK) - - -eci = ExternalCompilationInfo( - includes = ['lzma.h'], - libraries = ['lzma'], - ) -eci = platform.configure_external_library( - 'lzma', eci, - [dict(prefix='lzma-')]) -if not eci: - raise ImportError("Could not find lzma library") - - -class CConfig: - _compilation_info_ = eci - calling_conv = 'c' - - BUFSIZ = platform.ConstantInteger("BUFSIZ") - - lzma_stream = platform.Struct( - 'lzma_stream', - [('next_in', rffi.CCHARP), - ('avail_in', rffi.UINT), - ('total_in', rffi.UINT), - ('next_out', rffi.CCHARP), - ('avail_out', rffi.UINT), - ('total_out', rffi.UINT), - ]) - - lzma_options_lzma = platform.Struct( - 'lzma_options_lzma', - []) - -constant_names = ''' - LZMA_RUN LZMA_FINISH - LZMA_OK LZMA_GET_CHECK LZMA_NO_CHECK LZMA_STREAM_END - LZMA_PRESET_DEFAULT - LZMA_CHECK_ID_MAX - LZMA_TELL_ANY_CHECK LZMA_TELL_NO_CHECK - LZMA_FILTER_LZMA1 LZMA_FILTER_LZMA2 LZMA_FILTER_DELTA - LZMA_FILTER_IA64 LZMA_FILTER_X86 LZMA_FILTER_ARM LZMA_FILTER_ARMTHUMB - LZMA_FILTER_SPARC LZMA_FILTER_POWERPC - LZMA_PRESET_DEFAULT LZMA_PRESET_EXTREME - '''.split() -for name in constant_names: - setattr(CConfig, name, platform.ConstantInteger(name)) - -class cConfig(object): - pass -for k, v in platform.configure(CConfig).items(): - setattr(cConfig, k, v) - -for name in constant_names: - globals()[name] = getattr(cConfig, name) -lzma_stream = lltype.Ptr(cConfig.lzma_stream) -lzma_options_lzma = lltype.Ptr(cConfig.lzma_options_lzma) -BUFSIZ = cConfig.BUFSIZ -LZMA_CHECK_UNKNOWN = LZMA_CHECK_ID_MAX + 1 - -def external(name, args, result, **kwds): - return rffi.llexternal(name, args, result, compilation_info= - CConfig._compilation_info_, **kwds) - -lzma_ret = rffi.INT -lzma_action = rffi.INT -lzma_bool = rffi.INT - -lzma_lzma_preset = external('lzma_lzma_preset', [lzma_options_lzma, rffi.UINT], lzma_bool) -lzma_alone_encoder = external('lzma_alone_encoder', [lzma_stream, lzma_options_lzma], lzma_ret) -lzma_end = external('lzma_end', [lzma_stream], lltype.Void, releasegil=False) - -lzma_auto_decoder = external('lzma_auto_decoder', [lzma_stream, rffi.LONG, rffi.INT], lzma_ret) -lzma_get_check = external('lzma_get_check', [lzma_stream], rffi.INT) - -lzma_code = external('lzma_code', [lzma_stream, lzma_action], rffi.INT) - - -@specialize.arg(1) -def raise_error(space, fmt, *args): - raise oefmt(space.w_RuntimeError, fmt, *args) - - -def _catch_lzma_error(space, lzret): - if (lzret == LZMA_OK or lzret == LZMA_GET_CHECK or - lzret == LZMA_NO_CHECK or lzret == LZMA_STREAM_END): - return - raise raise_error(space, "Unrecognized error from liblzma: %d", lzret) - - -if BUFSIZ < 8192: - SMALLCHUNK = 8192 -else: - SMALLCHUNK = BUFSIZ -if rffi.sizeof(rffi.INT) > 4: - BIGCHUNK = 512 * 32 -else: - BIGCHUNK = 512 * 1024 - - -def _new_buffer_size(current_size): - # keep doubling until we reach BIGCHUNK; then the buffer size is no - # longer increased - if current_size < BIGCHUNK: - return current_size + current_size - return current_size - - -class OutBuffer(object): - """Handler for the output buffer. A bit custom code trying to - encapsulate the logic of setting up the fields of 'lzs' and - allocating raw memory as needed. - """ - def __init__(self, lzs, initial_size=SMALLCHUNK): - # when the constructor is called, allocate a piece of memory - # of length 'piece_size' and make lzs ready to dump there. - self.temp = [] - self.lzs = lzs - self._allocate_chunk(initial_size) - - def _allocate_chunk(self, size): - self.raw_buf, self.gc_buf, self.case_num = rffi.alloc_buffer(size) - self.current_size = size - self.lzs.c_next_out = self.raw_buf - rffi.setintfield(self.lzs, 'c_avail_out', size) - - def _get_chunk(self, chunksize): - assert 0 <= chunksize <= self.current_size - raw_buf = self.raw_buf - gc_buf = self.gc_buf - case_num = self.case_num - s = rffi.str_from_buffer(raw_buf, gc_buf, case_num, - self.current_size, chunksize) - rffi.keep_buffer_alive_until_here(raw_buf, gc_buf, case_num) - self.current_size = 0 - return s - - def prepare_next_chunk(self): - size = self.current_size - self.temp.append(self._get_chunk(size)) - self._allocate_chunk(_new_buffer_size(size)) - - def make_result_string(self): - count_unoccupied = rffi.getintfield(self.lzs, 'c_avail_out') - s = self._get_chunk(self.current_size - count_unoccupied) - if self.temp: - self.temp.append(s) - return ''.join(self.temp) - else: - return s - - def free(self): - if self.current_size > 0: - rffi.keep_buffer_alive_until_here(self.raw_buf, self.gc_buf, - self.case_num) - - def __enter__(self): - return self - def __exit__(self, *args): - self.free() - - -class W_LZMACompressor(W_Root): - def __init__(self, space, format): - self.format = format - self.lock = Lock(space) - self.flushed = False - self.lzs = lltype.malloc(lzma_stream.TO, flavor='raw', zero=True) - - def __del__(self): - lzma_end(self.lzs) - lltype.free(self.lzs, flavor='raw') - - def _init_alone(self, space, preset, w_filters): - if space.is_none(w_filters): - with lltype.scoped_alloc(lzma_options_lzma.TO) as options: - if lzma_lzma_preset(options, preset): - raise_error(space, "Invalid compression preset: %d", preset) - lzret = lzma_alone_encoder(self.lzs, options) - else: - raise oefmt(space.w_NotImplementedError, "Filter specs") - _catch_lzma_error(space, lzret) - - @staticmethod - @unwrap_spec(format=int, - w_check=WrappedDefault(None), - w_preset=WrappedDefault(None), - w_filters=WrappedDefault(None)) - def descr_new_comp(space, w_subtype, format=FORMAT_XZ, - w_check=None, w_preset=None, w_filters=None): - w_self = space.allocate_instance(W_LZMACompressor, w_subtype) - self = space.interp_w(W_LZMACompressor, w_self) - W_LZMACompressor.__init__(self, space, format) - - if space.is_none(w_preset): - preset = LZMA_PRESET_DEFAULT - else: - preset = space.int_w(w_preset) - - if format == FORMAT_ALONE: - self._init_alone(space, preset, w_filters) - else: - raise oefmt(space.w_NotImplementedError, "Format %d", format) - - return w_self - - @unwrap_spec(data='bufferstr') - def compress_w(self, space, data): - with self.lock: - if self.flushed: - raise oefmt(space.w_ValueError, "Compressor has been flushed") - result = self._compress(space, data, LZMA_RUN) - return space.wrapbytes(result) - - def flush_w(self, space): - with self.lock: - if self.flushed: - raise oefmt(space.w_ValueError, "Repeated call to flush()") - result = self._compress(space, "", LZMA_FINISH) - return space.wrapbytes(result) - - def _compress(self, space, data, action): - datasize = len(data) - with lltype.scoped_alloc(rffi.CCHARP.TO, datasize) as in_buf: - for i in range(datasize): - in_buf[i] = data[i] - - with OutBuffer(self.lzs) as out: - self.lzs.c_next_in = in_buf - rffi.setintfield(self.lzs, 'c_avail_in', datasize) - - while True: - lzret = lzma_code(self.lzs, action) - _catch_lzma_error(space, lzret) - - if (action == LZMA_RUN and - rffi.getintfield(self.lzs, 'c_avail_in') == 0): - break - if action == LZMA_FINISH and lzret == LZMA_STREAM_END: - break - elif rffi.getintfield(self.lzs, 'c_avail_out') == 0: - out.prepare_next_chunk() - - return out.make_result_string() - - -W_LZMACompressor.typedef = TypeDef("LZMACompressor", - __new__ = interp2app(W_LZMACompressor.descr_new_comp), - compress = interp2app(W_LZMACompressor.compress_w), - flush = interp2app(W_LZMACompressor.flush_w), -) - - -class W_LZMADecompressor(W_Root): - def __init__(self, space, format): - self.format = format - self.lock = Lock(space) - self.eof = False - self.lzs = lltype.malloc(lzma_stream.TO, flavor='raw', zero=True) - self.check = LZMA_CHECK_UNKNOWN - self.unused_data = '' - - def __del__(self): - lzma_end(self.lzs) - lltype.free(self.lzs, flavor='raw') - - @staticmethod - @unwrap_spec(format=int, - w_memlimit=WrappedDefault(None), - w_filters=WrappedDefault(None)) - def descr_new_dec(space, w_subtype, format=FORMAT_AUTO, - w_memlimit=None, w_filters=None): - w_self = space.allocate_instance(W_LZMADecompressor, w_subtype) - self = space.interp_w(W_LZMADecompressor, w_self) - W_LZMADecompressor.__init__(self, space, format) - - if space.is_none(w_memlimit): - memlimit = R_LONGLONG_MASK - else: - memlimit = space.r_ulonglong_w(w_memlimit) - - decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK - - if format == FORMAT_AUTO: - lzret = lzma_auto_decoder(self.lzs, memlimit, decoder_flags) - _catch_lzma_error(space, lzret) - else: - raise oefmt(space.w_NotImplementedError, "Format %d", format) - - return w_self - - @unwrap_spec(data='bufferstr') - def decompress_w(self, space, data): - with self.lock: - if self.eof: - raise oefmt(space.w_EOFError, "Already at end of stream") - result = self._decompress(space, data) - return space.wrapbytes(result) - - def _decompress(self, space, data): - datasize = len(data) - - with lltype.scoped_alloc(rffi.CCHARP.TO, datasize) as in_buf: - for i in range(datasize): - in_buf[i] = data[i] - - with OutBuffer(self.lzs) as out: - self.lzs.c_next_in = in_buf - rffi.setintfield(self.lzs, 'c_avail_in', datasize) - - while True: - lzret = lzma_code(self.lzs, LZMA_RUN) - _catch_lzma_error(space, lzret) - if lzret == LZMA_GET_CHECK or lzret == LZMA_NO_CHECK: - self.check = lzma_get_check(self.lzs) - if lzret == LZMA_STREAM_END: - self.eof = True - if rffi.getintfield(self.lzs, 'c_avail_in') > 0: - unused = [self.lzs.c_next_in[i] - for i in range( - rffi.getintfield(self.lzs, - 'c_avail_in'))] - self.unused_data = "".join(unused) - break - if rffi.getintfield(self.lzs, 'c_avail_in') == 0: - break - elif rffi.getintfield(self.lzs, 'c_avail_out') == 0: - out.prepare_next_chunk() - - return out.make_result_string() - - -W_LZMADecompressor.typedef = TypeDef("LZMADecompressor", - __new__ = interp2app(W_LZMADecompressor.descr_new_dec), - decompress = interp2app(W_LZMADecompressor.decompress_w), - eof = interp_attrproperty("eof", W_LZMADecompressor), - unused_data = interp_attrproperty_bytes("unused_data", W_LZMADecompressor), -) - - -W_LZMAError = _new_exception('LZMAError', W_Exception, 'Call to liblzma failed.') - - -def encode_filter_properties(space, w_filter): - """Return a bytes object encoding the options (properties) of the filter - specified by *filter* (a dict). - - The result does not include the filter ID itself, only the options. - """ - -def decode_filter_properties(space, w_filter_id, w_encoded_props): - """Return a dict describing a filter with ID *filter_id*, and options - (properties) decoded from the bytes object *encoded_props*. - """ - diff --git a/pypy/module/_lzma/test/test_lzma.py b/pypy/module/_lzma/test/test_lzma.py deleted file mode 100644 --- a/pypy/module/_lzma/test/test_lzma.py +++ /dev/null @@ -1,30 +0,0 @@ -class AppTestBZ2File: - spaceconfig = { - "usemodules": ["_lzma"] - } - - def test_module(self): - import lzma - - def test_simple_compress(self): - import lzma - compressed = lzma.compress(b'Insert Data Here', format=lzma.FORMAT_ALONE) - assert compressed == (b']\x00\x00\x80\x00\xff\xff\xff\xff\xff' - b'\xff\xff\xff\x00$\x9b\x8afg\x91' - b'(\xcb\xde\xfa\x03\r\x1eQT\xbe' - b't\x9e\xdfI]\xff\xf4\x9d\x80\x00') - decompressed = lzma.decompress(compressed) - assert decompressed == b'Insert Data Here' - - def test_exceptions(self): - import _lzma - import lzma - - assert hasattr(_lzma, 'LZMAError') - assert hasattr(lzma, 'LZMAError') - - assert _lzma.LZMAError is lzma.LZMAError - assert _lzma.LZMAError.__doc__ == 'Call to liblzma failed.' - - exc = raises(_lzma.LZMAError, 'raise _lzma.LZMAError') - exc = raises(_lzma.LZMAError, 'raise _lzma.LZMAError("bad thing")') diff --git a/pypy/module/_lzma/test/test_ztranslation.py b/pypy/module/_lzma/test/test_ztranslation.py deleted file mode 100644 --- a/pypy/module/_lzma/test/test_ztranslation.py +++ /dev/null @@ -1,4 +0,0 @@ -from pypy.objspace.fake.checkmodule import checkmodule - -def test_lzma_translates(): - checkmodule('_lzma') _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit