Hello community,

here is the log from the commit of package python3-Beaker for openSUSE:Factory 
checked in at 2016-02-01 19:56:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python3-Beaker (Old)
 and      /work/SRC/openSUSE:Factory/.python3-Beaker.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python3-Beaker"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python3-Beaker/python3-Beaker.changes    
2015-04-27 13:05:17.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python3-Beaker.new/python3-Beaker.changes       
2016-02-01 19:57:06.000000000 +0100
@@ -1,0 +2,18 @@
+Sat Jan 30 17:57:04 UTC 2016 - a...@gmx.de
+
+- specfile:
+  * update copyright year
+
+- update to version 1.8.0:
+  * Encrypted sessions can now specify nonce length for salt
+    generation through encrypt_nonce_bits parameter. set it to 48 for
+    backward compatibility with sessions generated before 1.8.0
+  * kwargs support in @cache_region decorator
+  * annotations support in @cache_region decorator
+  * data_serializer parameter in Session can now specify json to avoid
+    pickle security issues
+  * Invalid cookies are now skipped in cookie based sessions
+  * Memcached based on PyLibMC now share same connection pool for same
+    url
+
+-------------------------------------------------------------------

Old:
----
  Beaker-1.7.0.tar.gz

New:
----
  Beaker-1.8.0.tar.gz

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

Other differences:
------------------
++++++ python3-Beaker.spec ++++++
--- /var/tmp/diff_new_pack.U5wcME/_old  2016-02-01 19:57:07.000000000 +0100
+++ /var/tmp/diff_new_pack.U5wcME/_new  2016-02-01 19:57:07.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python3-Beaker
 #
-# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2016 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
@@ -17,7 +17,7 @@
 
 
 Name:           python3-Beaker
-Version:        1.7.0
+Version:        1.8.0
 Release:        0
 Url:            http://beaker.rtfd.org/
 Summary:        A Session and Caching library with WSGI Middleware

++++++ Beaker-1.7.0.tar.gz -> Beaker-1.8.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/Beaker.egg-info/PKG-INFO 
new/Beaker-1.8.0/Beaker.egg-info/PKG-INFO
--- old/Beaker-1.7.0/Beaker.egg-info/PKG-INFO   2015-04-22 17:32:50.000000000 
+0200
+++ new/Beaker-1.8.0/Beaker.egg-info/PKG-INFO   2016-01-27 12:40:12.000000000 
+0100
@@ -1,10 +1,10 @@
 Metadata-Version: 1.1
 Name: Beaker
-Version: 1.7.0
+Version: 1.8.0
 Summary: A Session and Caching library with WSGI Middleware
 Home-page: http://beaker.rtfd.org/
-Author: Ben Bangert, Mike Bayer, Philip Jenvey
-Author-email: b...@groovie.org, pjen...@groovie.org
+Author: Ben Bangert, Mike Bayer, Philip Jenvey, Alessandro Molina
+Author-email: b...@groovie.org, pjen...@groovie.org, a...@turbogears.org
 License: BSD
 Description: =========================
         Cache and Session Library
@@ -81,6 +81,7 @@
 Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
 Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
 Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
 Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/Beaker.egg-info/SOURCES.txt 
new/Beaker-1.8.0/Beaker.egg-info/SOURCES.txt
--- old/Beaker-1.7.0/Beaker.egg-info/SOURCES.txt        2015-04-22 
17:32:50.000000000 +0200
+++ new/Beaker-1.8.0/Beaker.egg-info/SOURCES.txt        2016-01-27 
12:40:12.000000000 +0100
@@ -6,6 +6,7 @@
 Beaker.egg-info/dependency_links.txt
 Beaker.egg-info/entry_points.txt
 Beaker.egg-info/not-zip-safe
+Beaker.egg-info/pbr.json
 Beaker.egg-info/requires.txt
 Beaker.egg-info/top_level.txt
 beaker/__init__.py
@@ -13,6 +14,7 @@
 beaker/cache.py
 beaker/container.py
 beaker/converters.py
+beaker/cookie.py
 beaker/exceptions.py
 beaker/middleware.py
 beaker/session.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/Beaker.egg-info/pbr.json 
new/Beaker-1.8.0/Beaker.egg-info/pbr.json
--- old/Beaker-1.7.0/Beaker.egg-info/pbr.json   1970-01-01 01:00:00.000000000 
+0100
+++ new/Beaker-1.8.0/Beaker.egg-info/pbr.json   2015-08-15 21:32:53.000000000 
+0200
@@ -0,0 +1 @@
+{"is_release": false, "git_version": "5c407db"}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/Beaker.egg-info/requires.txt 
new/Beaker-1.8.0/Beaker.egg-info/requires.txt
--- old/Beaker-1.7.0/Beaker.egg-info/requires.txt       2015-04-22 
17:32:50.000000000 +0200
+++ new/Beaker-1.8.0/Beaker.egg-info/requires.txt       2016-01-27 
12:40:12.000000000 +0100
@@ -1,11 +1,11 @@
-
+funcsigs
 
 [testsuite]
 nose
 webtest
 Mock
