Remove support for Python 2.7
issue7497 review53261002
This commit is contained in:
1 parent
d93712f126
commit
deb6bdeea6
8 files changed
+33
-52
No files matched your search
@@ -25,12 +25,6 @@ services:
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- IMAGE: python:2.7
|
||||
TOXENV: py27
|
||||
DATABASE: sqlite
|
||||
- IMAGE: python:2.7
|
||||
TOXENV: py27
|
||||
DATABASE: postgresql
|
||||
- IMAGE: python:3.4
|
||||
TOXENV: py34
|
||||
DATABASE: sqlite
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
* Remove support for Python 2.7
|
||||
* Add remove and reset session methods
|
||||
|
||||
Version 4.8.0 - 2018-04-23
|
||||
|
||||
@@ -4,7 +4,7 @@ Installing trytond_web_user
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
* Python 2.7 or later (http://www.python.org/)
|
||||
* Python 3.4 or later (http://www.python.org/)
|
||||
* trytond (http://www.tryton.org/)
|
||||
|
||||
Installation
|
||||
|
||||
@@ -5,8 +5,7 @@ from trytond.pool import PoolMeta, Pool
|
||||
__all__ = ['PartyReplace', 'PartyErase']
|
||||
|
||||
|
||||
class PartyReplace:
|
||||
__metaclass__ = PoolMeta
|
||||
class PartyReplace(metaclass=PoolMeta):
|
||||
__name__ = 'party.replace'
|
||||
|
||||
@classmethod
|
||||
@@ -16,8 +15,7 @@ class PartyReplace:
|
||||
]
|
||||
|
||||
|
||||
class PartyErase:
|
||||
__metaclass__ = PoolMeta
|
||||
class PartyErase(metaclass=PoolMeta):
|
||||
__name__ = 'party.erase'
|
||||
|
||||
def to_erase(self, party_id):
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
from setuptools import setup
|
||||
import re
|
||||
import os
|
||||
import io
|
||||
try:
|
||||
from configparser import ConfigParser
|
||||
except ImportError:
|
||||
from ConfigParser import ConfigParser
|
||||
import os
|
||||
import re
|
||||
from configparser import ConfigParser
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
def read(fname):
|
||||
@@ -27,6 +24,7 @@ def get_require_version(name):
|
||||
major_version, minor_version + 1)
|
||||
return require
|
||||
|
||||
|
||||
config = ConfigParser()
|
||||
config.readfp(open('tryton.cfg'))
|
||||
info = dict(config.items('tryton'))
|
||||
@@ -54,11 +52,6 @@ for dep in info.get('depends', []):
|
||||
requires.append(get_require_version('trytond'))
|
||||
|
||||
tests_require = []
|
||||
try:
|
||||
from unittest import mock
|
||||
mock.__version__
|
||||
except ImportError:
|
||||
tests_require.append('mock')
|
||||
dependency_links = []
|
||||
if minor_version % 2:
|
||||
dependency_links.append('https://trydevpi.tryton.org/')
|
||||
@@ -106,7 +99,6 @@ setup(name=name,
|
||||
'Natural Language :: Slovenian',
|
||||
'Natural Language :: Spanish',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
@@ -115,6 +107,7 @@ setup(name=name,
|
||||
'Topic :: Office/Business',
|
||||
],
|
||||
license='GPL-3',
|
||||
python_requires='>=3.4',
|
||||
install_requires=requires,
|
||||
extras_require={
|
||||
'BCrypt': ['bcrypt'],
|
||||
@@ -129,5 +122,4 @@ setup(name=name,
|
||||
test_suite='tests',
|
||||
test_loader='trytond.test_loader:Loader',
|
||||
tests_require=tests_require,
|
||||
use_2to3=True,
|
||||
)
|
||||
@@ -3,10 +3,7 @@
|
||||
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from unittest.mock import patch, ANY
|
||||
except ImportError:
|
||||
from mock import patch, ANY
|
||||
from unittest.mock import patch, ANY
|
||||
|
||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
from trytond.tests.test_tryton import suite as test_suite
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
[tox]
|
||||
envlist = {py27,py34,py35,py36}-{sqlite,postgresql},pypy-{sqlite,postgresql}
|
||||
envlist = {py34,py35,py36}-{sqlite,postgresql},pypy3-{sqlite,postgresql}
|
||||
|
||||
[testenv]
|
||||
commands = {envpython} setup.py test
|
||||
deps =
|
||||
{py27,py34,py35,py36}-postgresql: psycopg2 >= 2.5
|
||||
pypy-postgresql: psycopg2cffi >= 2.5
|
||||
{py34,py35,py36}-postgresql: psycopg2 >= 2.5
|
||||
pypy3-postgresql: psycopg2cffi >= 2.5
|
||||
sqlite: sqlitebck
|
||||
setenv =
|
||||
sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
|
||||
|
||||
@@ -5,8 +5,7 @@ import hashlib
|
||||
import random
|
||||
import string
|
||||
import time
|
||||
import urllib
|
||||
import urlparse
|
||||
import urllib.parse
|
||||
from email.header import Header
|
||||
|
||||
try:
|
||||
@@ -51,17 +50,17 @@ def _send_email(from_, users, email_func):
|
||||
|
||||
|
||||
def _add_params(url, **params):
|
||||
parts = urlparse.urlsplit(url)
|
||||
query = urlparse.parse_qsl(parts.query)
|
||||
parts = urllib.parse.urlsplit(url)
|
||||
query = urllib.parse.parse_qsl(parts.query)
|
||||
for key, value in sorted(params.items()):
|
||||
query.append((key, value))
|
||||
parts = list(parts)
|
||||
parts[3] = urllib.urlencode(query)
|
||||
return urlparse.urlunsplit(parts)
|
||||
parts[3] = urllib.parse.urlencode(query)
|
||||
return urllib.parse.urlunsplit(parts)
|
||||
|
||||
|
||||
def _extract_params(url):
|
||||
return urlparse.parse_qsl(urlparse.urlsplit(url).query)
|
||||
return urllib.parse.parse_qsl(urllib.parse.urlsplit(url).query)
|
||||
|
||||
|
||||
class User(DeactivableMixin, ModelSQL, ModelView):
|
||||
@@ -213,35 +212,35 @@ class User(DeactivableMixin, ModelSQL, ModelView):
|
||||
def hash_sha1(cls, password):
|
||||
salt = ''.join(random.sample(string.ascii_letters + string.digits, 8))
|
||||
salted_password = password + salt
|
||||
if isinstance(salted_password, unicode):
|
||||
if isinstance(salted_password, str):
|
||||
salted_password = salted_password.encode('utf-8')
|
||||
hash_ = hashlib.sha1(salted_password).hexdigest()
|
||||
return '$'.join(['sha1', hash_, salt])
|
||||
|
||||
@classmethod
|
||||
def check_sha1(cls, password, hash_):
|
||||
if isinstance(password, unicode):
|
||||
if isinstance(password, str):
|
||||
password = password.encode('utf-8')
|
||||
hash_method, hash_, salt = hash_.split('$', 2)
|
||||
salt = salt or ''
|
||||
if isinstance(salt, unicode):
|
||||
if isinstance(salt, str):
|
||||
salt = salt.encode('utf-8')
|
||||
assert hash_method == 'sha1'
|
||||
return hash_ == hashlib.sha1(password + salt).hexdigest()
|
||||
|
||||
@classmethod
|
||||
def hash_bcrypt(cls, password):
|
||||
if isinstance(password, unicode):
|
||||
if isinstance(password, str):
|
||||
password = password.encode('utf-8')
|
||||
hash_ = bcrypt.hashpw(password, bcrypt.gensalt()).decode('utf-8')
|
||||
return '$'.join(['bcrypt', hash_])
|
||||
|
||||
@classmethod
|
||||
def check_bcrypt(cls, password, hash_):
|
||||
if isinstance(password, unicode):
|
||||
if isinstance(password, str):
|
||||
password = password.encode('utf-8')
|
||||
hash_method, hash_ = hash_.split('$', 1)
|
||||
if isinstance(hash_, unicode):
|
||||
if isinstance(hash_, str):
|
||||
hash_ = hash_.encode('utf-8')
|
||||
assert hash_method == 'bcrypt'
|
||||
return hash_ == bcrypt.hashpw(password, hash_)
|
||||
@@ -279,10 +278,10 @@ class User(DeactivableMixin, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def validate_email_url(cls, url):
|
||||
parts = urlparse.urlsplit(url)
|
||||
parts = urllib.parse.urlsplit(url)
|
||||
tokens = filter(
|
||||
None, urlparse.parse_qs(parts.query).get('token', [None]))
|
||||
return cls.validate_email_token(tokens)
|
||||
None, urllib.parse.parse_qs(parts.query).get('token', [None]))
|
||||
return cls.validate_email_token(list(tokens))
|
||||
|
||||
@classmethod
|
||||
def validate_email_token(cls, tokens):
|
||||
@@ -304,7 +303,7 @@ class User(DeactivableMixin, ModelSQL, ModelView):
|
||||
def reset(user):
|
||||
return not (user.reset_password_token_expire
|
||||
and user.reset_password_token_expire > now)
|
||||
users = filter(reset, users)
|
||||
users = list(filter(reset, users))
|
||||
|
||||
for user in users:
|
||||
user.set_reset_password_token()
|
||||
@@ -334,8 +333,8 @@ class User(DeactivableMixin, ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def set_password_url(cls, url, password):
|
||||
parts = urlparse.urlsplit(url)
|
||||
query = urlparse.parse_qs(parts.query)
|
||||
parts = urllib.parse.urlsplit(url)
|
||||
query = urllib.parse.parse_qs(parts.query)
|
||||
email = query.get('email', [None])[0]
|
||||
token = query.get('token', [None])[0]
|
||||
return cls.set_password_token(email, token, password)
|
||||
|
||||
Reference in new issue
Block a user