From 3c67c050ad35c09faa0ff4eec70045ecfe2faa61204b1d1b22f458fe70e15544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Chv=C3=A1tal?= Date: Sat, 2 Nov 2019 11:51:47 +0000 Subject: [PATCH] Accepting request 744825 from home:jayvdb:branches:devel:languages:python - Replace builtin libbrotli v0.6 with system libbrotli 1.x with patches: - merged_pr_94.patch - pr_154-brotli-v1.patch - Remove build dependency stdc++ - Remove brotli/build.py from installed package OBS-URL: https://build.opensuse.org/request/show/744825 OBS-URL: https://build.opensuse.org/package/show/devel:languages:python/python-brotlipy?expand=0&rev=10 --- merged_pr_94.patch | 126 +++++++++++++++++++++++++++++++ pr_154-brotli-v1.patch | 163 ++++++++++++++++++++++++++++++++++++++++ python-brotlipy.changes | 9 +++ python-brotlipy.spec | 20 +++-- 4 files changed, 312 insertions(+), 6 deletions(-) create mode 100644 merged_pr_94.patch create mode 100644 pr_154-brotli-v1.patch diff --git a/merged_pr_94.patch b/merged_pr_94.patch new file mode 100644 index 0000000..e62e7d0 --- /dev/null +++ b/merged_pr_94.patch @@ -0,0 +1,126 @@ +From bd202a98e44947aaed2345278955a86ca8f42f8c Mon Sep 17 00:00:00 2001 +From: Felix Yan +Date: Tue, 6 Jun 2017 19:16:36 +0800 +Subject: [PATCH] Allow to build with shared brotli + +It would be nice to allow building with shared brotli since we have one +in the repositories. This commit would not break the default +installation. +--- + .travis.yml | 8 +++++- + setup.py | 67 ++++++++++++++++++++++++--------------------- + src/brotli/build.py | 8 +++++- + 3 files changed, 50 insertions(+), 33 deletions(-) + +Index: brotlipy-0.7.0/setup.py +=================================================================== +--- brotlipy-0.7.0.orig/setup.py ++++ brotlipy-0.7.0/setup.py +@@ -1,41 +1,15 @@ + #!/usr/bin/env python ++import os + from setuptools import find_packages, setup + + long_description = ( + open("README.rst").read() + '\n\n' + open("HISTORY.rst").read() + ) + +- +-setup( +- name="brotlipy", +- version="0.7.0", +- +- description="Python binding to the Brotli library", +- long_description=long_description, +- url="https://github.com/python-hyper/brotlipy/", +- license="MIT", +- +- author="Cory Benfield", +- author_email="cory@lukasa.co.uk", +- +- setup_requires=[ +- "cffi>=1.0.0", +- ], +- install_requires=[ +- "cffi>=1.0.0", +- ], +- extras_require={ +- ':python_version == "2.7" or python_version == "3.3"': ['enum34>=1.0.4, <2'], +- }, +- +- cffi_modules=["src/brotli/build.py:ffi"], +- +- packages=find_packages('src'), +- package_dir={'': 'src'}, +- +- ext_package="brotli", +- +- libraries=[ ++libraries = [] ++USE_SHARED_BROTLI = os.environ.get("USE_SHARED_BROTLI") ++if USE_SHARED_BROTLI != "1": ++ libraries = [ + ("libbrotli", { + "include_dirs": [ + "libbrotli/include", +@@ -67,7 +41,38 @@ setup( + 'libbrotli/enc/entropy_encode.c' + ] + }), ++ ] ++ ++setup( ++ name="brotlipy", ++ version="0.7.0", ++ ++ description="Python binding to the Brotli library", ++ long_description=long_description, ++ url="https://github.com/python-hyper/brotlipy/", ++ license="MIT", ++ ++ author="Cory Benfield", ++ author_email="cory@lukasa.co.uk", ++ ++ setup_requires=[ ++ "cffi>=1.0.0", + ], ++ install_requires=[ ++ "cffi>=1.0.0", ++ ], ++ extras_require={ ++ ':python_version == "2.7" or python_version == "3.3"': ['enum34>=1.0.4, <2'], ++ }, ++ ++ cffi_modules=["src/brotli/build.py:ffi"], ++ ++ packages=find_packages('src'), ++ package_dir={'': 'src'}, ++ ++ ext_package="brotli", ++ ++ libraries=libraries, + + zip_safe=False, + +Index: brotlipy-0.7.0/src/brotli/build.py +=================================================================== +--- brotlipy-0.7.0.orig/src/brotli/build.py ++++ brotlipy-0.7.0/src/brotli/build.py +@@ -1,10 +1,16 @@ + # -*- coding: utf-8 -*- ++import os + import sys + + from cffi import FFI + ffi = FFI() + +-libraries = ['libbrotli'] ++USE_SHARED_BROTLI = os.environ.get("USE_SHARED_BROTLI") ++if USE_SHARED_BROTLI != "1": ++ libraries = ['libbrotli'] ++else: ++ libraries = ['brotlienc', 'brotlidec'] ++ + if 'win32' not in str(sys.platform).lower(): + libraries.append('stdc++') + diff --git a/pr_154-brotli-v1.patch b/pr_154-brotli-v1.patch new file mode 100644 index 0000000..46e9cab --- /dev/null +++ b/pr_154-brotli-v1.patch @@ -0,0 +1,163 @@ +commit b2c5c4a0216408a1f3c74246f2334ed35827a55d +Author: John Vandenberg +Date: Fri Nov 1 18:31:50 2019 +0700 + + Update brotli to v1.0.7 + + Removes decommissioned custom dictionary functionality + which was removed from libbrotli. + + Closes https://github.com/python-hyper/brotlipy/issues/129 + +diff --git a/src/brotli/brotli.py b/src/brotli/brotli.py +index a9cfa39..cc08000 100644 +--- a/src/brotli/brotli.py ++++ b/src/brotli/brotli.py +@@ -95,8 +95,7 @@ def compress(data, + mode=DEFAULT_MODE, + quality=lib.BROTLI_DEFAULT_QUALITY, + lgwin=lib.BROTLI_DEFAULT_WINDOW, +- lgblock=0, +- dictionary=b''): ++ lgblock=0): + """ + Compress a string using Brotli. + +@@ -142,7 +141,6 @@ def compress(data, + quality=quality, + lgwin=lgwin, + lgblock=lgblock, +- dictionary=dictionary + ) + compressed_data = compressor._compress(data, lib.BROTLI_OPERATION_FINISH) + assert lib.BrotliEncoderIsFinished(compressor._encoder) == lib.BROTLI_TRUE +@@ -242,21 +240,13 @@ class Compressor(object): + range of this value is 16 to 24. If set to 0, the value will be set + based on ``quality``. + :type lgblock: ``int`` +- +- :param dictionary: A pre-set dictionary for LZ77. Please use this with +- caution: if a dictionary is used for compression, the same dictionary +- **must** be used for decompression! +- :type dictionary: ``bytes`` + """ +- _dictionary = None +- _dictionary_size = None + + def __init__(self, + mode=DEFAULT_MODE, + quality=lib.BROTLI_DEFAULT_QUALITY, + lgwin=lib.BROTLI_DEFAULT_WINDOW, +- lgblock=0, +- dictionary=b''): ++ lgblock=0): + enc = lib.BrotliEncoderCreateInstance( + ffi.NULL, ffi.NULL, ffi.NULL + ) +@@ -271,13 +261,6 @@ class Compressor(object): + _set_parameter(enc, lib.BROTLI_PARAM_LGWIN, "lgwin", lgwin) + _set_parameter(enc, lib.BROTLI_PARAM_LGBLOCK, "lgblock", lgblock) + +- if dictionary: +- self._dictionary = ffi.new("uint8_t []", dictionary) +- self._dictionary_size = len(dictionary) +- lib.BrotliEncoderSetCustomDictionary( +- enc, self._dictionary_size, self._dictionary +- ) +- + self._encoder = enc + + def _compress(self, data, operation): +@@ -358,31 +341,12 @@ class Decompressor(object): + """ + An object that allows for streaming decompression of Brotli-compressed + data. +- +- .. versionchanged:: 0.5.0 +- Added ``dictionary`` parameter. +- +- :param dictionary: A pre-set dictionary for LZ77. Please use this with +- caution: if a dictionary is used for compression, the same dictionary +- **must** be used for decompression! +- :type dictionary: ``bytes`` + """ +- _dictionary = None +- _dictionary_size = None + +- def __init__(self, dictionary=b''): ++ def __init__(self): + dec = lib.BrotliDecoderCreateInstance(ffi.NULL, ffi.NULL, ffi.NULL) + self._decoder = ffi.gc(dec, lib.BrotliDecoderDestroyInstance) + +- if dictionary: +- self._dictionary = ffi.new("uint8_t []", dictionary) +- self._dictionary_size = len(dictionary) +- lib.BrotliDecoderSetCustomDictionary( +- self._decoder, +- self._dictionary_size, +- self._dictionary +- ) +- + def decompress(self, data): + """ + Decompress part of a complete Brotli-compressed string. +diff --git a/src/brotli/build.py b/src/brotli/build.py +index 0e1bb80..f93d312 100644 +--- a/src/brotli/build.py ++++ b/src/brotli/build.py +@@ -93,20 +93,6 @@ ffi.cdef(""" + uint8_t** next_out, + size_t* total_out); + +- /* Fills the new state with a dictionary for LZ77, warming up the +- ringbuffer, e.g. for custom static dictionaries for data formats. +- Not to be confused with the built-in transformable dictionary of Brotli. +- |size| should be less or equal to 2^24 (16MiB), otherwise the dictionary +- will be ignored. The dictionary must exist in memory until decoding is +- done and is owned by the caller. To use: +- 1) Allocate and initialize state with BrotliCreateInstance +- 2) Use BrotliSetCustomDictionary +- 3) Use BrotliDecompressStream +- 4) Clean up and free state with BrotliDestroyState +- */ +- void BrotliDecoderSetCustomDictionary( +- BrotliDecoderState* s, size_t size, const uint8_t* dict); +- + /* Returns true, if decoder has some unconsumed output. + Otherwise returns false. */ + BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s); +@@ -205,15 +191,6 @@ ffi.cdef(""" + BrotliEncoderParameter p, + uint32_t value); + +- /* Fills the new state with a dictionary for LZ77, warming up the +- ringbuffer, e.g. for custom static dictionaries for data formats. +- Not to be confused with the built-in transformable dictionary of Brotli. +- To decode, use BrotliSetCustomDictionary() of the decoder with the same +- dictionary. */ +- void BrotliEncoderSetCustomDictionary(BrotliEncoderState* state, +- size_t size, +- const uint8_t* dict); +- + /* Check if encoder is in "finished" state, i.e. no more input is + acceptable and no more output will be produced. + Works only with BrotliEncoderCompressStream workflow. +diff --git a/test/test_simple_compression.py b/test/test_simple_compression.py +index b9921eb..e189f74 100644 +--- a/test/test_simple_compression.py ++++ b/test/test_simple_compression.py +@@ -106,14 +106,6 @@ def test_compressed_data_roundtrips(s): + assert brotli.decompress(brotli.compress(s)) == s + + +-@given(binary(), binary()) +-def test_compressed_data_with_dictionaries(s, dictionary): +- d = brotli.Decompressor(dictionary) +- compressed = brotli.compress(s, dictionary=dictionary) +- uncompressed = d.decompress(compressed) +- assert uncompressed == s +- +- + @pytest.mark.parametrize( + "params", + [ diff --git a/python-brotlipy.changes b/python-brotlipy.changes index fa327a8..01f7282 100644 --- a/python-brotlipy.changes +++ b/python-brotlipy.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Fri Nov 1 11:37:53 UTC 2019 - John Vandenberg + +- Replace builtin libbrotli v0.6 with system libbrotli 1.x with patches: + - merged_pr_94.patch + - pr_154-brotli-v1.patch +- Remove build dependency stdc++ +- Remove brotli/build.py from installed package + ------------------------------------------------------------------- Fri Mar 22 12:49:36 UTC 2019 - Tomáš Chvátal diff --git a/python-brotlipy.spec b/python-brotlipy.spec index 1eaded5..74c34f4 100644 --- a/python-brotlipy.spec +++ b/python-brotlipy.spec @@ -28,13 +28,15 @@ Source0: https://pypi.io/packages/source/b/brotlipy/brotlipy-%{version}.t # Copy of https://github.com/google/brotli/tree/46c1a881b41bb638c76247558aa04b1591af3aa7/tests/testdata Source1: testdata.tgz Source2: https://raw.githubusercontent.com/python-hyper/brotlipy/master/test/conftest.py +Patch0: merged_pr_94.patch +Patch1: pr_154-brotli-v1.patch BuildRequires: %{python_module cffi >= 1.0.0} BuildRequires: %{python_module devel} BuildRequires: %{python_module hypothesis} BuildRequires: %{python_module pytest} BuildRequires: %{python_module setuptools} BuildRequires: fdupes -BuildRequires: gcc-c++ +BuildRequires: libbrotli-devel BuildRequires: python-enum34 BuildRequires: python-rpm-macros Requires: python-cffi >= 1.0.0 @@ -51,7 +53,11 @@ directly from Python code. %prep %setup -q -n brotlipy-%{version} -mv libbrotli/LICENSE LICENSE.libbrotli +%autopatch -p1 +# Remove unnecessary dependency on stdc++ +# See https://github.com/python-hyper/brotlipy/pull/151 +sed -i 's/libraries.append.*stdc++.*$/pass/' src/brotli/build.py + cp %{SOURCE2} test/ cd libbrotli mkdir -p tests @@ -60,21 +66,23 @@ tar -xzf %{SOURCE1} %build export CFLAGS="%{optflags}" -export CXXFLAGS="%{optflags}" +export USE_SHARED_BROTLI=1 %python_build %install %python_install -%python_expand %fdupes %{buildroot}%{$python_sitearch} +%{python_expand rm -f %{buildroot}%{$python_sitearch}/brotli/build.py* %{buildroot}%{$python_sitearch}/brotli/__pycache__/build.* +%fdupes %{buildroot}%{$python_sitearch} +} %check # the skipped tests are benchmarks which can be flaky in OBS %python_expand PYTHONPATH=%{buildroot}%{$python_sitearch} $python -m pytest -k 'not (test_streaming_compression or test_streaming_compression_flush)' %files %{python_files} -%license LICENSE LICENSE.libbrotli +%license LICENSE %doc README.rst %{python_sitearch}/brotli -%{python_sitearch}/brotlipy-%{version}-py%{py_ver}.egg-info +%{python_sitearch}/brotlipy-%{version}-py*.egg-info %changelog