-coverage
 pycrypto
+coverage
 SQLALchemy
 
 [crypto]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/PKG-INFO new/Beaker-1.8.0/PKG-INFO
--- old/Beaker-1.7.0/PKG-INFO   2015-04-22 17:32:50.000000000 +0200
+++ new/Beaker-1.8.0/PKG-INFO   2016-01-27 12:40:12.000000000 +0100
@@ -1,10 +1,10 @@
 Metadata-Version: 1.1
 Name: Beaker
-Version: 1.7.0
+Version: 1.8.0
 Summary: A Session and Caching library with WSGI Middleware
 Home-page: http://beaker.rtfd.org/
-Author: Ben Bangert, Mike Bayer, Philip Jenvey
-Author-email: b...@groovie.org, pjen...@groovie.org
+Author: Ben Bangert, Mike Bayer, Philip Jenvey, Alessandro Molina
+Author-email: b...@groovie.org, pjen...@groovie.org, a...@turbogears.org
 License: BSD
 Description: =========================
         Cache and Session Library
@@ -81,6 +81,7 @@
 Classifier: Programming Language :: Python :: 3.2
 Classifier: Programming Language :: Python :: 3.3
 Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
 Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
 Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
 Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/beaker/__init__.py 
new/Beaker-1.8.0/beaker/__init__.py
--- old/Beaker-1.7.0/beaker/__init__.py 2015-02-25 16:49:49.000000000 +0100
+++ new/Beaker-1.8.0/beaker/__init__.py 2016-01-26 00:31:01.000000000 +0100
@@ -1 +1 @@
-__version__ = '1.7.0'
+__version__ = '1.8.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/beaker/_compat.py 
new/Beaker-1.8.0/beaker/_compat.py
--- old/Beaker-1.7.0/beaker/_compat.py  2015-04-20 21:56:09.000000000 +0200
+++ new/Beaker-1.8.0/beaker/_compat.py  2016-01-25 15:29:15.000000000 +0100
@@ -82,6 +82,7 @@
     def dictkeyslist(d):
         return d.keys()
 
+
 def im_func(f):
     if not PY2:  # pragma: no cover
         return getattr(f, '__func__', None)
@@ -154,3 +155,14 @@
     exec_("""def reraise(tp, value, tb=None):
     raise tp, value, tb
 """)
