Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-hiredis for openSUSE:Factory checked in at 2021-03-03 18:35:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-hiredis (Old) and /work/SRC/openSUSE:Factory/.python-hiredis.new.2378 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-hiredis" Wed Mar 3 18:35:41 2021 rev:5 rq:876522 version:1.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-hiredis/python-hiredis.changes 2020-01-16 18:22:43.489025178 +0100 +++ /work/SRC/openSUSE:Factory/.python-hiredis.new.2378/python-hiredis.changes 2021-03-03 18:35:55.751416503 +0100 @@ -1,0 +2,8 @@ +Mon Feb 1 09:48:43 UTC 2021 - Mark??ta Machov?? <[email protected]> + +- Update to 1.1.0 + * Allow "encoding" and "errors" attributes to be updated at runtime (see #96) +- Drop fix_build_dir_in_tests.patch +- Add hiredis1.patch to fix build with hiredis 1.0.0 + +------------------------------------------------------------------- Old: ---- fix_build_dir_in_tests.patch v1.0.1.tar.gz New: ---- hiredis1.patch v1.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-hiredis.spec ++++++ --- /var/tmp/diff_new_pack.mYXabU/_old 2021-03-03 18:35:56.423416985 +0100 +++ /var/tmp/diff_new_pack.mYXabU/_new 2021-03-03 18:35:56.427416988 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-hiredis # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,19 +18,19 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-hiredis -Version: 1.0.1 +Version: 1.1.0 Release: 0 Summary: Python wrapper for hiredis License: BSD-3-Clause 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: fix_build_dir_in_tests.patch Patch2: drop-vendor-sources.patch +Patch3: hiredis1.patch BuildRequires: %{python_module devel} BuildRequires: %{python_module setuptools} BuildRequires: fdupes -BuildRequires: hiredis-devel >= 0.13.3 +BuildRequires: hiredis-devel >= 1.0.0 BuildRequires: python-rpm-macros %python_subpackages @@ -49,7 +49,9 @@ %python_expand %fdupes %{buildroot}%{$python_sitearch} %check -%python_exec test.py +%python_exec setup.py build_ext --inplace +export PYTHONPATH=%{buildroot}%{$python_sitearch} +%python_exec test.py -v %files %{python_files} %license COPYING ++++++ hiredis1.patch ++++++ >From 9084152f624e8e593b4e86ddf8bd13329fdfc043 Mon Sep 17 00:00:00 2001 From: Illia Volochii <[email protected]> Date: Mon, 1 Mar 2021 20:48:33 +0200 Subject: [PATCH] Bump hiredis from 0.13.3 to 1.0.0 --- setup.py | 2 +- src/reader.c | 64 +++++++++++++++++++++++++++++++++++++++++++------- test/reader.py | 36 ++++++++++++++++++++++++++++ vendor/hiredis | 2 +- 4 files changed, 93 insertions(+), 11 deletions(-) Index: hiredis-py-1.1.0/src/reader.c =================================================================== --- hiredis-py-1.1.0.orig/src/reader.c +++ hiredis-py-1.1.0/src/reader.c @@ -69,8 +69,26 @@ static void *tryParentize(const redisRea PyObject *parent; if (task && task->parent) { parent = (PyObject*)task->parent->obj; - assert(PyList_CheckExact(parent)); - PyList_SET_ITEM(parent, task->idx, obj); + switch (task->parent->type) { + case REDIS_REPLY_MAP: + if (task->idx % 2 == 0) { + /* Set a temporary item to save the object as a key. */ + PyDict_SetItem(parent, obj, Py_None); + } else { + /* Pop the temporary item and set proper key and value. */ + PyObject *last_item = PyObject_CallMethod(parent, "popitem", NULL); + PyObject *last_key = PyTuple_GetItem(last_item, 0); + PyDict_SetItem(parent, last_key, obj); + } + break; + case REDIS_REPLY_SET: + assert(PyAnySet_CheckExact(parent)); + PySet_Add(parent, obj); + break; + default: + assert(PyList_CheckExact(parent)); + PyList_SET_ITEM(parent, task->idx, obj); + } } return obj; } @@ -131,14 +149,28 @@ static void *createStringObject(const re Py_INCREF(obj); } } else { + if (task->type == REDIS_REPLY_VERB) { + /* Skip 4 bytes of verbatim type header. */ + memmove(str, str+4, len); + len -= 4; + } obj = createDecodedString(self, str, len); } return tryParentize(task, obj); } -static void *createArrayObject(const redisReadTask *task, int elements) { +static void *createArrayObject(const redisReadTask *task, size_t elements) { PyObject *obj; - obj = PyList_New(elements); + switch (task->type) { + case REDIS_REPLY_MAP: + obj = PyDict_New(); + break; + case REDIS_REPLY_SET: + obj = PySet_New(NULL); + break; + default: + obj = PyList_New(elements); + } return tryParentize(task, obj); } @@ -148,28 +180,42 @@ static void *createIntegerObject(const r return tryParentize(task, obj); } +static void *createDoubleObject(const redisReadTask *task, double value, char *str, size_t le) { + PyObject *obj; + obj = PyFloat_FromDouble(value); + return tryParentize(task, obj); +} + static void *createNilObject(const redisReadTask *task) { PyObject *obj = Py_None; Py_INCREF(obj); return tryParentize(task, obj); } +static void *createBoolObject(const redisReadTask *task, int bval) { + PyObject *obj; + obj = PyBool_FromLong((long)bval); + return tryParentize(task, obj); +} + static void freeObject(void *obj) { Py_XDECREF(obj); } redisReplyObjectFunctions hiredis_ObjectFunctions = { createStringObject, // void *(*createString)(const redisReadTask*, char*, size_t); - createArrayObject, // void *(*createArray)(const redisReadTask*, int); + createArrayObject, // void *(*createArray)(const redisReadTask*, size_t); createIntegerObject, // void *(*createInteger)(const redisReadTask*, long long); + createDoubleObject, // void *(*createDoubleObject)(const redisReadTask*, double, char*, size_t); createNilObject, // void *(*createNil)(const redisReadTask*); + createBoolObject, // void *(*createBoolObject)(const redisReadTask*, int); freeObject // void (*freeObject)(void*); }; 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); + redisReaderFree(self->reader); Py_XDECREF(self->protocolErrorClass); Py_XDECREF(self->replyErrorClass); @@ -293,7 +339,7 @@ static PyObject *Reader_feed(hiredis_Rea goto error; } - redisReplyReaderFeed(self->reader, (char *)buf.buf + off, len); + redisReaderFeed(self->reader, (char *)buf.buf + off, len); PyBuffer_Release(&buf); Py_RETURN_NONE; @@ -312,8 +358,8 @@ static PyObject *Reader_gets(hiredis_Rea return NULL; } - if (redisReplyReaderGetReply(self->reader, (void**)&obj) == REDIS_ERR) { - errstr = redisReplyReaderGetError(self->reader); + if (redisReaderGetReply(self->reader, (void**)&obj) == REDIS_ERR) { + errstr = redisReaderGetError(self->reader); /* protocolErrorClass might be a callable. call it, then use it's type */ err = createError(self->protocolErrorClass, errstr, strlen(errstr)); if (err != NULL) { Index: hiredis-py-1.1.0/test/reader.py =================================================================== --- hiredis-py-1.1.0.orig/test/reader.py +++ hiredis-py-1.1.0/test/reader.py @@ -118,6 +118,42 @@ class ReaderTest(TestCase): self.reader.feed((":%d\r\n" % value).encode("ascii")) self.assertEquals(value, self.reply()) + def test_float(self): + value = -99.99 + self.reader.feed(b",%f\r\n" % value) + self.assertEqual(value, self.reply()) + + def test_boolean_true(self): + self.reader.feed(b"#t\r\n") + self.assertTrue(self.reply()) + + def test_boolean_false(self): + self.reader.feed(b"#f\r\n") + self.assertFalse(False, self.reply()) + + def test_none(self): + self.reader.feed(b"_\r\n") + self.assertIsNone(self.reply()) + + def test_set(self): + self.reader.feed(b"~3\r\n+tangerine\r\n_\r\n,10.5\r\n") + self.assertEqual({b"tangerine", None, 10.5}, self.reply()) + + def test_dict(self): + self.reader.feed(b"%2\r\n+radius\r\n,4.5\r\n+diameter\r\n:9\r\n") + self.assertEqual({b"radius": 4.5, b"diameter": 9}, self.reply()) + + def test_vector(self): + self.reader.feed(b">4\r\n+pubsub\r\n+message\r\n+channel\r\n+message\r\n") + self.assertEqual( + [b"pubsub", b"message", b"channel", b"message"], self.reply() + ) + + def test_verbatim_string(self): + value = b"text" + self.reader.feed(b"=8\r\ntxt:%s\r\n" % value) + self.assertEqual(value, self.reply()) + def test_status_string(self): self.reader.feed(b"+ok\r\n") self.assertEquals(b"ok", self.reply()) ++++++ v1.0.1.tar.gz -> v1.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiredis-py-1.0.1/.travis.yml new/hiredis-py-1.1.0/.travis.yml --- old/hiredis-py-1.0.1/.travis.yml 2019-11-13 11:31:27.000000000 +0100 +++ new/hiredis-py-1.1.0/.travis.yml 2020-07-15 11:38:55.000000000 +0200 @@ -11,7 +11,8 @@ - python: "3.6" - python: "3.7" dist: xenial - sudo: required + - python: "3.8" + dist: xenial # linux wheels - dist: trusty sudo: required @@ -34,13 +35,14 @@ - trying - master - /^v.*$/ + - py38 install: - | if [ -n "${HIREDIS_PY_BUILDWHEELS:-}" ]; then pip install cibuildwheel else - python setup.py build + python setup.py build_ext --inplace fi script: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiredis-py-1.0.1/CHANGELOG.md new/hiredis-py-1.1.0/CHANGELOG.md --- old/hiredis-py-1.0.1/CHANGELOG.md 2019-11-13 11:31:27.000000000 +0100 +++ new/hiredis-py-1.1.0/CHANGELOG.md 2020-07-15 11:38:55.000000000 +0200 @@ -1,3 +1,7 @@ +### 1.1.0 (2020-07-15) + +* Allow "encoding" and "errors" attributes to be updated at runtime (see #96) + ### 1.0.1 (2019-11-13) * Permit all allowed values of codec errors (see #86) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiredis-py-1.0.1/appveyor.yml new/hiredis-py-1.1.0/appveyor.yml --- old/hiredis-py-1.0.1/appveyor.yml 2019-11-13 11:31:27.000000000 +0100 +++ new/hiredis-py-1.1.0/appveyor.yml 2020-07-15 11:38:55.000000000 +0200 @@ -52,6 +52,14 @@ PYTHON_VERSION: "3.7.0" PYTHON_ARCH: "64" + - PYTHON: "C:\\Python38" + PYTHON_VERSION: "3.8.0" + PYTHON_ARCH: "32" + + - PYTHON: "C:\\Python38-x64" + PYTHON_VERSION: "3.8.0" + PYTHON_ARCH: "64" + # build wheels - PYTHON: "C:\\Python36-x64" PYTHON_VERSION: "3.6.6" @@ -68,7 +76,7 @@ build: off test_script: - - "%CMD_IN_ENV% python setup.py build" + - "%CMD_IN_ENV% python setup.py build_ext --inplace" - "%CMD_IN_ENV% python test.py" - ps: | if (Test-Path env:HIREDIS_PY_BUILDWHEELS) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiredis-py-1.0.1/hiredis/version.py new/hiredis-py-1.1.0/hiredis/version.py --- old/hiredis-py-1.0.1/hiredis/version.py 2019-11-13 11:31:27.000000000 +0100 +++ new/hiredis-py-1.1.0/hiredis/version.py 2020-07-15 11:38:55.000000000 +0200 @@ -1 +1 @@ -__version__ = "1.0.1" +__version__ = "1.1.0" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiredis-py-1.0.1/setup.py new/hiredis-py-1.1.0/setup.py --- old/hiredis-py-1.0.1/setup.py 2019-11-13 11:31:27.000000000 +0100 +++ new/hiredis-py-1.1.0/setup.py 2020-07-15 11:38:55.000000000 +0200 @@ -43,6 +43,7 @@ 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: Implementation :: CPython', 'Topic :: Software Development', ], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiredis-py-1.0.1/src/reader.c new/hiredis-py-1.1.0/src/reader.c --- old/hiredis-py-1.0.1/src/reader.c 2019-11-13 11:31:27.000000000 +0100 +++ new/hiredis-py-1.1.0/src/reader.c 2020-07-15 11:38:55.000000000 +0200 @@ -11,6 +11,7 @@ static PyObject *Reader_getmaxbuf(hiredis_ReaderObject *self); static PyObject *Reader_len(hiredis_ReaderObject *self); static PyObject *Reader_has_data(hiredis_ReaderObject *self); +static PyObject *Reader_set_encoding(hiredis_ReaderObject *self, PyObject *args, PyObject *kwds); static PyMethodDef hiredis_ReaderMethods[] = { {"feed", (PyCFunction)Reader_feed, METH_VARARGS, NULL }, @@ -19,6 +20,7 @@ {"getmaxbuf", (PyCFunction)Reader_getmaxbuf, METH_NOARGS, NULL }, {"len", (PyCFunction)Reader_len, METH_NOARGS, NULL }, {"has_data", (PyCFunction)Reader_has_data, METH_NOARGS, NULL }, + {"set_encoding", (PyCFunction)Reader_set_encoding, METH_VARARGS | METH_KEYWORDS, NULL }, { NULL } /* Sentinel */ }; @@ -189,6 +191,40 @@ return 1; } +static int _Reader_set_encoding(hiredis_ReaderObject *self, char *encoding, char *errors) { + PyObject *codecs, *result; + + if (encoding) { // validate that the encoding exists, raises LookupError if not + codecs = PyImport_ImportModule("codecs"); + if (!codecs) + return -1; + result = PyObject_CallMethod(codecs, "lookup", "s", encoding); + Py_DECREF(codecs); + if (!result) + return -1; + Py_DECREF(result); + self->encoding = encoding; + } else { + self->encoding = NULL; + } + + if (errors) { // validate that the error handler exists, raises LookupError if not + codecs = PyImport_ImportModule("codecs"); + if (!codecs) + return -1; + result = PyObject_CallMethod(codecs, "lookup_error", "s", errors); + Py_DECREF(codecs); + if (!result) + return -1; + Py_DECREF(result); + self->errors = errors; + } else { + self->errors = "strict"; + } + + return 0; +} + static int Reader_init(hiredis_ReaderObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = { "protocolError", "replyError", "encoding", "errors", NULL }; PyObject *protocolErrorClass = NULL; @@ -196,7 +232,7 @@ char *encoding = NULL; char *errors = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOss", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOzz", kwlist, &protocolErrorClass, &replyErrorClass, &encoding, &errors)) return -1; @@ -208,21 +244,7 @@ if (!_Reader_set_exception(&self->replyErrorClass, replyErrorClass)) return -1; - self->encoding = encoding; - if (errors) { // validate that the error handler exists, raises LookupError if not - PyObject *codecs, *result; - codecs = PyImport_ImportModule("codecs"); - if (!codecs) - return -1; - result = PyObject_CallMethod(codecs, "lookup_error", "s", errors); - Py_DECREF(codecs); - if (!result) - return -1; - Py_DECREF(result); - self->errors = errors; - } - - return 0; + return _Reader_set_encoding(self, encoding, errors); } static PyObject *Reader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -353,3 +375,18 @@ Py_RETURN_TRUE; Py_RETURN_FALSE; } + +static PyObject *Reader_set_encoding(hiredis_ReaderObject *self, PyObject *args, PyObject *kwds) { + static char *kwlist[] = { "encoding", "errors", NULL }; + char *encoding = NULL; + char *errors = NULL; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zz", kwlist, &encoding, &errors)) + return NULL; + + if(_Reader_set_encoding(self, encoding, errors) == -1) + return NULL; + + Py_RETURN_NONE; + +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiredis-py-1.0.1/test/__init__.py new/hiredis-py-1.1.0/test/__init__.py --- old/hiredis-py-1.0.1/test/__init__.py 2019-11-13 11:31:27.000000000 +0100 +++ new/hiredis-py-1.1.0/test/__init__.py 2020-07-15 11:38:55.000000000 +0200 @@ -3,10 +3,6 @@ version = sys.version.split(" ")[0] majorminor = version[0:3] -# Add path to hiredis.so load path -path = glob.glob("build/lib*-%s/hiredis" % majorminor)[0] -sys.path.insert(0, path) - from unittest import * from . import reader diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hiredis-py-1.0.1/test/reader.py new/hiredis-py-1.1.0/test/reader.py --- old/hiredis-py-1.0.1/test/reader.py 2019-11-13 11:31:27.000000000 +0100 +++ new/hiredis-py-1.1.0/test/reader.py 2020-07-15 11:38:55.000000000 +0200 @@ -141,11 +141,6 @@ self.reader.feed(b"$3\r\n" + snowman + b"\r\n") self.assertEquals(snowman.decode("utf-8"), 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") @@ -162,11 +157,11 @@ self.reader.feed(b"+\x80value\r\n") self.assertEquals("\udc80value", self.reader.gets()) - def test_invalid_encoding_error_handler(self): - self.assertRaises(LookupError, hiredis.Reader, errors='unknown') + def test_invalid_encoding(self): + self.assertRaises(LookupError, hiredis.Reader, encoding="unknown") - def test_reader_with_invalid_error_handler(self): - self.assertRaises(LookupError, hiredis.Reader, encoding="utf-8", errors='foo') + def test_invalid_encoding_error_handler(self): + self.assertRaises(LookupError, hiredis.Reader, errors="unknown") def test_should_decode_false_flag_prevents_decoding(self): snowman = b"\xe2\x98\x83" @@ -182,6 +177,33 @@ self.reader.feed(b"$3\r\n" + snowman + b"\r\n") self.assertEquals(snowman.decode("utf-8"), self.reader.gets(True)) + def test_set_encoding_with_different_encoding(self): + snowman_utf8 = b"\xe2\x98\x83" + snowman_utf16 = b"\xff\xfe\x03&" + self.reader = hiredis.Reader(encoding="utf-8") + self.reader.feed(b"$3\r\n" + snowman_utf8 + b"\r\n") + self.reader.feed(b"$4\r\n" + snowman_utf16 + b"\r\n") + self.assertEquals(snowman_utf8.decode('utf-8'), self.reader.gets()) + self.reader.set_encoding(encoding="utf-16", errors="strict") + self.assertEquals(snowman_utf16.decode('utf-16'), self.reader.gets()) + + def test_set_encoding_to_not_decode(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.decode('utf-8'), self.reader.gets()) + self.reader.set_encoding(encoding=None, errors=None) + self.assertEquals(snowman, self.reader.gets()) + + def test_set_encoding_invalid_encoding(self): + self.reader = hiredis.Reader(encoding="utf-8") + self.assertRaises(LookupError, self.reader.set_encoding, encoding="unknown") + + def test_set_encoding_invalid_error_handler(self): + self.reader = hiredis.Reader(encoding="utf-8") + self.assertRaises(LookupError, self.reader.set_encoding, encoding="utf-8", errors="unknown") + def test_null_multi_bulk(self): self.reader.feed(b"*-1\r\n") self.assertEquals(None, self.reply()) @@ -194,13 +216,6 @@ self.reader.feed(b"*2\r\n$5\r\nhello\r\n$5\r\nworld\r\n") self.assertEquals([b"hello", b"world"], self.reply()) - def test_multi_bulk_with_invalid_encoding_and_partial_reply(self): - self.reader = hiredis.Reader(encoding="unknown") - self.reader.feed(b"*2\r\n$5\r\nhello\r\n") - self.assertEquals(False, self.reply()) - self.reader.feed(b":1\r\n") - self.assertRaises(LookupError, self.reply) - def test_nested_multi_bulk(self): self.reader.feed(b"*2\r\n*2\r\n$5\r\nhello\r\n$5\r\nworld\r\n$1\r\n!\r\n") self.assertEquals([[b"hello", b"world"], b"!"], self.reply())
