Skip to content

Commit

Permalink
Drop support for Python 2.7 up to 3.6.
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Howitz committed Mar 1, 2023
1 parent 20e4e84 commit c16c1b1
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 74 deletions.
9 changes: 3 additions & 6 deletions setup.py
Expand Up @@ -12,7 +12,7 @@
#
##############################################################################
# This package is developed by the Zope Toolkit project, documented here:
# http://docs.zope.org/zopetoolkit
# https://zopetoolkit.readthedocs.io/
# When developing and releasing this package, please follow the documented
# Zope Toolkit policies as described by this documentation.
##############################################################################
Expand All @@ -39,7 +39,7 @@ def read(*rnames):
setup(name='zope.session',
version='5.0.dev0',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
author_email='zope-dev@zope.dev',
description='Client identification and sessions for Zope',
long_description=(
read('README.rst')
Expand All @@ -54,11 +54,7 @@ def read(*rnames):
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
Expand All @@ -75,6 +71,7 @@ def read(*rnames):
packages=find_packages('src'),
package_dir={'': 'src'},
namespace_packages=['zope', ],
python_requires='>=3.7',
install_requires=[
'setuptools',
'ZODB >= 4.2.0.b1',
Expand Down
21 changes: 7 additions & 14 deletions src/zope/session/http.py
Expand Up @@ -20,14 +20,7 @@
import time
from email.utils import formatdate
from hashlib import sha1


try:
# Python 3.3+: OS-independent CPU counter
from time import process_time
except ImportError: # pragma: no cover
# Python 2.7
from time import clock as process_time
from time import process_time

import zope.location
from persistent import Persistent
Expand Down Expand Up @@ -188,7 +181,7 @@ def __init__(self, namespace=None, secret=None):
if namespace is None:
namespace = "zope3_cs_%x" % (int(time.time()) - 1000000000)
if secret is None:
secret = u'%.20f' % random.random()
secret = '%.20f' % random.random()
self.namespace = namespace
self.secret = secret

Expand Down Expand Up @@ -221,7 +214,7 @@ def getClientId(self, request):
an `.IClientId`. This is because this method is used to implement
the `.IClientId` Adapter.
>>> type(id) == type(u'')
>>> type(id) == str
True
We don't set the client id unless we need to, so, for example,
Expand Down Expand Up @@ -249,7 +242,7 @@ def getClientId(self, request):
>>> bim.getClientId(request)
Traceback (most recent call last):
...
MissingClientIdException
zope.session.http.MissingClientIdException
>>> print(request.response.getCookie(bim.namespace))
None
Expand All @@ -274,7 +267,7 @@ def getClientId(self, request):
>>> bim.getClientId(request)
Traceback (most recent call last):
...
MissingClientIdException
zope.session.http.MissingClientIdException
>>> print(request.response.getCookie(bim.namespace))
None
Expand Down Expand Up @@ -305,7 +298,7 @@ def generateUniqueId(self):
True
"""
data = "%.20f%.20f%.20f" % (
data = "{:.20f}{:.20f}{:.20f}".format(
random.random(), time.time(), process_time())
digest = sha1(data.encode()).digest()
s = digestEncode(digest)
Expand Down Expand Up @@ -492,7 +485,7 @@ def setRequestId(self, request, id):
If the domain is specified, it will be set as a cookie attribute.
>>> bim.domain = u'.example.org'
>>> bim.domain = '.example.org'
>>> bim.setRequestId(request, '1234')
>>> cookie = request.response.getCookie(bim.namespace)
>>> print(cookie['domain'])
Expand Down
2 changes: 1 addition & 1 deletion src/zope/session/interfaces.py
Expand Up @@ -69,7 +69,7 @@ class ISessionDataContainer(IReadMapping, IWriteMapping):
:meth:`values` etc.
"""
timeout = schema.Int(
title=_(u"Timeout"),
title=_("Timeout"),
description=_(
"Number of seconds before data becomes stale and may "
"be removed. A value of '0' means no expiration."),
Expand Down
37 changes: 9 additions & 28 deletions src/zope/session/session.py
Expand Up @@ -16,8 +16,10 @@
import base64
import random
import time
from collections import UserDict
from heapq import heapify
from heapq import heappop
from threading import get_ident

import persistent
import ZODB
Expand All @@ -38,38 +40,17 @@
from zope.session.interfaces import ISessionPkgData


try:
from UserDict import IterableUserDict as UserDict
except ImportError:
# Py3: New UserDict location.
from collections import UserDict

try:
from thread import get_ident
except ImportError:
# Py3: New get_ident location
from threading import get_ident

_PY3 = bytes is not str
encodebytes = base64.encodebytes if _PY3 else base64.encodestring
text_type = str if _PY3 else unicode # noqa: F821 undefined name 'unicode' PY2

try:
import string
transtable = string.maketrans(b'+/', b'-.')
except AttributeError:
# Python 3
transtable = bytes.maketrans(b'+/', b'-.')
transtable = bytes.maketrans(b'+/', b'-.')


def digestEncode(s):
"""Encode SHA digest for cookie."""
return encodebytes(s)[:-2].translate(transtable)
return base64.encodebytes(s)[:-2].translate(transtable)


@zope.interface.implementer(IClientId)
@zope.component.adapter(IRequest)
class ClientId(text_type):
class ClientId(str):
"""
Default implementation of `zope.session.interfaces.IClientId`.
Expand Down Expand Up @@ -102,7 +83,7 @@ class ClientId(text_type):
def __new__(cls, request):
id_manager = zope.component.getUtility(IClientIdManager)
cid = id_manager.getClientId(request)
return text_type.__new__(cls, cid)
return str.__new__(cls, cid)


@zope.interface.implementer(ISessionDataContainer)
Expand Down Expand Up @@ -372,7 +353,7 @@ def __init__(self):
self.resolution = 5 * 60
self.timeout = 1 * 60 * 60
# Something unique
self.key = '%s.%s.%s' % (time.time(), random.random(), id(self))
self.key = '{}.{}.{}'.format(time.time(), random.random(), id(self))

_ram_storage = ZODB.MappingStorage.MappingStorage()
_ram_db = ZODB.DB(_ram_storage)
Expand All @@ -393,13 +374,13 @@ def _getData(self):
data = property(_getData, None)

def sweep(self):
super(RAMSessionDataContainer, self).sweep()
super().sweep()
self._ram_db.pack(time.time())


@zope.interface.implementer(ISession)
@zope.component.adapter(IRequest)
class Session(object):
class Session:
"""
Default implementation of `zope.session.interfaces.ISession`
"""
Expand Down
26 changes: 1 addition & 25 deletions src/zope/session/tests.py
Expand Up @@ -118,38 +118,14 @@ def testSessionIterationBug(self):

def test_suite():
import doctest
import re

from zope.testing import renormalizing

checker = renormalizing.RENormalizing([
# Python 3 strings remove the "u".
(re.compile("u('.*?')"),
r"\1"),
(re.compile('u(".*?")'),
r"\1"),
# Python 3 bytes add a "b".
(re.compile("b('.*?')"),
r"\1"),
(re.compile('b(".*?")'),
r"\1"),
# Python 3 adds module name to exceptions.
(re.compile("zope.session.http.MissingClientIdException"),
r"MissingClientIdException"),
])

flags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
suite = unittest.defaultTestLoader.loadTestsFromName(__name__)

suite.addTest(doctest.DocTestSuite(
'zope.session.session',
checker=checker,
tearDown=tearDownTransaction))
suite.addTest(doctest.DocTestSuite(
'zope.session.http',
checker=checker,
optionflags=flags))
return suite


if __name__ == '__main__':
unittest.main()

0 comments on commit c16c1b1

Please sign in to comment.