+
+
+try:
+    from inspect import signature as func_signature
+except ImportError:
+    from funcsigs import signature as func_signature
+
+
+def bindfuncargs(arginfo, args, kwargs):
+    boundargs = arginfo.bind(*args, **kwargs)
+    return boundargs.args, boundargs.kwargs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/beaker/cache.py 
new/Beaker-1.8.0/beaker/cache.py
--- old/Beaker-1.7.0/beaker/cache.py    2015-02-25 16:37:38.000000000 +0100
+++ new/Beaker-1.8.0/beaker/cache.py    2015-11-13 22:21:53.000000000 +0100
@@ -7,8 +7,9 @@
 
 """
 import warnings
-from beaker._compat import u_, unicode_text
+from itertools import chain
 
+from beaker._compat import u_, unicode_text, func_signature, bindfuncargs
 import beaker.container as container
 import beaker.util as util
 from beaker.crypto.util import sha1
@@ -537,7 +538,7 @@
         _cache_decorator_invalidate(cache, key_length, args)
 
 
-def _cache_decorate(deco_args, manager, kwargs, region):
+def _cache_decorate(deco_args, manager, options, region):
     """Return a caching function decorator."""
 
     cache = [None]
@@ -545,9 +546,10 @@
     def decorate(func):
         namespace = util.func_namespace(func)
         skip_self = util.has_self_arg(func)
+        signature = func_signature(func)
 
         @wraps(func)
-        def cached(*args):
+        def cached(*args, **kwargs):
             if not cache[0]:
                 if region is not None:
                     if region not in cache_regions:
@@ -555,24 +557,32 @@
                             'Cache region not configured: %s' % region)
                     reg = cache_regions[region]
                     if not reg.get('enabled', True):
-                        return func(*args)
+                        return func(*args, **kwargs)
                     cache[0] = Cache._get_cache(namespace, reg)
                 elif manager:
-                    cache[0] = manager.get_cache(namespace, **kwargs)
+                    cache[0] = manager.get_cache(namespace, **options)
                 else:
                     raise Exception("'manager + kwargs' or 'region' "
                                     "argument is required")
 
+            cache_key_kwargs = []
+            if kwargs:
+                # kwargs provided, merge them in positional args
+                # to avoid having different cache keys.
+                args, kwargs = bindfuncargs(signature, args, kwargs)
+                cache_key_kwargs = [u_(':').join((u_(key), u_(value))) for 
key, value in kwargs.items()]
+
             cache_key_args = args
             if skip_self:
                 cache_key_args = args[1:]
-            cache_key = u_(" ").join(map(u_, deco_args + cache_key_args))
+
+            cache_key = u_(" ").join(map(u_, chain(deco_args, cache_key_args, 
cache_key_kwargs)))
 
             if region:
                 cachereg = cache_regions[region]
                 key_length = cachereg.get('key_length', 
util.DEFAULT_CACHE_KEY_LENGTH)
             else:
-                key_length = kwargs.pop('key_length', 
util.DEFAULT_CACHE_KEY_LENGTH)
+                key_length = options.pop('key_length', 
util.DEFAULT_CACHE_KEY_LENGTH)
 
             # TODO: This is probably a bug as length is checked before 
converting to UTF8
             # which will cause cache_key to grow in size.
@@ -580,7 +590,7 @@
                 cache_key = sha1(cache_key.encode('utf-8')).hexdigest()
 
             def go():
-                return func(*args)
+                return func(*args, **kwargs)
 
             return cache[0].get_value(cache_key, createfunc=go)
         cached._arg_namespace = namespace
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/beaker/cookie.py 
new/Beaker-1.8.0/beaker/cookie.py
--- old/Beaker-1.7.0/beaker/cookie.py   1970-01-01 01:00:00.000000000 +0100
+++ new/Beaker-1.8.0/beaker/cookie.py   2015-11-22 14:54:40.000000000 +0100
@@ -0,0 +1,69 @@
+import sys
+from ._compat import http_cookies
+
+# Some versions of Python 2.7 and later won't need this encoding bug fix:
+_cookie_encodes_correctly = http_cookies.SimpleCookie().value_encode(';') == 
(';', '"\\073"')
+
+# Cookie pickling bug is fixed in Python 2.7.9 and Python 3.4.3+
+# http://bugs.python.org/issue22775
+cookie_pickles_properly = (
+    (sys.version_info[:2] == (2, 7) and sys.version_info >= (2, 7, 9)) or
+    sys.version_info >= (3, 4, 3)
+)
+
+
+# Adapted from Django.http.cookies and always enabled the bad_cookies
+# behaviour to cope with any invalid cookie key while keeping around
+# the session.
+class SimpleCookie(http_cookies.SimpleCookie):
+    if not cookie_pickles_properly:
+        def __setitem__(self, key, value):
+            # Apply the fix from http://bugs.python.org/issue22775 where
+            # it's not fixed in Python itself
+            if isinstance(value, http_cookies.Morsel):
+                # allow assignment of constructed Morsels (e.g. for pickling)
+                dict.__setitem__(self, key, value)
+            else:
+                super(SimpleCookie, self).__setitem__(key, value)
+
+    if not _cookie_encodes_correctly:
+        def value_encode(self, val):
+            # Some browsers do not support quoted-string from RFC 2109,
+            # including some versions of Safari and Internet Explorer.
+            # These browsers split on ';', and some versions of Safari
+            # are known to split on ', '. Therefore, we encode ';' and ','
+
+            # SimpleCookie already does the hard work of encoding and decoding.
+            # It uses octal sequences like '\\012' for newline etc.
+            # and non-ASCII chars. We just make use of this mechanism, to
+            # avoid introducing two encoding schemes which would be confusing
+            # and especially awkward for javascript.
+
+            # NB, contrary to Python docs, value_encode returns a tuple 
containing
+            # (real val, encoded_val)
+            val, encoded = super(SimpleCookie, self).value_encode(val)
+
+            encoded = encoded.replace(";", "\\073").replace(",", "\\054")
+            # If encoded now contains any quoted chars, we need double quotes
+            # around the whole string.
+            if "\\" in encoded and not encoded.startswith('"'):
+                encoded = '"' + encoded + '"'
+
+            return val, encoded
+
+    def load(self, rawdata):
+        self.bad_cookies = set()
+        super(SimpleCookie, self).load(rawdata)
+        for key in self.bad_cookies:
+            del self[key]
+
+    # override private __set() method:
+    # (needed for using our Morsel, and for laxness with CookieError
+    def _BaseCookie__set(self, key, real_value, coded_value):
+        try:
+            super(SimpleCookie, self)._BaseCookie__set(key, real_value, 
coded_value)
+        except http_cookies.CookieError:
+            if not hasattr(self, 'bad_cookies'):
+                self.bad_cookies = set()
+            self.bad_cookies.add(key)
+            dict.__setitem__(self, key, http_cookies.Morsel())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/beaker/crypto/__init__.py 
new/Beaker-1.8.0/beaker/crypto/__init__.py
--- old/Beaker-1.7.0/beaker/crypto/__init__.py  2015-02-25 16:37:38.000000000 
+0100
+++ new/Beaker-1.8.0/beaker/crypto/__init__.py  2016-01-25 23:36:28.000000000 
+0100
@@ -7,6 +7,7 @@
 from beaker import util
 
 keyLength = None
+DEFAULT_NONCE_BITS = 128
 
 if JYTHON:
     try:
@@ -42,3 +43,12 @@
     # os.urandom() returns truly random data, this will have no effect on the
     # overall security.
     return pbkdf2(master_key, salt, iterations=iterations, dklen=keyLength)
+
+
+def get_nonce_size(number_of_bits):
+    if number_of_bits % 8:
+        raise ValueError('Nonce complexity currently supports multiples of 8')
+
+    bytes = number_of_bits // 8
+    b64bytes = ((4 * bytes // 3) + 3) & ~3
+    return bytes, b64bytes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/beaker/crypto/pbkdf2.py 
new/Beaker-1.8.0/beaker/crypto/pbkdf2.py
--- old/Beaker-1.7.0/beaker/crypto/pbkdf2.py    2015-02-25 16:37:38.000000000 
+0100
+++ new/Beaker-1.8.0/beaker/crypto/pbkdf2.py    2016-01-23 11:54:31.000000000 
+0100
@@ -1,3 +1,8 @@
+"""
+PBKDF2 Implementation adapted from django.utils.crypto.
+
+This is used to generate the encryption key for enciphered sessions.
+"""
 from beaker._compat import bytes_, xrange_
 
 import hmac
@@ -22,10 +27,14 @@
 if hasattr(hashlib, "pbkdf2_hmac"):
     def pbkdf2(password, salt, iterations, dklen=0, digest=None):
         """
