Hello community,

here is the log from the commit of package python-repoze.lru for 
openSUSE:Factory checked in at 2017-12-04 10:01:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-repoze.lru (Old)
 and      /work/SRC/openSUSE:Factory/.python-repoze.lru.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-repoze.lru"

Mon Dec  4 10:01:16 2017 rev:9 rq:544313 version:0.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-repoze.lru/python-repoze.lru.changes      
2017-08-24 18:33:01.281177712 +0200
+++ /work/SRC/openSUSE:Factory/.python-repoze.lru.new/python-repoze.lru.changes 
2017-12-04 10:01:17.694770238 +0100
@@ -1,0 +2,5 @@
+Wed Nov 15 00:06:03 UTC 2017 - [email protected]
+
+- update to 0.7 
+
+-------------------------------------------------------------------

Old:
----
  repoze.lru-0.6.tar.gz

New:
----
  repoze.lru-0.7.tar.gz

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

Other differences:
------------------
++++++ python-repoze.lru.spec ++++++
--- /var/tmp/diff_new_pack.3vpkev/_old  2017-12-04 10:01:18.462742365 +0100
+++ /var/tmp/diff_new_pack.3vpkev/_new  2017-12-04 10:01:18.466742219 +0100
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-repoze.lru
-Version:        0.6
+Version:        0.7
 Release:        0
 Summary:        A tiny LRU cache implementation and decorator
 License:        SUSE-Repoze
@@ -50,7 +50,7 @@
 
 %files %{python_files}
 %defattr(-,root,root,-)
