Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-repoze.who for openSUSE:Factory checked in at 2023-12-08 22:33:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-repoze.who (Old) and /work/SRC/openSUSE:Factory/.python-repoze.who.new.25432 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-repoze.who" Fri Dec 8 22:33:34 2023 rev:9 rq:1132101 version:3.0.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-repoze.who/python-repoze.who.changes 2023-06-12 15:27:29.475421104 +0200 +++ /work/SRC/openSUSE:Factory/.python-repoze.who.new.25432/python-repoze.who.changes 2023-12-08 22:34:27.065293134 +0100 @@ -1,0 +2,9 @@ +Fri Dec 8 13:40:57 UTC 2023 - Dirk Müller <dmuel...@suse.com> + +- update to 3.0.0: + * Add support for Python 3.9, 3.10 and 3.11. + * Drop support for Python 2.7, 3.4, 3.5, and 3.6. + * Add Github Actions workflow to exercise unit tests / + coverage. + +------------------------------------------------------------------- Old: ---- repoze.who-2.4.1.tar.gz New: ---- repoze.who-3.0.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-repoze.who.spec ++++++ --- /var/tmp/diff_new_pack.aPQL0d/_old 2023-12-08 22:34:27.681315800 +0100 +++ /var/tmp/diff_new_pack.aPQL0d/_new 2023-12-08 22:34:27.681315800 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-repoze.who # -# Copyright (c) 2022 SUSE LLC +# Copyright (c) 2023 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %global modname repoze.who %{?sle15_python_module_pythons} Name: python-repoze.who -Version: 2.4.1 +Version: 3.0.0 Release: 0 Summary: Identification and authentication framework for WSGI License: SUSE-Repoze ++++++ repoze.who-2.4.1.tar.gz -> repoze.who-3.0.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/.gitignore new/repoze.who-3.0.0/.gitignore --- old/repoze.who-2.4.1/.gitignore 2015-03-18 20:33:59.000000000 +0100 +++ new/repoze.who-3.0.0/.gitignore 2022-02-01 18:00:08.000000000 +0100 @@ -1,8 +1,10 @@ +build/ +dist/ +docs/.build/ +docs/_build/ +.tox/ *.pyc *.egg-info .coverage -docs/.build -.tox coverage.xml nosetests.xml -docs/_build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/.travis.yml new/repoze.who-3.0.0/.travis.yml --- old/repoze.who-2.4.1/.travis.yml 2022-01-31 17:53:31.000000000 +0100 +++ new/repoze.who-3.0.0/.travis.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,31 +0,0 @@ -# Wire up travis -language: python -sudo : false - -matrix: - include: - - python: 2.7 - env: TOXENV=py27 - - python: 3.4 - env: TOXENV=py34 - - python: 3.5 - env: TOXENV=py35 - - python: 3.6 - env: TOXENV=py36 - - python: 3.7 - env: TOXENV=py37 - - python: 3.8 - env: TOXENV=py38 - - python: pypy - env: TOXENV=pypy - - python: pypy3 - env: TOXENV=pypy3 - - python: 3.8 - env: TOXENV=cover - -install: - - travis_retry pip install tox - -script: - - travis_retry tox - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/CHANGES.rst new/repoze.who-3.0.0/CHANGES.rst --- old/repoze.who-2.4.1/CHANGES.rst 2022-02-01 17:56:46.000000000 +0100 +++ new/repoze.who-3.0.0/CHANGES.rst 2023-01-25 15:56:30.000000000 +0100 @@ -1,6 +1,20 @@ repoze.who Changelog ==================== +3.0.0 (2023-01-16) +------------------ + +- No changes from 3.0.0b1. + +3.0.0b1 (2023-01-16) +-------------------- + +- Add support for Python 3.9, 3.10 and 3.11. + +- Drop support for Python 2.7, 3.4, 3.5, and 3.6. + +- Add Github Actions workflow to exercise unit tests / coverage. + 2.4.1 (2022-02-01) ------------------ @@ -14,7 +28,7 @@ 2.4 (2020-06-03) ---------------- -- Add upport for Python 3.6, 3.7, and 3.8. +- Add support for Python 3.6, 3.7, and 3.8. - Drop support for Python 3.3. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/PKG-INFO new/repoze.who-3.0.0/PKG-INFO --- old/repoze.who-2.4.1/PKG-INFO 2022-02-01 17:57:35.634601400 +0100 +++ new/repoze.who-3.0.0/PKG-INFO 2023-01-25 15:57:22.017574000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: repoze.who -Version: 2.4.1 +Version: 3.0.0 Summary: repoze.who is an identification and authentication framework for WSGI. Home-page: http://www.repoze.org Author: Agendaless Consulting @@ -75,6 +75,20 @@ repoze.who Changelog ==================== + 3.0.0 (2023-01-16) + ------------------ + + - No changes from 3.0.0b1. + + 3.0.0b1 (2023-01-16) + -------------------- + + - Add support for Python 3.9, 3.10 and 3.11. + + - Drop support for Python 2.7, 3.4, 3.5, and 3.6. + + - Add Github Actions workflow to exercise unit tests / coverage. + 2.4.1 (2022-02-01) ------------------ @@ -88,7 +102,7 @@ 2.4 (2020-06-03) ---------------- - - Add upport for Python 3.6, 3.7, and 3.8. + - Add support for Python 3.6, 3.7, and 3.8. - Drop support for Python 3.3. @@ -796,14 +810,12 @@ Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Internet :: WWW/HTTP @@ -811,4 +823,3 @@ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application Provides-Extra: docs -Provides-Extra: testing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/_auth_tkt.py new/repoze.who-3.0.0/repoze/who/_auth_tkt.py --- old/repoze.who-2.4.1/repoze/who/_auth_tkt.py 2022-02-01 17:55:33.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/_auth_tkt.py 2022-02-01 19:25:16.000000000 +0100 @@ -37,12 +37,11 @@ non-Python code run under Apache. """ import hashlib +import http.cookies import time as time_mod +import urllib.parse -from repoze.who._compat import encodestring -from repoze.who._compat import SimpleCookie -from repoze.who._compat import url_quote -from repoze.who._compat import url_unquote +from repoze.who._helpers import encodestring DEFAULT_DIGEST = hashlib.md5 @@ -132,14 +131,14 @@ def cookie_value(self): v = '%s%08x%s!' % (self.digest(), int(self.time), - url_quote(self.userid)) + urllib.parse.quote(self.userid)) if self.tokens: v += self.tokens + '!' v += self.user_data return v def cookie(self): - c = SimpleCookie() + c = http.cookies.SimpleCookie() c_val = encodestring(self.cookie_value()) c_val = c_val.strip().replace('\n', '') c[self.cookie_name] = c_val @@ -182,7 +181,7 @@ userid, data = ticket[digest_hexa_size + 8:].split('!', 1) except ValueError: raise BadTicket('userid is not followed by !') - userid = url_unquote(userid) + userid = urllib.parse.unquote(userid) if '!' in data: tokens, user_data = data.split('!', 1) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/_compat.py new/repoze.who-3.0.0/repoze/who/_compat.py --- old/repoze.who-2.4.1/repoze/who/_compat.py 2015-03-18 20:33:59.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/_compat.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,134 +0,0 @@ -try: - STRING_TYPES = (str, unicode) -except NameError: #pragma NO COVER Python >= 3.0 - STRING_TYPES = (str,) - -try: - u = unicode -except NameError: #pragma NO COVER Python >= 3.0 - u = str - b = bytes -else: #pragma NO COVER Python < 3.0 - b = str - -import base64 -if 'decodebytes' in base64.__dict__: #pragma NO COVER Python >= 3.0 - decodebytes = base64.decodebytes - encodebytes = base64.encodebytes - def decodestring(value): - return base64.decodebytes(bytes(value, 'ascii')).decode('ascii') - def encodestring(value): - return base64.encodebytes(bytes(value, 'ascii')).decode('ascii') -else: #pragma NO COVER Python < 3.0 - decodebytes = base64.decodestring - encodebytes = base64.encodestring - decodestring = base64.decodestring - encodestring = base64.encodestring - -try: - from urllib.parse import parse_qs -except ImportError: #pragma NO COVER Python < 3.0 - from cgi import parse_qs - from cgi import parse_qsl -else: #pragma NO COVER Python >= 3.0 - from urllib.parse import parse_qsl - -try: - import ConfigParser -except ImportError: #pragma NO COVER Python >= 3.0 - from configparser import ConfigParser - from configparser import ParsingError -else: #pragma NO COVER Python < 3.0 - from ConfigParser import SafeConfigParser as ConfigParser - from ConfigParser import ParsingError - -try: - from Cookie import SimpleCookie -except ImportError: #pragma NO COVER Python >= 3.0 - from http.cookies import SimpleCookie - from http.cookies import CookieError -else: #pragma NO COVER Python < 3.0 - from Cookie import CookieError - -try: - from itertools import izip_longest -except ImportError: #pragma NO COVER Python >= 3.0 - from itertools import zip_longest as izip_longest - -try: - from StringIO import StringIO -except ImportError: #pragma NO COVER Python >= 3.0 - from io import StringIO - -try: - from urllib import urlencode -except ImportError: #pragma NO COVER Python >= 3.0 - from urllib.parse import urlencode - from urllib.parse import quote as url_quote - from urllib.parse import unquote as url_unquote -else: #pragma NO COVER Python < 3.0 - from urllib import quote as url_quote - from urllib import unquote as url_unquote - -try: - from urlparse import urlparse -except ImportError: #pragma NO COVER Python >= 3.0 - from urllib.parse import urlparse - from urllib.parse import urlunparse -else: #pragma NO COVER Python < 3.0 - from urlparse import urlunparse - -import wsgiref.util -import wsgiref.headers - -def REQUEST_METHOD(environ): - return environ['REQUEST_METHOD'] - -def CONTENT_TYPE(environ): - return environ.get('CONTENT_TYPE', '') - -def USER_AGENT(environ): - return environ.get('HTTP_USER_AGENT') - -def AUTHORIZATION(environ): - return environ.get('HTTP_AUTHORIZATION', '') - -def get_cookies(environ): - header = environ.get('HTTP_COOKIE', '') - if 'paste.cookies' in environ: - cookies, check_header = environ['paste.cookies'] - if check_header == header: - return cookies - cookies = SimpleCookie() - try: - cookies.load(header) - except CookieError: #pragma NO COVER (can't see how to provoke this) - pass - environ['paste.cookies'] = (cookies, header) - return cookies - -def construct_url(environ): - return wsgiref.util.request_uri(environ) - -def header_value(environ, key): - headers = wsgiref.headers.Headers(environ) - values = headers.get(key) - if not values: - return "" - if isinstance(values, list): #pragma NO COVER can't be true under Py3k. - return ",".join(values) - else: - return values - -def must_decode(value): - if type(value) is b: - try: - return value.decode('utf-8') - except UnicodeDecodeError: - return value.decode('latin1') - return value - -def must_encode(value): - if type(value) is u: - return value.encode('utf-8') - return value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/_helpers.py new/repoze.who-3.0.0/repoze/who/_helpers.py --- old/repoze.who-2.4.1/repoze/who/_helpers.py 1970-01-01 01:00:00.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/_helpers.py 2022-02-01 19:25:16.000000000 +0100 @@ -0,0 +1,54 @@ +import base64 +import http.cookies +import wsgiref.util +import wsgiref.headers + +def encodestring(value): + return base64.encodebytes(bytes(value, 'ascii')).decode('ascii') + +def REQUEST_METHOD(environ): + return environ['REQUEST_METHOD'] + +def CONTENT_TYPE(environ): + return environ.get('CONTENT_TYPE', '') + +def USER_AGENT(environ): + return environ.get('HTTP_USER_AGENT') + +def AUTHORIZATION(environ): + return environ.get('HTTP_AUTHORIZATION', '') + +def get_cookies(environ): + header = environ.get('HTTP_COOKIE', '') + if 'paste.cookies' in environ: + cookies, check_header = environ['paste.cookies'] + if check_header == header: + return cookies + cookies = http.cookies.SimpleCookie() + try: + cookies.load(header) + except http.cookies.CookieError: #pragma NO COVER (can't see how to provoke this) + pass + environ['paste.cookies'] = (cookies, header) + return cookies + +def construct_url(environ): + return wsgiref.util.request_uri(environ) + +def header_value(environ, key): + headers = wsgiref.headers.Headers(environ) + values = headers.get(key) + return values or "" + +def must_decode(value): + if type(value) is bytes: + try: + return value.decode('utf-8') + except UnicodeDecodeError: + return value.decode('latin1') + return value + +def must_encode(value): + if type(value) is str: + return value.encode('utf-8') + return value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/classifiers.py new/repoze.who-3.0.0/repoze/who/classifiers.py --- old/repoze.who-2.4.1/repoze/who/classifiers.py 2015-03-18 20:33:59.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/classifiers.py 2022-02-01 19:25:16.000000000 +0100 @@ -1,6 +1,6 @@ -from repoze.who._compat import CONTENT_TYPE -from repoze.who._compat import REQUEST_METHOD -from repoze.who._compat import USER_AGENT +from repoze.who._helpers import CONTENT_TYPE +from repoze.who._helpers import REQUEST_METHOD +from repoze.who._helpers import USER_AGENT from zope.interface import directlyProvides from repoze.who.interfaces import IRequestClassifier diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/config.py new/repoze.who-3.0.0/repoze/who/config.py --- old/repoze.who-2.4.1/repoze/who/config.py 2016-05-28 02:45:11.000000000 +0200 +++ new/repoze.who-3.0.0/repoze/who/config.py 2022-02-01 19:25:16.000000000 +0100 @@ -1,5 +1,7 @@ """ Configuration parser """ +import configparser +from io import StringIO import logging from pkg_resources import EntryPoint import sys @@ -14,9 +16,6 @@ from repoze.who.interfaces import IPlugin from repoze.who.interfaces import IRequestClassifier from repoze.who.middleware import PluggableAuthenticationMiddleware -from repoze.who._compat import StringIO -from repoze.who._compat import ConfigParser -from repoze.who._compat import ParsingError def _resolve(name): if name: @@ -71,7 +70,7 @@ def parse(self, text): if getattr(text, 'readline', None) is None: text = StringIO(text) - cp = ConfigParser(defaults={'here': self.here}) + cp = configparser.ConfigParser(defaults={'here': self.here}) try: cp.read_file(text) except AttributeError: #pragma NO COVER Python < 3.0 @@ -161,7 +160,7 @@ try: try: parser.parse(opened) - except ParsingError: + except configparser.ParsingError: warnings.warn('Invalid who config file: %s' % config_file, stacklevel=2) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/middleware.py new/repoze.who-3.0.0/repoze/who/middleware.py --- old/repoze.who-2.4.1/repoze/who/middleware.py 2016-05-31 19:28:55.000000000 +0200 +++ new/repoze.who-3.0.0/repoze/who/middleware.py 2022-02-01 19:25:16.000000000 +0100 @@ -1,9 +1,9 @@ +from io import StringIO import logging import sys from repoze.who.api import APIFactory from repoze.who.interfaces import IChallenger -from repoze.who._compat import StringIO _STARTED = '-- repoze.who request started (%s) --' _ENDED = '-- repoze.who request ended (%s) --' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/auth_tkt.py new/repoze.who-3.0.0/repoze/who/plugins/auth_tkt.py --- old/repoze.who-2.4.1/repoze/who/plugins/auth_tkt.py 2020-06-02 22:54:09.000000000 +0200 +++ new/repoze.who-3.0.0/repoze/who/plugins/auth_tkt.py 2022-02-01 19:25:16.000000000 +0100 @@ -4,21 +4,17 @@ import hashlib import os import time +from urllib.parse import parse_qsl +from urllib.parse import urlencode from wsgiref.handlers import _monthname # Locale-independent, RFC-2616 from wsgiref.handlers import _weekdayname # Locale-independent, RFC-2616 -try: - from urllib.parse import urlencode, parse_qsl -except ImportError: - from urllib import urlencode - from urlparse import parse_qsl from zope.interface import implementer from repoze.who.interfaces import IIdentifier from repoze.who.interfaces import IAuthenticator -from repoze.who._compat import get_cookies +from repoze.who._helpers import get_cookies import repoze.who._auth_tkt as auth_tkt -from repoze.who._compat import STRING_TYPES _UTCNOW = None # unit tests can replace def _utcnow(): #pragma NO COVERAGE @@ -220,7 +216,7 @@ id(self)) #pragma NO COVERAGE def _bool(value): - if isinstance(value, STRING_TYPES): + if isinstance(value, str): return value.lower() in ('yes', 'true', '1') return value diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/basicauth.py new/repoze.who-3.0.0/repoze/who/plugins/basicauth.py --- old/repoze.who-2.4.1/repoze/who/plugins/basicauth.py 2015-03-18 20:33:59.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/plugins/basicauth.py 2022-02-01 19:25:16.000000000 +0100 @@ -1,3 +1,4 @@ +import base64 import binascii from webob.exc import HTTPUnauthorized @@ -5,9 +6,8 @@ from repoze.who.interfaces import IIdentifier from repoze.who.interfaces import IChallenger -from repoze.who._compat import AUTHORIZATION -from repoze.who._compat import decodebytes -from repoze.who._compat import must_decode +from repoze.who._helpers import AUTHORIZATION +from repoze.who._helpers import must_decode @implementer(IIdentifier, IChallenger) class BasicAuthPlugin(object): @@ -28,7 +28,7 @@ if authmeth.lower() == b'basic': try: auth = auth.strip() - auth = decodebytes(auth) + auth = base64.decodebytes(auth) except binascii.Error: # can't decode return None try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/htpasswd.py new/repoze.who-3.0.0/repoze/who/plugins/htpasswd.py --- old/repoze.who-2.4.1/repoze/who/plugins/htpasswd.py 2022-02-01 17:23:22.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/plugins/htpasswd.py 2022-02-01 19:25:16.000000000 +0100 @@ -4,7 +4,6 @@ from repoze.who.interfaces import IAuthenticator from repoze.who.utils import resolveDotted -from repoze.who._compat import izip_longest def _padding_for_file_lines(): @@ -86,7 +85,7 @@ def _same_string(x, y): # Attempt at isochronous string comparison. mismatches = filter(None, [a != b for a, b, ignored - in izip_longest(x, y, PADDING)]) + in itertools.zip_longest(x, y, PADDING)]) if type(mismatches) != list: #pragma NO COVER Python >= 3.0 mismatches = list(mismatches) return len(mismatches) == 0 @@ -99,7 +98,7 @@ def sha1_check(password, hashed): from hashlib import sha1 from base64 import standard_b64encode - from repoze.who._compat import must_encode + from repoze.who._helpers import must_encode b_password = must_encode(password) b_sha1_digest = sha1(b_password).digest() b_b64_sha1_digest = standard_b64encode(b_sha1_digest) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/redirector.py new/repoze.who-3.0.0/repoze/who/plugins/redirector.py --- old/repoze.who-2.4.1/repoze/who/plugins/redirector.py 2015-03-18 20:33:59.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/plugins/redirector.py 2022-02-01 19:25:16.000000000 +0100 @@ -1,14 +1,14 @@ +from urllib.parse import parse_qs +from urllib.parse import urlencode +from urllib.parse import urlparse +from urllib.parse import urlunparse from webob.exc import HTTPFound + from zope.interface import implementer from repoze.who.interfaces import IChallenger -from repoze.who._compat import construct_url -from repoze.who._compat import header_value -from repoze.who._compat import parse_qs -from repoze.who._compat import u -from repoze.who._compat import urlencode -from repoze.who._compat import urlparse -from repoze.who._compat import urlunparse +from repoze.who._helpers import construct_url +from repoze.who._helpers import header_value @implementer(IChallenger) class RedirectorPlugin(object): @@ -62,7 +62,7 @@ reason_param=None, reason_header=None, ): - if login_url in (u(''), b'', None): + if login_url in (u'', b'', None): raise ValueError("No 'login_url'") if reason_header is not None and reason_param is None: raise Exception("Can't set 'reason_header' without 'reason_param'.") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/tests/fixtures/testapp.py new/repoze.who-3.0.0/repoze/who/plugins/tests/fixtures/testapp.py --- old/repoze.who-2.4.1/repoze/who/plugins/tests/fixtures/testapp.py 2014-12-13 00:37:43.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/plugins/tests/fixtures/testapp.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,53 +0,0 @@ -def tack_environ(environ, msg): - import pprint - penv = pprint.pformat(environ) - return msg + '\n\n' + penv - -def deny(start_response, environ, msg): - ct = 'text/plain' - msg = tack_environ(environ, msg) - cl = str(len(msg)) - start_response('401 Unauthorized', - [ ('Content-Type', ct), - ('Content-Length', cl) ], - ) - -def allow(start_response, environ, msg): - ct = 'text/plain' - msg = tack_environ(environ, msg) - cl = str(len(msg)) - start_response('200 OK', - [ ('Content-Type', ct), - ('Content-Length', cl) ], - ) - return [msg] - -def app(environ, start_response): - path_info = environ['PATH_INFO'] - remote_user = environ.get('REMOTE_USER') - if path_info.endswith('/shared'): - if not remote_user: - return deny(start_response, environ, 'You cant do that') - else: - return allow(start_response, environ, - 'Welcome to the shared area, %s' % remote_user) - elif path_info.endswith('/admin'): - if remote_user != 'admin': - return deny(start_response, environ, 'Only admin can do that') - else: - return allow(start_response, environ, 'Hello, admin!') - elif path_info.endswith('/chris'): - if remote_user != 'chris': - return deny(start_response, environ, 'Only chris can do that') - else: - return allow(start_response, environ, 'Hello, chris!') - else: - return allow(start_response, environ, 'Unprotected page') - -def make_app(global_config, **kw): - return app - - - - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/tests/test_authtkt.py new/repoze.who-3.0.0/repoze/who/plugins/tests/test_authtkt.py --- old/repoze.who-2.4.1/repoze/who/plugins/tests/test_authtkt.py 2020-06-02 22:54:09.000000000 +0200 +++ new/repoze.who-3.0.0/repoze/who/plugins/tests/test_authtkt.py 2022-02-01 19:25:16.000000000 +0100 @@ -501,31 +501,12 @@ ('Set-Cookie', 'auth_tkt="%s"; Path=/' % new_val)) - def test_remember_creds_different_long_userid(self): - try: - long - except NameError: #pragma NO COVER Python >= 3.0 - return - plugin = self._makeOne('secret') - old_val = self._makeTicket(userid='userid') - environ = self._makeEnviron({'HTTP_COOKIE':'auth_tkt=%s' % old_val}) - new_val = self._makeTicket(userid='1', userdata='userid_type=int') - result = plugin.remember(environ, {'repoze.who.userid':long(1), - 'userdata':{}}) - self.assertEqual(len(result), 3) - self.assertEqual(result[0], - ('Set-Cookie', - 'auth_tkt="%s"; Path=/' % new_val)) - def test_remember_creds_different_unicode_userid(self): plugin = self._makeOne('secret') old_val = self._makeTicket(userid='userid') environ = self._makeEnviron({'HTTP_COOKIE':'auth_tkt=%s' % old_val}) userid = b'\xc2\xa9'.decode('utf-8') - if type(b'') == type(''): - userdata = 'userid_type=unicode' - else: # pragma: no cover Py3k - userdata = '' + userdata = '' new_val = self._makeTicket(userid=userid.encode('utf-8'), userdata=userdata) result = plugin.remember(environ, {'repoze.who.userid':userid, @@ -739,12 +720,11 @@ secret="fiddly", digest_algo='foo23') def test_remember_max_age_unicode(self): - from repoze.who._compat import u plugin = self._makeOne('secret') environ = {'HTTP_HOST':'example.com'} tkt = self._makeTicket(userid='chris', userdata='') result = plugin.remember(environ, {'repoze.who.userid': 'chris', - 'max_age': u('500')}) + 'max_age': u'500'}) name, value = result.pop(0) self.assertEqual('Set-Cookie', name) self.assertTrue(isinstance(value, str)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/tests/test_basicauth.py new/repoze.who-3.0.0/repoze/who/plugins/tests/test_basicauth.py --- old/repoze.who-2.4.1/repoze/who/plugins/tests/test_basicauth.py 2015-03-18 20:33:59.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/plugins/tests/test_basicauth.py 2022-02-01 19:25:16.000000000 +0100 @@ -58,7 +58,7 @@ self.assertEqual(creds, None) def test_identify_basic_badrepr(self): - from repoze.who._compat import encodebytes + from base64 import encodebytes plugin = self._makeOne('realm') value = encodebytes(b'foo').decode('ascii') environ = self._makeEnviron({'HTTP_AUTHORIZATION':'Basic %s' % value}) @@ -66,7 +66,7 @@ self.assertEqual(creds, None) def test_identify_basic_ok(self): - from repoze.who._compat import encodebytes + from base64 import encodebytes plugin = self._makeOne('realm') value = encodebytes(b'foo:bar').decode('ascii') environ = self._makeEnviron({'HTTP_AUTHORIZATION':'Basic %s' % value}) @@ -74,7 +74,7 @@ self.assertEqual(creds, {'login':'foo', 'password':'bar'}) def test_identify_basic_ok_utf8_values(self): - from repoze.who._compat import encodebytes + from base64 import encodebytes LOGIN = b'b\xc3\xa2tard' PASSWD = b'l\xc3\xa0 demain' plugin = self._makeOne('realm') @@ -85,7 +85,7 @@ 'password': PASSWD.decode('utf-8')}) def test_identify_basic_ok_latin1_values(self): - from repoze.who._compat import encodebytes + from base64 import encodebytes LOGIN = b'b\xe2tard' PASSWD = b'l\xe0 demain' plugin = self._makeOne('realm') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/tests/test_htpasswd.py new/repoze.who-3.0.0/repoze/who/plugins/tests/test_htpasswd.py --- old/repoze.who-2.4.1/repoze/who/plugins/tests/test_htpasswd.py 2022-02-01 17:23:22.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/plugins/tests/test_htpasswd.py 2022-02-01 19:25:16.000000000 +0100 @@ -23,7 +23,7 @@ verifyClass(IAuthenticator, klass) def test_authenticate_nocreds(self): - from repoze.who._compat import StringIO + from io import StringIO io = StringIO() plugin = self._makeOne(io, None) environ = self._makeEnviron() @@ -32,7 +32,7 @@ self.assertEqual(result, None) def test_authenticate_nolines(self): - from repoze.who._compat import StringIO + from io import StringIO io = StringIO() def check(password, hashed): return True @@ -43,7 +43,7 @@ self.assertEqual(result, None) def test_authenticate_nousermatch(self): - from repoze.who._compat import StringIO + from io import StringIO io = StringIO('nobody:foo') def check(password, hashed): return True @@ -54,7 +54,7 @@ self.assertEqual(result, None) def test_authenticate_match(self): - from repoze.who._compat import StringIO + from io import StringIO io = StringIO('chrism:pass') def check(password, hashed): return True @@ -65,7 +65,7 @@ self.assertEqual(result, 'chrism') def test_authenticate_badline(self): - from repoze.who._compat import StringIO + from io import StringIO io = StringIO('badline\nchrism:pass') def check(password, hashed): return True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/tests/test_redirector.py new/repoze.who-3.0.0/repoze/who/plugins/tests/test_redirector.py --- old/repoze.who-2.4.1/repoze/who/plugins/tests/test_redirector.py 2015-03-18 20:33:59.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/plugins/tests/test_redirector.py 2022-02-01 19:25:16.000000000 +0100 @@ -19,7 +19,7 @@ reason_header=reason_header) def _makeEnviron(self, path_info='/', identifier=None): - from repoze.who._compat import StringIO + from io import StringIO if identifier is None: credentials = {'login':'chris', 'password':'password'} identifier = DummyIdentifier(credentials) @@ -59,8 +59,8 @@ reason_header='X-Reason') def test_challenge(self): - from ..._compat import parse_qsl - from ..._compat import urlparse + from urllib.parse import parse_qsl + from urllib.parse import urlparse plugin = self._makeOne(came_from_param='came_from', reason_param='reason', reason_header='X-Authorization-Failure-Reason', @@ -93,8 +93,8 @@ self.assertEqual(sr.status, '302 Found') def test_challenge_with_reason_header(self): - from ..._compat import parse_qsl - from ..._compat import urlparse + from urllib.parse import parse_qsl + from urllib.parse import urlparse plugin = self._makeOne(came_from_param='came_from', reason_param='reason', reason_header='X-Authorization-Failure-Reason', @@ -125,8 +125,8 @@ self.assertEqual(reason_value, 'you are ugly') def test_challenge_with_custom_reason_header(self): - from ..._compat import parse_qsl - from ..._compat import urlparse + from urllib.parse import parse_qsl + from urllib.parse import urlparse plugin = self._makeOne(came_from_param='came_from', reason_param='reason', reason_header='X-Custom-Auth-Failure', @@ -154,8 +154,8 @@ self.assertEqual(came_from_value, 'http://www.example.com/?default=1') def test_challenge_w_reason_no_reason_param_no_came_from_param(self): - from ..._compat import parse_qsl - from ..._compat import urlparse + from urllib.parse import parse_qsl + from urllib.parse import urlparse plugin = self._makeOne() environ = self._makeEnviron() app = plugin.challenge( @@ -178,8 +178,8 @@ self.assertEqual(parts[3], '') def test_challenge_w_reason_no_reason_param_w_came_from_param(self): - from ..._compat import parse_qsl - from ..._compat import urlparse + from urllib.parse import parse_qsl + from urllib.parse import urlparse plugin = self._makeOne(came_from_param='came_from', ) environ = self._makeEnviron() @@ -205,8 +205,8 @@ self.assertEqual(came_from_value, 'http://www.example.com/?default=1') def test_challenge_with_reason_and_custom_reason_param(self): - from ..._compat import parse_qsl - from ..._compat import urlparse + from urllib.parse import parse_qsl + from urllib.parse import urlparse plugin = self._makeOne(came_from_param='came_from', reason_param='auth_failure', reason_header='X-Custom-Auth-Failure', @@ -238,8 +238,8 @@ self.assertEqual(reason_value, 'you are ugly') def test_challenge_wo_reason_w_came_from_param(self): - from ..._compat import parse_qsl - from ..._compat import urlparse + from urllib.parse import parse_qsl + from urllib.parse import urlparse plugin = self._makeOne(came_from_param='came_from') environ = self._makeEnviron() app = plugin.challenge( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/plugins/tests/test_sql.py new/repoze.who-3.0.0/repoze/who/plugins/tests/test_sql.py --- old/repoze.who-2.4.1/repoze/who/plugins/tests/test_sql.py 2015-03-18 20:33:59.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/plugins/tests/test_sql.py 2022-02-01 19:25:16.000000000 +0100 @@ -88,10 +88,9 @@ self.assertEqual(result, True) def test_shaprefix_w_unicode_cleartext(self): - from repoze.who._compat import u stored = '{SHA}' + self._get_sha_hex_digest() compare = self._getFUT() - result = compare(u('password'), stored) + result = compare(u'password', stored) self.assertEqual(result, True) def test_shaprefix_fail(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/restrict.py new/repoze.who-3.0.0/repoze/who/restrict.py --- old/repoze.who-2.4.1/repoze/who/restrict.py 2016-05-28 02:45:45.000000000 +0200 +++ new/repoze.who-3.0.0/repoze/who/restrict.py 2022-02-01 19:25:16.000000000 +0100 @@ -1,8 +1,6 @@ # Authorization middleware from pkg_resources import EntryPoint -from repoze.who._compat import STRING_TYPES - def authenticated_predicate(): def _predicate(environ): return 'REMOTE_USER' in environ or 'repoze.who.identity' in environ @@ -28,6 +26,6 @@ def make_predicate_restriction(app, global_config, predicate, enabled=True, **kw): - if isinstance(predicate, STRING_TYPES): + if isinstance(predicate, str): predicate = EntryPoint.parse('x=%s' % predicate).resolve() return PredicateRestriction(app, predicate, enabled, **kw) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/tests/test__auth_tkt.py new/repoze.who-3.0.0/repoze/who/tests/test__auth_tkt.py --- old/repoze.who-2.4.1/repoze/who/tests/test__auth_tkt.py 2022-02-01 17:55:33.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/tests/test__auth_tkt.py 2022-02-01 19:25:16.000000000 +0100 @@ -4,7 +4,7 @@ class AuthTicketTests(unittest.TestCase): def _getTargetClass(self): - from .._auth_tkt import AuthTicket + from repoze.who._auth_tkt import AuthTicket return AuthTicket def _makeOne(self, *args, **kw): @@ -12,7 +12,7 @@ def test_ctor_defaults(self): import hashlib - from .. import _auth_tkt + from repoze.who import _auth_tkt with _Monkey(_auth_tkt, time_mod=_Timemod): tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4') self.assertEqual(tkt.secret, 'SEEKRIT') @@ -94,7 +94,7 @@ self.assertEqual(tkt.digest_algo, hashlib.sha1) def test_digest(self): - from .._auth_tkt import calculate_digest, hashlib + from repoze.who._auth_tkt import calculate_digest, hashlib tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', tokens=('a', 'b'), user_data='DATA', time=_WHEN, cookie_name='oatmeal', secure=True) @@ -103,7 +103,7 @@ self.assertEqual(tkt.digest(), digest) def test_cookie_value_wo_tokens_or_userdata(self): - from .._auth_tkt import calculate_digest, hashlib + from repoze.who._auth_tkt import calculate_digest, hashlib tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', time=_WHEN) digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', '', '', hashlib.md5) @@ -111,7 +111,7 @@ '%s%08xUSERID!' % (digest, _WHEN)) def test_cookie_value_w_tokens_and_userdata(self): - from .._auth_tkt import calculate_digest, hashlib + from repoze.who._auth_tkt import calculate_digest, hashlib tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', tokens=('a', 'b'), user_data='DATA', time=_WHEN) digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', @@ -120,8 +120,8 @@ '%s%08xUSERID!a,b!DATA' % (digest, _WHEN)) def test_cookie_not_secure_wo_tokens_or_userdata(self): - from .._auth_tkt import calculate_digest, hashlib - from .._compat import encodestring + from repoze.who._auth_tkt import calculate_digest, hashlib + from repoze.who._helpers import encodestring tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', time=_WHEN, cookie_name='oatmeal') digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', @@ -134,8 +134,8 @@ self.assertEqual(cookie['oatmeal']['secure'], '') def test_cookie_secure_w_tokens_and_userdata(self): - from .._auth_tkt import calculate_digest, hashlib - from .._compat import encodestring + from repoze.who._auth_tkt import calculate_digest, hashlib + from repoze.who._helpers import encodestring tkt = self._makeOne('SEEKRIT', 'USERID', '1.2.3.4', tokens=('a', 'b'), user_data='DATA', time=_WHEN, cookie_name='oatmeal', secure=True) @@ -152,7 +152,7 @@ class BadTicketTests(unittest.TestCase): def _getTargetClass(self): - from .._auth_tkt import BadTicket + from repoze.who._auth_tkt import BadTicket return BadTicket def _makeOne(self, *args, **kw): @@ -173,11 +173,11 @@ def _callFUT(self, secret='SEEKRIT', ticket=None, ip='1.2.3.4', digest="md5"): - from .._auth_tkt import parse_ticket + from repoze.who._auth_tkt import parse_ticket return parse_ticket(secret, ticket, ip, digest) def test_bad_timestamp(self): - from .._auth_tkt import BadTicket + from repoze.who._auth_tkt import BadTicket TICKET = '12345678901234567890123456789012XXXXXXXXuserid!' try: self._callFUT(ticket=TICKET) @@ -188,7 +188,7 @@ self.fail('Did not raise') def test_no_bang_after_userid(self): - from .._auth_tkt import BadTicket + from repoze.who._auth_tkt import BadTicket TICKET = '1234567890123456789012345678901201020304userid' try: self._callFUT(ticket=TICKET) @@ -198,7 +198,7 @@ self.fail('Did not raise') def test_wo_tokens_or_data_bad_digest(self): - from .._auth_tkt import BadTicket + from repoze.who._auth_tkt import BadTicket TICKET = '1234567890123456789012345678901201020304userid!' try: self._callFUT(ticket=TICKET) @@ -208,7 +208,7 @@ self.fail('Did not raise') def test_wo_tokens_or_data_ok_digest(self): - from .._auth_tkt import calculate_digest, hashlib + from repoze.who._auth_tkt import calculate_digest, hashlib digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', '', '', hashlib.md5) TICKET = '%s%08xUSERID!' % (digest, _WHEN) @@ -219,7 +219,7 @@ self.assertEqual(user_data, '') def test_w_tokens_and_data_ok_digest(self): - from .._auth_tkt import calculate_digest, hashlib + from repoze.who._auth_tkt import calculate_digest, hashlib digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', 'a,b', 'DATA', hashlib.md5) TICKET = '%s%08xUSERID!a,b!DATA' % (digest, _WHEN) @@ -230,7 +230,7 @@ self.assertEqual(user_data, 'DATA') def test_w_tokens_and_data_ok_alternate_digest(self): - from .._auth_tkt import calculate_digest, hashlib + from repoze.who._auth_tkt import calculate_digest, hashlib digest = calculate_digest('1.2.3.4', _WHEN, 'SEEKRIT', 'USERID', 'a,b', 'DATA', hashlib.sha256) TICKET = '%s%08xUSERID!a,b!DATA' % (digest, _WHEN) @@ -248,29 +248,28 @@ def test_ints_to_bytes(self): from struct import pack - from .._auth_tkt import ints2bytes + from repoze.who._auth_tkt import ints2bytes self.assertEqual(ints2bytes([1, 2, 3, 4]), pack('>BBBB', 1, 2, 3, 4)) def test_encode_ip_timestamp(self): from struct import pack - from .._auth_tkt import encode_ip_timestamp + from repoze.who._auth_tkt import encode_ip_timestamp self.assertEqual(encode_ip_timestamp('1.2.3.4', _WHEN), pack('>BBBBL', 1, 2, 3, 4, _WHEN)) def test_maybe_encode_bytes(self): - from .._auth_tkt import maybe_encode + from repoze.who._auth_tkt import maybe_encode foo = b'foo' self.assertTrue(maybe_encode(foo) is foo) def test_maybe_encode_native_string(self): - from .._auth_tkt import maybe_encode + from repoze.who._auth_tkt import maybe_encode foo = 'foo' self.assertEqual(maybe_encode(foo), b'foo') def test_maybe_encode_unicode(self): - from .._auth_tkt import maybe_encode - from .._compat import u - foo = u('foo') + from repoze.who._auth_tkt import maybe_encode + foo = u'foo' self.assertEqual(maybe_encode(foo), b'foo') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/tests/test__compat.py new/repoze.who-3.0.0/repoze/who/tests/test__compat.py --- old/repoze.who-2.4.1/repoze/who/tests/test__compat.py 2015-03-18 20:33:59.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/tests/test__compat.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,131 +0,0 @@ -import unittest - - -class CompatTests(unittest.TestCase): - - def test_REQUEST_METHOD_miss(self): - # PEP 3333 says CONTENT_TYPE is mandatory - from .._compat import REQUEST_METHOD - self.assertRaises(KeyError, REQUEST_METHOD, {}) - - def test_REQUEST_METHOD_hit(self): - from .._compat import REQUEST_METHOD - self.assertEqual(REQUEST_METHOD({'REQUEST_METHOD': 'FOO'}), 'FOO') - - def test_CONTENT_TYPE_miss(self): - # PEP 3333 says CONTENT_TYPE is optional - from .._compat import CONTENT_TYPE - self.assertEqual(CONTENT_TYPE({}), '') - - def test_CONTENT_TYPE_hit(self): - from .._compat import CONTENT_TYPE - self.assertEqual(CONTENT_TYPE({'CONTENT_TYPE': 'text/html'}), - 'text/html') - - def test_USER_AGENT_miss(self): - from .._compat import USER_AGENT - self.assertEqual(USER_AGENT({}), None) - - def test_USER_AGENT_hit(self): - from .._compat import USER_AGENT - self.assertEqual(USER_AGENT({'HTTP_USER_AGENT': 'FOO'}), 'FOO') - - def test_AUTHORIZATION_miss(self): - from .._compat import AUTHORIZATION - self.assertEqual(AUTHORIZATION({}), '') - - def test_AUTHORIZATION_hit(self): - from .._compat import AUTHORIZATION - self.assertEqual(AUTHORIZATION({'HTTP_AUTHORIZATION': 'FOO'}), 'FOO') - - def test_get_cookies_no_cache_ok_header_value(self): - from .._compat import get_cookies - from .._compat import SimpleCookie - environ = {'HTTP_COOKIE': 'qux=spam'} - cookies = get_cookies(environ) - self.assertTrue(isinstance(cookies, SimpleCookie)) - self.assertEqual(len(cookies), 1) - self.assertEqual(cookies['qux'].value, 'spam') - self.assertEqual(environ['paste.cookies'], (cookies, 'qux=spam')) - - def test_get_cookies_w_cache_miss(self): - from .._compat import get_cookies - from .._compat import SimpleCookie - environ = {'HTTP_COOKIE': 'qux=spam', - 'paste.cookies': (object(), 'foo=bar'), - } - cookies = get_cookies(environ) - self.assertTrue(isinstance(cookies, SimpleCookie)) - self.assertEqual(len(cookies), 1) - self.assertEqual(cookies['qux'].value, 'spam') - self.assertEqual(environ['paste.cookies'], (cookies, 'qux=spam')) - - def test_get_cookies_w_cache_hit(self): - from .._compat import get_cookies - from .._compat import SimpleCookie - existing = SimpleCookie() - existing['foo'] = 'bar' - environ = {'HTTP_COOKIE': 'qux=spam', - 'paste.cookies': (existing, 'qux=spam'), - } - cookies = get_cookies(environ) - self.assertTrue(cookies is existing) - - def test_construct_url(self): - from .._compat import construct_url - environ = {'wsgi.url_scheme': 'http', - 'HTTP_HOST': 'example.com', - } - self.assertEqual(construct_url(environ), 'http://example.com/') - - def test_header_value_miss(self): - from .._compat import header_value - self.assertEqual(header_value([], 'nonesuch'), '') - - def test_header_value_simple(self): - from .._compat import header_value - self.assertEqual(header_value([('simple', 'SIMPLE')], 'simple'), - 'SIMPLE') - - def test_must_decode_non_string(self): - from .._compat import must_decode - foo = object() - self.assertTrue(must_decode(foo) is foo) - - def test_must_decode_unicode(self): - from .._compat import must_decode - from .._compat import u - foo = u('foo') - self.assertTrue(must_decode(foo) is foo) - - def test_must_decode_utf8(self): - from .._compat import must_decode - foo = b'b\xc3\xa2tard' - self.assertEqual(must_decode(foo), foo.decode('utf-8')) - - def test_must_decode_latin1(self): - from .._compat import must_decode - foo = b'b\xe2tard' - self.assertEqual(must_decode(foo), foo.decode('latin1')) - - def test_must_encode_non_string(self): - from .._compat import must_encode - foo = object() - self.assertTrue(must_encode(foo) is foo) - - def test_must_encode_unicode(self): - from .._compat import must_encode - from .._compat import u - foo = u('foo') - self.assertEqual(must_encode(foo), foo.encode('utf-8')) - - def test_must_encode_utf8(self): - from .._compat import must_encode - foo = b'b\xc3\xa2tard' - self.assertTrue(must_encode(foo) is foo) - - def test_must_encode_latin1(self): - from .._compat import must_encode - foo = b'b\xe2tard' - self.assertTrue(must_encode(foo) is foo) - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/tests/test__helpers.py new/repoze.who-3.0.0/repoze/who/tests/test__helpers.py --- old/repoze.who-2.4.1/repoze/who/tests/test__helpers.py 1970-01-01 01:00:00.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/tests/test__helpers.py 2022-02-01 19:25:16.000000000 +0100 @@ -0,0 +1,129 @@ +import unittest + + +class CompatTests(unittest.TestCase): + + def test_REQUEST_METHOD_miss(self): + # PEP 3333 says CONTENT_TYPE is mandatory + from repoze.who._helpers import REQUEST_METHOD + self.assertRaises(KeyError, REQUEST_METHOD, {}) + + def test_REQUEST_METHOD_hit(self): + from repoze.who._helpers import REQUEST_METHOD + self.assertEqual(REQUEST_METHOD({'REQUEST_METHOD': 'FOO'}), 'FOO') + + def test_CONTENT_TYPE_miss(self): + # PEP 3333 says CONTENT_TYPE is optional + from repoze.who._helpers import CONTENT_TYPE + self.assertEqual(CONTENT_TYPE({}), '') + + def test_CONTENT_TYPE_hit(self): + from repoze.who._helpers import CONTENT_TYPE + self.assertEqual(CONTENT_TYPE({'CONTENT_TYPE': 'text/html'}), + 'text/html') + + def test_USER_AGENT_miss(self): + from repoze.who._helpers import USER_AGENT + self.assertEqual(USER_AGENT({}), None) + + def test_USER_AGENT_hit(self): + from repoze.who._helpers import USER_AGENT + self.assertEqual(USER_AGENT({'HTTP_USER_AGENT': 'FOO'}), 'FOO') + + def test_AUTHORIZATION_miss(self): + from repoze.who._helpers import AUTHORIZATION + self.assertEqual(AUTHORIZATION({}), '') + + def test_AUTHORIZATION_hit(self): + from repoze.who._helpers import AUTHORIZATION + self.assertEqual(AUTHORIZATION({'HTTP_AUTHORIZATION': 'FOO'}), 'FOO') + + def test_get_cookies_no_cache_ok_header_value(self): + from http.cookies import SimpleCookie + from repoze.who._helpers import get_cookies + environ = {'HTTP_COOKIE': 'qux=spam'} + cookies = get_cookies(environ) + self.assertTrue(isinstance(cookies, SimpleCookie)) + self.assertEqual(len(cookies), 1) + self.assertEqual(cookies['qux'].value, 'spam') + self.assertEqual(environ['paste.cookies'], (cookies, 'qux=spam')) + + def test_get_cookies_w_cache_miss(self): + from http.cookies import SimpleCookie + from repoze.who._helpers import get_cookies + environ = {'HTTP_COOKIE': 'qux=spam', + 'paste.cookies': (object(), 'foo=bar'), + } + cookies = get_cookies(environ) + self.assertTrue(isinstance(cookies, SimpleCookie)) + self.assertEqual(len(cookies), 1) + self.assertEqual(cookies['qux'].value, 'spam') + self.assertEqual(environ['paste.cookies'], (cookies, 'qux=spam')) + + def test_get_cookies_w_cache_hit(self): + from http.cookies import SimpleCookie + from repoze.who._helpers import get_cookies + existing = SimpleCookie() + existing['foo'] = 'bar' + environ = {'HTTP_COOKIE': 'qux=spam', + 'paste.cookies': (existing, 'qux=spam'), + } + cookies = get_cookies(environ) + self.assertTrue(cookies is existing) + + def test_construct_url(self): + from repoze.who._helpers import construct_url + environ = {'wsgi.url_scheme': 'http', + 'HTTP_HOST': 'example.com', + } + self.assertEqual(construct_url(environ), 'http://example.com/') + + def test_header_value_miss(self): + from repoze.who._helpers import header_value + self.assertEqual(header_value([], 'nonesuch'), '') + + def test_header_value_simple(self): + from repoze.who._helpers import header_value + self.assertEqual(header_value([('simple', 'SIMPLE')], 'simple'), + 'SIMPLE') + + def test_must_decode_non_string(self): + from repoze.who._helpers import must_decode + foo = object() + self.assertTrue(must_decode(foo) is foo) + + def test_must_decode_unicode(self): + from repoze.who._helpers import must_decode + foo = u'foo' + self.assertTrue(must_decode(foo) is foo) + + def test_must_decode_utf8(self): + from repoze.who._helpers import must_decode + foo = b'b\xc3\xa2tard' + self.assertEqual(must_decode(foo), foo.decode('utf-8')) + + def test_must_decode_latin1(self): + from repoze.who._helpers import must_decode + foo = b'b\xe2tard' + self.assertEqual(must_decode(foo), foo.decode('latin1')) + + def test_must_encode_non_string(self): + from repoze.who._helpers import must_encode + foo = object() + self.assertTrue(must_encode(foo) is foo) + + def test_must_encode_unicode(self): + from repoze.who._helpers import must_encode + foo = u'foo' + self.assertEqual(must_encode(foo), foo.encode('utf-8')) + + def test_must_encode_utf8(self): + from repoze.who._helpers import must_encode + foo = b'b\xc3\xa2tard' + self.assertTrue(must_encode(foo) is foo) + + def test_must_encode_latin1(self): + from repoze.who._helpers import must_encode + foo = b'b\xe2tard' + self.assertTrue(must_encode(foo) is foo) + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/tests/test_config.py new/repoze.who-3.0.0/repoze/who/tests/test_config.py --- old/repoze.who-2.4.1/repoze/who/tests/test_config.py 2015-03-18 20:34:00.000000000 +0100 +++ new/repoze.who-3.0.0/repoze/who/tests/test_config.py 2022-02-01 19:25:16.000000000 +0100 @@ -40,7 +40,7 @@ self.assertEqual(len(config.mdproviders), 0) def test_parse_empty_file(self): - from repoze.who._compat import StringIO + from io import StringIO config = self._makeOne() config.parse(StringIO()) self.assertEqual(config.request_classifier, None) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze/who/tests/test_middleware.py new/repoze.who-3.0.0/repoze/who/tests/test_middleware.py --- old/repoze.who-2.4.1/repoze/who/tests/test_middleware.py 2016-05-31 19:33:27.000000000 +0200 +++ new/repoze.who-3.0.0/repoze/who/tests/test_middleware.py 2022-02-01 19:25:16.000000000 +0100 @@ -511,7 +511,7 @@ self.assertTrue(wrapper.buffer) def test_finish_response(self): - from repoze.who._compat import StringIO + from io import StringIO statuses = [] headerses = [] datases = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze.who.egg-info/PKG-INFO new/repoze.who-3.0.0/repoze.who.egg-info/PKG-INFO --- old/repoze.who-2.4.1/repoze.who.egg-info/PKG-INFO 2022-02-01 17:57:35.000000000 +0100 +++ new/repoze.who-3.0.0/repoze.who.egg-info/PKG-INFO 2023-01-25 15:57:21.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: repoze.who -Version: 2.4.1 +Version: 3.0.0 Summary: repoze.who is an identification and authentication framework for WSGI. Home-page: http://www.repoze.org Author: Agendaless Consulting @@ -75,6 +75,20 @@ repoze.who Changelog ==================== + 3.0.0 (2023-01-16) + ------------------ + + - No changes from 3.0.0b1. + + 3.0.0b1 (2023-01-16) + -------------------- + + - Add support for Python 3.9, 3.10 and 3.11. + + - Drop support for Python 2.7, 3.4, 3.5, and 3.6. + + - Add Github Actions workflow to exercise unit tests / coverage. + 2.4.1 (2022-02-01) ------------------ @@ -88,7 +102,7 @@ 2.4 (2020-06-03) ---------------- - - Add upport for Python 3.6, 3.7, and 3.8. + - Add support for Python 3.6, 3.7, and 3.8. - Drop support for Python 3.3. @@ -796,14 +810,12 @@ Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Internet :: WWW/HTTP @@ -811,4 +823,3 @@ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application Provides-Extra: docs -Provides-Extra: testing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze.who.egg-info/SOURCES.txt new/repoze.who-3.0.0/repoze.who.egg-info/SOURCES.txt --- old/repoze.who-2.4.1/repoze.who.egg-info/SOURCES.txt 2022-02-01 17:57:35.000000000 +0100 +++ new/repoze.who-3.0.0/repoze.who.egg-info/SOURCES.txt 2023-01-25 15:57:21.000000000 +0100 @@ -1,6 +1,5 @@ .bzrignore .gitignore -.travis.yml CHANGES.rst CONTRIBUTORS.txt COPYRIGHT.txt @@ -40,7 +39,7 @@ repoze.who.egg-info/top_level.txt repoze/who/__init__.py repoze/who/_auth_tkt.py -repoze/who/_compat.py +repoze/who/_helpers.py repoze/who/api.py repoze/who/classifiers.py repoze/who/config.py @@ -62,10 +61,9 @@ repoze/who/plugins/tests/test_sql.py repoze/who/plugins/tests/fixtures/__init__.py repoze/who/plugins/tests/fixtures/test.htpasswd -repoze/who/plugins/tests/fixtures/testapp.py repoze/who/tests/__init__.py repoze/who/tests/test__auth_tkt.py -repoze/who/tests/test__compat.py +repoze/who/tests/test__helpers.py repoze/who/tests/test_api.py repoze/who/tests/test_classifiers.py repoze/who/tests/test_config.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/repoze.who.egg-info/requires.txt new/repoze.who-3.0.0/repoze.who.egg-info/requires.txt --- old/repoze.who-2.4.1/repoze.who.egg-info/requires.txt 2022-02-01 17:57:35.000000000 +0100 +++ new/repoze.who-3.0.0/repoze.who.egg-info/requires.txt 2023-01-25 15:57:21.000000000 +0100 @@ -7,9 +7,3 @@ WebOb repoze.sphinx.autointerface zope.interface - -[testing] -WebOb -coverage -nose -zope.interface diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/setup.cfg new/repoze.who-3.0.0/setup.cfg --- old/repoze.who-2.4.1/setup.cfg 2022-02-01 17:57:35.634601400 +0100 +++ new/repoze.who-3.0.0/setup.cfg 2023-01-25 15:57:22.017574000 +0100 @@ -1,14 +1,8 @@ [easy_install] zip_ok = false -[nosetests] -nocapture = 1 -cover-package = repoze.who -cover-erase = 1 -cover-min-percentage = 100 - [aliases] -dev = develop easy_install repoze.who[testing] +dev = develop [egg_info] tag_build = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/setup.py new/repoze.who-3.0.0/setup.py --- old/repoze.who-2.4.1/setup.py 2022-02-01 17:56:22.000000000 +0100 +++ new/repoze.who-3.0.0/setup.py 2023-01-25 15:56:36.000000000 +0100 @@ -27,25 +27,22 @@ README = _read_file('README.rst') CHANGES = _read_file('CHANGES.rst') tests_require = ['WebOb', 'zope.interface'] -testing_extras = tests_require + ['nose', 'coverage'] docs_extras = tests_require + ['Sphinx', 'repoze.sphinx.autointerface'] setup(name='repoze.who', - version='2.4.1', + version='3.0.0', description=('repoze.who is an identification and authentication ' 'framework for WSGI.'), long_description='\n\n'.join([README, CHANGES]), classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", - "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 :: 3.7", "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Internet :: WWW/HTTP", @@ -73,7 +70,6 @@ authenticated = repoze.who.restrict:make_authenticated_restriction """, extras_require = { - 'testing': testing_extras, 'docs': docs_extras, }, ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/repoze.who-2.4.1/tox.ini new/repoze.who-3.0.0/tox.ini --- old/repoze.who-2.4.1/tox.ini 2022-01-31 18:41:51.000000000 +0100 +++ new/repoze.who-3.0.0/tox.ini 2023-01-17 01:05:52.000000000 +0100 @@ -1,6 +1,6 @@ [tox] envlist = - py27,pypy,py34,py35,py36,py37,py38,pypy3,cover,docs + py37,py38,py39,py310,py311,pypy3,cover,docs [testenv] commands = @@ -18,10 +18,10 @@ [testenv:cover] skip_install = true basepython = - python3.8 + python3.10 commands = coverage combine - coverage report --fail-under=100 --show-missing --omit="*fixture*" + coverage report --fail-under=100 --show-missing coverage xml deps = coverage @@ -30,7 +30,7 @@ [testenv:docs] basepython = - python3.8 + python3.10 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