-        Implements PBKDF2 with the same API as Django's existing
-        implementation, using the stdlib.
+        Implements PBKDF2 using the stdlib. This is used in Python 2.7.8+ and 
3.4+.
+
+        HMAC+SHA256 is used as the default pseudo random function.
 
-        This is used in Python 2.7.8+ and 3.4+.
+        As of 2014, 100,000 iterations was the recommended default which took
+        100ms on a 2.7Ghz Intel i7 with an optimized implementation. This is
+        probably the bare minimum for security given 1000 iterations was
+        recommended in 2001.
         """
         if digest is None:
             digest = hashlib.sha1
@@ -46,10 +55,7 @@
         100ms on a 2.7Ghz Intel i7 with an optimized implementation. This is
         probably the bare minimum for security given 1000 iterations was
         recommended in 2001. This code is very well optimized for CPython and
-        is about five times slower than OpenSSL's implementation. Look in
-        django.contrib.auth.hashers for the present default, it is lower than
-        the recommended 100,000 because of the performance difference between
-        this and an optimized implementation.
+        is about five times slower than OpenSSL's implementation.
         """
         assert iterations > 0
         if not digest:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/beaker/ext/memcached.py 
new/Beaker-1.8.0/beaker/ext/memcached.py
--- old/Beaker-1.7.0/beaker/ext/memcached.py    2015-02-25 16:37:38.000000000 
+0100
+++ new/Beaker-1.8.0/beaker/ext/memcached.py    2016-01-23 11:49:56.000000000 
+0100
@@ -159,6 +159,8 @@
 class PyLibMCNamespaceManager(MemcachedNamespaceManager):
     """Provide thread-local support for pylibmc."""
 
+    pools = SyncDict()
+
     def __init__(self, *arg, **kw):
         super(PyLibMCNamespaceManager, self).__init__(*arg, **kw)
 
@@ -176,7 +178,9 @@
                         servers=url.split(';'), behaviors=behaviors,
                         binary=(protocol == 'binary'), username=username,
                         password=password)
-        self.pool = pylibmc.ThreadMappedPool(self.mc)
+        self.pool = PyLibMCNamespaceManager.pools.get(
+                        (memcache_module, url),
+                        pylibmc.ThreadMappedPool, self.mc)
 
     def __getitem__(self, key):
         with self.pool.reserve() as mc:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/beaker/session.py 
new/Beaker-1.8.0/beaker/session.py
--- old/Beaker-1.7.0/beaker/session.py  2015-02-25 16:37:38.000000000 +0100
+++ new/Beaker-1.8.0/beaker/session.py  2016-01-25 23:36:28.000000000 +0100
@@ -3,11 +3,11 @@
 import os
 import time
 from datetime import datetime, timedelta
-from beaker.crypto import hmac as HMAC, hmac_sha1 as SHA1, sha1
+from beaker.crypto import hmac as HMAC, hmac_sha1 as SHA1, sha1, 
get_nonce_size, DEFAULT_NONCE_BITS
 from beaker import crypto, util
 from beaker.cache import clsmap
 from beaker.exceptions import BeakerException, InvalidCryptoBackendError
-
+from beaker.cookie import SimpleCookie
 
 __all__ = ['SignedCookie', 'Session']
 
@@ -42,7 +42,7 @@
             return raw_id.replace('+', '-').replace('/', '_').rstrip('=')
 
 
-class SignedCookie(http_cookies.BaseCookie):
+class SignedCookie(SimpleCookie):
     """Extends python cookie to give digital signature support"""
     def __init__(self, secret, input=None):
         self.secret = secret.encode('UTF-8')
@@ -93,20 +93,26 @@
     :param cookie_expires: Expiration date for cookie
     :param cookie_domain: Domain to use for the cookie.
     :param cookie_path: Path to use for the cookie.
