Hello community,
here is the log from the commit of package python-python-memcached for
openSUSE:Factory checked in at 2018-08-10 09:49:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-memcached (Old)
and /work/SRC/openSUSE:Factory/.python-python-memcached.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-memcached"
Fri Aug 10 09:49:12 2018 rev:15 rq:628113 version:1.59
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-python-memcached/python-python-memcached.changes
2017-09-04 12:33:40.321873404 +0200
+++
/work/SRC/openSUSE:Factory/.python-python-memcached.new/python-python-memcached.changes
2018-08-10 09:49:13.298216161 +0200
@@ -1,0 +2,12 @@
+Wed Aug 8 13:56:44 UTC 2018 - [email protected]
+
+- Kill memcache deamon at the end of the tests
+
+-------------------------------------------------------------------
+Wed Aug 8 13:28:02 UTC 2018 - [email protected]
+
+- Version update to 1.59:
+ * Various fixes for python 3.7 and 3.6
+- Run tests
+
+-------------------------------------------------------------------
Old:
----
python-memcached-1.58.tar.gz
New:
----
1.59.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-python-memcached.spec ++++++
--- /var/tmp/diff_new_pack.RO83hC/_old 2018-08-10 09:49:14.062217390 +0200
+++ /var/tmp/diff_new_pack.RO83hC/_new 2018-08-10 09:49:14.062217390 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-python-memcached
#
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 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
@@ -18,23 +18,21 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
%define oldpython python
-%bcond_with test
Name: python-python-memcached
-Version: 1.58
+Version: 1.59
Release: 0
Summary: Pure python memcached client
License: Python-2.0
Group: Development/Languages/Python
-Url: http://www.tummy.com/Community/software/python-memcached/
-Source:
https://files.pythonhosted.org/packages/source/p/python-memcached/python-memcached-%{version}.tar.gz
-BuildRequires: %{python_module devel}
+URL: https://github.com/linsomniac/python-memcached
+Source:
https://github.com/linsomniac/python-memcached/archive/%{version}.tar.gz
+BuildRequires: %{python_module mock}
+BuildRequires: %{python_module nose}
BuildRequires: %{python_module setuptools}
BuildRequires: %{python_module six}
-BuildRequires: python-rpm-macros
-%if %{with test}
-BuildRequires: %{python_module nose}
BuildRequires: memcached
-%endif
+BuildRequires: python-rpm-macros
+BuildRequires: util-linux
Requires: memcached
Requires: python-six
BuildArch: noarch
@@ -55,6 +53,9 @@
%prep
%setup -q -n python-memcached-%{version}
+sed -i \
+ -e 's:#!/usr/bin/env python::' \
+ memcache.py
%build
%python_build
@@ -62,14 +63,14 @@
%install
%python_install
-%if %{with test}
%check
+/usr/sbin/memcached -dv -P $PWD/memcached.pid
%python_expand nosetests-%{$python_bin_suffix}
-%endif
+kill -9 $(cat $PWD/memcached.pid)
%files %{python_files}
-%defattr(-,root,root,-)
-%doc README.md PSF.LICENSE
+%license PSF.LICENSE
+%doc README.md
%{python_sitelib}/*
%changelog
++++++ python-memcached-1.58.tar.gz -> 1.59.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/.travis.yml
new/python-memcached-1.59/.travis.yml
--- old/python-memcached-1.58/.travis.yml 2016-05-27 22:06:00.000000000
+0200
+++ new/python-memcached-1.59/.travis.yml 2017-12-15 05:15:52.000000000
+0100
@@ -1,13 +1,15 @@
language: python
python:
- - 2.6
- 2.7
- - 3.2
- - 3.3
- 3.4
+ - 3.5
+ - 3.6
- pypy
services:
- memcached
install: python setup.py install
-before_script: pip install nose
-script: nosetests
+before_script: pip install -r test-requirements.txt
+script:
+ - flake8
+ - nosetests
+ - python -c 'import memcache; memcache._doctest()'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/ChangeLog
new/python-memcached-1.59/ChangeLog
--- old/python-memcached-1.58/ChangeLog 2016-05-27 22:06:00.000000000 +0200
+++ new/python-memcached-1.59/ChangeLog 2017-12-15 05:15:52.000000000 +0100
@@ -1,3 +1,23 @@
+ * Added testing for Python 3.5 and 3.6 (PR from Tim Graham) #110, #131
+
+ * Fixed typos in docstrings (PR from Romuald Brunet, reviewed by Tim
+ Graham) #105
+
+ * Removing Python 2.6, 3.2, and 3.3 testing (PR from Tim Graham) #115, #116
+
+ * Removing unnecessary parens in return statements (PR from Tim Graham)
+ #113
+
+ * Remove unused _has_unicode/_str_cls vars (PR from Tim Graham) #111
+
+ * Add flake8 testing and cleanups (PR from Tim Graham, cleanups from Sean
+ Reifschneider) #112
+
+ * Fixed storing non-ASCII values on Python 2 and binary values on Python 3
+ (PR from Nicolas Noé) #135
+
+ * Fixed touch(..., time=0) command (PR from Nicolas Noé) #137
+
Fri, 27 May 2016 13:44:55 -0600 Sean Reifschneider <[email protected]>
* 1.58 release.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/PKG-INFO
new/python-memcached-1.59/PKG-INFO
--- old/python-memcached-1.58/PKG-INFO 2016-05-27 22:06:00.000000000 +0200
+++ new/python-memcached-1.59/PKG-INFO 2017-12-15 05:15:52.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.0
Name: python-memcached
-Version: 1.58
+Version: 1.59
Summary: A Python memcached client library.
Home-page: http://www.tummy.com/Community/software/python-memcached/
Author: Sean Reifschneider
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/memcache.py
new/python-memcached-1.59/memcache.py
--- old/python-memcached-1.58/memcache.py 2016-05-27 22:06:00.000000000
+0200
+++ new/python-memcached-1.59/memcache.py 2017-12-15 05:15:52.000000000
+0100
@@ -48,7 +48,7 @@
from __future__ import print_function
import binascii
-import os
+from io import BytesIO
import re
import socket
import sys
@@ -66,9 +66,7 @@
def cmemcache_hash(key):
- return (
- (((binascii.crc32(key) & 0xffffffff)
- >> 16) & 0x7fff) or 1)
+ return (((binascii.crc32(key) & 0xffffffff) >> 16) & 0x7fff) or 1
serverHashFunction = cmemcache_hash
@@ -77,18 +75,6 @@
global serverHashFunction
serverHashFunction = binascii.crc32
-from io import BytesIO
-if six.PY2:
- try:
- unicode
- except NameError:
- _has_unicode = False
- else:
- _has_unicode = True
-else:
- _has_unicode = True
-
-_str_cls = six.string_types
valid_key_chars_re = re.compile(b'[\x21-\x7e\x80-\xff]+$')
@@ -148,6 +134,7 @@
_FLAG_INTEGER = 1 << 1
_FLAG_LONG = 1 << 2
_FLAG_COMPRESSED = 1 << 3
+ _FLAG_TEXT = 1 << 4
_SERVER_RETRIES = 10 # how many times to try finding a free server.
@@ -343,7 +330,7 @@
stats = line.decode('ascii').split(' ', 2)
serverData[stats[1]] = stats[2]
- return(data)
+ return data
def get_slab_stats(self):
data = []
@@ -366,7 +353,7 @@
break
item = line.split(' ', 2)
if line.startswith('STAT active_slabs') or
line.startswith('STAT total_malloced'):
- serverData[item[1]]=item[2]
+ serverData[item[1]] = item[2]
else:
# 0 = STAT, 1 = ITEM, 2 = Value
slab = item[1].split(':', 2)
@@ -566,7 +553,7 @@
if not server:
return 0
self._statlog(cmd)
- if time is not None and time != 0:
+ if time is not None:
headers = str(time)
else:
headers = None
@@ -580,7 +567,7 @@
if line and line.strip() in expected:
return 1
self.debuglog('%s expected %s, got: %r'
- % (cmd, ' or '.join(expected), line))
+ % (cmd, b' or '.join(expected), line))
except socket.error as msg:
if isinstance(msg, tuple):
msg = msg[1]
@@ -729,9 +716,9 @@
routine. If the value being cached is a string, then the
length of the string is measured, else if the value is an
object, then the length of the pickle result is measured. If
- the resulting attempt at compression yeilds a larger string
+ the resulting attempt at compression yields a larger string
than the input, then it is discarded. For backwards
- compatability, this parameter defaults to 0, indicating don't
+ compatibility, this parameter defaults to 0, indicating don't
ever try to compress.
@param noreply: optional parameter instructs the server to not
@@ -766,9 +753,9 @@
routine. If the value being cached is a string, then the
length of the string is measured, else if the value is an
object, then the length of the pickle result is measured. If
- the resulting attempt at compression yeilds a larger string
+ the resulting attempt at compression yields a larger string
than the input, then it is discarded. For backwards
- compatability, this parameter defaults to 0, indicating don't
+ compatibility, this parameter defaults to 0, indicating don't
ever try to compress.
@param noreply: optional parameter instructs the server to not
@@ -777,7 +764,9 @@
return self._set("cas", key, val, time, min_compress_len, noreply)
def _map_and_prefix_keys(self, key_iterable, key_prefix):
- """Compute the mapping of server (_Host instance) -> list of keys to
+ """Map keys to the servers they will reside on.
+
+ Compute the mapping of server (_Host instance) -> list of keys to
stuff onto that server, as well as the mapping of prefixed key
-> original key.
"""
@@ -846,9 +835,9 @@
'''Sets multiple keys in the memcache doing just one query.
>>> notset_keys = mc.set_multi({'key1' : 'val1', 'key2' : 'val2'})
- >>> mc.get_multi(['key1', 'key2']) == {'key1' : 'val1',
- ... 'key2' : 'val2'}
- 1
+ >>> keys = mc.get_multi(['key1', 'key2'])
+ >>> keys == {'key1': 'val1', 'key2': 'val2'}
+ True
This method is recommended over regular L{set} as it lowers
@@ -868,14 +857,13 @@
sending to memcache. Allows you to efficiently stuff these
keys into a pseudo-namespace in memcache:
- >> notset_keys = mc.set_multi(
+ >>> notset_keys = mc.set_multi(
... {'key1' : 'val1', 'key2' : 'val2'},
... key_prefix='subspace_')
>>> len(notset_keys) == 0
True
- >>> mc.get_multi(['subspace_key1',
- ... 'subspace_key2']) == {'subspace_key1': 'val1',
- ... 'subspace_key2' : 'val2'}
+ >>> keys = mc.get_multi(['subspace_key1', 'subspace_key2'])
+ >>> keys == {'subspace_key1': 'val1', 'subspace_key2': 'val2'}
True
Causes key 'subspace_key1' and 'subspace_key2' to be
@@ -889,9 +877,9 @@
routine. If the value being cached is a string, then the
length of the string is measured, else if the value is an
object, then the length of the pickle result is
- measured. If the resulting attempt at compression yeilds a
+ measured. If the resulting attempt at compression yields a
larger string than the input, then it is discarded. For
- backwards compatability, this parameter defaults to 0,
+ backwards compatibility, this parameter defaults to 0,
indicating don't ever try to compress.
@param noreply: optional parameter instructs the server to not
@@ -968,18 +956,23 @@
the new value itself.
"""
flags = 0
- if isinstance(val, six.binary_type):
+ # Check against the exact type, rather than using isinstance(), so that
+ # subclasses of native types (such as markup-safe strings) are pickled
+ # and restored as instances of the correct class.
+ val_type = type(val)
+ if val_type == six.binary_type:
pass
- elif isinstance(val, six.text_type):
+ elif val_type == six.text_type:
+ flags |= Client._FLAG_TEXT
val = val.encode('utf-8')
- elif isinstance(val, int):
+ elif val_type == int:
flags |= Client._FLAG_INTEGER
val = '%d' % val
if six.PY3:
val = val.encode('ascii')
# force no attempt to compress this silly string.
min_compress_len = 0
- elif six.PY2 and isinstance(val, long):
+ elif six.PY2 and isinstance(val, long): # noqa: F821
flags |= Client._FLAG_LONG
val = str(val)
if six.PY3:
@@ -1012,7 +1005,7 @@
# silently do not store if value length exceeds maximum
if (self.server_max_value_length != 0 and
len(val) > self.server_max_value_length):
- return(0)
+ return 0
return (flags, len(val), val)
@@ -1033,7 +1026,7 @@
store_info = self._val_to_store_info(val, min_compress_len)
if not store_info:
- return(0)
+ return 0
flags, len_val, encoded_val = store_info
if cmd == 'cas':
@@ -1048,8 +1041,7 @@
server.send_cmd(fullcmd)
if noreply:
return True
- return(server.expect(b"STORED", raise_exception=True)
- == b"STORED")
+ return server.expect(b"STORED", raise_exception=True) ==
b"STORED"
except socket.error as msg:
if isinstance(msg, tuple):
msg = msg[1]
@@ -1154,7 +1146,7 @@
... key_prefix='pfx_') == {'k1' : 1, 'k2' : 2}
1
- get_mult [ and L{set_multi} ] can take str()-ables like ints /
+ get_multi [ and L{set_multi} ] can take str()-ables like ints /
longs as keys too. Such as your db pri key fields. They're
rotored through str() before being passed off to memcache,
with or without the use of a key_prefix. In this mode, the
@@ -1186,7 +1178,7 @@
prefix.
@return: A dictionary of key/value pairs that were
- available. If key_prefix was provided, the keys in the retured
+ available. If key_prefix was provided, the keys in the returned
dictionary will not have it present.
'''
@@ -1264,20 +1256,18 @@
if flags & Client._FLAG_COMPRESSED:
buf = self.decompressor(buf)
flags &= ~Client._FLAG_COMPRESSED
-
if flags == 0:
- # Bare string
- if six.PY3:
- val = buf.decode('utf8')
- else:
- val = buf
+ # Bare bytes
+ val = buf
+ elif flags & Client._FLAG_TEXT:
+ val = buf.decode('utf-8')
elif flags & Client._FLAG_INTEGER:
val = int(buf)
elif flags & Client._FLAG_LONG:
if six.PY3:
val = int(buf)
else:
- val = long(buf)
+ val = long(buf) # noqa: F821
elif flags & Client._FLAG_PICKLE:
try:
file = BytesIO(buf)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/releasescript.auto
new/python-memcached-1.59/releasescript.auto
--- old/python-memcached-1.58/releasescript.auto 1970-01-01
01:00:00.000000000 +0100
+++ new/python-memcached-1.59/releasescript.auto 2017-12-15
05:15:52.000000000 +0100
@@ -0,0 +1,5 @@
+#!/bin/sh
+#
+# Run when the .tar file is created, updates the .spec file.
+
+# All done in "do_release" now.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/setup.cfg
new/python-memcached-1.59/setup.cfg
--- old/python-memcached-1.58/setup.cfg 2016-05-27 22:06:00.000000000 +0200
+++ new/python-memcached-1.59/setup.cfg 2017-12-15 05:15:52.000000000 +0100
@@ -3,5 +3,8 @@
packager = Sean Reifschneider <[email protected]>
requires = python-memcached
+[flake8]
+ignore = H304,H405
+
[wheel]
universal = 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/setup.py
new/python-memcached-1.59/setup.py
--- old/python-memcached-1.58/setup.py 2016-05-27 22:06:00.000000000 +0200
+++ new/python-memcached-1.59/setup.py 2017-12-15 05:15:52.000000000 +0100
@@ -4,32 +4,33 @@
from setuptools import setup # noqa
-setup(name="python-memcached",
- version=get_module_constant('memcache', '__version__'),
- description="Pure python memcached client",
- long_description=open("README.md").read(),
- author="Evan Martin",
- author_email="[email protected]",
- maintainer="Sean Reifschneider",
- maintainer_email="[email protected]",
- url="http://www.tummy.com/Community/software/python-memcached/",
- download_url="ftp://ftp.tummy.com/pub/python-memcached/",
- py_modules=["memcache"],
- install_requires=open('requirements.txt').read().split(),
- classifiers=[
- "Development Status :: 5 - Production/Stable",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: Python Software Foundation License",
- "Operating System :: OS Independent",
- "Programming Language :: Python",
- "Topic :: Internet",
- "Topic :: Software Development :: Libraries :: Python Modules",
- "Programming Language :: Python",
- "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"
- ])
+setup(
+ name="python-memcached",
+ version=get_module_constant('memcache', '__version__'),
+ description="Pure python memcached client",
+ long_description=open("README.md").read(),
+ author="Evan Martin",
+ author_email="[email protected]",
+ maintainer="Sean Reifschneider",
+ maintainer_email="[email protected]",
+ url="http://www.tummy.com/Community/software/python-memcached/",
+ download_url="ftp://ftp.tummy.com/pub/python-memcached/",
+ py_modules=["memcache"],
+ install_requires=open('requirements.txt').read().split(),
+ classifiers=[
+ "Development Status :: 5 - Production/Stable",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: Python Software Foundation License",
+ "Operating System :: OS Independent",
+ "Programming Language :: Python",
+ "Topic :: Internet",
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 2",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.4",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: 3.6",
+ ],
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/test-requirements.txt
new/python-memcached-1.59/test-requirements.txt
--- old/python-memcached-1.58/test-requirements.txt 2016-05-27
22:06:00.000000000 +0200
+++ new/python-memcached-1.59/test-requirements.txt 2017-12-15
05:15:52.000000000 +0100
@@ -1,3 +1,4 @@
nose
coverage
hacking
+mock
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/tests/test_memcache.py
new/python-memcached-1.59/tests/test_memcache.py
--- old/python-memcached-1.58/tests/test_memcache.py 2016-05-27
22:06:00.000000000 +0200
+++ new/python-memcached-1.59/tests/test_memcache.py 2017-12-15
05:15:52.000000000 +0100
@@ -1,21 +1,13 @@
+# -*- coding: utf-8 -*-
from __future__ import print_function
import unittest
+import zlib
-import six
+import mock
-from memcache import Client, SERVER_MAX_KEY_LENGTH, SERVER_MAX_VALUE_LENGTH
-
-try:
- _str_cls = basestring
-except NameError:
- _str_cls = str
-
-
-def to_s(val):
- if not isinstance(val, _str_cls):
- return "%s (%s)" % (val, type(val))
- return "%s" % val
+from memcache import Client, _Host, SERVER_MAX_KEY_LENGTH,
SERVER_MAX_VALUE_LENGTH # noqa: H301
+from .utils import captured_stderr
class FooStruct(object):
@@ -34,11 +26,12 @@
class TestMemcache(unittest.TestCase):
def setUp(self):
- # TODO: unix socket server stuff
+ # TODO(): unix socket server stuff
servers = ["127.0.0.1:11211"]
self.mc = Client(servers, debug=1)
def tearDown(self):
+ self.mc.flush_all()
self.mc.disconnect_all()
def check_setget(self, key, val, noreply=False):
@@ -58,6 +51,13 @@
self.assertEqual(result, True)
self.assertEqual(self.mc.get("long"), None)
+ @mock.patch.object(_Host, 'send_cmd')
+ @mock.patch.object(_Host, 'readline')
+ def test_touch(self, mock_readline, mock_send_cmd):
+ with captured_stderr():
+ self.mc.touch('key')
+ mock_send_cmd.assert_called_with(b'touch key 0')
+
def test_get_multi(self):
self.check_setget("gm_a_string", "some random string")
self.check_setget("gm_an_integer", 42)
@@ -129,7 +129,7 @@
self.check_setget("bool", True)
def test_unicode_key(self):
- s = six.u('\u4f1a')
+ s = u'\u4f1a'
maxlen = SERVER_MAX_KEY_LENGTH // len(s.encode('utf-8'))
key = s * maxlen
@@ -137,6 +137,32 @@
value = self.mc.get(key)
self.assertEqual(value, 5)
+ def test_unicode_value(self):
+ key = 'key'
+ value = u'Iñtërnâtiônàlizætiøn2'
+ self.mc.set(key, value)
+ cached_value = self.mc.get(key)
+ self.assertEqual(value, cached_value)
+
+ def test_binary_string(self):
+ value = 'value_to_be_compressed'
+ compressed_value = zlib.compress(value.encode())
+
+ self.mc.set('binary1', compressed_value)
+ compressed_result = self.mc.get('binary1')
+ self.assertEqual(compressed_value, compressed_result)
+ self.assertEqual(value, zlib.decompress(compressed_result).decode())
+
+ self.mc.add('binary1-add', compressed_value)
+ compressed_result = self.mc.get('binary1-add')
+ self.assertEqual(compressed_value, compressed_result)
+ self.assertEqual(value, zlib.decompress(compressed_result).decode())
+
+ self.mc.set_multi({'binary1-set_many': compressed_value})
+ compressed_result = self.mc.get('binary1-set_many')
+ self.assertEqual(compressed_value, compressed_result)
+ self.assertEqual(value, zlib.decompress(compressed_result).decode())
+
def test_ignore_too_large_value(self):
# NOTE: "MemCached: while expecting[...]" is normal...
key = 'keyhere'
@@ -146,7 +172,13 @@
self.assertEqual(self.mc.get(key), value)
value = 'a' * SERVER_MAX_VALUE_LENGTH
- self.assertFalse(self.mc.set(key, value))
+ with captured_stderr() as log:
+ self.assertIs(self.mc.set(key, value), False)
+ self.assertEqual(
+ log.getvalue(),
+ "MemCached: while expecting 'STORED', got unexpected response "
+ "'SERVER_ERROR object too large for cache'\n"
+ )
# This test fails if the -I option is used on the memcached server
self.assertTrue(self.mc.get(key) is None)
@@ -166,16 +198,38 @@
"""Testing set_multi() with no memcacheds running."""
self.mc.disconnect_all()
- for server in self.mc.servers:
- server.mark_dead('test')
+ with captured_stderr() as log:
+ for server in self.mc.servers:
+ server.mark_dead('test')
+ self.assertIn('Marking dead.', log.getvalue())
errors = self.mc.set_multi({'key1': 'a', 'key2': 'b'})
self.assertEqual(sorted(errors), ['key1', 'key2'])
def test_disconnect_all_delete_multi(self):
"""Testing delete_multi() with no memcacheds running."""
self.mc.disconnect_all()
- ret = self.mc.delete_multi({'keyhere': 'a', 'keythere': 'b'})
+ with captured_stderr() as output:
+ ret = self.mc.delete_multi(('keyhere', 'keythere'))
self.assertEqual(ret, 1)
+ self.assertEqual(
+ output.getvalue(),
+ "MemCached: while expecting 'DELETED', got unexpected response "
+ "'NOT_FOUND'\n"
+ "MemCached: while expecting 'DELETED', got unexpected response "
+ "'NOT_FOUND'\n"
+ )
+
+ @mock.patch.object(_Host, 'send_cmd') # Don't send any commands.
+ @mock.patch.object(_Host, 'readline')
+ def test_touch_unexpected_reply(self, mock_readline, mock_send_cmd):
+ """touch() logs an error upon receiving an unexpected reply."""
+ mock_readline.return_value = 'SET' # the unexpected reply
+ with captured_stderr() as output:
+ self.mc.touch('key')
+ self.assertEqual(
+ output.getvalue(),
+ "MemCached: touch expected %s, got: 'SET'\n" % b'TOUCHED'
+ )
if __name__ == '__main__':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/tests/test_setmulti.py
new/python-memcached-1.59/tests/test_setmulti.py
--- old/python-memcached-1.58/tests/test_setmulti.py 2016-05-27
22:06:00.000000000 +0200
+++ new/python-memcached-1.59/tests/test_setmulti.py 2017-12-15
05:15:52.000000000 +0100
@@ -13,8 +13,10 @@
import sys
import unittest
+from .utils import captured_stderr
+
sys.path.append('..')
-import memcache
+import memcache # noqa: E402
DEBUG = False
@@ -60,10 +62,10 @@
def test_Socket_Disconnect(self):
mapping = {'foo': 'FOO', 'bar': 'BAR'}
- bad_keys = self.mc.set_multi(mapping)
-
+ with captured_stderr() as log:
+ bad_keys = self.mc.set_multi(mapping)
+ self.assertIn('connection closed in readline().', log.getvalue())
self.assertEqual(sorted(bad_keys), ['bar', 'foo'])
-
if DEBUG:
print('set_multi({0!r}) -> {1!r}'.format(mapping, bad_keys))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/tests/utils.py
new/python-memcached-1.59/tests/utils.py
--- old/python-memcached-1.58/tests/utils.py 1970-01-01 01:00:00.000000000
+0100
+++ new/python-memcached-1.59/tests/utils.py 2017-12-15 05:15:52.000000000
+0100
@@ -0,0 +1,30 @@
+from contextlib import contextmanager
+import sys
+
+from six import StringIO
+
+
+@contextmanager
+def captured_output(stream_name):
+ """Return a context manager used by captured_stdout/stdin/stderr
+ that temporarily replaces the sys stream *stream_name* with a StringIO.
+
+ This function and the following ``captured_std*`` are copied
+ from CPython's ``test.support`` module.
+ """
+ orig_stdout = getattr(sys, stream_name)
+ setattr(sys, stream_name, StringIO())
+ try:
+ yield getattr(sys, stream_name)
+ finally:
+ setattr(sys, stream_name, orig_stdout)
+
+
+def captured_stderr():
+ """Capture the output of sys.stderr:
+
+ with captured_stderr() as stderr:
+ print('hello', file=sys.stderr)
+ self.assertEqual(stderr.getvalue(), 'hello\n')
+ """
+ return captured_output('stderr')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-memcached-1.58/tox.ini
new/python-memcached-1.59/tox.ini
--- old/python-memcached-1.58/tox.ini 2016-05-27 22:06:00.000000000 +0200
+++ new/python-memcached-1.59/tox.ini 2017-12-15 05:15:52.000000000 +0100
@@ -1,6 +1,6 @@
[tox]
minversion = 1.6
-envlist = py26,py27,py32,py33,py34,pypy,pep8
+envlist = py27,py34,py35,p36,pypy,pep8
skipsdist = True
[testenv]
@@ -23,4 +23,5 @@
commands = nosetests --with-coverage {posargs}
[flake8]
-exclude =
.venv*,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*.egg,.update-venv
+exclude =
.venv*,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*.egg,.update-venv,build
+max-line-length = 119