-%doc CHANGES.txt COPYRIGHT.txt LICENSE.txt README.txt
+%doc LICENSE.txt
 %{python_sitelib}/*
 
 %changelog

++++++ repoze.lru-0.6.tar.gz -> repoze.lru-0.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/.coveragerc 
new/repoze.lru-0.7/.coveragerc
--- old/repoze.lru-0.6/.coveragerc      1970-01-01 01:00:00.000000000 +0100
+++ new/repoze.lru-0.7/.coveragerc      2016-11-12 23:29:27.000000000 +0100
@@ -0,0 +1,3 @@
+[report]
+show_missing = True
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/.travis.yml 
new/repoze.lru-0.7/.travis.yml
--- old/repoze.lru-0.6/.travis.yml      1970-01-01 01:00:00.000000000 +0100
+++ new/repoze.lru-0.7/.travis.yml      2016-11-12 23:48:42.000000000 +0100
@@ -0,0 +1,26 @@
+# Wire up travis
+language: python
+sudo: false
+
+matrix:
+  include:
+    - python: 3.5
+      env: TOXENV=py35
+
+env:
+  - TOXENV=py27
+  - TOXENV=py33
+  - TOXENV=py34
+  - TOXENV=pypy
+  - TOXENV=pypy3
+  - TOXENV=cover
+
+install:
+  - travis_retry pip install tox
+
+script:
+  - travis_retry tox
+
+notifications:
+  email:
+    - [email protected]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/CHANGES.txt 
new/repoze.lru-0.7/CHANGES.txt
--- old/repoze.lru-0.6/CHANGES.txt      2012-07-12 20:45:06.000000000 +0200
+++ new/repoze.lru-0.7/CHANGES.txt      1970-01-01 01:00:00.000000000 +0100
@@ -1,72 +0,0 @@
-Changelog
-=========
-
-0.6 (2012-07-12)
-----------------
-
-- Added a 'CacheMaker' helper class:  a maker keeps references (by name)
-  to the caches it creates, to permit them to be cleared.
-
-- Added statistics to each cache, tracking lookups, hits, misses, and
-  evictions.
-
-- Automated building Sphinx docs and testing example snippets under ``tox``.
-
-- Added Sphinx documentation.
-
-- Dropped support for Python 2.5.
-
-- Added support for PyPy.
-
-- Added ``setup.py docs`` alias (installs ``Sphinx`` and dependencies).
-
-- Added ``setup.py dev`` alias (runs ``develop`` plus installs ``nose``
-  and ``coverage``).
-
-- Added support for CI under supported Pythons using ``tox``.
-
-- Bug: Remove potential race condition on lock in face of interrupts
-  (Issue #10).
-
-0.5 (2012-03-24)
-----------------
-
-- Feature: added a new "invalidate()" method to allow removal of items from
-  the cache (issue #8).
-
-- Bug: LRUCache.put() could take multiple seconds on large caches (Issue #7).
-
-- Bug: LRUCache was not thread safe (Issue #6).
-
-- Bug: LRUCache.clock would waste RAM (Issue #4).
-
-- Bug: repeated pushing of an entry would remove other cache entries
-  (Issue #3).
-
-- Bug: LRUCache would evict entries even when not full (Issue #2).
-
-0.4 (2011-09-04)
-----------------
-
-- Moved to GitHub (https://github.com/repoze/repoze.lru).
-
-- Added Python 3.2 support.
-
-- Python 2.4 no longer supported.
-
-- Added tox.ini for easier testing.
-
-0.3 (2009/06/16)
-----------------
-
-- Add a thread lock around ``clear`` logic.
-
-0.2 (2009/06/15)
-----------------
-
-- Add a ``clear`` method.
-
-0.1 (2009/06/14)
-----------------
-
-- Initial release.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/CONTRIBUTORS.txt 
new/repoze.lru-0.7/CONTRIBUTORS.txt
--- old/repoze.lru-0.6/CONTRIBUTORS.txt 2012-07-05 15:36:30.000000000 +0200
+++ new/repoze.lru-0.7/CONTRIBUTORS.txt 2016-11-12 23:10:28.000000000 +0100
@@ -106,3 +106,4 @@
 - Tres Seaver, 2011/02/22
 - Joel Bohman, 2011/08/16
 - Julien Tayon, 2012/07/04
+- Cosmin Basca, 2014/07/12
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/PKG-INFO new/repoze.lru-0.7/PKG-INFO
--- old/repoze.lru-0.6/PKG-INFO 2012-07-12 20:48:37.000000000 +0200
+++ new/repoze.lru-0.7/PKG-INFO 2017-09-07 07:00:09.000000000 +0200
@@ -1,103 +1,24 @@
 Metadata-Version: 1.1
 Name: repoze.lru
-Version: 0.6
+Version: 0.7
 Summary: A tiny LRU cache implementation and decorator
 Home-page: http://www.repoze.org
 Author: Agendaless Consulting
 Author-email: [email protected]
 License: BSD-derived (http://www.repoze.org/LICENSE.txt)
-Description: repoze.lru
-        ==========
+Description: 
         
-        ``repoze.lru`` is a LRU (least recently used) cache implementation.  
Keys and
-        values that are not used frequently will be evicted from the cache 
faster
-        than keys and values that are used frequently.  It works under Python 
2.5,
-        Python 2.6, Python 2.7, and Python 3.2.
-        
-        Please see ``docs/index.rst`` for detailed documentation.
-        
-        
-        Changelog
-        =========
-        
-        0.6 (2012-07-12)
-        ----------------
-        
-        - Added a 'CacheMaker' helper class:  a maker keeps references (by 
name)
-          to the caches it creates, to permit them to be cleared.
-        
-        - Added statistics to each cache, tracking lookups, hits, misses, and
-          evictions.
-        
-        - Automated building Sphinx docs and testing example snippets under 
``tox``.
-        
-        - Added Sphinx documentation.
-        
-        - Dropped support for Python 2.5.
-        
-        - Added support for PyPy.
-        
-        - Added ``setup.py docs`` alias (installs ``Sphinx`` and dependencies).
-        
-        - Added ``setup.py dev`` alias (runs ``develop`` plus installs ``nose``
-          and ``coverage``).
-        
-        - Added support for CI under supported Pythons using ``tox``.
-        
-        - Bug: Remove potential race condition on lock in face of interrupts
-          (Issue #10).
-        
-        0.5 (2012-03-24)
-        ----------------
-        
-        - Feature: added a new "invalidate()" method to allow removal of items 
from
-          the cache (issue #8).
-        
-        - Bug: LRUCache.put() could take multiple seconds on large caches 
(Issue #7).
-        
-        - Bug: LRUCache was not thread safe (Issue #6).
-        
-        - Bug: LRUCache.clock would waste RAM (Issue #4).
-        
-        - Bug: repeated pushing of an entry would remove other cache entries
-          (Issue #3).
-        
-        - Bug: LRUCache would evict entries even when not full (Issue #2).
-        
-        0.4 (2011-09-04)
-        ----------------
-        
-        - Moved to GitHub (https://github.com/repoze/repoze.lru).
-        
-        - Added Python 3.2 support.
-        
-        - Python 2.4 no longer supported.
-        
-        - Added tox.ini for easier testing.
-        
-        0.3 (2009/06/16)
-        ----------------
-        
-        - Add a thread lock around ``clear`` logic.
-        
-        0.2 (2009/06/15)
-        ----------------
-        
-        - Add a ``clear`` method.
-        
-        0.1 (2009/06/14)
-        ----------------
-        
-        - Initial release.
         
 Keywords: repoze lru cache
 Platform: UNKNOWN
 Classifier: Intended Audience :: Developers
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: License :: Repoze Public License
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/README.rst 
new/repoze.lru-0.7/README.rst
--- old/repoze.lru-0.6/README.rst       1970-01-01 01:00:00.000000000 +0100
+++ new/repoze.lru-0.7/README.rst       2017-09-07 06:53:52.000000000 +0200
@@ -0,0 +1,9 @@
+repoze.lru
+==========
+
+``repoze.lru`` is a LRU (least recently used) cache implementation.  Keys and
+values that are not used frequently will be evicted from the cache faster
+than keys and values that are used frequently.  It works under Python 2.7 and 
Python 3.4+.
+
+Please see ``docs/index.rst`` for detailed documentation, or view them
+online at http://docs.repoze.org/lru/.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/README.txt 
new/repoze.lru-0.7/README.txt
--- old/repoze.lru-0.6/README.txt       2012-06-11 23:14:39.000000000 +0200
+++ new/repoze.lru-0.7/README.txt       1970-01-01 01:00:00.000000000 +0100
@@ -1,9 +0,0 @@
-repoze.lru
-==========
-
-``repoze.lru`` is a LRU (least recently used) cache implementation.  Keys and
-values that are not used frequently will be evicted from the cache faster
-than keys and values that are used frequently.  It works under Python 2.5,
-Python 2.6, Python 2.7, and Python 3.2.
-
-Please see ``docs/index.rst`` for detailed documentation.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/repoze/__init__.py 
new/repoze.lru-0.7/repoze/__init__.py
--- old/repoze.lru-0.6/repoze/__init__.py       2011-02-25 16:23:45.000000000 
+0100
+++ new/repoze.lru-0.7/repoze/__init__.py       2013-06-24 20:58:51.000000000 
+0200
@@ -1 +1,4 @@
-__import__('pkg_resources').declare_namespace(__name__)
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    __path__ = __import__('pkgutil').extend_path(__path__, __name__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/repoze/lru/__init__.py 
new/repoze.lru-0.7/repoze/lru/__init__.py
--- old/repoze.lru-0.6/repoze/lru/__init__.py   2012-07-05 15:36:30.000000000 
+0200
+++ new/repoze.lru-0.7/repoze/lru/__init__.py   2016-11-13 00:58:23.000000000 
+0100
@@ -1,5 +1,6 @@
 """ LRU caching class and decorator """
-from __future__ import with_statement
+from abc import abstractmethod
+from abc import ABCMeta
 
 import threading
 import time
@@ -12,7 +13,51 @@
 _DEFAULT_TIMEOUT = 2 ** 60
 
 
-class LRUCache(object):
+class Cache(object):
+    __metaclass__ = ABCMeta
+
+    @abstractmethod
+    def clear(self):
+        """Remove all entries from the cache"""
+
+    @abstractmethod
+    def get(self, key, default=None):
+        """Return value for key. If not in cache, return default"""
+
+    @abstractmethod
+    def put(self, key, val):
+        """Add key to the cache with value val"""
+
+    @abstractmethod
+    def invalidate(self, key):
+        """Remove key from the cache"""
+
+
+class UnboundedCache(Cache):
+    """
+    a simple unbounded cache backed by a dictionary
+    """
+
+    def __init__(self):
+        self._data = dict()
+
+    def get(self, key, default=None):
+        return self._data.get(key, default)
+
+    def clear(self):
+        self._data.clear()
+
+    def invalidate(self, key):
+        try:
+            del self._data[key]
+        except KeyError:
+            pass
+
+    def put(self, key, val):
+        self._data[key] = val
+
+
+class LRUCache(Cache):
     """ Implements a pseudo-LRU algorithm (CLOCK)
 
     The Clock algorithm is not kept strictly to improve performance, e.g. to
@@ -130,7 +175,7 @@
         # else: key was not in cache. Nothing to do.
 
 
-class ExpiringLRUCache(object):
+class ExpiringLRUCache(Cache):
     """ Implements a pseudo-LRU algorithm (CLOCK) with expiration times
 
     The Clock algorithm is not kept strictly to improve performance, e.g. to
@@ -270,27 +315,50 @@
     timeout parameter specifies after how many seconds a cached entry should
     be considered invalid.
     """
-    def __init__(self, maxsize, cache=None, timeout=None): # cache is an arg 
to serve tests
+    def __init__(self,
+                 maxsize,
+                 cache=None, # cache is an arg to serve tests
+                 timeout=None,
+                 ignore_unhashable_args=False):
         if cache is None:
-            if timeout is None:
+            if maxsize is None:
+                cache = UnboundedCache()
+            elif timeout is None:
                 cache = LRUCache(maxsize)
             else:
                 cache = ExpiringLRUCache(maxsize, default_timeout=timeout)
         self.cache = cache
+        self._ignore_unhashable_args = ignore_unhashable_args
 
-    def __call__(self, f):
+    def __call__(self, func):
         cache = self.cache
         marker = _MARKER
-        def lru_cached(*arg):
-            val = cache.get(arg, marker)
-            if val is marker:
-                val = f(*arg)
-                cache.put(arg, val)
-            return val
-        lru_cached.__module__ = f.__module__
-        lru_cached.__name__ = f.__name__
-        lru_cached.__doc__ = f.__doc__
-        return lru_cached
+
+        def cached_wrapper(*args, **kwargs):
+            try:
+                key = (args, frozenset(kwargs.items())) if kwargs else args
+            except TypeError as e:
+                if self._ignore_unhashable_args:
+                    return func(*args, **kwargs)
+                else:
+                    raise e
+            else:
+                val = cache.get(key, marker)
+                if val is marker:
+                    val = func(*args, **kwargs)
+                    cache.put(key, val)
+                return val
+
+        def _maybe_copy(source, target, attr):
+            value = getattr(source, attr, source)
+            if value is not source:
+                setattr(target, attr, value)
+
+        _maybe_copy(func, cached_wrapper, '__module__')
+        _maybe_copy(func, cached_wrapper, '__name__')
+        _maybe_copy(func, cached_wrapper, '__doc__')
+        cached_wrapper._cache = cache
+        return cached_wrapper
 
 
 class CacheMaker(object):
@@ -312,7 +380,7 @@
             while True:
                 name = str(uuid.uuid4())
                 ## the probability of collision is so low ....
-                if name not in self._cache:
+                if name not in self._cache:  # pragma: NO COVER
                     break
 
         if name in self._cache:
@@ -328,7 +396,12 @@
             timeout = self._timeout
 
         return name, maxsize, timeout
-    
+
+    def memoized(self, name=None):
+        name, maxsize, _ = self._resolve_setting(name, 0)
+        cache = self._cache[name] = UnboundedCache()
+        return lru_cache(None, cache)
+
     def lrucache(self, name=None, maxsize=None):
         """Named arguments:
         
@@ -350,12 +423,12 @@
           the constructor
 
         - timeout (optional) is an int, overriding any default value set by
-          the constructor or the default value (%d seconds)  
+          the constructor or the default value (%d seconds)
         """ % _DEFAULT_TIMEOUT
         name, maxsize, timeout = self._resolve_setting(name, maxsize, timeout)
         cache = self._cache[name] = ExpiringLRUCache(maxsize, timeout)
         return lru_cache(maxsize, cache, timeout)
-    
+
     def clear(self, *names):
         """Clear the given cache(s).
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/repoze/lru/tests.py 
new/repoze.lru-0.7/repoze/lru/tests.py
--- old/repoze.lru-0.6/repoze/lru/tests.py      2012-07-05 15:36:30.000000000 
+0200
+++ new/repoze.lru-0.7/repoze/lru/tests.py      2016-11-13 01:53:11.000000000 
+0100
@@ -8,14 +8,67 @@
     pass
 
 
+class UnboundedCacheTests(unittest.TestCase):
+
+    def _getTargetClass(self):
+        from repoze.lru import UnboundedCache
+        return UnboundedCache
+
+    def _makeOne(self):
+        return self._getTargetClass()()
+
+    def test_ctor(self):
+        cache = self._makeOne()
+        self.assertEqual(cache._data, {})
+
+    def test_get_miss_no_default(self):
+        cache = self._makeOne()
+        self.assertIsNone(cache.get('nonesuch'))
+
+    def test_get_miss_explicit_default(self):
+        cache = self._makeOne()
+        default = object()
+        self.assertIs(cache.get('nonesuch', default), default)
+
+    def test_get_hit(self):
+        cache = self._makeOne()
+        extant = cache._data['extant'] = object()
+        self.assertIs(cache.get('extant'), extant)
+
+    def test_clear(self):
+        cache = self._makeOne()
+        extant = cache._data['extant'] = object()
+        cache.clear()
+        self.assertIsNone(cache.get('extant'))
+
+    def test_invalidate_miss(self):
+        cache = self._makeOne()
+        cache.invalidate('nonesuch')  # does not raise
+
+    def test_invalidate_hit(self):
+        cache = self._makeOne()
+        extant = cache._data['extant'] = object()
+        cache.invalidate('extant')
+        self.assertIsNone(cache.get('extant'))
+
+    def test_put(self):
+        cache = self._makeOne()
+        extant = object()
+        cache.put('extant', extant)
+        self.assertIs(cache._data['extant'], extant)
+
+
 class LRUCacheTests(unittest.TestCase):
 
     def _getTargetClass(self):
         from repoze.lru import LRUCache
         return LRUCache
 
+    def _makeOne(self, size):
+        return self._getTargetClass()(size)
+
     def check_cache_is_consistent(self, cache):
-        """Return if cache is consistent, else raise fail test case."""
+        #Return if cache is consistent, else raise fail test case.
         # cache.hand/maxpos/size
         self.assertTrue(cache.hand < len(cache.clock_keys))
         self.assertTrue(cache.hand >= 0)
@@ -45,21 +98,18 @@
         for clock_ref in cache.clock_refs:
             self.assertTrue(clock_ref is True or clock_ref is False)
 
-    def _makeOne(self, size):
-        return self._getTargetClass()(size)
-
     def test_size_lessthan_1(self):
         self.assertRaises(ValueError, self._makeOne, 0)
 
     def test_get(self):
         cache = self._makeOne(1)
         # Must support different types of keys
-        self.assertEqual(cache.get("foo"), None)
-        self.assertEqual(cache.get(42), None)
-        self.assertEqual(cache.get(("foo", 42)), None)
-        self.assertEqual(cache.get(None), None)
-        self.assertEqual(cache.get(""), None)
-        self.assertEqual(cache.get(object()), None)
+        self.assertIsNone(cache.get("foo"))
+        self.assertIsNone(cache.get(42))
+        self.assertIsNone(cache.get(("foo", 42)))
+        self.assertIsNone(cache.get(None))
+        self.assertIsNone(cache.get(""))
+        self.assertIsNone(cache.get(object()))
         # Check if default value is used
         self.assertEqual(cache.get("foo", "bar"), "bar")
         self.assertEqual(cache.get("foo", default="bar"), "bar")
@@ -101,24 +151,24 @@
         cache.put("FOO", "BAR")
 
         cache.invalidate("foo")
-        self.assertEqual(cache.get("foo"), None)
+        self.assertIsNone(cache.get("foo"))
         self.assertEqual(cache.get("FOO"), "BAR")
         self.check_cache_is_consistent(cache)
 
         cache.invalidate("FOO")
-        self.assertEqual(cache.get("foo"), None)
-        self.assertEqual(cache.get("FOO"), None)
+        self.assertIsNone(cache.get("foo"))
+        self.assertIsNone(cache.get("FOO"))
         self.assertEqual(cache.data, {})
         self.check_cache_is_consistent(cache)
 
         cache.put("foo", "bar")
         cache.invalidate("nonexistingkey")
         self.assertEqual(cache.get("foo"), "bar")
-        self.assertEqual(cache.get("FOO"), None)
+        self.assertIsNone(cache.get("FOO"))
         self.check_cache_is_consistent(cache)
 
     def test_small_cache(self):
-        """Cache of size 1 must work"""
+        #Cache of size 1 must work
         cache = self._makeOne(1)
 
         cache.put("foo", "bar")
@@ -127,31 +177,31 @@
 
         cache.put("FOO", "BAR")
         self.assertEqual(cache.get("FOO"), "BAR")
-        self.assertEqual(cache.get("foo"), None)
+        self.assertIsNone(cache.get("foo"))
         self.check_cache_is_consistent(cache)
 
         # put() again
         cache.put("FOO", "BAR")
         self.assertEqual(cache.get("FOO"), "BAR")
-        self.assertEqual(cache.get("foo"), None)
+        self.assertIsNone(cache.get("foo"))
         self.check_cache_is_consistent(cache)
 
         # invalidate()
         cache.invalidate("FOO")
         self.check_cache_is_consistent(cache)
-        self.assertEqual(cache.get("FOO"), None)
-        self.assertEqual(cache.get("foo"), None)
+        self.assertIsNone(cache.get("FOO"))
+        self.assertIsNone(cache.get("foo"))
 
         # clear()
         cache.put("foo", "bar")
         self.assertEqual(cache.get("foo"), "bar")
         cache.clear()
         self.check_cache_is_consistent(cache)
-        self.assertEqual(cache.get("FOO"), None)
-        self.assertEqual(cache.get("foo"), None)
+        self.assertIsNone(cache.get("FOO"))
+        self.assertIsNone(cache.get("foo"))
 
     def test_equal_but_not_identical(self):
-        """equal but not identical keys must be treated the same"""
+        #equal but not identical keys must be treated the same
         cache = self._makeOne(1)
         tuple_one = (1, 1)
         tuple_two = (1, 1)
@@ -164,11 +214,11 @@
         cache = self._makeOne(1)
         cache.put(tuple_one, 42)
         cache.invalidate(tuple_two)
-        self.assertEqual(cache.get(tuple_one), None)
-        self.assertEqual(cache.get(tuple_two), None)
+        self.assertIsNone(cache.get(tuple_one))
+        self.assertIsNone(cache.get(tuple_two))
 
     def test_perfect_hitrate(self):
-        """If cache size equals number of items, expect 100% cache hits"""
+        #If cache size equals number of items, expect 100% cache hits
         size = 1000
         cache = self._makeOne(size)
 
@@ -188,7 +238,7 @@
         self.check_cache_is_consistent(cache)
 
     def test_imperfect_hitrate(self):
-        """If cache size == half the number of items -> hit rate ~50%"""
+        #If cache size == half the number of items -> hit rate ~50%
         size = 1000
         cache = self._makeOne(size / 2)
 
@@ -250,7 +300,7 @@
 
     def test_it(self):
         cache = self._makeOne(3)
-        self.assertEqual(cache.get('a'), None)
+        self.assertIsNone(cache.get('a'))
 
         cache.put('a', '1')
         pos, value = cache.data.get('a')
@@ -286,17 +336,17 @@
         # because "a" is the first item with ref==False that is found.
         cache.put('d', '4')
         self.assertEqual(len(cache.data), 3)
-        self.assertEqual(cache.data.get('a'), None)
+        self.assertIsNone(cache.data.get('a'))
 
         # Only item "d" has ref==True. cache.hand points at "b", so "b"
         # will be evicted when "e" is inserted. "c" will be left alone.
         cache.put('e', '5')
         self.assertEqual(len(cache.data), 3)
-        self.assertEqual(cache.data.get('b'), None)
+        self.assertIsNone(cache.data.get('b'))
         self.assertEqual(cache.get('d'), '4')
         self.assertEqual(cache.get('e'), '5')
-        self.assertEqual(cache.get('a'), None)
-        self.assertEqual(cache.get('b'), None)
+        self.assertIsNone(cache.get('a'))
+        self.assertIsNone(cache.get('b'))
         self.assertEqual(cache.get('c'), '3')
 
         self.check_cache_is_consistent(cache)
@@ -312,14 +362,14 @@
         if default_timeout is None:
             return self._getTargetClass()(size)
         else:
-            return self._getTargetClass()(size, 
default_timeout=default_timeout)
+            return self._getTargetClass()(
+                size, default_timeout=default_timeout)
 
     def check_cache_is_consistent(self, cache):
-        """Return if cache is consistent, else raise fail test case.
-
-        This is slightly different for ExpiringLRUCache since self.data
-        contains 3-tuples instead of 2-tuples.
-        """
+        #Return if cache is consistent, else raise fail test case.
+        #
+        #This is slightly different for ExpiringLRUCache since self.data
+        #contains 3-tuples instead of 2-tuples.
         # cache.hand/maxpos/size
         self.assertTrue(cache.hand < len(cache.clock_keys))
         self.assertTrue(cache.hand >= 0)
@@ -351,12 +401,11 @@
             self.assertTrue(clock_ref is True or clock_ref is False)
 
     def test_it(self):
-        """Test a sequence of operations
-
-        Looks at internal data, which is different for ExpiringLRUCache.
-        """
+        #Test a sequence of operations
+        #
+        # Looks at internal data, which is different for ExpiringLRUCache.
         cache = self._makeOne(3)
-        self.assertEqual(cache.get('a'), None)
+        self.assertIsNone(cache.get('a'))
 
         cache.put('a', '1')
         pos, value, expires = cache.data.get('a')
@@ -392,23 +441,23 @@
         # because "a" is the first item with ref==False that is found.
         cache.put('d', '4')
         self.assertEqual(len(cache.data), 3)
-        self.assertEqual(cache.data.get('a'), None)
+        self.assertIsNone(cache.data.get('a'))
 
         # Only item "d" has ref==True. cache.hand points at "b", so "b"
         # will be evicted when "e" is inserted. "c" will be left alone.
         cache.put('e', '5')
         self.assertEqual(len(cache.data), 3)
-        self.assertEqual(cache.data.get('b'), None)
+        self.assertIsNone(cache.data.get('b'))
         self.assertEqual(cache.get('d'), '4')
         self.assertEqual(cache.get('e'), '5')
-        self.assertEqual(cache.get('a'), None)
-        self.assertEqual(cache.get('b'), None)
+        self.assertIsNone(cache.get('a'))
+        self.assertIsNone(cache.get('b'))
         self.assertEqual(cache.get('c'), '3')
 
         self.check_cache_is_consistent(cache)
 
     def test_default_timeout(self):
-        """Default timeout provided at init time must be applied"""
+        #Default timeout provided at init time must be applied.
         # Provide no default timeout -> entries must remain valid
         cache = self._makeOne(3)
         cache.put("foo", "bar")
@@ -425,12 +474,12 @@
 
         time.sleep(0.1)
         cache.put("FOO", "BAR")
-        self.assertEqual(cache.get("foo"), None)
+        self.assertIsNone(cache.get("foo"))
         self.assertEqual(cache.get("FOO"), "BAR")
         self.check_cache_is_consistent(cache)
 
     def test_different_timeouts(self):
-        """Timeouts must be per entry, default applied when none provided"""
+        #Timeouts must be per entry, default applied when none provided
         cache = self._makeOne(3, default_timeout=0.1)
 
         cache.put("one", 1)
@@ -444,26 +493,26 @@
 
         # Entry "one" must expire, "two"/"three" remain valid
         time.sleep(0.1)
-        self.assertEqual(cache.get("one"), None)
+        self.assertIsNone(cache.get("one"))
         self.assertEqual(cache.get("two"), 2)
         self.assertEqual(cache.get("three"), 3)
 
         # Only "three" remains valid
         time.sleep(0.1)
-        self.assertEqual(cache.get("one"), None)
-        self.assertEqual(cache.get("two"), None)
+        self.assertIsNone(cache.get("one"))
+        self.assertIsNone(cache.get("two"))
         self.assertEqual(cache.get("three"), 3)
 
         # All have expired
         time.sleep(0.1)
-        self.assertEqual(cache.get("one"), None)
-        self.assertEqual(cache.get("two"), None)
-        self.assertEqual(cache.get("three"), None)
+        self.assertIsNone(cache.get("one"))
+        self.assertIsNone(cache.get("two"))
+        self.assertIsNone(cache.get("three"))
 
         self.check_cache_is_consistent(cache)
 
     def test_renew_timeout(self):
-        """Re-putting an entry must update timeout"""
+        #Re-putting an entry must update timeout
         cache = self._makeOne(3, default_timeout=0.2)
 
         cache.put("foo", "bar")
@@ -485,7 +534,7 @@
         time.sleep(0.1)
         # "foo2" must have expired
         self.assertEqual(cache.get("foo"), "bar")
-        self.assertEqual(cache.get("foo2"), None)
+        self.assertIsNone(cache.get("foo2"))
         self.assertEqual(cache.get("foo3"), "bar3")
         self.check_cache_is_consistent(cache)
 
@@ -496,8 +545,27 @@
         from repoze.lru import lru_cache
         return lru_cache
 
-    def _makeOne(self, maxsize, cache, timeout=None):
-        return self._getTargetClass()(maxsize, timeout=timeout, cache=cache)
+    def _makeOne(self, *args, **kw):
+        return self._getTargetClass()(*args, **kw)
+
+    def test_ctor_no_size(self):
+        from repoze.lru import UnboundedCache
+        decorator = self._makeOne(maxsize=None)
+        self.assertIsInstance(decorator.cache, UnboundedCache)
+        self.assertEqual(decorator.cache._data, {})
+
+    def test_ctor_w_size_no_timeout(self):
+        from repoze.lru import LRUCache
+        decorator = self._makeOne(maxsize=10)
+        self.assertIsInstance(decorator.cache, LRUCache)
+        self.assertEqual(decorator.cache.size, 10)
+
+    def test_ctor_w_size_w_timeout(self):
+        from repoze.lru import ExpiringLRUCache
+        decorator = self._makeOne(maxsize=10, timeout=30)
+        self.assertIsInstance(decorator.cache, ExpiringLRUCache)
+        self.assertEqual(decorator.cache.size, 10)
+        self.assertEqual(decorator.cache.default_timeout, 30)
 
     def test_ctor_nocache(self):
         decorator = self._makeOne(10, None)
@@ -522,6 +590,14 @@
         self.assertEqual(result, 2)
         self.assertEqual(len(cache), 2)
 
+    def test_cache_attr(self):
+        cache = DummyLRUCache()
+        decorator = self._makeOne(0, cache)
+        def wrapped(key): #pragma NO COVER
+            return key
+        decorated = decorator(wrapped)
+        self.assertTrue(decorated._cache is cache)
+
     def test_multiargs(self):
         cache = DummyLRUCache()
         decorator = self._makeOne(0, cache)
@@ -533,8 +609,43 @@
         self.assertEqual(result, (3, 4, 5))
         self.assertEqual(len(cache), 1)
 
+    def test_multiargs_keywords(self):
+        cache = DummyLRUCache()
+        decorator = self._makeOne(0, cache)
+        def moreargs(*args, **kwargs):
+            return args, kwargs
+        decorated = decorator(moreargs)
+        result = decorated(3, 4, 5, a=1, b=2, c=3)
+        self.assertEqual(
+            cache[((3, 4, 5), frozenset([ ('a',1), ('b',2), ('c',3) ]))],
+            ((3, 4, 5), {'a':1, 'b':2, 'c':3}))
+        self.assertEqual(result, ((3, 4, 5), {'a':1, 'b':2, 'c':3}))
+        self.assertEqual(len(cache), 1)
+
+    def test_multiargs_keywords_ignore_unhashable_true(self):
+        cache = DummyLRUCache()
+        decorator = self._makeOne(0, cache, ignore_unhashable_args=True)
+        def moreargs(*args, **kwargs):
+            return args, kwargs
+        decorated = decorator(moreargs)
+        result = decorated(3, 4, 5, a=1, b=[1, 2, 3])
+        self.assertEqual(len(cache), 0)
+        self.assertEqual(result, ((3, 4, 5), {'a':1, 'b':[1, 2, 3]}))
+
+    def test_multiargs_keywords_ignore_unhashable(self):
+        cache = DummyLRUCache()
+        decorator = self._makeOne(0, cache, ignore_unhashable_args=False)
+
+        def moreargs(*args, **kwargs):  # pragma: NO COVER
+            return args, kwargs
+
+        decorated = decorator(moreargs)
+
+        with self.assertRaises(TypeError):
+            decorated(3, 4, 5, a=1, b=[1, 2, 3])
+
     def test_expiry(self):
-        """When timeout is given, decorator must eventually forget entries"""
+        #When timeout is given, decorator must eventually forget entries
         @self._makeOne(1, None, timeout=0.1)
         def sleep_a_bit(param):
             time.sleep(0.1)
@@ -562,6 +673,16 @@
         self.assertEqual(result3, 2 * "hello")
         self.assertTrue(stop - start > 0.1)
 
+    def test_partial(self):
+        #lru_cache decorator must not crash on functools.partial instances
+        def add(a,b):
+            return a + b
+        from functools import partial
+        from repoze.lru import lru_cache
+        add_five = partial(add, 5)
+        decorated = lru_cache(20)(add_five)
+        self.assertEqual(decorated(3), 8)
+
 
 class DummyLRUCache(dict):
 
@@ -644,6 +765,15 @@
         self.assertEqual(len(maker._cache['two'].data), 10)
         self.assertEqual(len(maker._cache['three'].data), 0)
 
+    def test_memoized(self):
+        from repoze.lru import lru_cache
+        from repoze.lru import UnboundedCache
+        maker = self._makeOne(maxsize=10)
+        memo = maker.memoized('test')
+        self.assertIsInstance(memo, lru_cache)
+        self.assertIsInstance(memo.cache, UnboundedCache)
+        self.assertIs(memo.cache, maker._cache['test'])
+
     def test_expiring(self):
         size = 10
         timeout = 10
@@ -651,10 +781,13 @@
         cache = self._makeOne(maxsize=size, timeout=timeout)
         for i in range(100):
             if not i:
-                decorated = cache.expiring_lrucache(name=name)(_adder)
+                decorator = cache.expiring_lrucache(name=name)
+                decorated = decorator(_adder)
                 self.assertEqual( cache._cache[name].size,size)
             else:
-                decorated = cache.expiring_lrucache()(_adder)
+                decorator = cache.expiring_lrucache()
+                decorated = decorator(_adder)
+                self.assertEqual(decorator.cache.default_timeout, timeout)
             decorated(10)
 
         self.assertEqual( len(cache._cache) , 100)
@@ -668,5 +801,14 @@
             self.assertEqual( _cache.size,size)
             self.assertEqual(len(_cache.data),0)
 
+    def test_expiring_w_timeout(self):
+        size = 10
+        maker_timeout = 10
+        timeout = 20
+        name = "name"
+        cache = self._makeOne(maxsize=size, timeout=maker_timeout)
+        decorator = cache.expiring_lrucache(name=name, timeout=20)
+        self.assertEqual(decorator.cache.default_timeout, timeout)
+
 def _adder(x):
     return x + 10
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/repoze.lru.egg-info/PKG-INFO 
new/repoze.lru-0.7/repoze.lru.egg-info/PKG-INFO
--- old/repoze.lru-0.6/repoze.lru.egg-info/PKG-INFO     2012-07-12 
20:48:37.000000000 +0200
+++ new/repoze.lru-0.7/repoze.lru.egg-info/PKG-INFO     2017-09-07 
07:00:09.000000000 +0200
@@ -1,103 +1,24 @@
 Metadata-Version: 1.1
 Name: repoze.lru
-Version: 0.6
+Version: 0.7
 Summary: A tiny LRU cache implementation and decorator
 Home-page: http://www.repoze.org
 Author: Agendaless Consulting
 Author-email: [email protected]
 License: BSD-derived (http://www.repoze.org/LICENSE.txt)
-Description: repoze.lru
-        ==========
+Description: 
         
-        ``repoze.lru`` is a LRU (least recently used) cache implementation.  
Keys and
-        values that are not used frequently will be evicted from the cache 
faster
-        than keys and values that are used frequently.  It works under Python 
2.5,
-        Python 2.6, Python 2.7, and Python 3.2.
-        
-        Please see ``docs/index.rst`` for detailed documentation.
-        
-        
-        Changelog
-        =========
-        
-        0.6 (2012-07-12)
-        ----------------
-        
-        - Added a 'CacheMaker' helper class:  a maker keeps references (by 
name)
-          to the caches it creates, to permit them to be cleared.
-        
-        - Added statistics to each cache, tracking lookups, hits, misses, and
-          evictions.
-        
-        - Automated building Sphinx docs and testing example snippets under 
``tox``.
-        
-        - Added Sphinx documentation.
-        
-        - Dropped support for Python 2.5.
-        
-        - Added support for PyPy.
-        
-        - Added ``setup.py docs`` alias (installs ``Sphinx`` and dependencies).
-        
-        - Added ``setup.py dev`` alias (runs ``develop`` plus installs ``nose``
-          and ``coverage``).
-        
-        - Added support for CI under supported Pythons using ``tox``.
-        
-        - Bug: Remove potential race condition on lock in face of interrupts
-          (Issue #10).
-        
-        0.5 (2012-03-24)
-        ----------------
-        
-        - Feature: added a new "invalidate()" method to allow removal of items 
from
-          the cache (issue #8).
-        
-        - Bug: LRUCache.put() could take multiple seconds on large caches 
(Issue #7).
-        
-        - Bug: LRUCache was not thread safe (Issue #6).
-        
-        - Bug: LRUCache.clock would waste RAM (Issue #4).
-        
-        - Bug: repeated pushing of an entry would remove other cache entries
-          (Issue #3).
-        
-        - Bug: LRUCache would evict entries even when not full (Issue #2).
-        
-        0.4 (2011-09-04)
-        ----------------
-        
-        - Moved to GitHub (https://github.com/repoze/repoze.lru).
-        
-        - Added Python 3.2 support.
-        
-        - Python 2.4 no longer supported.
-        
-        - Added tox.ini for easier testing.
-        
-        0.3 (2009/06/16)
-        ----------------
-        
-        - Add a thread lock around ``clear`` logic.
-        
-        0.2 (2009/06/15)
-        ----------------
-        
-        - Add a ``clear`` method.
-        
-        0.1 (2009/06/14)
-        ----------------
-        
-        - Initial release.
         
 Keywords: repoze lru cache
 Platform: UNKNOWN
 Classifier: Intended Audience :: Developers
 Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: Implementation :: CPython
 Classifier: Programming Language :: Python :: Implementation :: PyPy
 Classifier: License :: Repoze Public License
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/repoze.lru.egg-info/SOURCES.txt 
new/repoze.lru-0.7/repoze.lru.egg-info/SOURCES.txt
--- old/repoze.lru-0.6/repoze.lru.egg-info/SOURCES.txt  2012-07-12 
20:48:37.000000000 +0200
+++ new/repoze.lru-0.7/repoze.lru.egg-info/SOURCES.txt  2017-09-07 
07:00:09.000000000 +0200
@@ -1,9 +1,10 @@
+.coveragerc
 .gitignore
-CHANGES.txt
+.travis.yml
 CONTRIBUTORS.txt
 COPYRIGHT.txt
 LICENSE.txt
-README.txt
+README.rst
 setup.cfg
 setup.py
 tox.ini
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/repoze.lru.egg-info/requires.txt 
new/repoze.lru-0.7/repoze.lru.egg-info/requires.txt
--- old/repoze.lru-0.6/repoze.lru.egg-info/requires.txt 2012-07-12 
20:48:37.000000000 +0200
+++ new/repoze.lru-0.7/repoze.lru.egg-info/requires.txt 2017-09-07 
07:00:09.000000000 +0200
@@ -1,8 +1,7 @@
 
-
 [docs]
 Sphinx
 
 [testing]
 nose
-coverage
\ No newline at end of file
+coverage
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/setup.cfg new/repoze.lru-0.7/setup.cfg
--- old/repoze.lru-0.6/setup.cfg        2012-07-12 20:48:37.000000000 +0200
+++ new/repoze.lru-0.7/setup.cfg        2017-09-07 07:00:09.000000000 +0200
@@ -15,5 +15,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/setup.py new/repoze.lru-0.7/setup.py
--- old/repoze.lru-0.6/setup.py 2012-07-12 20:45:17.000000000 +0200
+++ new/repoze.lru-0.7/setup.py 2017-09-07 06:59:19.000000000 +0200
@@ -1,4 +1,4 @@
-##############################################################################
+# #############################################################################
 #
 # Copyright (c) 2009 Agendaless Consulting and Contributors.
 # All Rights Reserved.
@@ -18,8 +18,8 @@
 
 here = os.path.abspath(os.path.dirname(__file__))
 try:
-    README = open(os.path.join(here, 'README.txt')).read()
-    CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
+    README = open(os.path.join(here, 'README.rst')).read()
+    CHANGES = open(os.path.join(here, 'CHANGESrsttxt')).read()
 except:
     README = ''
     CHANGES = ''
@@ -27,20 +27,22 @@
 testing_extras = ['nose', 'coverage']
 
 setup(name='repoze.lru',
-      version='0.6',
+      version='0.7',
       description='A tiny LRU cache implementation and decorator',
-      long_description=README + '\n\n' +  CHANGES,
+      long_description=README + '\n\n' + CHANGES,
       classifiers=[
-        "Intended Audience :: Developers",
-        "Programming Language :: Python",
-        "Programming Language :: Python :: 2.6",
-        "Programming Language :: Python :: 2.7",
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.2",
-        "Programming Language :: Python :: Implementation :: CPython",
-        "Programming Language :: Python :: Implementation :: PyPy",
-        "License :: Repoze Public License",
-        ],
+          "Intended Audience :: Developers",
+          "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",
+          "Programming Language :: Python :: Implementation :: CPython",
+          "Programming Language :: Python :: Implementation :: PyPy",
+          "License :: Repoze Public License",
+      ],
       keywords='repoze lru cache',
       author="Agendaless Consulting",
       author_email="[email protected]",
@@ -50,14 +52,14 @@
       include_package_data=True,
       namespace_packages=['repoze'],
       zip_safe=False,
-      tests_require = [],
-      install_requires = [],
+      tests_require=[],
+      install_requires=[],
       test_suite="repoze.lru",
-      entry_points = """\
+      entry_points="""\
       """,
-      extras_require = {
-        'testing':  testing_extras,
-        'docs':  ['Sphinx',],
+      extras_require={
+          'testing': testing_extras,
+          'docs': ['Sphinx', ],
       }
 )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/repoze.lru-0.6/tox.ini new/repoze.lru-0.7/tox.ini
--- old/repoze.lru-0.6/tox.ini  2012-06-11 23:09:27.000000000 +0200
+++ new/repoze.lru-0.7/tox.ini  2017-09-07 06:53:22.000000000 +0200
@@ -1,22 +1,17 @@
 [tox]
 envlist = 
-    py26,py27,py32,pypy,cover,docs
+    py27,py34,py35,py36,pypy,pypy3,cover,docs
 
 [testenv]
 commands = 
-    python setup.py test -q
-deps =
-    setuptools-git
-    virtualenv
+    python setup.py -q test -q
 
 [testenv:cover]
 basepython =
-    python2.6
+    python2.7
 commands = 
-    nosetests --with-xunit --with-xcoverage
+    nosetests --with-xunit --with-xcoverage --cover-branch 
--cover-min-percentage=100
 deps =
-    setuptools-git
-    virtualenv
     nose
     coverage
     nosexcover
@@ -27,7 +22,7 @@
 
 [testenv:docs]
 basepython =
-    python2.6
+    python2.7
 commands = 
     sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
     sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest


Reply via email to