+    :param data_serializer: If ``"json"`` or ``"pickle"`` should be used
+                              to serialize data. By default ``pickle`` is used.
     :param secure: Whether or not the cookie should only be sent over SSL.
     :param httponly: Whether or not the cookie should only be accessible by
                      the browser not by JavaScript.
     :param encrypt_key: The key to use for the local session encryption, if not
                         provided the session will not be encrypted.
     :param validate_key: The key used to sign the local encrypted session
-
+    :param encrypt_nonce_bits: Number of bits used to generate nonce for 
encryption key salt.
+                               For security reason this is 128bits be default. 
If you want
+                               to keep backward compatibility with sessions 
generated before 1.8.0
+                               set this to 48.
     """
     def __init__(self, request, id=None, invalidate_corrupt=False,
                  use_cookies=True, type=None, data_dir=None,
                  key='beaker.session.id', timeout=None, cookie_expires=True,
-                 cookie_domain=None, cookie_path='/', secret=None,
+                 cookie_domain=None, cookie_path='/', 
data_serializer='pickle', secret=None,
                  secure=False, namespace_class=None, httponly=False,
-                 encrypt_key=None, validate_key=None, **namespace_args):
+                 encrypt_key=None, validate_key=None, 
encrypt_nonce_bits=DEFAULT_NONCE_BITS,
+                 **namespace_args):
         if not type:
             if data_dir:
                 self.type = 'file'
@@ -126,6 +132,7 @@
         self.timeout = timeout
         self.use_cookies = use_cookies
         self.cookie_expires = cookie_expires
+        self.data_serializer = data_serializer
 
         # Default cookie domain/path
         self._domain = cookie_domain
@@ -136,6 +143,7 @@
         self.httponly = httponly
         self.encrypt_key = encrypt_key
         self.validate_key = validate_key
+        self.encrypt_nonce_size = get_nonce_size(encrypt_nonce_bits)
         self.id = id
         self.accessed_dict = {}
         self.invalidate_corrupt = invalidate_corrupt
@@ -148,7 +156,7 @@
                 except http_cookies.CookieError:
                     self.cookie = SignedCookie(secret, input=None)
             else:
-                self.cookie = http_cookies.SimpleCookie(input=cookieheader)
+                self.cookie = SimpleCookie(input=cookieheader)
 
             if not self.id and self.key in self.cookie:
                 self.id = self.cookie[self.key].value
@@ -226,7 +234,7 @@
             self.last_accessed = None
         if self.use_cookies:
             self._set_cookie_values()
-            sc = set_new == False
+            sc = set_new is False
             self._update_cookie_out(set_cookie=sc)
 
     @property
@@ -257,13 +265,14 @@
         """Serialize, encipher, and base64 the session dict"""
         session_data = session_data or self.copy()
         if self.encrypt_key:
-            nonce = b64encode(os.urandom(6))[:8]
+            nonce_len, nonce_b64len = self.encrypt_nonce_size
+            nonce = b64encode(os.urandom(nonce_len))[:nonce_b64len]
             encrypt_key = crypto.generateCryptoKeys(self.encrypt_key,
                                                     self.validate_key + nonce, 
1)
-            data = pickle.dumps(session_data, 2)
+            data = util.serialize(session_data, self.data_serializer)
             return nonce + b64encode(crypto.aesEncrypt(data, encrypt_key))
         else:
-            data = pickle.dumps(session_data, 2)
+            data = util.serialize(session_data, self.data_serializer)
             return b64encode(data)
 
     def _decrypt_data(self, session_data):
@@ -271,10 +280,11 @@
         dict"""
         if self.encrypt_key:
             try:
-                nonce = session_data[:8]
+                __, nonce_b64len = self.encrypt_nonce_size
+                nonce = session_data[:nonce_b64len]
                 encrypt_key = crypto.generateCryptoKeys(self.encrypt_key,
                                                         self.validate_key + 
nonce, 1)
-                payload = b64decode(session_data[8:])
+                payload = b64decode(session_data[nonce_b64len:])
                 data = crypto.aesDecrypt(payload, encrypt_key)
             except:
                 # As much as I hate a bare except, we get some insane errors
@@ -284,16 +294,16 @@
                     return None
                 else:
                     raise
-            try:
-                return pickle.loads(data)
-            except:
-                if self.invalidate_corrupt:
-                    return None
-                else:
-                    raise
         else:
             data = b64decode(session_data)
-            return pickle.loads(data)
+
+        try:
+            return util.deserialize(data, self.data_serializer)
+        except:
+            if self.invalidate_corrupt:
+                return None
+            else:
+                raise
 
     def _delete_cookie(self):
         self.request['set_cookie'] = True
@@ -480,6 +490,8 @@
     :param cookie_expires: Expiration date for cookie
     :param cookie_domain: Domain to use for the cookie.
     :param cookie_path: Path to use for the cookie.
+    :param data_serializer: If ``"json"`` or ``"pickle"`` should be used
+                              to serialize data. By default ``pickle`` is used.
     :param secure: Whether or not the cookie should only be sent over SSL.
     :param httponly: Whether or not the cookie should only be accessible by
                      the browser not by JavaScript.
