Hello community,

here is the log from the commit of package python-hiredis for openSUSE:Factory 
checked in at 2019-08-27 10:27:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-hiredis (Old)
 and      /work/SRC/openSUSE:Factory/.python-hiredis.new.7948 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-hiredis"

Tue Aug 27 10:27:21 2019 rev:2 rq:726269 version:1.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-hiredis/python-hiredis.changes    
2018-08-31 10:46:44.611369390 +0200
+++ /work/SRC/openSUSE:Factory/.python-hiredis.new.7948/python-hiredis.changes  
2019-08-27 10:27:22.971914451 +0200
@@ -1,0 +2,16 @@
+Mon Aug 26 11:43:18 UTC 2019 - Marketa Calabkova <mcalabk...@suse.com>
+
+- Update to 1.0.0
+  * (BREAKING CHANGE) Add ability to control how unicode decoding 
+    errors are handled
+  * Removed support for EOL Python 2.6, 3.2, and 3.3.
+  * Upgrade hiredis to 0.13.3
+  * Fix non-utf8 reply parsing causing segmentation fault in Python 3
+  * Expose len method to retrieve the buffer length
+  * Fix crash when custom exception raise error (on init)
+  * Sort list of source files to allow reproducible building
+- Drop obsolete patch reproducible-build.patch
+- Added patch drop-vendor-sources.patch
+  * the vendor directory appears empty
+
+-------------------------------------------------------------------

Old:
----
  reproducible-build.patch
  v0.2.0.tar.gz

New:
----
  drop-vendor-sources.patch
  v1.0.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-hiredis.spec ++++++
--- /var/tmp/diff_new_pack.egE8u9/_old  2019-08-27 10:27:24.375914346 +0200
+++ /var/tmp/diff_new_pack.egE8u9/_new  2019-08-27 10:27:24.379914347 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-hiredis
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,13 +12,13 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-hiredis
-Version:        0.2.0
+Version:        1.0.0
 Release:        0
 Summary:        Python wrapper for hiredis
 License:        BSD-3-Clause
@@ -26,12 +26,12 @@
 URL:            https://github.com/redis/hiredis-py
 Source:         https://github.com/redis/hiredis-py/archive/v%{version}.tar.gz
 Patch0:         0001-Use-system-libhiredis.patch
-Patch1:         reproducible-build.patch
-Patch2:         fix_build_dir_in_tests.patch
+Patch1:         fix_build_dir_in_tests.patch
+Patch2:         drop-vendor-sources.patch
 BuildRequires:  %{python_module devel}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
-BuildRequires:  hiredis-devel
+BuildRequires:  hiredis-devel >= 0.13.3
 BuildRequires:  python-rpm-macros
 %python_subpackages
 

++++++ 0001-Use-system-libhiredis.patch ++++++
--- /var/tmp/diff_new_pack.egE8u9/_old  2019-08-27 10:27:24.391914346 +0200
+++ /var/tmp/diff_new_pack.egE8u9/_new  2019-08-27 10:27:24.391914346 +0200
@@ -12,33 +12,17 @@
  setup.py | 9 ++++++---
  1 file changed, 6 insertions(+), 3 deletions(-)
 