@@ -491,11 +503,12 @@
     def __init__(self, request, key='beaker.session.id', timeout=None,
                  cookie_expires=True, cookie_domain=None, cookie_path='/',
                  encrypt_key=None, validate_key=None, secure=False,
-                 httponly=False, **kwargs):
+                 httponly=False, data_serializer='pickle',
+                 encrypt_nonce_bits=DEFAULT_NONCE_BITS, **kwargs):
 
         if not crypto.has_aes and encrypt_key:
             raise InvalidCryptoBackendError("No AES library is installed, 
can't generate "
-                                  "encrypted cookie-only Session.")
+                                            "encrypted cookie-only Session.")
 
         self.request = request
         self.key = key
@@ -503,11 +516,13 @@
         self.cookie_expires = cookie_expires
         self.encrypt_key = encrypt_key
         self.validate_key = validate_key
+        self.encrypt_nonce_size = get_nonce_size(encrypt_nonce_bits)
         self.request['set_cookie'] = False
         self.secure = secure
         self.httponly = httponly
         self._domain = cookie_domain
         self._path = cookie_path
+        self.data_serializer = data_serializer
 
         try:
             cookieheader = request['cookie']
@@ -655,8 +670,7 @@
             if params.get('type') == 'cookie':
                 self.__dict__['_sess'] = CookieSession(req, **params)
             else:
-                self.__dict__['_sess'] = Session(req, use_cookies=True,
-                                                 **params)
+                self.__dict__['_sess'] = Session(req, **params)
         return self.__dict__['_sess']
 
     def __getattr__(self, attr):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/beaker/util.py 
new/Beaker-1.8.0/beaker/util.py
--- old/Beaker-1.7.0/beaker/util.py     2015-02-25 16:37:38.000000000 +0100
+++ new/Beaker-1.8.0/beaker/util.py     2016-01-26 00:40:54.000000000 +0100
@@ -1,5 +1,6 @@
 """Beaker utilities"""
-from ._compat import PY2, string_type, unicode_text, NoneType, dictkeyslist, 
im_class, im_func
+from ._compat import PY2, string_type, unicode_text, NoneType, dictkeyslist, 
im_class, im_func, pickle, func_signature, \
+    default_im_func
 
 try:
     import threading as _threading
@@ -15,7 +16,8 @@
 import warnings
 import sys
 import inspect
-
+import json
+import zlib
 
 from beaker.converters import asbool
 from beaker import exceptions
@@ -24,7 +26,8 @@
 DEFAULT_CACHE_KEY_LENGTH = 250
 
 __all__ = ["ThreadLocal", "WeakValuedRegistry", "SyncDict", "encoded_path",
-           "verify_directory"]
+           "verify_directory",
+           "serialize", "deserialize"]
 
 
 def function_named(fn, name):
@@ -87,8 +90,8 @@
 
 def has_self_arg(func):
     """Return True if the given function has a 'self' argument."""
-    args = inspect.getargspec(func)
-    if args and args[0] and args[0][0] in ('self', 'cls'):
+    args = list(func_signature(func).parameters)
+    if args and args[0] in ('self', 'cls'):
         return True
     else:
         return False
@@ -285,31 +288,25 @@
 
 def coerce_session_params(params):
     rules = [
-        ('data_dir', (str, NoneType), "data_dir must be a string "
-         "referring to a directory."),
-        ('lock_dir', (str, NoneType), "lock_dir must be a string referring to 
a "
-         "directory."),
+        ('data_dir', (str, NoneType), "data_dir must be a string referring to 
a directory."),
+        ('lock_dir', (str, NoneType), "lock_dir must be a string referring to 
a directory."),
         ('type', (str, NoneType), "Session type must be a string."),
-        ('cookie_expires', (bool, datetime, timedelta, int), "Cookie expires 
was "
-         "not a boolean, datetime, int, or timedelta instance."),
-        ('cookie_domain', (str, NoneType), "Cookie domain must be a "
-         "string."),
-        ('cookie_path', (str, NoneType), "Cookie path must be a "
-         "string."),
+        ('cookie_expires', (bool, datetime, timedelta, int),
+         "Cookie expires was not a boolean, datetime, int, or timedelta 
instance."),
+        ('cookie_domain', (str, NoneType), "Cookie domain must be a string."),
+        ('cookie_path', (str, NoneType), "Cookie path must be a string."),
         ('id', (str,), "Session id must be a string."),
         ('key', (str,), "Session key must be a string."),
         ('secret', (str, NoneType), "Session secret must be a string."),
-        ('validate_key', (str, NoneType), "Session encrypt_key must be "
-         "a string."),
-        ('encrypt_key', (str, NoneType), "Session validate_key must be "
-         "a string."),
+        ('validate_key', (str, NoneType), "Session encrypt_key must be a 
string."),
+        ('encrypt_key', (str, NoneType), "Session validate_key must be a 
string."),
+        ('encrypt_nonce_bits', (int, NoneType), "Session encrypt_nonce_bits 
must be a number"),
         ('secure', (bool, NoneType), "Session secure must be a boolean."),
         ('httponly', (bool, NoneType), "Session httponly must be a boolean."),
-        ('timeout', (int, NoneType), "Session timeout must be an "
-         "integer."),
+        ('timeout', (int, NoneType), "Session timeout must be an integer."),
         ('auto', (bool, NoneType), "Session is created if accessed."),
-        ('webtest_varname', (str, NoneType), "Session varname must be "
-         "a string."),
+        ('webtest_varname', (str, NoneType), "Session varname must be a 
string."),
+        ('data_serializer', (str,), "data_serializer must be a string.")
     ]
     opts = verify_rules(params, rules)
     cookie_expires = opts.get('cookie_expires')
@@ -321,19 +318,16 @@
 
 def coerce_cache_params(params):
     rules = [
-        ('data_dir', (str, NoneType), "data_dir must be a string "
-         "referring to a directory."),
-        ('lock_dir', (str, NoneType), "lock_dir must be a string referring to 
a "
-         "directory."),
+        ('data_dir', (str, NoneType), "data_dir must be a string referring to 
a directory."),
+        ('lock_dir', (str, NoneType), "lock_dir must be a string referring to 
a directory."),
         ('type', (str,), "Cache type must be a string."),
-        ('enabled', (bool, NoneType), "enabled must be true/false "
-         "if present."),
-        ('expire', (int, NoneType), "expire must be an integer representing "
-         "how many seconds the cache is valid for"),
-        ('regions', (list, tuple, NoneType), "Regions must be a "
-         "comma seperated list of valid regions"),
-        ('key_length', (int, NoneType), "key_length must be an integer "
-         "which indicates the longest a key can be before hashing"),
+        ('enabled', (bool, NoneType), "enabled must be true/false if 
present."),
+        ('expire', (int, NoneType),
+         "expire must be an integer representing how many seconds the cache is 
valid for"),
+        ('regions', (list, tuple, NoneType),
+         "Regions must be a comma seperated list of valid regions"),
+        ('key_length', (int, NoneType),
+         "key_length must be an integer which indicates the longest a key can 
be before hashing"),
     ]
     return verify_rules(params, rules)
 
@@ -344,37 +338,31 @@
         ('no_block', (bool, int), 'no_block must be a boolean or an integer'),
         ('receive_timeout', (int,), 'receive_timeout must be an integer'),
         ('send_timeout', (int,), 'send_timeout must be an integer'),
-        ('ketama_hash', (str,), 'ketama_hash must be a string designating '
-         'a valid hashing strategy option'),
+        ('ketama_hash', (str,),
+         'ketama_hash must be a string designating a valid hashing strategy 
option'),
         ('_poll_timeout', (int,), '_poll_timeout must be an integer'),
         ('auto_eject', (bool, int), 'auto_eject must be an integer'),
         ('retry_timeout', (int,), 'retry_timeout must be an integer'),
         ('_sort_hosts', (bool, int), '_sort_hosts must be an integer'),
         ('_io_msg_watermark', (int,), '_io_msg_watermark must be an integer'),
         ('ketama', (bool, int), 'ketama must be a boolean or an integer'),
-        ('ketama_weighted', (bool, int), 'ketama_weighted must be a boolean or 
'
-         'an integer'),
-        ('_io_key_prefetch', (int, bool), '_io_key_prefetch must be a boolean '
-         'or an integer'),
-        ('_hash_with_prefix_key', (bool, int), '_hash_with_prefix_key must be '
-         'a boolean or an integer'),
-        ('tcp_nodelay', (bool, int), 'tcp_nodelay must be a boolean or an '
-         'integer'),
+        ('ketama_weighted', (bool, int), 'ketama_weighted must be a boolean or 
an integer'),
+        ('_io_key_prefetch', (int, bool), '_io_key_prefetch must be a boolean 
or an integer'),
+        ('_hash_with_prefix_key', (bool, int),
+         '_hash_with_prefix_key must be a boolean or an integer'),
+        ('tcp_nodelay', (bool, int), 'tcp_nodelay must be a boolean or an 
integer'),
         ('failure_limit', (int,), 'failure_limit must be an integer'),
-        ('buffer_requests', (bool, int), 'buffer_requests must be a boolean '
-         'or an integer'),
+        ('buffer_requests', (bool, int), 'buffer_requests must be a boolean or 
an integer'),
         ('_socket_send_size', (int,), '_socket_send_size must be an integer'),
         ('num_replicas', (int,), 'num_replicas must be an integer'),
         ('remove_failed', (int,), 'remove_failed must be an integer'),
         ('_noreply', (bool, int), '_noreply must be a boolean or an integer'),
-        ('_io_bytes_watermark', (int,), '_io_bytes_watermark must be an '
-         'integer'),
+        ('_io_bytes_watermark', (int,), '_io_bytes_watermark must be an 
integer'),
         ('_socket_recv_size', (int,), '_socket_recv_size must be an integer'),
-        ('distribution', (str,), 'distribution must be a string designating '
-         'a valid distribution option'),
+        ('distribution', (str,),
+         'distribution must be a string designating a valid distribution 
option'),
         ('connect_timeout', (int,), 'connect_timeout must be an integer'),
-        ('hash', (str,), 'hash must be a string designating a valid hashing '
-         'option'),
+        ('hash', (str,), 'hash must be a string designating a valid hashing 
option'),
         ('verify_keys', (bool, int), 'verify_keys must be a boolean or an 
integer'),
         ('dead_timeout', (int,), 'dead_timeout must be an integer')
     ]
@@ -452,3 +440,17 @@
         return '%s.%s' % (kls.__module__, kls.__name__)
     else:
         return '%s|%s' % (inspect.getsourcefile(func), func.__name__)
+
+
+def serialize(data, method):
+    if method == 'json':
+        return zlib.compress(json.dumps(data).encode('utf-8'))
+    else:
+        return pickle.dumps(data, 2)
+
+
+def deserialize(data_string, method):
+    if method == 'json':
+        return json.loads(zlib.decompress(data_string).decode('utf-8'))
+    else:
+        return pickle.loads(data_string)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/setup.cfg new/Beaker-1.8.0/setup.cfg
--- old/Beaker-1.7.0/setup.cfg  2015-04-22 17:32:50.000000000 +0200
+++ new/Beaker-1.8.0/setup.cfg  2016-01-27 12:40:12.000000000 +0100
@@ -5,6 +5,7 @@
 with-doctest = True
 cover-package = beaker
 cover-inclusive = True
+ignore-files = annotated_functions.py
 
 [egg_info]
 tag_build = 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Beaker-1.7.0/setup.py new/Beaker-1.8.0/setup.py
--- old/Beaker-1.7.0/setup.py   2015-02-25 16:37:38.000000000 +0100
+++ new/Beaker-1.8.0/setup.py   2016-01-26 00:08:52.000000000 +0100
@@ -1,9 +1,11 @@
 import os
 import sys
 import re
+import inspect
 
 from setuptools import setup, find_packages
 
+py_version = sys.version_info[:2]
 here = os.path.abspath(os.path.dirname(__file__))
 v = open(os.path.join(here, 'beaker', '__init__.py'))
 VERSION = re.compile(r".*__version__ = '(.*?)'", re.S).match(v.read()).group(1)
@@ -14,14 +16,26 @@
 except IOError:
     README = ''
 
-tests_require = ['nose', 'webtest', 'Mock', 'coverage', 'pycrypto']
+
+INSTALL_REQUIRES = []
+if not hasattr(inspect, 'signature'):
+    # On Python 2.6, 2.7 and 3.2 we need funcsigs dependency
+    INSTALL_REQUIRES.append('funcsigs')
+
+
+TESTS_REQUIRE = ['nose', 'webtest', 'Mock', 'pycrypto']
+
+if py_version == (3, 2):
+    TESTS_REQUIRE.append('coverage < 4.0')
+else:
+    TESTS_REQUIRE.append('coverage')
 
 if not sys.platform.startswith('java') and not sys.platform == 'cli':
-    tests_require.extend(['SQLALchemy'])
+    TESTS_REQUIRE.extend(['SQLALchemy'])
     try:
         import sqlite3
     except ImportError:
-        tests_require.append('pysqlite')
+        TESTS_REQUIRE.append('pysqlite')
 
 setup(name='Beaker',
       version=VERSION,
@@ -39,25 +53,26 @@
       'Programming Language :: Python :: 3.2',
       'Programming Language :: Python :: 3.3',
       'Programming Language :: Python :: 3.4',
+      'Programming Language :: Python :: 3.5',
       'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
       'Topic :: Internet :: WWW/HTTP :: WSGI',
       'Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware',
       ],
       keywords='wsgi myghty session web cache middleware',
-      author='Ben Bangert, Mike Bayer, Philip Jenvey',
-      author_email='b...@groovie.org, pjen...@groovie.org',
+      author='Ben Bangert, Mike Bayer, Philip Jenvey, Alessandro Molina',
+      author_email='b...@groovie.org, pjen...@groovie.org, 
a...@turbogears.org',
       url='http://beaker.rtfd.org/',
       license='BSD',
       packages=find_packages(exclude=['ez_setup', 'examples', 'tests', 
'tests.*']),
       zip_safe=False,
-      install_requires=[],
+      install_requires=INSTALL_REQUIRES,
       extras_require={
           'crypto': ['pycryptopp>=0.5.12'],
           'pycrypto': ['pycrypto'],
-          'testsuite': [tests_require]
+          'testsuite': [TESTS_REQUIRE]
       },
       test_suite='nose.collector',
-      tests_require=tests_require,
+      tests_require=TESTS_REQUIRE,
       entry_points="""
           [paste.filter_factory]
           beaker_session = beaker.middleware:session_filter_factory


Reply via email to