-diff --git a/setup.py b/setup.py
-index 9eab077..ed74eb8 100755
---- a/setup.py
-+++ b/setup.py
-@@ -45,7 +45,8 @@ lib = ("hiredis_for_hiredis_py", {
- 
+Index: hiredis-py-1.0.0/setup.py
+===================================================================
+--- hiredis-py-1.0.0.orig/setup.py
++++ hiredis-py-1.0.0/setup.py
+@@ -13,7 +13,8 @@ def version():
  ext = Extension("hiredis.hiredis",
-   sources=glob.glob("src/*.c"),
+   sources=sorted(glob.glob("src/*.c") +
+                  ["vendor/hiredis/%s.c" % src for src in ("read", "sds")]),
 -  include_dirs=["vendor"])
 +  include_dirs=["vendor"],
 +  extra_link_args=["-lhiredis"])
  
  setup(
    name="hiredis",
-@@ -57,11 +58,13 @@ setup(
-   keywords=["Redis"],
-   license="BSD",
-   packages=["hiredis"],
--  libraries=[lib],
-+  # Disabled in Debian, we use the system hiredis library
-+  # libraries=[lib],
-   ext_modules=[ext],
- 
-   # Override "install_lib" command
--  cmdclass={ "install_lib": install_lib },
-+  # Debian: disable and link against the system hiredis library
-+  # cmdclass={ "install_lib": install_lib },
- 
-   classifiers=[
-     'Development Status :: 5 - Production/Stable',

++++++ drop-vendor-sources.patch ++++++
Index: hiredis-py-1.0.0/setup.py
===================================================================
--- hiredis-py-1.0.0.orig/setup.py
+++ hiredis-py-1.0.0/setup.py
@@ -11,8 +11,7 @@ def version():
   return module.__version__
 
 ext = Extension("hiredis.hiredis",
-  sources=sorted(glob.glob("src/*.c") +
-                 ["vendor/hiredis/%s.c" % src for src in ("read", "sds")]),
+  sources=sorted(glob.glob("src/*.c")),
   include_dirs=["vendor"],
   extra_link_args=["-lhiredis"])
 
++++++ v0.2.0.tar.gz -> v1.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/.travis.yml 
new/hiredis-py-1.0.0/.travis.yml
--- old/hiredis-py-0.2.0/.travis.yml    2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/.travis.yml    2019-01-20 08:39:27.000000000 +0100
@@ -1,12 +1,83 @@
+sudo: false
 language: python
+dist: trusty
 
-python:
-  - "2.6"
-  - "2.7"
-  - "3.2"
-  - "3.3"
-  - "3.4"
 
-install: "python setup.py build"
+matrix:
+  include:
+  - python: "2.7"
+  - python: "3.4"
+  - python: "3.5"
+  - python: "3.6"
+  - python: "3.7"
+    dist: xenial
+    sudo: required
+  # linux wheels
+  - dist: trusty
+    sudo: required
+    services:
+      - docker
+    env: HIREDIS_PY_BUILDWHEELS=1
+  # osx wheels
+  - os: osx
+    osx_image: xcode9.4
+    language: generic
+    env: HIREDIS_PY_BUILDWHEELS=1
+    python: "3.6"
+    before_install:
+      - SSL_CERT_FILE=$(brew --prefix)/etc/openssl/cert.pem
+      - sudo pip install -U pip setuptools twine
 
-script: "python test.py"
+branches:
+  only:
+    - staging
+    - trying
+    - master
+    - /^v.*$/
+
+install:
+  - |
+    if [ -n "${HIREDIS_PY_BUILDWHEELS:-}" ]; then
+      pip install cibuildwheel
+    else
+      python setup.py build
+    fi
+
+script:
+  - |
+    if [ -n "${HIREDIS_PY_BUILDWHEELS:-}" ]; then
+      cibuildwheel --output-dir dist
+    else
+      python test.py
+    fi
+
+before_deploy: ls dist/
+
+deploy:
+  # deploy master non-tags to Test PyPI
+  - provider: pypi
+    user: ifduyue
+    password:
+      secure: 
"Hn8n7k11TQQF2PWbx8aYhVf6j5bVh8s9/5HuA0eEW4Vl3TmBzyrh2OPKPgrlh9WLvkBUyl0SJzvqxh+SOKP3dg6XOItvZzm/ZnN77gVbrMkjpNOmfENb6Amdx7y1uDG60UFd5H35D8SoinGmW9QSyxMjB7eIH+qybGUXoSV4BaM="
+    server: https://test.pypi.org/legacy/
+    distributions: sdist
+    skip_existing: true
+    skip_cleanup: true
+    on:
+      repo: redis/hiredis-py
+      tags: false
+      branch: master
+      condition: -n "${HIREDIS_PY_BUILDWHEELS:-}"
+
+  # deploy tags to PyPI
+  - provider: pypi
+    user: ifduyue
+    password:
+      secure: 
"WgO8677gsCeftEIdozL5albCmXuVwuyHLZur6mP1cvEGDGdzatDCwZJkM1pdOCy4xXYYz3+bMsya5gLbQmGZOYBzieAb4CYR+O38Kd0mVCoZpK7TYmN55G+Tn3bztxFOBtInqd9bf1JkPE5eXN7Lc4rkMhMmafxoN8aBVPlfhRM="
+    distributions: sdist
+    skip_existing: true
+    skip_cleanup: true
+    on:
+      repo: redis/hiredis-py
+      tags: true
+      condition: -n "${HIREDIS_PY_BUILDWHEELS:-}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/CHANGELOG.md 
new/hiredis-py-1.0.0/CHANGELOG.md
--- old/hiredis-py-0.2.0/CHANGELOG.md   2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/CHANGELOG.md   2019-01-20 08:39:27.000000000 +0100
@@ -1,3 +1,24 @@
+### 1.0.0 (2019-01-20)
+
+* **(BREAKING CHANGE)** Add ability to control how unicode decoding errors are 
handled (see #82)
+* Removed support for EOL Python 2.6, 3.2, and 3.3.
+
+### 0.3.1 (2018-12-24)
+
+* Include test files in sdist tarball (see #80)
+
+### 0.3.0 (2018-11-16)
+
+* Upgrade hiredis to 0.13.3
+* Add optional "shouldDecode" argument to Reader.gets() (see #77)
+* Add a "has_data" method to Reader objects (see #78)
+* Fix non-utf8 reply parsing causing segmentation fault in Python 3 (see #73)
+* Rename `state` to `hiredis_py_module_state` to avoid conflicts (see #72)
+* Expose len method to retrieve the buffer length (see #61)
+* Fix crash when custom exception raise error (on init) (see #57)
+* incref before PyModule_AddObject which steals references (see #48)
+* Sort list of source files to allow reproducible building (see #47)
+
 ### 0.2.0 (2015-04-03)
 
 * Allow usage of setuptools
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/MANIFEST.in 
new/hiredis-py-1.0.0/MANIFEST.in
--- old/hiredis-py-0.2.0/MANIFEST.in    2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/MANIFEST.in    2019-01-20 08:39:27.000000000 +0100
@@ -1,7 +1,10 @@
 include COPYING
 include MANIFEST.in
+include README.md
 include src/*.[ch]
 include vendor/hiredis/COPYING
 include vendor/hiredis/*.[ch]
-exclude vendor/hiredis/example*
-exclude vendor/hiredis/text*
+include test.py
+graft test
+global-exclude __pycache__
+global-exclude *.py[co]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/README.md 
new/hiredis-py-1.0.0/README.md
--- old/hiredis-py-0.2.0/README.md      2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/README.md      2019-01-20 08:39:27.000000000 +0100
@@ -1,6 +1,7 @@
 # hiredis-py
 
-[![Build 
Status](https://travis-ci.org/redis/hiredis-py.svg?branch=v0.1.2)](https://travis-ci.org/redis/hiredis-py)
+[![Build 
Status](https://travis-ci.org/redis/hiredis-py.svg?branch=master)](https://travis-ci.org/redis/hiredis-py)
+[![Windows Build 
Status](https://ci.appveyor.com/api/projects/status/muso9gbe316tjsac/branch/master?svg=true)](https://ci.appveyor.com/project/duyue/hiredis-py/)
 
 Python extension that wraps protocol parsing code in [hiredis][hiredis].
 It primarily speeds up parsing of multi bulk replies.
@@ -9,19 +10,20 @@
 
 ## Install
 
-hiredis-py is available on [PyPi](http://pypi.python.org/pypi/hiredis), and
-can be installed with:
+hiredis-py is available on [PyPI](https://pypi.org/project/hiredis/), and can
+be installed with:
 
 ```
-easy_install hiredis
+pip install hiredis
 ```
 
 ### Requirements
 
-hiredis-py requires **Python 2.6 or higher**.
+hiredis-py requires **Python 2.7 or 3.4+**.
 
 Make sure Python development headers are available when installing hiredis-py.
-On Ubuntu/Debian systems, install them with `apt-get install python-dev`.
+On Ubuntu/Debian systems, install them with `apt-get install python-dev` for 
Python 2
+or `apt-get install python3-dev` for Python 3.
 
 ## Usage
 
@@ -66,16 +68,23 @@
 initializing it:
 
 ```python
->>> reader = hiredis.Reader(encoding="utf-8")
+>>> reader = hiredis.Reader(encoding="utf-8", errors="strict")
 >>> reader.feed("$3\r\n\xe2\x98\x83\r\n")
 >>> reader.gets()
 u'☃'
 ```
 
-When bulk data in a reply could not be properly decoded using the specified
-encoding, it will be returned as a plain string. When the encoding cannot be
-found, a `LookupError` will be raised after calling `gets` for the first reply
-with bulk data (identical to what Python's `unicode` method would do).
+Decoding of bulk data will be attempted using the specified encoding and
+error handler. If the error handler is `'strict'` (the default), a
+`UnicodeDecodeError` is raised when data cannot be dedcoded. This is identical
+to Python's default behavior. Other valid values to `errors` include
+`'replace'`, `'ignore'`, and `'backslashreplace'`. More information on the
+behavior of these error handlers can be found
+[here](https://docs.python.org/3/howto/unicode.html#the-string-type).
+
+
+When the specified encoding cannot be found, a `LookupError` will be raised
+when calling `gets` for the first reply with bulk data.
 
 #### Error handling
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/appveyor/run_with_env.cmd 
new/hiredis-py-1.0.0/appveyor/run_with_env.cmd
--- old/hiredis-py-0.2.0/appveyor/run_with_env.cmd      2015-04-03 
22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/appveyor/run_with_env.cmd      2019-01-20 
08:39:27.000000000 +0100
@@ -1,4 +1,7 @@
-:: To build extensions for 64 bit Python 3, we need to configure environment
+:: To build extensions for 64 bit Python 3.5 or later no special environment 
needs
+:: to be configured.
+::
+:: To build extensions for 64 bit Python 3.4 or earlier, we need to configure 
environment
 :: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
 :: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1)
 ::
@@ -15,31 +18,47 @@
 :: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
 :: http://stackoverflow.com/a/13751649/163740
 ::
-:: Author: Olivier Grisel
+:: Original Author: Olivier Grisel
 :: License: CC0 1.0 Universal: 
http://creativecommons.org/publicdomain/zero/1.0/
+:: This version based on updates for python 3.5 by Phil Elson at:
+::     https://github.com/pelson/Obvious-CI/tree/master/scripts
+
 @ECHO OFF
 
 SET COMMAND_TO_RUN=%*
 SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows
 
 SET MAJOR_PYTHON_VERSION="%PYTHON_VERSION:~0,1%"
+SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1%
 IF %MAJOR_PYTHON_VERSION% == "2" (
     SET WINDOWS_SDK_VERSION="v7.0"
+    SET SET_SDK_64=Y
 ) ELSE IF %MAJOR_PYTHON_VERSION% == "3" (
     SET WINDOWS_SDK_VERSION="v7.1"
+    IF %MINOR_PYTHON_VERSION% LEQ 4 (
+        SET SET_SDK_64=Y
+    ) ELSE (
+        SET SET_SDK_64=N
+    )
 ) ELSE (
     ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%"
     EXIT 1
 )
 
 IF "%PYTHON_ARCH%"=="64" (
-    ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python 
%MAJOR_PYTHON_VERSION% on a 64 bit architecture
-    SET DISTUTILS_USE_SDK=1
-    SET MSSdk=1
-    "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q 
-version:%WINDOWS_SDK_VERSION%
-    "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
-    ECHO Executing: %COMMAND_TO_RUN%
-    call %COMMAND_TO_RUN% || EXIT 1
+    IF %SET_SDK_64% == Y (
+        ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python 
%MAJOR_PYTHON_VERSION% on a 64 bit architecture
+        SET DISTUTILS_USE_SDK=1
+        SET MSSdk=1
+        "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q 
-version:%WINDOWS_SDK_VERSION%
+        "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release
+        ECHO Executing: %COMMAND_TO_RUN%
+        call %COMMAND_TO_RUN% || EXIT 1
+    )  ELSE (
+        ECHO Using default MSVC build environment for 64 bit architecture
+        ECHO Executing: %COMMAND_TO_RUN%
+        call %COMMAND_TO_RUN% || EXIT 1
+    )
 ) ELSE (
     ECHO Using default MSVC build environment for 32 bit architecture
     ECHO Executing: %COMMAND_TO_RUN%
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/appveyor.yml 
new/hiredis-py-1.0.0/appveyor.yml
--- old/hiredis-py-0.2.0/appveyor.yml   2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/appveyor.yml   2019-01-20 08:39:27.000000000 +0100
@@ -5,6 +5,11 @@
     # /E:ON and /V:ON options are not enabled in the batch script intepreter
     # See: http://stackoverflow.com/a/13751649/163740
     CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd"
+    PYPI_USER: ifduyue
+    PYPI_TEST_PASSWORD:
+      secure: Ub5TGKonq/xFgzRLFMCcKQ==
+    PYPI_PASSWORD:
+      secure: fFfFN5N5920gtX3+pwrOddk/psDk3wK67snCOt209bc=
 
   matrix:
     - PYTHON: "C:\\Python27"
@@ -15,14 +20,6 @@
       PYTHON_VERSION: "2.7.8"
       PYTHON_ARCH: "64"
 
-    - PYTHON: "C:\\Python33"
-      PYTHON_VERSION: "3.3.5"
-      PYTHON_ARCH: "32"
-
-    - PYTHON: "C:\\Python33-x64"
-      PYTHON_VERSION: "3.3.5"
-      PYTHON_ARCH: "64"
-
     - PYTHON: "C:\\Python34"
       PYTHON_VERSION: "3.4.1"
       PYTHON_ARCH: "32"
@@ -31,6 +28,37 @@
       PYTHON_VERSION: "3.4.1"
       PYTHON_ARCH: "64"
 
+    - PYTHON: "C:\\Python35"
+      PYTHON_VERSION: "3.5.0"
+      PYTHON_ARCH: "32"
+
+    - PYTHON: "C:\\Python35-x64"
+      PYTHON_VERSION: "3.5.0"
+      PYTHON_ARCH: "64"
+
+    - PYTHON: "C:\\Python36"
+      PYTHON_VERSION: "3.6.6"
+      PYTHON_ARCH: "32"
+
+    - PYTHON: "C:\\Python36-x64"
+      PYTHON_VERSION: "3.6.6"
+      PYTHON_ARCH: "64"
+
+    - PYTHON: "C:\\Python37"
+      PYTHON_VERSION: "3.7.0"
+      PYTHON_ARCH: "32"
+
+    - PYTHON: "C:\\Python37-x64"
+      PYTHON_VERSION: "3.7.0"
+      PYTHON_ARCH: "64"
+
+    # build wheels
+    - PYTHON: "C:\\Python36-x64"
+      PYTHON_VERSION: "3.6.6"
+      PYTHON_ARCH: "64"
+      HIREDIS_PY_BUILDWHEELS: 1
+
+
 install:
   - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
   - "python --version"
@@ -42,3 +70,32 @@
 test_script:
   - "%CMD_IN_ENV% python setup.py build"
   - "%CMD_IN_ENV% python test.py"
+  - ps: |
+      if (Test-Path env:HIREDIS_PY_BUILDWHEELS) {
+        python -m pip install -U pip setuptools cibuildwheel
+        cibuildwheel --output-dir wheels
+        ls wheels
+      }
+
+artifacts:
+  - path: wheels\*.whl
+    name: Wheels
+
+on_success:
+    # deploy master non-tags to Test PyPI
+    - ps: |
+        if (!(Test-Path env:HIREDIS_PY_BUILDWHEELS)) { return }
+        if (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) { return }
+        if ($env:APPVEYOR_REPO_NAME -ne 'redis/hiredis-py') { return }
+        if ($env:APPVEYOR_REPO_BRANCH -ne 'master') { return }
+        pip install -U twine
+        twine upload -u $env:PYPI_USER -p $env:PYPI_TEST_PASSWORD 
--repository-url https://test.pypi.org/legacy/ --skip-existing wheels\*.whl
+
+    # deploy tags to PyPI
+    - ps: |
+        if (!(Test-Path env:HIREDIS_PY_BUILDWHEELS)) { return }
+        if (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) { return }
+        if ($env:APPVEYOR_REPO_NAME -ne 'redis/hiredis-py') { return }
+        if ($env:APPVEYOR_REPO_TAG -ne 'true') { return }
+        pip install -U twine
+        twine upload -u $env:PYPI_USER -p $env:PYPI_PASSWORD --skip-existing 
wheels\*.whl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/hiredis/version.py 
new/hiredis-py-1.0.0/hiredis/version.py
--- old/hiredis-py-0.2.0/hiredis/version.py     2015-04-03 22:50:50.000000000 
+0200
+++ new/hiredis-py-1.0.0/hiredis/version.py     2019-01-20 08:39:27.000000000 
+0100
@@ -1 +1 @@
-__version__ = "0.2.0"
+__version__ = "1.0.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/setup.py 
new/hiredis-py-1.0.0/setup.py
--- old/hiredis-py-0.2.0/setup.py       2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/setup.py       2019-01-20 08:39:27.000000000 +0100
@@ -2,67 +2,33 @@
 
 try:
   from setuptools import setup, Extension
-  from setuptools.command import install_lib as _install_lib
 except ImportError:
   from distutils.core import setup, Extension
-  from distutils.command import install_lib as _install_lib
 import sys, imp, os, glob
 
 def version():
   module = imp.load_source("hiredis.version", "hiredis/version.py")
   return module.__version__
 
-# Patch "install_lib" command to run build_clib before build_ext
-# to properly work with easy_install.
-# See: http://bugs.python.org/issue5243
-class install_lib(_install_lib.install_lib):
-  def build(self):
-    if not self.skip_build:
-      if self.distribution.has_pure_modules():
-        self.run_command('build_py')
-        if self.distribution.has_c_libraries():
-          self.run_command('build_clib')
-        if self.distribution.has_ext_modules():
-          self.run_command('build_ext')
-
-# To link the extension with the C library, distutils passes the "-lLIBRARY"
-# option to the linker. This makes it go through its library search path. If it
-# finds a shared object of the specified library in one of the system-wide
-# library paths, it will dynamically link it.
-#
-# We want the linker to statically link the version of hiredis that is included
-# with hiredis-py. However, the linker may pick up the shared library version
-# of hiredis, if it is available through one of the system-wide library paths.
-# To prevent this from happening, we use an obfuscated library name such that
-# the only version the linker will be able to find is the right version.
-#
-# This is a terrible hack, but patching distutils to do the right thing for all
-# supported Python versions is worse...
-#
-# Also see: https://github.com/pietern/hiredis-py/issues/15
-lib = ("hiredis_for_hiredis_py", {
-  "sources": ["vendor/hiredis/%s.c" % src for src in ("read", "sds")]})
-
 ext = Extension("hiredis.hiredis",
-  sources=glob.glob("src/*.c"),
+  sources=sorted(glob.glob("src/*.c") +
+                 ["vendor/hiredis/%s.c" % src for src in ("read", "sds")]),
   include_dirs=["vendor"])
 
 setup(
   name="hiredis",
   version=version(),
   description="Python wrapper for hiredis",
+  long_description=open('README.md', 'r').read(),
+  long_description_content_type='text/markdown',
   url="https://github.com/redis/hiredis-py";,
   author="Jan-Erik Rediger, Pieter Noordhuis",
   author_email="jane...@fnordig.de, pcnoordh...@gmail.com",
   keywords=["Redis"],
   license="BSD",
   packages=["hiredis"],
-  libraries=[lib],
   ext_modules=[ext],
-
-  # Override "install_lib" command
-  cmdclass={ "install_lib": install_lib },
-
+  python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
   classifiers=[
     'Development Status :: 5 - Production/Stable',
     'Intended Audience :: Developers',
@@ -71,12 +37,12 @@
     'Operating System :: POSIX',
     'Programming Language :: C',
     'Programming Language :: Python :: 2',
-    'Programming Language :: Python :: 2.6',
     'Programming Language :: Python :: 2.7',
     'Programming Language :: Python :: 3',
-    'Programming Language :: Python :: 3.2',
-    'Programming Language :: Python :: 3.3',
     'Programming Language :: Python :: 3.4',
+    'Programming Language :: Python :: 3.5',
+    'Programming Language :: Python :: 3.6',
+    'Programming Language :: Python :: 3.7',
     'Programming Language :: Python :: Implementation :: CPython',
     'Topic :: Software Development',
   ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/src/hiredis.c 
new/hiredis-py-1.0.0/src/hiredis.c
--- old/hiredis-py-0.2.0/src/hiredis.c  2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/src/hiredis.c  2019-01-20 08:39:27.000000000 +0100
@@ -28,7 +28,7 @@
     NULL /* m_free */
 };
 #else
-struct hiredis_ModuleState state;
+struct hiredis_ModuleState hiredis_py_module_state;
 #endif
 
 /* Keep pointer around for other classes to access the module state. */
@@ -63,8 +63,11 @@
     HIREDIS_STATE->HiErr_ReplyError =
         PyErr_NewException(MOD_HIREDIS ".ReplyError", 
HIREDIS_STATE->HiErr_Base, NULL);
 
+    Py_INCREF(HIREDIS_STATE->HiErr_Base);
     PyModule_AddObject(mod_hiredis, "HiredisError", HIREDIS_STATE->HiErr_Base);
+    Py_INCREF(HIREDIS_STATE->HiErr_ProtocolError);
     PyModule_AddObject(mod_hiredis, "ProtocolError", 
HIREDIS_STATE->HiErr_ProtocolError);
+    Py_INCREF(HIREDIS_STATE->HiErr_ReplyError);
     PyModule_AddObject(mod_hiredis, "ReplyError", 
HIREDIS_STATE->HiErr_ReplyError);
 
     Py_INCREF(&hiredis_ReaderType);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/src/hiredis.h 
new/hiredis-py-1.0.0/src/hiredis.h
--- old/hiredis-py-0.2.0/src/hiredis.h  2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/src/hiredis.h  2019-01-20 08:39:27.000000000 +0100
@@ -25,8 +25,8 @@
 #if IS_PY3K
 #define GET_STATE(__s) ((struct hiredis_ModuleState*)PyModule_GetState(__s))
 #else
-extern struct hiredis_ModuleState state;
-#define GET_STATE(__s) (&state)
+extern struct hiredis_ModuleState hiredis_py_module_state;
+#define GET_STATE(__s) (&hiredis_py_module_state)
 #endif
 
 /* Keep pointer around for other classes to access the module state. */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/src/reader.c 
new/hiredis-py-1.0.0/src/reader.c
--- old/hiredis-py-0.2.0/src/reader.c   2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/src/reader.c   2019-01-20 08:39:27.000000000 +0100
@@ -6,15 +6,19 @@
 static int Reader_init(hiredis_ReaderObject *self, PyObject *args, PyObject 
*kwds);
 static PyObject *Reader_new(PyTypeObject *type, PyObject *args, PyObject 
*kwds);
 static PyObject *Reader_feed(hiredis_ReaderObject *self, PyObject *args);
-static PyObject *Reader_gets(hiredis_ReaderObject *self);
+static PyObject *Reader_gets(hiredis_ReaderObject *self, PyObject *args);
 static PyObject *Reader_setmaxbuf(hiredis_ReaderObject *self, PyObject *arg);
 static PyObject *Reader_getmaxbuf(hiredis_ReaderObject *self);
+static PyObject *Reader_len(hiredis_ReaderObject *self);
+static PyObject *Reader_has_data(hiredis_ReaderObject *self);
 
 static PyMethodDef hiredis_ReaderMethods[] = {
     {"feed", (PyCFunction)Reader_feed, METH_VARARGS, NULL },
-    {"gets", (PyCFunction)Reader_gets, METH_NOARGS, NULL },
+    {"gets", (PyCFunction)Reader_gets, METH_VARARGS, NULL },
     {"setmaxbuf", (PyCFunction)Reader_setmaxbuf, METH_O, NULL },
     {"getmaxbuf", (PyCFunction)Reader_getmaxbuf, METH_NOARGS, NULL },
+    {"len", (PyCFunction)Reader_len, METH_NOARGS, NULL },
+    {"has_data", (PyCFunction)Reader_has_data, METH_NOARGS, NULL },
     { NULL }  /* Sentinel */
 };
 
@@ -72,28 +76,20 @@
 static PyObject *createDecodedString(hiredis_ReaderObject *self, const char 
*str, size_t len) {
     PyObject *obj;
 
-    if (self->encoding == NULL) {
+    if (self->encoding == NULL || !self->shouldDecode) {
         obj = PyBytes_FromStringAndSize(str, len);
     } else {
-        obj = PyUnicode_Decode(str, len, self->encoding, NULL);
+        obj = PyUnicode_Decode(str, len, self->encoding, self->errors);
         if (obj == NULL) {
-            if (PyErr_ExceptionMatches(PyExc_ValueError)) {
-                /* Ignore encoding and simply return plain string. */
-                obj = PyBytes_FromStringAndSize(str, len);
-            } else {
-                assert(PyErr_ExceptionMatches(PyExc_LookupError));
-
-                /* Store error when this is the first. */
-                if (self->error.ptype == NULL)
-                    PyErr_Fetch(&(self->error.ptype), &(self->error.pvalue),
-                            &(self->error.ptraceback));
-
-                /* Return Py_None as placeholder to let the error bubble up and
-                 * be used when a full reply in Reader#gets(). */
-                obj = Py_None;
-                Py_INCREF(obj);
-            }
-
+            /* Store error when this is the first. */
+            if (self->error.ptype == NULL)
+                PyErr_Fetch(&(self->error.ptype), &(self->error.pvalue),
+                        &(self->error.ptraceback));
+
+            /* Return Py_None as placeholder to let the error bubble up and
+             * be used when a full reply in Reader#gets(). */
+            obj = Py_None;
+            Py_INCREF(obj);
             PyErr_Clear();
         }
     }
@@ -103,13 +99,19 @@
 }
 
 static void *createError(PyObject *errorCallable, char *errstr, size_t len) {
-    PyObject *obj;
+    PyObject *obj, *errmsg;
+
+    #if IS_PY3K
+    errmsg = PyUnicode_DecodeUTF8(errstr, len, "replace");
+    #else
+    errmsg = Py_BuildValue("s#", errstr, len);
+    #endif
+    assert(errmsg != NULL); /* TODO: properly handle OOM etc */
+
+    obj = PyObject_CallFunctionObjArgs(errorCallable, errmsg, NULL);
+    Py_DECREF(errmsg);
+    /* obj can be NULL if custom error class raised another exception */
 
-    PyObject *args = Py_BuildValue("(s#)", errstr, len);
-    assert(args != NULL); /* TODO: properly handle OOM etc */
-    obj = PyObject_CallObject(errorCallable, args);
-    assert(obj != NULL);
-    Py_DECREF(args);
     return obj;
 }
 
@@ -119,10 +121,16 @@
 
     if (task->type == REDIS_REPLY_ERROR) {
         obj = createError(self->replyErrorClass, str, len);
+        if (obj == NULL) {
+            if (self->error.ptype == NULL)
+                PyErr_Fetch(&(self->error.ptype), &(self->error.pvalue),
+                        &(self->error.ptraceback));
+            obj = Py_None;
+            Py_INCREF(obj);
+        }
     } else {
         obj = createDecodedString(self, str, len);
     }
-
     return tryParentize(task, obj);
 }
 
@@ -157,9 +165,9 @@
 };
 
 static void Reader_dealloc(hiredis_ReaderObject *self) {
+    // we don't need to free self->encoding as the buffer is managed by Python
+    // https://docs.python.org/3/c-api/arg.html#strings-and-buffers
     redisReplyReaderFree(self->reader);
-    if (self->encoding)
-        free(self->encoding);
     Py_XDECREF(self->protocolErrorClass);
     Py_XDECREF(self->replyErrorClass);
 
@@ -182,13 +190,14 @@
 }
 
 static int Reader_init(hiredis_ReaderObject *self, PyObject *args, PyObject 
*kwds) {
-    static char *kwlist[] = { "protocolError", "replyError", "encoding", NULL 
};
+    static char *kwlist[] = { "protocolError", "replyError", "encoding", 
"errors", NULL };
     PyObject *protocolErrorClass = NULL;
     PyObject *replyErrorClass = NULL;
-    PyObject *encodingObj = NULL;
+    char *encoding = NULL;
+    char *errors = NULL;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOO", kwlist,
-        &protocolErrorClass, &replyErrorClass, &encodingObj))
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOss", kwlist,
+        &protocolErrorClass, &replyErrorClass, &encoding, &errors))
             return -1;
 
     if (protocolErrorClass)
@@ -199,25 +208,19 @@
         if (!_Reader_set_exception(&self->replyErrorClass, replyErrorClass))
             return -1;
 
-    if (encodingObj) {
-        PyObject *encbytes;
-        char *encstr;
-        int enclen;
-
-        if (PyUnicode_Check(encodingObj))
-            encbytes = PyUnicode_AsASCIIString(encodingObj);
-        else
-            encbytes = PyObject_Bytes(encodingObj);
-
-        if (encbytes == NULL)
+    self->encoding = encoding;
+    if(errors) {
+        if (strcmp(errors, "strict") != 0 &&
+            strcmp(errors, "replace") != 0 &&
+            strcmp(errors, "ignore") != 0 &&
+            strcmp(errors, "backslashreplace") != 0) {
+
+            PyErr_SetString(PyExc_LookupError,
+                            "if specified, errors must be one of "
+                            "{'strict', 'replace', 'ignore', 
'backslashreplace'}");
             return -1;
-
-        enclen = PyBytes_Size(encbytes);
-        encstr = PyBytes_AsString(encbytes);
-        self->encoding = (char*)malloc(enclen+1);
-        memcpy(self->encoding, encstr, enclen);
-        self->encoding[enclen] = '\0';
-        Py_DECREF(encbytes);
+        }
+        self->errors = errors;
     }
 
     return 0;
@@ -232,6 +235,8 @@
         self->reader->privdata = self;
 
         self->encoding = NULL;
+        self->errors = "strict";  // default to "strict" to mimic Python
+        self->shouldDecode = 1;
         self->protocolErrorClass = HIREDIS_STATE->HiErr_ProtocolError;
         self->replyErrorClass = HIREDIS_STATE->HiErr_ReplyError;
         Py_INCREF(self->protocolErrorClass);
@@ -276,19 +281,26 @@
     return NULL;
 }
 
-static PyObject *Reader_gets(hiredis_ReaderObject *self) {
+static PyObject *Reader_gets(hiredis_ReaderObject *self, PyObject *args) {
     PyObject *obj;
     PyObject *err;
     char *errstr;
 
+    self->shouldDecode = 1;
+    if (!PyArg_ParseTuple(args, "|i", &self->shouldDecode)) {
+        return NULL;
+    }
+
     if (redisReplyReaderGetReply(self->reader, (void**)&obj) == REDIS_ERR) {
         errstr = redisReplyReaderGetError(self->reader);
         /* protocolErrorClass might be a callable. call it, then use it's type 
*/
         err = createError(self->protocolErrorClass, errstr, strlen(errstr));
-        obj = PyObject_Type(err);
-        PyErr_SetString(obj, errstr);
-        Py_DECREF(obj);
-        Py_DECREF(err);
+        if (err != NULL) {
+            obj = PyObject_Type(err);
+            PyErr_SetString(obj, errstr);
+            Py_DECREF(obj);
+            Py_DECREF(err);
+        }
         return NULL;
     }
 
@@ -332,3 +344,13 @@
 static PyObject *Reader_getmaxbuf(hiredis_ReaderObject *self) {
     return PyLong_FromSize_t(self->reader->maxbuf);
 }
+
+static PyObject *Reader_len(hiredis_ReaderObject *self) {
+    return PyLong_FromSize_t(self->reader->len);
+}
+
+static PyObject *Reader_has_data(hiredis_ReaderObject *self) {
+    if(self->reader->pos < self->reader->len)
+        Py_RETURN_TRUE;
+    Py_RETURN_FALSE;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/src/reader.h 
new/hiredis-py-1.0.0/src/reader.h
--- old/hiredis-py-0.2.0/src/reader.h   2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/src/reader.h   2019-01-20 08:39:27.000000000 +0100
@@ -7,6 +7,8 @@
     PyObject_HEAD
     redisReader *reader;
     char *encoding;
+    char *errors;
+    int shouldDecode;
     PyObject *protocolErrorClass;
     PyObject *replyErrorClass;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/hiredis-py-0.2.0/test/reader.py 
new/hiredis-py-1.0.0/test/reader.py
--- old/hiredis-py-0.2.0/test/reader.py 2015-04-03 22:50:50.000000000 +0200
+++ new/hiredis-py-1.0.0/test/reader.py 2019-01-20 08:39:27.000000000 +0100
@@ -3,6 +3,8 @@
 import hiredis
 import sys
 
+IS_PY3K = sys.version_info[0] >= 3
+
 class ReaderTest(TestCase):
   def setUp(self):
     self.reader = hiredis.Reader()
@@ -36,6 +38,13 @@
   def test_fail_with_wrong_protocol_error_class(self):
     self.assertRaises(TypeError, hiredis.Reader, protocolError="wrong")
 
+  def test_faulty_protocol_error_class(self):
+    def make_error(errstr):
+      1 / 0
+    self.reader = hiredis.Reader(protocolError=make_error)
+    self.reader.feed(b"x")
+    self.assertRaises(ZeroDivisionError, self.reply)
+
   def test_error_string(self):
     self.reader.feed(b"-error\r\n")
     error = self.reply()
@@ -62,9 +71,29 @@
     self.assertEquals(CustomException, type(error))
     self.assertEquals(("error",), error.args)
 
+  def test_error_string_with_non_utf8_chars(self):
+    self.reader.feed(b"-error \xd1\r\n")
+    error = self.reply()
+
+    if IS_PY3K:
+      expected = "error \ufffd"
+    else:
+      expected = b"error \xd1"
+
+    self.assertEquals(hiredis.ReplyError, type(error))
+    self.assertEquals((expected,), error.args)
+
   def test_fail_with_wrong_reply_error_class(self):
     self.assertRaises(TypeError, hiredis.Reader, replyError="wrong")
 
+  def test_faulty_reply_error_class(self):
+    def make_error(errstr):
+      1 / 0
+
+    self.reader = hiredis.Reader(replyError=make_error)
+    self.reader.feed(b"-error\r\n")
+    self.assertRaises(ZeroDivisionError, self.reply)
+
   def test_errors_in_nested_multi_bulk(self):
     self.reader.feed(b"*2\r\n-err0\r\n-err1\r\n")
 
@@ -72,6 +101,18 @@
       self.assertEquals(hiredis.ReplyError, type(error))
       self.assertEquals((r,), error.args)
 
+  def test_errors_with_non_utf8_chars_in_nested_multi_bulk(self):
+    self.reader.feed(b"*2\r\n-err\xd1\r\n-err1\r\n")
+
+    if IS_PY3K:
+      expected = "err\ufffd"
+    else:
+      expected = b"err\xd1"
+
+    for r, error in zip((expected, "err1"), self.reply()):
+      self.assertEquals(hiredis.ReplyError, type(error))
+      self.assertEquals((r,), error.args)
+
   def test_integer(self):
     value = 2**63-1 # Largest 64-bit signed integer
     self.reader.feed((":%d\r\n" % value).encode("ascii"))
@@ -100,17 +141,41 @@
     self.reader.feed(b"$3\r\n" + snowman + b"\r\n")
     self.assertEquals(snowman.decode("utf-8"), self.reply())
 
-  def test_bulk_string_with_other_encoding(self):
-    snowman = b"\xe2\x98\x83"
-    self.reader = hiredis.Reader(encoding="utf-32")
-    self.reader.feed(b"$3\r\n" + snowman + b"\r\n")
-    self.assertEquals(snowman, self.reply())
-
   def test_bulk_string_with_invalid_encoding(self):
     self.reader = hiredis.Reader(encoding="unknown")
     self.reader.feed(b"$5\r\nhello\r\n")
     self.assertRaises(LookupError, self.reply)
 
+  def test_decode_errors_defaults_to_strict(self):
+    self.reader = hiredis.Reader(encoding="utf-8")
+    self.reader.feed(b"+\x80\r\n")
+    self.assertRaises(UnicodeDecodeError, self.reader.gets)
+
+  def test_decode_error_with_ignore_errors(self):
+    self.reader = hiredis.Reader(encoding="utf-8", errors="ignore")
+    self.reader.feed(b"+\x80value\r\n")
+    self.assertEquals("value", self.reader.gets())
+
+  def test_invalid_encoding_error_handler(self):
+    self.assertRaises(LookupError, hiredis.Reader, errors='unknown')
+
+  def test_reader_with_invalid_error_handler(self):
+    self.assertRaises(LookupError, hiredis.Reader, encoding="utf-8", 
errors='foo')
+
+  def test_should_decode_false_flag_prevents_decoding(self):
+    snowman = b"\xe2\x98\x83"
+    self.reader = hiredis.Reader(encoding="utf-8")
+    self.reader.feed(b"$3\r\n" + snowman + b"\r\n")
+    self.reader.feed(b"$3\r\n" + snowman + b"\r\n")
+    self.assertEquals(snowman, self.reader.gets(False))
+    self.assertEquals(snowman.decode("utf-8"), self.reply())
+
+  def test_should_decode_true_flag_decodes_as_normal(self):
+    snowman = b"\xe2\x98\x83"
+    self.reader = hiredis.Reader(encoding="utf-8")
+    self.reader.feed(b"$3\r\n" + snowman + b"\r\n")
+    self.assertEquals(snowman.decode("utf-8"), self.reader.gets(True))
+
   def test_null_multi_bulk(self):
     self.reader.feed(b"*-1\r\n")
     self.assertEquals(None, self.reply())
@@ -166,9 +231,8 @@
     self.assertEquals(b"ok", self.reply())
 
   def test_feed_bytearray(self):
-    if sys.hexversion >= 0x02060000:
-      self.reader.feed(bytearray(b"+ok\r\n"))
-      self.assertEquals(b"ok", self.reply())
+    self.reader.feed(bytearray(b"+ok\r\n"))
+    self.assertEquals(b"ok", self.reply())
 
   def test_maxbuf(self):
     defaultmaxbuf = self.reader.getmaxbuf()
@@ -179,3 +243,26 @@
     self.reader.setmaxbuf(None)
     self.assertEquals(defaultmaxbuf, self.reader.getmaxbuf())
     self.assertRaises(ValueError, self.reader.setmaxbuf, -4)
+
+  def test_len(self):
+    self.assertEquals(0, self.reader.len())
+    data = b"+ok\r\n"
+    self.reader.feed(data)
+    self.assertEquals(len(data), self.reader.len())
+
+    # hiredis reallocates and removes unused buffer once
+    # there is at least 1K of not used data.
+    calls = int((1024 / len(data))) + 1
+    for i in range(calls):
+        self.reader.feed(data)
+        self.reply()
+
+    self.assertEquals(5, self.reader.len())
+
+  def test_reader_has_data(self):
+    self.assertEquals(False, self.reader.has_data())
+    data = b"+ok\r\n"
+    self.reader.feed(data)
+    self.assertEquals(True, self.reader.has_data())
+    self.reply()
+    self.assertEquals(False, self.reader.has_data())


Reply via email to