Drop python2 support
This mostly consists in removing the dependency on "six" and updating
the code to use only Python3 idioms.
Notice that we previously used TemporaryDirectory from
cubicweb.devtools.testlib for compatibility with Python2. We now
directly import it from tempfile.
--- a/cubicweb.spec Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb.spec Fri Apr 05 17:58:19 2019 +0200
@@ -21,7 +21,6 @@
BuildArch: noarch
Requires: %{python}
-Requires: %{python}-six >= 1.4.0
Requires: %{python}-logilab-common >= 1.4.0
Requires: %{python}-logilab-mtconverter >= 0.8.0
Requires: %{python}-rql >= 0.34.0
@@ -29,7 +28,6 @@
Requires: %{python}-logilab-database >= 1.15.0
Requires: %{python}-passlib
Requires: %{python}-lxml
-Requires: %{python}-unittest2 >= 0.7.0
Requires: %{python}-markdown
Requires: pytz
# the schema view uses `dot'; at least on el5, png output requires graphviz-gd
--- a/cubicweb/__init__.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/__init__.py Fri Apr 05 17:58:19 2019 +0200
@@ -27,8 +27,6 @@
import warnings
import zlib
-from six import PY2, binary_type, text_type
-
from logilab.common.logging_ext import set_log_methods
from yams.constraints import BASE_CONVERTERS, BASE_CHECKERS
from yams.schema import role_name as rname
@@ -40,11 +38,7 @@
from yams import ValidationError
from cubicweb._exceptions import * # noqa
-if PY2:
- # http://bugs.python.org/issue10211
- from StringIO import StringIO as BytesIO
-else:
- from io import BytesIO
+from io import BytesIO
# ignore the pygments UserWarnings
warnings.filterwarnings('ignore', category=UserWarning,
@@ -63,12 +57,12 @@
# '_' is available to mark internationalized string but should not be used to
# do the actual translation
-_ = text_type
+_ = str
class Binary(BytesIO):
"""class to hold binary data. Use BytesIO to prevent use of unicode data"""
- _allowed_types = (binary_type, bytearray, buffer if PY2 else memoryview) # noqa: F405
+ _allowed_types = (bytes, bytearray, memoryview)
def __init__(self, buf=b''):
assert isinstance(buf, self._allowed_types), \
@@ -144,7 +138,7 @@
def check_password(eschema, value):
- return isinstance(value, (binary_type, Binary))
+ return isinstance(value, (bytes, Binary))
BASE_CHECKERS['Password'] = check_password
@@ -153,7 +147,7 @@
def str_or_binary(value):
if isinstance(value, Binary):
return value
- return binary_type(value)
+ return bytes(value)
BASE_CONVERTERS['Password'] = str_or_binary
--- a/cubicweb/__pkginfo__.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/__pkginfo__.py Fri Apr 05 17:58:19 2019 +0200
@@ -34,7 +34,7 @@
classifiers = [
'Environment :: Web Environment',
'Framework :: CubicWeb',
- 'Programming Language :: Python',
+ 'Programming Language :: Python :: 3',
'Programming Language :: JavaScript',
]
--- a/cubicweb/_exceptions.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/_exceptions.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,8 +21,6 @@
from warnings import warn
-from six import PY2, text_type
-
from logilab.common.decorators import cachedproperty
from yams import ValidationError
@@ -32,21 +30,15 @@
class CubicWebException(Exception):
"""base class for cubicweb server exception"""
msg = ""
- def __unicode__(self):
+
+ def __str__(self):
if self.msg:
if self.args:
return self.msg % tuple(self.args)
else:
return self.msg
else:
- return u' '.join(text_type(arg) for arg in self.args)
-
- def __str__(self):
- res = self.__unicode__()
- if PY2:
- res = res.encode('utf-8')
- return res
-
+ return u' '.join(str(arg) for arg in self.args)
class ConfigurationError(CubicWebException):
"""a misconfiguration error"""
@@ -98,7 +90,7 @@
def rtypes(self):
if 'rtypes' in self.kwargs:
return self.kwargs['rtypes']
- cstrname = text_type(self.kwargs['cstrname'])
+ cstrname = str(self.kwargs['cstrname'])
cstr = self.session.find('CWUniqueTogetherConstraint', name=cstrname).one()
return sorted(rtype.name for rtype in cstr.relations)
@@ -119,7 +111,7 @@
msg1 = u'You are not allowed to perform %s operation on %s'
var = None
- def __unicode__(self):
+ def __str__(self):
try:
if self.args and len(self.args) == 2:
return self.msg1 % self.args
@@ -127,7 +119,7 @@
return u' '.join(self.args)
return self.msg
except Exception as ex:
- return text_type(ex)
+ return str(ex)
class Forbidden(SecurityError):
"""raised when a user tries to perform a forbidden action
--- a/cubicweb/_gcdebug.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/_gcdebug.py Fri Apr 05 17:58:19 2019 +0200
@@ -15,12 +15,8 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-from __future__ import print_function
-
import gc, types, weakref
-from six import PY2
-
from cubicweb.schema import CubicWebRelationSchema, CubicWebEntitySchema
try:
from cubicweb.web.request import _NeedAuthAccessMock
@@ -37,9 +33,6 @@
types.ModuleType, types.FunctionType, types.MethodType,
types.MemberDescriptorType, types.GetSetDescriptorType,
)
-if PY2:
- # weakref.WeakKeyDictionary fails isinstance check on Python 3.5.
- IGNORE_CLASSES += (weakref.WeakKeyDictionary, )
if _NeedAuthAccessMock is not None:
IGNORE_CLASSES = IGNORE_CLASSES + (_NeedAuthAccessMock,)
--- a/cubicweb/crypto.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/crypto.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,8 +19,7 @@
from base64 import b64encode, b64decode
-
-from six.moves import cPickle as pickle
+import pickle
from Crypto.Cipher import Blowfish
@@ -38,7 +37,7 @@
string = pickle.dumps(data)
string = string + '*' * (8 - len(string) % 8)
string = b64encode(_cypherer(seed).encrypt(string))
- return unicode(string)
+ return str(string)
def decrypt(string, seed):
--- a/cubicweb/cwconfig.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/cwconfig.py Fri Apr 05 17:58:19 2019 +0200
@@ -166,8 +166,6 @@
Directory where pid files will be written
"""
-from __future__ import print_function
-
import importlib
import logging
import logging.config
@@ -182,8 +180,6 @@
from threading import Lock
from warnings import filterwarnings
-from six import text_type
-
from logilab.common.decorators import cached
from logilab.common.logging_ext import set_log_methods, init_log
from logilab.common.configuration import (Configuration, Method,
@@ -641,7 +637,7 @@
self.adjust_sys_path()
self.load_defaults()
# will be properly initialized later by _gettext_init
- self.translations = {'en': (text_type, lambda ctx, msgid: text_type(msgid) )}
+ self.translations = {'en': (str, lambda ctx, msgid: str(msgid) )}
self._site_loaded = set()
# don't register ReStructured Text directives by simple import, avoid pb
# with eg sphinx.
@@ -990,7 +986,7 @@
# set to true while creating an instance
self.creating = creating
super(CubicWebConfiguration, self).__init__(debugmode)
- fake_gettext = (text_type, lambda ctx, msgid: text_type(msgid))
+ fake_gettext = (str, lambda ctx, msgid: str(msgid))
for lang in self.available_languages():
self.translations[lang] = fake_gettext
self._cubes = None
--- a/cubicweb/cwctl.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/cwctl.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,8 +18,6 @@
"""the cubicweb-ctl tool, based on logilab.common.clcommands to
provide a pluggable commands system.
"""
-from __future__ import print_function
-
# *ctl module should limit the number of import to be imported as quickly as
# possible (for cubicweb-ctl reactivity, necessary for instance for usable bash
# completion). So import locally in command helpers.
--- a/cubicweb/cwgettext.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/cwgettext.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,8 +18,6 @@
import gettext
-from six import PY3
-
class cwGNUTranslations(gettext.GNUTranslations):
# The encoding of a msgctxt and a msgid in a .mo file is
@@ -85,8 +83,7 @@
else:
return msgid2
- if PY3:
- ugettext = gettext.GNUTranslations.gettext
+ ugettext = gettext.GNUTranslations.gettext
def upgettext(self, context, message):
ctxt_message_id = self.CONTEXT_ENCODING % (context, message)
@@ -97,7 +94,7 @@
return self.ugettext(message)
if self._fallback:
return self._fallback.upgettext(context, message)
- return unicode(message)
+ return str(message)
return tmsg
def unpgettext(self, context, msgid1, msgid2, n):
@@ -108,9 +105,9 @@
if self._fallback:
return self._fallback.unpgettext(context, msgid1, msgid2, n)
if n == 1:
- tmsg = unicode(msgid1)
+ tmsg = str(msgid1)
else:
- tmsg = unicode(msgid2)
+ tmsg = str(msgid2)
return tmsg
--- a/cubicweb/cwvreg.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/cwvreg.py Fri Apr 05 17:58:19 2019 +0200
@@ -24,8 +24,6 @@
from datetime import datetime, date, time, timedelta
from functools import reduce
-from six import text_type, binary_type
-
from logilab.common.decorators import cached, clear_cache
from logilab.common.deprecation import class_deprecated
from logilab.common.modutils import clean_sys_modules
@@ -218,9 +216,9 @@
"""
obj = self.select(oid, req, rset=rset, **kwargs)
res = obj.render(**kwargs)
- if isinstance(res, text_type):
+ if isinstance(res, str):
return res.encode(req.encoding)
- assert isinstance(res, binary_type)
+ assert isinstance(res, bytes)
return res
def possible_views(self, req, rset=None, **kwargs):
--- a/cubicweb/dataimport/csv.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/dataimport/csv.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,18 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Functions to help importing CSV data"""
-from __future__ import absolute_import, print_function
-
import codecs
import csv as csvmod
-from six import PY2, PY3, string_types
-
from logilab.common import shellutils
def count_lines(stream_or_filename):
- if isinstance(stream_or_filename, string_types):
+ if isinstance(stream_or_filename, str):
f = open(stream_or_filename)
else:
f = stream_or_filename
@@ -42,7 +38,7 @@
def ucsvreader_pb(stream_or_path, encoding='utf-8', delimiter=',', quotechar='"',
skipfirst=False, withpb=True, skip_empty=True):
"""same as :func:`ucsvreader` but a progress bar is displayed as we iter on rows"""
- if isinstance(stream_or_path, string_types):
+ if isinstance(stream_or_path, str):
stream = open(stream_or_path, 'rb')
else:
stream = stream_or_path
@@ -68,19 +64,14 @@
separators) will be skipped. This is useful for Excel exports which may be
full of such lines.
"""
- if PY3:
- stream = codecs.getreader(encoding)(stream)
+ stream = codecs.getreader(encoding)(stream)
it = iter(csvmod.reader(stream, delimiter=delimiter, quotechar=quotechar))
if not ignore_errors:
if skipfirst:
next(it)
for row in it:
- if PY2:
- decoded = [item.decode(encoding) for item in row]
- else:
- decoded = row
- if not skip_empty or any(decoded):
- yield decoded
+ if not skip_empty or any(row):
+ yield row
else:
if skipfirst:
try:
@@ -97,9 +88,5 @@
# Error in CSV, ignore line and continue
except csvmod.Error:
continue
- if PY2:
- decoded = [item.decode(encoding) for item in row]
- else:
- decoded = row
- if not skip_empty or any(decoded):
- yield decoded
+ if not skip_empty or any(row):
+ yield row
--- a/cubicweb/dataimport/massive_store.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/dataimport/massive_store.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,9 +22,6 @@
import logging
from uuid import uuid4
-from six import text_type
-from six.moves import range
-
from cubicweb.dataimport import stores, pgstore
from cubicweb.server.schema2sql import eschema_sql_def
@@ -70,7 +67,7 @@
"""
super(MassiveObjectStore, self).__init__(cnx)
- self.uuid = text_type(uuid4()).replace('-', '')
+ self.uuid = str(uuid4()).replace('-', '')
self.slave_mode = slave_mode
if metagen is None:
metagen = stores.MetadataGenerator(cnx)
--- a/cubicweb/dataimport/pgstore.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/dataimport/pgstore.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,17 +17,13 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Postgres specific store"""
-from __future__ import print_function
-
import warnings
import os.path as osp
from io import StringIO
from time import asctime
from datetime import date, datetime, time
from collections import defaultdict
-
-from six import string_types, integer_types, text_type, add_metaclass
-from six.moves import cPickle as pickle, range
+import pickle
from cubicweb.utils import make_uid
from cubicweb.server.sqlutils import SQL_PREFIX
@@ -108,7 +104,7 @@
def _copyfrom_buffer_convert_number(value, **opts):
'''Convert a number into its string representation'''
- return text_type(value)
+ return str(value)
def _copyfrom_buffer_convert_string(value, **opts):
'''Convert string value.
@@ -140,8 +136,8 @@
# (types, converter) list.
_COPYFROM_BUFFER_CONVERTERS = [
(type(None), _copyfrom_buffer_convert_None),
- (integer_types + (float,), _copyfrom_buffer_convert_number),
- (string_types, _copyfrom_buffer_convert_string),
+ ((int, float), _copyfrom_buffer_convert_number),
+ (str, _copyfrom_buffer_convert_string),
(datetime, _copyfrom_buffer_convert_datetime),
(date, _copyfrom_buffer_convert_date),
(time, _copyfrom_buffer_convert_time),
@@ -185,7 +181,7 @@
for types, converter in _COPYFROM_BUFFER_CONVERTERS:
if isinstance(value, types):
value = converter(value, **convert_opts)
- assert isinstance(value, text_type)
+ assert isinstance(value, str)
break
else:
raise ValueError("Unsupported value type %s" % type(value))
--- a/cubicweb/dataimport/stores.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/dataimport/stores.py Fri Apr 05 17:58:19 2019 +0200
@@ -62,8 +62,6 @@
from copy import copy
from itertools import count
-from six import add_metaclass
-
import pytz
from logilab.common.decorators import cached
@@ -362,8 +360,7 @@
return self._mdgen.source
-@add_metaclass(class_deprecated)
-class MetaGenerator(object):
+class MetaGenerator(object, metaclass=class_deprecated):
"""Class responsible for generating standard metadata for imported entities. You may want to
derive it to add application specific's metadata.
--- a/cubicweb/dataimport/test/test_pgstore.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/dataimport/test/test_pgstore.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,16 +20,11 @@
import datetime as DT
-from six import PY3
from logilab.common.testlib import TestCase, unittest_main
from cubicweb.dataimport import pgstore
-if PY3:
- long = int
-
-
class CreateCopyFromBufferTC(TestCase):
# test converters
@@ -41,7 +36,7 @@
def test_convert_number(self):
cnvt = pgstore._copyfrom_buffer_convert_number
self.assertEqual(u'42', cnvt(42))
- self.assertEqual(u'42', cnvt(long(42)))
+ self.assertEqual(u'42', cnvt(int(42)))
self.assertEqual(u'42.42', cnvt(42.42))
def test_convert_string(self):
@@ -68,9 +63,9 @@
# test buffer
def test_create_copyfrom_buffer_tuple(self):
- data = ((42, long(42), 42.42, u'éléphant', DT.date(666, 1, 13), DT.time(6, 6, 6),
+ data = ((42, int(42), 42.42, u'éléphant', DT.date(666, 1, 13), DT.time(6, 6, 6),
DT.datetime(666, 6, 13, 6, 6, 6)),
- (6, long(6), 6.6, u'babar', DT.date(2014, 1, 14), DT.time(4, 2, 1),
+ (6, int(6), 6.6, u'babar', DT.date(2014, 1, 14), DT.time(4, 2, 1),
DT.datetime(2014, 1, 1, 0, 0, 0)))
results = pgstore._create_copyfrom_buffer(data)
# all columns
--- a/cubicweb/devtools/__init__.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/__init__.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Test tools for cubicweb"""
-from __future__ import print_function
-
import os
import sys
import errno
@@ -31,10 +29,9 @@
from hashlib import sha1 # pylint: disable=E0611
from os.path import abspath, join, exists, split, isdir, dirname
from functools import partial
+import pickle
import filelock
-from six import text_type
-from six.moves import cPickle as pickle
from logilab.common.decorators import cached, clear_cache
@@ -93,7 +90,7 @@
DEFAULT_PSQL_SOURCES = DEFAULT_SOURCES.copy()
DEFAULT_PSQL_SOURCES['system'] = DEFAULT_SOURCES['system'].copy()
DEFAULT_PSQL_SOURCES['system']['db-driver'] = 'postgres'
-DEFAULT_PSQL_SOURCES['system']['db-user'] = text_type(getpass.getuser())
+DEFAULT_PSQL_SOURCES['system']['db-user'] = getpass.getuser()
DEFAULT_PSQL_SOURCES['system']['db-password'] = None
# insert a dumb value as db-host to avoid unexpected connection to local server
DEFAULT_PSQL_SOURCES['system']['db-host'] = 'REPLACEME'
@@ -395,7 +392,7 @@
from cubicweb.repoapi import connect
repo = self.get_repo()
sources = self.config.read_sources_file()
- login = text_type(sources['admin']['login'])
+ login = sources['admin']['login']
password = sources['admin']['password'] or 'xxx'
cnx = connect(repo, login, password=password)
return cnx
--- a/cubicweb/devtools/devctl.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/devctl.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,8 +18,6 @@
"""additional cubicweb-ctl commands and command handlers for cubicweb and
cubicweb's cubes development
"""
-from __future__ import print_function
-
# *ctl module should limit the number of import to be imported as quickly as
# possible (for cubicweb-ctl reactivity, necessary for instance for usable bash
# completion). So import locally in command helpers.
@@ -33,8 +31,6 @@
from pytz import UTC
-from six.moves import input
-
from logilab.common import STD_BLACKLIST
from logilab.common.modutils import clean_sys_modules
from logilab.common.fileutils import ensure_fs_mode
@@ -717,7 +713,6 @@
longdesc = input(
'Enter a long description (leave empty to reuse the short one): ')
dependencies = {
- 'six': '>= 1.4.0',
'cubicweb': '>= %s' % cubicwebversion,
}
if verbose:
--- a/cubicweb/devtools/fake.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/fake.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from contextlib import contextmanager
-from six import string_types
-
from logilab.database import get_db_helper
from cubicweb.req import RequestSessionBase
@@ -98,7 +96,7 @@
def set_request_header(self, header, value, raw=False):
"""set an incoming HTTP header (for test purpose only)"""
- if isinstance(value, string_types):
+ if isinstance(value, str):
value = [value]
if raw:
# adding encoded header is important, else page content
--- a/cubicweb/devtools/fill.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/fill.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,9 +17,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""This modules defines func / methods for creating test repositories"""
-from __future__ import print_function
-
-
import logging
from random import randint, choice
@@ -28,9 +25,6 @@
from decimal import Decimal
import inspect
-from six import text_type, add_metaclass
-from six.moves import range
-
from logilab.common import attrdict
from logilab.mtconverter import xml_escape
from yams.constraints import (SizeConstraint, StaticVocabularyConstraint,
@@ -234,7 +228,7 @@
"""
for cst in self.eschema.rdef(attrname).constraints:
if isinstance(cst, StaticVocabularyConstraint):
- return text_type(choice(cst.vocabulary()))
+ return choice(cst.vocabulary())
return None
# XXX nothing to do here
@@ -270,8 +264,7 @@
return type.__new__(mcs, name, bases, classdict)
-@add_metaclass(autoextend)
-class ValueGenerator(_ValueGenerator):
+class ValueGenerator(_ValueGenerator, metaclass=autoextend):
pass
@@ -359,7 +352,7 @@
fmt = vreg.property_value('ui.float-format')
value = fmt % value
else:
- value = text_type(value)
+ value = value
return entity
--- a/cubicweb/devtools/httptest.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/httptest.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,15 +18,12 @@
"""this module contains base classes and utilities for integration with running
http server
"""
-from __future__ import print_function
+import http.client
import random
import threading
import socket
-
-from six.moves import range, http_client
-from six.moves.urllib.parse import urlparse
-
+from urllib.parse import urlparse
from cubicweb.devtools.testlib import CubicWebTC
@@ -83,7 +80,7 @@
passwd = user
response = self.web_get("login?__login=%s&__password=%s" %
(user, passwd))
- assert response.status == http_client.SEE_OTHER, response.status
+ assert response.status == http.client.SEE_OTHER, response.status
self._ident_cookie = response.getheader('Set-Cookie')
assert self._ident_cookie
return True
@@ -95,7 +92,7 @@
self._ident_cookie = None
def web_request(self, path='', method='GET', body=None, headers=None):
- """Return an http_client.HTTPResponse object for the specified path
+ """Return an http.client.HTTPResponse object for the specified path
Use available credential if available.
"""
@@ -131,7 +128,7 @@
def start_server(self):
from cubicweb.wsgi.handler import CubicWebWSGIApplication
from wsgiref import simple_server
- from six.moves import queue
+ import queue
config = self.config
port = config['port'] or 8080
@@ -164,7 +161,7 @@
self.fail(start_flag.get())
parseurl = urlparse(self.config['base-url'])
assert parseurl.port == self.config['port'], (self.config['base-url'], self.config['port'])
- self._web_test_cnx = http_client.HTTPConnection(parseurl.hostname,
+ self._web_test_cnx = http.client.HTTPConnection(parseurl.hostname,
parseurl.port)
self._ident_cookie = None
--- a/cubicweb/devtools/instrument.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/instrument.py Fri Apr 05 17:58:19 2019 +0200
@@ -14,8 +14,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Instrumentation utilities"""
-from __future__ import print_function
-
import os
try:
--- a/cubicweb/devtools/qunit.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/qunit.py Fri Apr 05 17:58:19 2019 +0200
@@ -15,16 +15,13 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-from __future__ import absolute_import, print_function
-
import os, os.path as osp
import errno
import shutil
-from tempfile import mkdtemp
+from queue import Queue, Empty
+from tempfile import mkdtemp, TemporaryDirectory
from subprocess import Popen, PIPE, STDOUT
-from six.moves.queue import Queue, Empty
-
# imported by default to simplify further import statements
from logilab.common.testlib import Tags
import webtest.http
@@ -34,7 +31,6 @@
from cubicweb.web.controller import Controller
from cubicweb.web.views.staticcontrollers import StaticFileController, STATIC_CONTROLLERS
from cubicweb.devtools import webtest as cwwebtest
-from cubicweb.devtools.testlib import TemporaryDirectory
class FirefoxHelper(object):
--- a/cubicweb/devtools/repotest.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/repotest.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,8 +19,6 @@
This module contains functions to initialize a new repository.
"""
-from __future__ import print_function
-
from contextlib import contextmanager
from pprint import pprint
--- a/cubicweb/devtools/stresstester.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/stresstester.py Fri Apr 05 17:58:19 2019 +0200
@@ -41,8 +41,6 @@
Copyright (c) 2003-2011 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
http://www.logilab.fr/ -- mailto:contact@logilab.fr
"""
-from __future__ import print_function
-
import os
import sys
import threading
--- a/cubicweb/devtools/test/unittest_dbfill.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/test/unittest_dbfill.py Fri Apr 05 17:58:19 2019 +0200
@@ -23,8 +23,6 @@
import datetime
import io
-from six.moves import range
-
from logilab.common.testlib import TestCase, unittest_main
from cubicweb.devtools.fill import ValueGenerator, make_tel
--- a/cubicweb/devtools/test/unittest_devctl.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/test/unittest_devctl.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,10 +21,9 @@
import os.path as osp
import sys
from subprocess import Popen, PIPE, STDOUT
+from tempfile import TemporaryDirectory
from unittest import TestCase
-from cubicweb.devtools.testlib import TemporaryDirectory
-
def newcube(directory, name):
cmd = ['cubicweb-ctl', 'newcube', '--directory', directory, name]
--- a/cubicweb/devtools/test/unittest_httptest.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/test/unittest_httptest.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,7 +17,7 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""unittest for cubicweb.devtools.httptest module"""
-from six.moves import http_client
+import http.client
from logilab.common.testlib import Tags
from cubicweb.devtools.httptest import CubicWebServerTC
@@ -28,12 +28,12 @@
def test_response(self):
try:
response = self.web_get()
- except http_client.NotConnected as ex:
+ except http.client.NotConnected as ex:
self.fail("Can't connection to test server: %s" % ex)
def test_response_anon(self):
response = self.web_get()
- self.assertEqual(response.status, http_client.OK)
+ self.assertEqual(response.status, http.client.OK)
def test_base_url(self):
if self.config['base-url'] not in self.web_get().read().decode('ascii'):
@@ -47,20 +47,20 @@
def test_response_denied(self):
response = self.web_get()
- self.assertEqual(response.status, http_client.FORBIDDEN)
+ self.assertEqual(response.status, http.client.FORBIDDEN)
def test_login(self):
response = self.web_get()
- if response.status != http_client.FORBIDDEN:
+ if response.status != http.client.FORBIDDEN:
self.skipTest('Already authenticated, "test_response_denied" must have failed')
# login
self.web_login(self.admlogin, self.admpassword)
response = self.web_get()
- self.assertEqual(response.status, http_client.OK, response.body)
+ self.assertEqual(response.status, http.client.OK, response.body)
# logout
self.web_logout()
response = self.web_get()
- self.assertEqual(response.status, http_client.FORBIDDEN, response.body)
+ self.assertEqual(response.status, http.client.FORBIDDEN, response.body)
if __name__ == '__main__':
--- a/cubicweb/devtools/test/unittest_i18n.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/test/unittest_i18n.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,14 +19,13 @@
"""unit tests for i18n messages generator"""
from contextlib import contextmanager
-from io import StringIO, BytesIO
+from io import StringIO
import os
import os.path as osp
import sys
from subprocess import PIPE, Popen, STDOUT
from unittest import TestCase, main
-from six import PY2
from mock import patch
from cubicweb.devtools import devctl
@@ -91,7 +90,7 @@
@contextmanager
def capture_stdout():
- stream = BytesIO() if PY2 else StringIO()
+ stream = StringIO()
sys.stdout = stream
yield stream
stream.seek(0)
--- a/cubicweb/devtools/test/unittest_testlib.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/test/unittest_testlib.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from io import BytesIO, StringIO
from unittest import TextTestRunner
-from six import PY2
-
from logilab.common.testlib import TestSuite, TestCase, unittest_main
from logilab.common.registry import yes
@@ -52,7 +50,7 @@
class WebTestTC(TestCase):
def setUp(self):
- output = BytesIO() if PY2 else StringIO()
+ output = StringIO()
self.runner = TextTestRunner(stream=output)
def test_error_raised(self):
--- a/cubicweb/devtools/test/unittest_webtest.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/test/unittest_webtest.py Fri Apr 05 17:58:19 2019 +0200
@@ -1,4 +1,4 @@
-from six.moves import http_client
+import http.client
from logilab.common.testlib import Tags
from cubicweb.devtools.webtest import CubicWebTestTC
@@ -21,19 +21,19 @@
def test_reponse_denied(self):
res = self.webapp.get('/', expect_errors=True)
- self.assertEqual(http_client.FORBIDDEN, res.status_int)
+ self.assertEqual(http.client.FORBIDDEN, res.status_int)
def test_login(self):
res = self.webapp.get('/', expect_errors=True)
- self.assertEqual(http_client.FORBIDDEN, res.status_int)
+ self.assertEqual(http.client.FORBIDDEN, res.status_int)
self.login(self.admlogin, self.admpassword)
res = self.webapp.get('/')
- self.assertEqual(http_client.OK, res.status_int)
+ self.assertEqual(http.client.OK, res.status_int)
self.logout()
res = self.webapp.get('/', expect_errors=True)
- self.assertEqual(http_client.FORBIDDEN, res.status_int)
+ self.assertEqual(http.client.FORBIDDEN, res.status_int)
if __name__ == '__main__':
--- a/cubicweb/devtools/testlib.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/devtools/testlib.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,20 +17,15 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Base classes and utilities for cubicweb tests"""
-from __future__ import print_function
-
import sys
import re
-import warnings
from os.path import dirname, join, abspath
from math import log
from contextlib import contextmanager
from inspect import isgeneratorfunction
from itertools import chain
-
-from six import binary_type, text_type, string_types, reraise
-from six.moves import range
-from six.moves.urllib.parse import urlparse, parse_qs, unquote as urlunquote
+from unittest import TestCase
+from urllib.parse import urlparse, parse_qs, unquote as urlunquote
import yams.schema
@@ -53,22 +48,6 @@
from cubicweb.devtools.fill import insert_entity_queries, make_relations_queries
from cubicweb.web.views.authentication import Session
-if sys.version_info[:2] < (3, 4):
- from unittest2 import TestCase
- if not hasattr(TestCase, 'subTest'):
- raise ImportError('no subTest support in available unittest2')
- try:
- from backports.tempfile import TemporaryDirectory # noqa
- except ImportError:
- # backports.tempfile not available
- TemporaryDirectory = None
-else:
- from unittest import TestCase
- from tempfile import TemporaryDirectory # noqa
-
-# in python 2.7, DeprecationWarning are not shown anymore by default
-warnings.filterwarnings('default', category=DeprecationWarning)
-
# provide a data directory for the test class ##################################
@@ -326,7 +305,6 @@
"""provide a new RepoAccess object for a given user
The access is automatically closed at the end of the test."""
- login = text_type(login)
access = RepoAccess(self.repo, login, self.requestcls)
self._open_access.add(access)
return access
@@ -347,7 +325,7 @@
db_handler.restore_database(self.test_db_id)
self.repo = db_handler.get_repo(startup=True)
# get an admin session (without actual login)
- login = text_type(db_handler.config.default_admin_config['login'])
+ login = db_handler.config.default_admin_config['login']
self.admin_access = self.new_access(login)
# config management ########################################################
@@ -365,7 +343,7 @@
been properly bootstrapped.
"""
admincfg = config.default_admin_config
- cls.admlogin = text_type(admincfg['login'])
+ cls.admlogin = admincfg['login']
cls.admpassword = admincfg['password']
# uncomment the line below if you want rql queries to be logged
# config.global_set_option('query-log-file',
@@ -458,15 +436,13 @@
"""create and return a new user entity"""
if password is None:
password = login
- if login is not None:
- login = text_type(login)
user = req.create_entity('CWUser', login=login,
upassword=password, **kwargs)
req.execute('SET X in_group G WHERE X eid %%(x)s, G name IN(%s)'
% ','.join(repr(str(g)) for g in groups),
{'x': user.eid})
if email is not None:
- req.create_entity('EmailAddress', address=text_type(email),
+ req.create_entity('EmailAddress', address=email,
reverse_primary_email=user)
user.cw_clear_relation_cache('in_group', 'subject')
if commit:
@@ -524,7 +500,7 @@
"""
torestore = []
for erschema, etypeperms in chain(perm_overrides, perm_kwoverrides.items()):
- if isinstance(erschema, string_types):
+ if isinstance(erschema, str):
erschema = self.schema[erschema]
for action, actionperms in etypeperms.items():
origperms = erschema.permissions[action]
@@ -730,7 +706,7 @@
req.form will be setup using the url's query string
"""
with self.admin_access.web_request(url=url) as req:
- if isinstance(url, text_type):
+ if isinstance(url, str):
url = url.encode(req.encoding) # req.setup_params() expects encoded strings
querystring = urlparse(url)[-2]
params = parse_qs(querystring)
@@ -911,7 +887,7 @@
msg = '[%s in %s] %s' % (klass, view.__regid__, exc)
except Exception:
msg = '[%s in %s] undisplayable exception' % (klass, view.__regid__)
- reraise(AssertionError, AssertionError(msg), sys.exc_info()[-1])
+ raise AssertionError(msg).with_traceback(sys.exc_info()[-1])
return self._check_html(output, view, template)
def get_validator(self, view=None, content_type=None, output=None):
@@ -944,7 +920,7 @@
def _check_html(self, output, view, template='main-template'):
"""raises an exception if the HTML is invalid"""
output = output.strip()
- if isinstance(output, text_type):
+ if isinstance(output, str):
# XXX
output = output.encode('utf-8')
validator = self.get_validator(view, output=output)
@@ -977,8 +953,8 @@
position = getattr(exc, "position", (0,))[0]
if position:
# define filter
- if isinstance(content, binary_type):
- content = text_type(content, sys.getdefaultencoding(), 'replace')
+ if isinstance(content, bytes):
+ content = str(content, sys.getdefaultencoding(), 'replace')
content = validator.preprocess_data(content)
content = content.splitlines()
width = int(log(len(content), 10)) + 1
--- a/cubicweb/entities/__init__.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/entities/__init__.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""base application's entities class implementation: `AnyEntity`"""
-from six import text_type, string_types
-
from logilab.common.decorators import classproperty
from cubicweb import Unauthorized
@@ -34,7 +32,7 @@
@classproperty
def cw_etype(cls):
"""entity type as a unicode string"""
- return text_type(cls.__regid__)
+ return cls.__regid__
@classmethod
def cw_create_url(cls, req, **kwargs):
@@ -111,8 +109,8 @@
if rtype is None:
return self.dc_title().lower()
value = self.cw_attr_value(rtype)
- # do not restrict to `unicode` because Bytes will return a `str` value
- if isinstance(value, string_types):
+ # do not restrict to `str` because Bytes will return a `str` value
+ if isinstance(value, str):
return self.printable_value(rtype, format='text/plain').lower()
return value
--- a/cubicweb/entities/authobjs.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/entities/authobjs.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""entity classes user and group entities"""
-from six import string_types, text_type
-
from logilab.common.decorators import cached
from cubicweb import Unauthorized
@@ -110,13 +108,12 @@
return self._cw.vreg.property_value(key)
def set_property(self, pkey, value):
- value = text_type(value)
try:
prop = self._cw.execute(
'CWProperty X WHERE X pkey %(k)s, X for_user U, U eid %(u)s',
{'k': pkey, 'u': self.eid}).get_entity(0, 0)
except Exception:
- kwargs = dict(pkey=text_type(pkey), value=value)
+ kwargs = dict(pkey=pkey, value=value)
if self.is_in_group('managers'):
kwargs['for_user'] = self
self._cw.create_entity('CWProperty', **kwargs)
@@ -129,7 +126,7 @@
:type groups: str or iterable(str)
:param groups: a group name or an iterable on group names
"""
- if isinstance(groups, string_types):
+ if isinstance(groups, str):
groups = frozenset((groups,))
elif isinstance(groups, (tuple, list)):
groups = frozenset(groups)
--- a/cubicweb/entities/lib.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/entities/lib.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,9 +20,7 @@
from warnings import warn
from datetime import datetime
-
-from six.moves import range
-from six.moves.urllib.parse import urlsplit, urlunsplit
+from urllib.parse import urlsplit, urlunsplit
from logilab.mtconverter import xml_escape
--- a/cubicweb/entities/sources.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/entities/sources.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,8 +21,6 @@
from socket import gethostname
import logging
-from six import text_type
-
from logilab.common.textutils import text_to_dict
from logilab.common.configuration import OptionError
from logilab.mtconverter import xml_escape
--- a/cubicweb/entities/wfobjs.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/entities/wfobjs.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,12 +21,6 @@
* workflow history (TrInfo)
* adapter for workflowable entities (IWorkflowableAdapter)
"""
-from __future__ import print_function
-
-
-
-from six import text_type, string_types
-
from logilab.common.decorators import cached, clear_cache
from cubicweb.entities import AnyEntity, fetch_config
@@ -98,7 +92,7 @@
def transition_by_name(self, trname):
rset = self._cw.execute('Any T, TN WHERE T name TN, T name %(n)s, '
'T transition_of WF, WF eid %(wf)s',
- {'n': text_type(trname), 'wf': self.eid})
+ {'n': trname, 'wf': self.eid})
if rset:
return rset.get_entity(0, 0)
return None
@@ -115,7 +109,7 @@
def add_state(self, name, initial=False, **kwargs):
"""add a state to this workflow"""
- state = self._cw.create_entity('State', name=text_type(name), **kwargs)
+ state = self._cw.create_entity('State', name=name, **kwargs)
self._cw.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s',
{'s': state.eid, 'wf': self.eid})
if initial:
@@ -127,7 +121,7 @@
def _add_transition(self, trtype, name, fromstates,
requiredgroups=(), conditions=(), **kwargs):
- tr = self._cw.create_entity(trtype, name=text_type(name), **kwargs)
+ tr = self._cw.create_entity(trtype, name=name, **kwargs)
self._cw.execute('SET T transition_of WF '
'WHERE T eid %(t)s, WF eid %(wf)s',
{'t': tr.eid, 'wf': self.eid})
@@ -257,13 +251,13 @@
for gname in requiredgroups:
rset = self._cw.execute('SET T require_group G '
'WHERE T eid %(x)s, G name %(gn)s',
- {'x': self.eid, 'gn': text_type(gname)})
+ {'x': self.eid, 'gn': gname})
assert rset, '%s is not a known group' % gname
- if isinstance(conditions, string_types):
+ if isinstance(conditions, str):
conditions = (conditions,)
for expr in conditions:
- if isinstance(expr, string_types):
- kwargs = {'expr': text_type(expr)}
+ if isinstance(expr, str):
+ kwargs = {'expr': expr}
else:
assert isinstance(expr, dict)
kwargs = expr
@@ -415,7 +409,7 @@
"""return the default workflow for entities of this type"""
# XXX CWEType method
wfrset = self._cw.execute('Any WF WHERE ET default_workflow WF, '
- 'ET name %(et)s', {'et': text_type(self.entity.cw_etype)})
+ 'ET name %(et)s', {'et': self.entity.cw_etype})
if wfrset:
return wfrset.get_entity(0, 0)
self.warning("can't find any workflow for %s", self.entity.cw_etype)
@@ -480,7 +474,7 @@
'Any T,TT, TN WHERE S allowed_transition T, S eid %(x)s, '
'T type TT, T type %(type)s, '
'T name TN, T transition_of WF, WF eid %(wfeid)s',
- {'x': self.current_state.eid, 'type': text_type(type),
+ {'x': self.current_state.eid, 'type': type,
'wfeid': self.current_workflow.eid})
for tr in rset.entities():
if tr.may_be_fired(self.entity.eid):
@@ -529,7 +523,7 @@
def _get_transition(self, tr):
assert self.current_workflow
- if isinstance(tr, string_types):
+ if isinstance(tr, str):
_tr = self.current_workflow.transition_by_name(tr)
assert _tr is not None, 'not a %s transition: %s' % (
self.__regid__, tr)
--- a/cubicweb/entity.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/entity.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,9 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Base class for entity objects manipulated in clients"""
-from six import text_type, string_types, integer_types
-from six.moves import range
-
from logilab.common.decorators import cached
from logilab.common.registry import yes
from logilab.mtconverter import TransformData, xml_escape
@@ -55,7 +52,6 @@
"""return True if value can be used at the end of a Rest URL path"""
if value is None:
return False
- value = text_type(value)
# the check for ?, /, & are to prevent problems when running
# behind Apache mod_proxy
if value == u'' or u'?' in value or u'/' in value or u'&' in value:
@@ -265,7 +261,7 @@
select = Select()
mainvar = select.get_variable(mainvar)
select.add_selected(mainvar)
- elif isinstance(mainvar, string_types):
+ elif isinstance(mainvar, str):
assert mainvar in select.defined_vars
mainvar = select.get_variable(mainvar)
# eases string -> syntax tree test transition: please remove once stable
@@ -506,12 +502,12 @@
return NotImplemented
def __eq__(self, other):
- if isinstance(self.eid, integer_types):
+ if isinstance(self.eid, int):
return self.eid == other.eid
return self is other
def __hash__(self):
- if isinstance(self.eid, integer_types):
+ if isinstance(self.eid, int):
return self.eid
return super(Entity, self).__hash__()
@@ -639,7 +635,7 @@
if path is None:
# fallback url: <base-url>/<eid> url is used as cw entities uri,
# prefer it to <base-url>/<etype>/eid/<eid>
- return text_type(value)
+ return str(value)
return u'%s/%s' % (path, self._cw.url_quote(value))
def cw_attr_metadata(self, attr, metadata):
@@ -657,7 +653,7 @@
attr = str(attr)
if value is _marker:
value = getattr(self, attr)
- if isinstance(value, string_types):
+ if isinstance(value, str):
value = value.strip()
if value is None or value == '': # don't use "not", 0 is an acceptable value
return u''
--- a/cubicweb/ext/rest.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/ext/rest.py Fri Apr 05 17:58:19 2019 +0200
@@ -38,9 +38,7 @@
from itertools import chain
from logging import getLogger
from os.path import join
-
-from six import text_type
-from six.moves.urllib.parse import urlsplit
+from urllib.parse import urlsplit
from docutils import statemachine, nodes, utils, io
from docutils.core import Publisher
@@ -403,7 +401,7 @@
the data formatted as HTML or the original data if an error occurred
"""
req = context._cw
- if isinstance(data, text_type):
+ if isinstance(data, str):
encoding = 'utf-8'
# remove unprintable characters unauthorized in xml
data = data.translate(ESC_UCAR_TABLE)
@@ -448,8 +446,8 @@
return res
except BaseException:
LOGGER.exception('error while publishing ReST text')
- if not isinstance(data, text_type):
- data = text_type(data, encoding, 'replace')
+ if not isinstance(data, str):
+ data = data.encode(encoding, 'replace')
return xml_escape(req._('error while publishing ReST text')
+ '\n\n' + data)
--- a/cubicweb/ext/test/unittest_rest.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/ext/test/unittest_rest.py Fri Apr 05 17:58:19 2019 +0200
@@ -15,7 +15,6 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-from six import PY3
from logilab.common.testlib import unittest_main
from cubicweb.devtools.testlib import CubicWebTC
@@ -93,8 +92,7 @@
context = self.context(req)
out = rest_publish(context, ':rql:`Any X WHERE X is CWUser:toto`')
self.assertTrue(out.startswith("<p>an error occurred while interpreting this "
- "rql directive: ObjectNotFound(%s'toto'" %
- ('' if PY3 else 'u')),
+ "rql directive: ObjectNotFound('toto'"),
out)
def test_rql_role_without_vid(self):
--- a/cubicweb/hooks/integrity.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/hooks/integrity.py Fri Apr 05 17:58:19 2019 +0200
@@ -23,8 +23,6 @@
from threading import Lock
-from six import text_type
-
from cubicweb import validation_error, neg_role
from cubicweb.schema import (META_RTYPES, WORKFLOW_RTYPES,
RQLConstraint, RQLUniqueConstraint)
@@ -276,7 +274,7 @@
value = edited[attr]
except KeyError:
continue # no text to tidy
- if isinstance(value, text_type): # filter out None and Binary
+ if isinstance(value, str): # filter out None and Binary
if getattr(entity, str(metaattr)) == 'text/html':
edited[attr] = soup2xhtml(value, self._cw.encoding)
--- a/cubicweb/hooks/test/unittest_hooks.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/hooks/test/unittest_hooks.py Fri Apr 05 17:58:19 2019 +0200
@@ -24,8 +24,6 @@
from datetime import datetime
-from six import text_type
-
from pytz import utc
from cubicweb import ValidationError
@@ -211,7 +209,7 @@
with self.assertRaises(ValidationError) as cm:
cnx.execute('INSERT CWUser X: X login "admin", X upassword "admin"')
ex = cm.exception
- ex.translate(text_type)
+ ex.translate(str)
self.assertIsInstance(ex.entity, int)
self.assertEqual(ex.errors,
{'': u'some relations violate a unicity constraint',
--- a/cubicweb/hooks/test/unittest_syncsession.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/hooks/test/unittest_syncsession.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,8 +22,6 @@
syncschema.py hooks are mostly tested in server/test/unittest_migrations.py
"""
-from six import text_type
-
from cubicweb import ValidationError
from cubicweb.devtools.testlib import CubicWebTC
@@ -35,13 +33,13 @@
with self.assertRaises(ValidationError) as cm:
req.execute('INSERT CWProperty X: X pkey "bla.bla", '
'X value "hop", X for_user U')
- cm.exception.translate(text_type)
+ cm.exception.translate(str)
self.assertEqual(cm.exception.errors,
{'pkey-subject': 'unknown property key bla.bla'})
with self.assertRaises(ValidationError) as cm:
req.execute('INSERT CWProperty X: X pkey "bla.bla", X value "hop"')
- cm.exception.translate(text_type)
+ cm.exception.translate(str)
self.assertEqual(cm.exception.errors,
{'pkey-subject': 'unknown property key bla.bla'})
--- a/cubicweb/i18n.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/i18n.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,17 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Some i18n/gettext utilities."""
-from __future__ import print_function
-
-
-
import re
import os
from os.path import join, basename, splitext, exists
from glob import glob
-from six import PY2
-
from cubicweb.toolsutils import create_dir
def extract_from_tal(files, output_file):
@@ -42,11 +36,7 @@
def add_msg(w, msgid, msgctx=None):
"""write an empty pot msgid definition"""
- if PY2 and isinstance(msgid, unicode):
- msgid = msgid.encode('utf-8')
if msgctx:
- if PY2 and isinstance(msgctx, unicode):
- msgctx = msgctx.encode('utf-8')
w('msgctxt "%s"\n' % msgctx)
msgid = msgid.replace('"', r'\"').splitlines()
if len(msgid) > 1:
--- a/cubicweb/mail.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/mail.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Common utilies to format / send emails."""
-
-
from base64 import b64encode, b64decode
from time import time
from email.mime.multipart import MIMEMultipart
@@ -28,21 +26,13 @@
from email.utils import formatdate
from socket import gethostname
-from six import PY2, PY3, text_type
-
def header(ustring):
- if PY3:
- return Header(ustring, 'utf-8')
- return Header(ustring.encode('UTF-8'), 'UTF-8')
+ return Header(ustring, 'utf-8')
-def addrheader(uaddr, uname=None):
+def addrheader(addr, uname=None):
# even if an email address should be ascii, encode it using utf8 since
# automatic tests may generate non ascii email address
- if PY2:
- addr = uaddr.encode('UTF-8')
- else:
- addr = uaddr
if uname:
val = '%s <%s>' % (header(uname).encode(), addr)
else:
@@ -86,7 +76,7 @@
to_addrs and cc_addrs are expected to be a list of email address without
name
"""
- assert isinstance(content, text_type), repr(content)
+ assert isinstance(content, str), repr(content)
msg = MIMEText(content.encode('UTF-8'), 'plain', 'UTF-8')
# safety: keep only the first newline
try:
@@ -97,13 +87,13 @@
if uinfo.get('email'):
email = uinfo['email']
elif config and config['sender-addr']:
- email = text_type(config['sender-addr'])
+ email = config['sender-addr']
else:
email = u''
if uinfo.get('name'):
name = uinfo['name']
elif config and config['sender-name']:
- name = text_type(config['sender-name'])
+ name = config['sender-name']
else:
name = u''
msg['From'] = addrheader(email, name)
--- a/cubicweb/md5crypt.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/md5crypt.py Fri Apr 05 17:58:19 2019 +0200
@@ -43,9 +43,6 @@
from hashlib import md5 # pylint: disable=E0611
-from six import text_type, indexbytes
-from six.moves import range
-
def to64 (v, n):
ret = bytearray()
@@ -56,9 +53,9 @@
return ret
def crypt(pw, salt):
- if isinstance(pw, text_type):
+ if isinstance(pw, str):
pw = pw.encode('utf-8')
- if isinstance(salt, text_type):
+ if isinstance(salt, str):
salt = salt.encode('ascii')
# Take care of the magic string if present
if salt.startswith(MAGIC):
@@ -102,20 +99,20 @@
final = md5(ctx1).digest()
# Final xform
passwd = b''
- passwd += to64((indexbytes(final, 0) << 16)
- |(indexbytes(final, 6) << 8)
- |(indexbytes(final, 12)),4)
- passwd += to64((indexbytes(final, 1) << 16)
- |(indexbytes(final, 7) << 8)
- |(indexbytes(final, 13)), 4)
- passwd += to64((indexbytes(final, 2) << 16)
- |(indexbytes(final, 8) << 8)
- |(indexbytes(final, 14)), 4)
- passwd += to64((indexbytes(final, 3) << 16)
- |(indexbytes(final, 9) << 8)
- |(indexbytes(final, 15)), 4)
- passwd += to64((indexbytes(final, 4) << 16)
- |(indexbytes(final, 10) << 8)
- |(indexbytes(final, 5)), 4)
- passwd += to64((indexbytes(final, 11)), 2)
+ passwd += to64((final[0] << 16)
+ |(final[6] << 8)
+ |(final[12]),4)
+ passwd += to64((final[1] << 16)
+ |(final[7] << 8)
+ |(final[13]), 4)
+ passwd += to64((final[2] << 16)
+ |(final[8] << 8)
+ |(final[14]), 4)
+ passwd += to64((final[3] << 16)
+ |(final[9] << 8)
+ |(final[15]), 4)
+ passwd += to64((final[4] << 16)
+ |(final[10] << 8)
+ |(final[5]), 4)
+ passwd += to64((final[11]), 2)
return passwd
--- a/cubicweb/migration.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/migration.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""utilities for instances migration"""
-from __future__ import print_function
import sys
import os
@@ -25,8 +24,6 @@
from os.path import exists, join, basename, splitext
from itertools import chain
-from six import string_types
-
from logilab.common import IGNORED_EXTENSIONS
from logilab.common.decorators import cached
from logilab.common.configuration import REQUIRED, read_old_config
@@ -405,7 +402,7 @@
"""modify the list of used cubes in the in-memory config
returns newly inserted cubes, including dependencies
"""
- if isinstance(cubes, string_types):
+ if isinstance(cubes, str):
cubes = (cubes,)
origcubes = self.config.cubes()
newcubes = [p for p in self.config.expand_cubes(cubes)
--- a/cubicweb/misc/migration/3.10.0_Any.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/misc/migration/3.10.0_Any.py Fri Apr 05 17:58:19 2019 +0200
@@ -1,5 +1,3 @@
-from six import text_type
-
add_entity_type('CWSource')
add_relation_definition('CWSource', 'cw_source', 'CWSource')
add_entity_type('CWSourceHostConfig')
@@ -18,7 +16,7 @@
continue
config = u'\n'.join('%s=%s' % (key, value) for key, value in cfg.items()
if key != 'adapter' and value is not None)
- create_entity('CWSource', name=text_type(uri), type=text_type(cfg['adapter']),
+ create_entity('CWSource', name=uri, type=cfg['adapter'],
config=config)
commit()
--- a/cubicweb/misc/migration/3.15.0_Any.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/misc/migration/3.15.0_Any.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,7 +16,7 @@
sconfig.set_option(opt, val)
except OptionError:
continue
- cfgstr = text_type(generate_source_config(sconfig), source._cw.encoding)
+ cfgstr = str(generate_source_config(sconfig), source._cw.encoding)
source.cw_set(config=cfgstr)
--- a/cubicweb/misc/migration/bootstrapmigration_repository.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/misc/migration/bootstrapmigration_repository.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,11 +19,6 @@
it should only include low level schema changes
"""
-
-from __future__ import print_function
-
-from six import text_type
-
from cubicweb import ConfigurationError
from cubicweb.server.session import hooks_control
from cubicweb.server import schemaserial as ss
@@ -120,7 +115,6 @@
default = yams.DATE_FACTORY_MAP[atype](default)
else:
assert atype == 'String', atype
- default = text_type(default)
return Binary.zpickle(default)
dbh = repo.system_source.dbhelper
--- a/cubicweb/misc/migration/postcreate.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/misc/migration/postcreate.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,19 +16,15 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""cubicweb post creation script, set user's workflow"""
-from __future__ import print_function
-
-from six import text_type
-
from cubicweb import _
# insert versions
create_entity('CWProperty', pkey=u'system.version.cubicweb',
- value=text_type(config.cubicweb_version()))
+ value=str(config.cubicweb_version()))
for cube in config.cubes():
create_entity('CWProperty', pkey=u'system.version.%s' % cube.lower(),
- value=text_type(config.cube_version(cube)))
+ value=str(config.cube_version(cube)))
# some entities have been added before schema entities, add their missing 'is' and
# 'is_instance_of' relations
@@ -56,7 +52,7 @@
print('Hopefully this is not a production instance...')
elif anonlogin:
from cubicweb.server import create_user
- create_user(session, text_type(anonlogin), anonpwd, u'guests')
+ create_user(session, anonlogin, anonpwd, u'guests')
# need this since we already have at least one user in the database (the default admin)
for user in rql('Any X WHERE X is CWUser').entities():
--- a/cubicweb/misc/scripts/migration_helper.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/misc/scripts/migration_helper.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,9 +19,6 @@
"""Helper functions for migrations that aren't reliable enough or too dangerous
to be available in the standard migration environment
"""
-from __future__ import print_function
-
-
def drop_entity_types_fast(*etypes, **kwargs):
"""drop an entity type bypassing all hooks
--- a/cubicweb/multipart.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/multipart.py Fri Apr 05 17:58:19 2019 +0200
@@ -37,16 +37,12 @@
__version__ = '0.1'
__license__ = 'MIT'
+from io import BytesIO
from tempfile import TemporaryFile
+from urllib.parse import parse_qs
from wsgiref.headers import Headers
import re, sys
-try:
- from io import BytesIO
-except ImportError: # pragma: no cover (fallback for Python 2.5)
- from StringIO import StringIO as BytesIO
-from six import PY3, text_type
-from six.moves.urllib.parse import parse_qs
##############################################################################
################################ Helper & Misc ################################
@@ -88,7 +84,7 @@
yield key, value
def tob(data, enc='utf8'): # Convert strings to bytes (py2 and py3)
- return data.encode(enc) if isinstance(data, text_type) else data
+ return data.encode(enc) if isinstance(data, str) else data
def copy_file(stream, target, maxread=-1, buffer_size=2*16):
''' Read from :stream and write to :target until :maxread or EOF. '''
@@ -400,15 +396,11 @@
data = stream.read(mem_limit)
if stream.read(1): # These is more that does not fit mem_limit
raise MultipartError("Request too big. Increase MAXMEM.")
- if PY3:
- data = data.decode('ascii')
+ data = data.decode('ascii')
data = parse_qs(data, keep_blank_values=True)
for key, values in data.items():
for value in values:
- if PY3:
- forms[key] = value
- else:
- forms[key.decode(charset)] = value.decode(charset)
+ forms[key] = value
else:
raise MultipartError("Unsupported content type.")
except MultipartError:
--- a/cubicweb/predicates.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/predicates.py Fri Apr 05 17:58:19 2019 +0200
@@ -24,9 +24,6 @@
from warnings import warn
from operator import eq
-from six import string_types, integer_types
-from six.moves import range
-
from logilab.common.registry import Predicate, objectify_predicate
from yams.schema import BASE_TYPES, role_name
@@ -610,7 +607,7 @@
super(is_instance, self).__init__(**kwargs)
self.expected_etypes = expected_etypes
for etype in self.expected_etypes:
- assert isinstance(etype, string_types), etype
+ assert isinstance(etype, str), etype
def __str__(self):
return '%s(%s)' % (self.__class__.__name__,
@@ -670,7 +667,7 @@
score = scorefunc(*args, **kwargs)
if not score:
return 0
- if isinstance(score, integer_types):
+ if isinstance(score, int):
return score
return 1
self.score_entity = intscore
@@ -1088,7 +1085,7 @@
See :class:`cubicweb.entities.wfobjs.TrInfo` for more information.
"""
- if isinstance(tr_names, string_types):
+ if isinstance(tr_names, str):
tr_names = set((tr_names,))
def match_etype_and_transition(trinfo):
# take care trinfo.transition is None when calling change_state
@@ -1288,7 +1285,7 @@
raise ValueError("match_form_params() can't be called with both "
"positional and named arguments")
if expected:
- if len(expected) == 1 and not isinstance(expected[0], string_types):
+ if len(expected) == 1 and not isinstance(expected[0], str):
raise ValueError("match_form_params() positional arguments "
"must be strings")
super(match_form_params, self).__init__(*expected)
--- a/cubicweb/pyramid/__init__.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/pyramid/__init__.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,10 +21,10 @@
"""Pyramid interface to CubicWeb"""
import atexit
+from configparser import SafeConfigParser
import os
import warnings
-from six.moves.configparser import SafeConfigParser
import wsgicors
from cubicweb.cwconfig import CubicWebConfiguration as cwcfg
--- a/cubicweb/pyramid/profile.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/pyramid/profile.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,7 +21,6 @@
""" Tools for profiling.
See :ref:`profiling`."""
-from __future__ import print_function
import cProfile
import itertools
--- a/cubicweb/pyramid/pyramidctl.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/pyramid/pyramidctl.py Fri Apr 05 17:58:19 2019 +0200
@@ -25,8 +25,6 @@
the pyramid script 'pserve'.
"""
-from __future__ import print_function
-
import atexit
import errno
import os
--- a/cubicweb/pyramid/resources.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/pyramid/resources.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
"""Pyramid resource definitions for CubicWeb."""
-from six import text_type
-
from rql import TypeResolverException
from pyramid.decorator import reify
@@ -62,7 +60,7 @@
# conflicting eid/type
raise HTTPNotFound()
else:
- rset = req.execute(st.as_string(), {'x': text_type(self.value)})
+ rset = req.execute(st.as_string(), {'x': self.value})
return rset
--- a/cubicweb/pyramid/test/test_config.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/pyramid/test/test_config.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,11 +19,11 @@
import os
from os import path
+from tempfile import TemporaryDirectory
from unittest import TestCase
from mock import patch
-from cubicweb.devtools.testlib import TemporaryDirectory
from cubicweb.pyramid import config
--- a/cubicweb/pyramid/test/test_hooks.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/pyramid/test/test_hooks.py Fri Apr 05 17:58:19 2019 +0200
@@ -1,5 +1,3 @@
-from six import text_type
-
from cubicweb.pyramid.test import PyramidCWTest
from cubicweb.pyramid import tools
@@ -11,10 +9,10 @@
cnx.execute('DELETE CWProperty X WHERE X for_user U, U eid %(u)s',
{'u': cnx.user.eid})
else:
- cnx.user.set_property(u'ui.language', text_type(lang))
+ cnx.user.set_property(u'ui.language', lang)
cnx.commit()
- request.response.text = text_type(cnx.user.properties.get('ui.language', ''))
+ request.response.text = cnx.user.properties.get('ui.language', '')
return request.response
@@ -29,7 +27,7 @@
{'u': cnx.user.eid})
cnx.commit()
- request.response.text = text_type(','.join(sorted(cnx.user.groups)))
+ request.response.text = ','.join(sorted(cnx.user.groups))
return request.response
--- a/cubicweb/req.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/req.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,11 +18,9 @@
"""Base class for request/session"""
from datetime import time, datetime, timedelta
-
-from six import PY2, PY3, text_type
-from six.moves.urllib.parse import (parse_qs, parse_qsl,
- quote as urlquote, unquote as urlunquote,
- urlsplit, urlunsplit)
+from urllib.parse import (parse_qs, parse_qsl,
+ quote as urlquote, unquote as urlunquote,
+ urlsplit, urlunsplit)
from logilab.common.decorators import cached
from logilab.common.date import ustrftime, strptime, todate, todatetime
@@ -73,7 +71,7 @@
self.user = None
self.lang = None
self.local_perm_cache = {}
- self._ = text_type
+ self._ = str
def _set_user(self, orig_user):
"""set the user for this req_session_base
@@ -97,10 +95,10 @@
gettext, pgettext = self.vreg.config.translations[lang]
except KeyError:
assert self.vreg.config.mode == 'test'
- gettext = text_type
+ gettext = str
def pgettext(x, y):
- return text_type(y)
+ return str(y)
# use _cw.__ to translate a message without registering it to the catalog
self._ = self.__ = gettext
@@ -274,9 +272,6 @@
necessary encoding / decoding. Also it's designed to quote each
part of a url path and so the '/' character will be encoded as well.
"""
- if PY2 and isinstance(value, text_type):
- quoted = urlquote(value.encode(self.encoding), safe=safe)
- return text_type(quoted, self.encoding)
return urlquote(str(value), safe=safe)
def url_unquote(self, quoted):
@@ -285,28 +280,13 @@
decoding is based on `self.encoding` which is the encoding
used in `url_quote`
"""
- if PY3:
- return urlunquote(quoted)
- if isinstance(quoted, text_type):
- quoted = quoted.encode(self.encoding)
- try:
- return text_type(urlunquote(quoted), self.encoding)
- except UnicodeDecodeError: # might occurs on manually typed URLs
- return text_type(urlunquote(quoted), 'iso-8859-1')
+ return urlunquote(quoted)
def url_parse_qsl(self, querystring):
"""return a list of (key, val) found in the url quoted query string"""
- if PY3:
- for key, val in parse_qsl(querystring):
- yield key, val
- return
- if isinstance(querystring, text_type):
- querystring = querystring.encode(self.encoding)
for key, val in parse_qsl(querystring):
- try:
- yield text_type(key, self.encoding), text_type(val, self.encoding)
- except UnicodeDecodeError: # might occurs on manually typed URLs
- yield text_type(key, 'iso-8859-1'), text_type(val, 'iso-8859-1')
+ yield key, val
+ return
def rebuild_url(self, url, **newparams):
"""return the given url with newparams inserted. If any new params
@@ -314,8 +294,6 @@
newparams may only be mono-valued.
"""
- if PY2 and isinstance(url, text_type):
- url = url.encode(self.encoding)
schema, netloc, path, query, fragment = urlsplit(url)
query = parse_qs(query)
# sort for testing predictability
@@ -386,7 +364,7 @@
as_string = formatters[attrtype]
except KeyError:
self.error('given bad attrtype %s', attrtype)
- return text_type(value)
+ return str(value)
return as_string(value, self, props, displaytime)
def format_date(self, date, date_format=None, time=False):
--- a/cubicweb/rqlrewrite.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/rqlrewrite.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,8 +21,6 @@
This is used for instance for read security checking in the repository.
"""
-from six import text_type, string_types
-
from rql import nodes as n, stmts, TypeResolverException
from rql.utils import common_parent
@@ -640,7 +638,7 @@
while argname in self.kwargs:
argname = subselect.allocate_varname()
subselect.add_constant_restriction(subselect.get_variable(self.u_varname),
- 'eid', text_type(argname), 'Substitute')
+ 'eid', argname, 'Substitute')
self.kwargs[argname] = self.session.user.eid
add_types_restriction(self.schema, subselect, subselect,
solutions=self.solutions)
@@ -795,7 +793,7 @@
# insert "U eid %(u)s"
stmt.add_constant_restriction(
stmt.get_variable(self.u_varname),
- 'eid', text_type(argname), 'Substitute')
+ 'eid', argname, 'Substitute')
self.kwargs[argname] = self.session.user.eid
return self.u_varname
key = (self.current_expr, self.varmap, vname)
@@ -917,7 +915,7 @@
return n.Constant(vi['const'], 'Int')
return n.VariableRef(stmt.get_variable(selectvar))
vname_or_term = self._get_varname_or_term(node.name)
- if isinstance(vname_or_term, string_types):
+ if isinstance(vname_or_term, str):
return n.VariableRef(stmt.get_variable(vname_or_term))
# shared term
return vname_or_term.copy(stmt)
--- a/cubicweb/rset.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/rset.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,10 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""The `ResultSet` class which is returned as result of an rql query"""
-
-from six import PY3, text_type
-from six.moves import range
-
from logilab.common.decorators import cached, clear_cache, copy_cache
from rql import nodes, stmts
@@ -366,13 +362,7 @@
"""return the result set's origin rql as a string, with arguments
substitued
"""
- encoding = self.req.encoding
- rqlstr = self.syntax_tree().as_string(kwargs=self.args)
- if PY3:
- return rqlstr
- if isinstance(rqlstr, text_type):
- return rqlstr
- return text_type(rqlstr, encoding)
+ return self.syntax_tree().as_string(kwargs=self.args)
# client helper methods ###################################################
--- a/cubicweb/rtags.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/rtags.py Fri Apr 05 17:58:19 2019 +0200
@@ -39,8 +39,6 @@
import logging
-from six import string_types
-
from logilab.common.logging_ext import set_log_methods
from logilab.common.registry import RegistrableInstance, yes
@@ -182,7 +180,7 @@
return tag
def _tag_etype_attr(self, etype, attr, desttype='*', *args, **kwargs):
- if isinstance(attr, string_types):
+ if isinstance(attr, str):
attr, role = attr, 'subject'
else:
attr, role = attr
--- a/cubicweb/schema.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/schema.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,17 +17,12 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""classes to define schemas for CubicWeb"""
-from __future__ import print_function
-
from functools import wraps
import re
from os.path import join
from hashlib import md5
from logging import getLogger
-from six import PY2, text_type, string_types, add_metaclass
-from six.moves import range
-
from logilab.common.decorators import cached, clear_cache, monkeypatch, cachedproperty
from logilab.common.logging_ext import set_log_methods
from logilab.common.textutils import splitstrip
@@ -145,8 +140,6 @@
added/removed for instance)
"""
union = parse(u'Any 1 WHERE %s' % rqlstring).as_string()
- if PY2 and isinstance(union, str):
- union = union.decode('utf-8')
return union.split(' WHERE ', 1)[1]
@@ -218,7 +211,7 @@
"""
self.eid = eid # eid of the entity representing this rql expression
assert mainvars, 'bad mainvars %s' % mainvars
- if isinstance(mainvars, string_types):
+ if isinstance(mainvars, str):
mainvars = set(splitstrip(mainvars))
elif not isinstance(mainvars, set):
mainvars = set(mainvars)
@@ -579,9 +572,9 @@
key = key + '_' + form
# ensure unicode
if context is not None:
- return text_type(req.pgettext(context, key))
+ return req.pgettext(context, key)
else:
- return text_type(req._(key))
+ return req._(key)
def _override_method(cls, method_name=None, pass_original=False):
@@ -627,7 +620,7 @@
"""
assert action in self.ACTIONS, action
try:
- return frozenset(g for g in self.permissions[action] if isinstance(g, string_types))
+ return frozenset(g for g in self.permissions[action] if isinstance(g, str))
except KeyError:
return ()
@@ -646,7 +639,7 @@
"""
assert action in self.ACTIONS, action
try:
- return tuple(g for g in self.permissions[action] if not isinstance(g, string_types))
+ return tuple(g for g in self.permissions[action] if not isinstance(g, str))
except KeyError:
return ()
@@ -1333,8 +1326,7 @@
return cls
-@add_metaclass(workflowable_definition)
-class WorkflowableEntityType(ybo.EntityType):
+class WorkflowableEntityType(ybo.EntityType, metaclass=workflowable_definition):
"""Use this base class instead of :class:`EntityType` to have workflow
relations (i.e. `in_state`, `wf_info_for` and `custom_workflow`) on your
entity type.
--- a/cubicweb/server/__init__.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/__init__.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,13 +20,8 @@
The server module contains functions to initialize a new repository.
"""
-from __future__ import print_function
-
from contextlib import contextmanager
-from six import text_type, string_types
-from six.moves import filter
-
from logilab.common.modutils import LazyObject
from logilab.common.textutils import splitstrip
from logilab.common.registry import yes
@@ -133,7 +128,7 @@
if not debugmode:
DEBUG = 0
return
- if isinstance(debugmode, string_types):
+ if isinstance(debugmode, str):
for mode in splitstrip(debugmode, sep='|'):
DEBUG |= globals()[mode]
else:
@@ -192,7 +187,7 @@
user = session.create_entity('CWUser', login=login, upassword=pwd)
for group in groups:
session.execute('SET U in_group G WHERE U eid %(u)s, G name %(group)s',
- {'u': user.eid, 'group': text_type(group)})
+ {'u': user.eid, 'group': group})
return user
@@ -270,17 +265,17 @@
# insert base groups and default admin
print('-> inserting default user and default groups.')
try:
- login = text_type(sourcescfg['admin']['login'])
+ login = sourcescfg['admin']['login']
pwd = sourcescfg['admin']['password']
except KeyError:
if interactive:
msg = 'enter login and password of the initial manager account'
login, pwd = manager_userpasswd(msg=msg, confirm=True)
else:
- login, pwd = text_type(source['db-user']), source['db-password']
+ login, pwd = source['db-user'], source['db-password']
# sort for eid predicatability as expected in some server tests
for group in sorted(BASE_GROUPS):
- cnx.create_entity('CWGroup', name=text_type(group))
+ cnx.create_entity('CWGroup', name=group)
admin = create_user(cnx, login, pwd, u'managers')
cnx.execute('SET X owned_by U WHERE X is IN (CWGroup,CWSource), U eid %(u)s',
{'u': admin.eid})
--- a/cubicweb/server/checkintegrity.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/checkintegrity.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,7 +20,6 @@
* integrity of a CubicWeb repository. Hum actually only the system database is
checked.
"""
-from __future__ import print_function
import sys
from datetime import datetime
--- a/cubicweb/server/hook.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/hook.py Fri Apr 05 17:58:19 2019 +0200
@@ -245,7 +245,6 @@
.. autoclass:: cubicweb.server.hook.LateOperation
.. autoclass:: cubicweb.server.hook.DataOperationMixIn
"""
-from __future__ import print_function
from logging import getLogger
from itertools import chain
--- a/cubicweb/server/migractions.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/migractions.py Fri Apr 05 17:58:19 2019 +0200
@@ -26,9 +26,6 @@
* add an entity
* execute raw RQL queries
"""
-from __future__ import print_function
-
-
import sys
import os
@@ -41,8 +38,6 @@
from copy import copy
from contextlib import contextmanager
-from six import PY2, text_type
-
from logilab.common.decorators import cached, clear_cache
from yams.buildobjs import EntityType
@@ -153,7 +148,7 @@
def cube_upgraded(self, cube, version):
self.cmd_set_property('system.version.%s' % cube.lower(),
- text_type(version))
+ str(version))
self.commit()
def shutdown(self):
@@ -1005,7 +1000,7 @@
# elif simply renaming an entity type
else:
self.rqlexec('SET ET name %(newname)s WHERE ET is CWEType, ET name %(on)s',
- {'newname': text_type(newname), 'on': oldname},
+ {'newname': newname, 'on': oldname},
ask_confirm=False)
if commit:
self.commit()
@@ -1217,8 +1212,6 @@
values = []
for k, v in kwargs.items():
values.append('X %s %%(%s)s' % (k, k))
- if PY2 and isinstance(v, str):
- kwargs[k] = unicode(v)
rql = 'SET %s WHERE %s' % (','.join(values), ','.join(restriction))
self.rqlexec(rql, kwargs, ask_confirm=self.verbosity >= 2)
if commit:
@@ -1250,7 +1243,7 @@
self.rqlexec('SET C value %%(v)s WHERE X from_entity S, X relation_type R,'
'X constrained_by C, C cstrtype CT, CT name "SizeConstraint",'
'S name "%s", R name "%s"' % (etype, rtype),
- {'v': text_type(SizeConstraint(size).serialize())},
+ {'v': SizeConstraint(size).serialize()},
ask_confirm=self.verbosity >= 2)
else:
self.rqlexec('DELETE X constrained_by C WHERE X from_entity S, X relation_type R,'
@@ -1287,7 +1280,7 @@
:rtype: `Workflow`
"""
- wf = self.cmd_create_entity('Workflow', name=text_type(name),
+ wf = self.cmd_create_entity('Workflow', name=name,
**kwargs)
if not isinstance(wfof, (list, tuple)):
wfof = (wfof,)
@@ -1297,19 +1290,18 @@
for etype in wfof:
eschema = self.repo.schema[etype]
- etype = text_type(etype)
if ensure_workflowable:
assert 'in_state' in eschema.subjrels, _missing_wf_rel(etype)
assert 'custom_workflow' in eschema.subjrels, _missing_wf_rel(etype)
assert 'wf_info_for' in eschema.objrels, _missing_wf_rel(etype)
rset = self.rqlexec(
'SET X workflow_of ET WHERE X eid %(x)s, ET name %(et)s',
- {'x': wf.eid, 'et': text_type(etype)}, ask_confirm=False)
+ {'x': wf.eid, 'et': etype}, ask_confirm=False)
assert rset, 'unexistant entity type %s' % etype
if default:
self.rqlexec(
'SET ET default_workflow X WHERE X eid %(x)s, ET name %(et)s',
- {'x': wf.eid, 'et': text_type(etype)}, ask_confirm=False)
+ {'x': wf.eid, 'et': etype}, ask_confirm=False)
if commit:
self.commit()
return wf
@@ -1340,13 +1332,13 @@
To set a user specific property value, use appropriate method on CWUser
instance.
"""
- value = text_type(value)
+ value = str(value)
try:
prop = self.rqlexec(
'CWProperty X WHERE X pkey %(k)s, NOT X for_user U',
- {'k': text_type(pkey)}, ask_confirm=False).get_entity(0, 0)
+ {'k': str(pkey)}, ask_confirm=False).get_entity(0, 0)
except Exception:
- self.cmd_create_entity('CWProperty', pkey=text_type(pkey), value=value)
+ self.cmd_create_entity('CWProperty', pkey=str(pkey), value=value)
else:
prop.cw_set(value=value)
--- a/cubicweb/server/querier.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/querier.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,13 +18,8 @@
"""Helper classes to execute RQL queries on a set of sources, performing
security checking and data aggregation.
"""
-from __future__ import print_function
-
from itertools import repeat
-from six import text_type, string_types, integer_types
-from six.moves import range, zip
-
from rql import RQLSyntaxError, CoercionError
from rql.stmts import Union
from rql.nodes import ETYPE_PYOBJ_MAP, etype_from_pyobj, Relation, Exists, Not
@@ -442,13 +437,13 @@
relations = {}
for subj, rtype, obj in self.relation_defs():
# if a string is given into args instead of an int, we get it here
- if isinstance(subj, string_types):
+ if isinstance(subj, str):
subj = int(subj)
- elif not isinstance(subj, integer_types):
+ elif not isinstance(subj, int):
subj = subj.entity.eid
- if isinstance(obj, string_types):
+ if isinstance(obj, str):
obj = int(obj)
- elif not isinstance(obj, integer_types):
+ elif not isinstance(obj, int):
obj = obj.entity.eid
if repo.schema.rschema(rtype).inlined:
if subj not in edited_entities:
@@ -623,7 +618,7 @@
def parse(rql, annotate=False, parse=rqlhelper.parse):
"""Return a freshly parsed syntax tree for the given RQL."""
try:
- return parse(text_type(rql), annotate=annotate)
+ return parse(rql, annotate=annotate)
except UnicodeError:
raise RQLSyntaxError(rql)
self._parse = parse
--- a/cubicweb/server/repository.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/repository.py Fri Apr 05 17:58:19 2019 +0200
@@ -26,13 +26,10 @@
* handles session management
"""
-from __future__ import print_function
-
from itertools import chain
from contextlib import contextmanager
from logging import getLogger
-
-from six.moves import range, queue
+import queue
from logilab.common.decorators import cached, clear_cache
--- a/cubicweb/server/rqlannotation.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/rqlannotation.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,8 +19,6 @@
code generation.
"""
-from __future__ import print_function
-
from rql import BadRQLQuery
from rql.nodes import Relation, VariableRef, Constant, Variable, Or
from rql.utils import common_parent
--- a/cubicweb/server/schema2sql.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/schema2sql.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,9 +19,6 @@
from hashlib import md5
-from six import string_types, text_type
-from six.moves import range
-
from yams.constraints import (SizeConstraint, UniqueConstraint, Attribute,
NOW, TODAY)
from logilab import database
@@ -88,9 +85,9 @@
given attributes of the entity schema (actually, the later may be a schema or a string).
"""
# keep giving eschema instead of table name for bw compat
- table = text_type(eschema)
+ table = str(eschema)
# unique_index_name is used as name of CWUniqueConstraint, hence it should be unicode
- return text_type(build_index_name(table, attrs, 'unique_'))
+ return build_index_name(table, attrs, 'unique_')
def iter_unique_index_names(eschema):
@@ -204,7 +201,7 @@
return cstrname, ' AND '.join(condition)
elif constraint.type() == 'StaticVocabularyConstraint':
sample = next(iter(constraint.vocabulary()))
- if not isinstance(sample, string_types):
+ if not isinstance(sample, str):
values = ', '.join(str(word) for word in constraint.vocabulary())
else:
# XXX better quoting?
--- a/cubicweb/server/schemaserial.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/schemaserial.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,14 +17,10 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""functions for schema / permissions (de)serialization using RQL"""
-from __future__ import print_function
-
import json
import sys
import sqlite3
-from six import PY2, text_type, string_types
-
from logilab.common.shellutils import ProgressBar, DummyProgressBar
from yams import BadSchemaDefinition, schema as schemamod, buildobjs as ybo, constraints
@@ -378,7 +374,7 @@
cstrtypemap = {}
rql = 'INSERT CWConstraintType X: X name %(ct)s'
for cstrtype in CONSTRAINTS:
- cstrtypemap[cstrtype] = execute(rql, {'ct': text_type(cstrtype)},
+ cstrtypemap[cstrtype] = execute(rql, {'ct': cstrtype},
build_descr=False)[0][0]
pb.update()
# serialize relations
@@ -483,7 +479,7 @@
for i, name in enumerate(unique_together):
rschema = eschema.schema.rschema(name)
rtype = 'T%d' % i
- substs[rtype] = text_type(rschema.type)
+ substs[rtype] = rschema.type
relations.append('C relations %s' % rtype)
restrictions.append('%(rtype)s name %%(%(rtype)s)s' % {'rtype': rtype})
relations = ', '.join(relations)
@@ -494,18 +490,10 @@
def _ervalues(erschema):
- try:
- type_ = text_type(erschema.type)
- except UnicodeDecodeError as e:
- raise Exception("can't decode %s [was %s]" % (erschema.type, e))
- try:
- desc = text_type(erschema.description) or u''
- except UnicodeDecodeError as e:
- raise Exception("can't decode %s [was %s]" % (erschema.description, e))
return {
- 'name': type_,
+ 'name': erschema.type,
'final': erschema.final,
- 'description': desc,
+ 'description': erschema.description,
}
# rtype serialization
@@ -531,10 +519,7 @@
values['final'] = rschema.final
values['symmetric'] = rschema.symmetric
values['inlined'] = rschema.inlined
- if PY2 and isinstance(rschema.fulltext_container, str):
- values['fulltext_container'] = unicode(rschema.fulltext_container)
- else:
- values['fulltext_container'] = rschema.fulltext_container
+ values['fulltext_container'] = rschema.fulltext_container
relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
return relations, values
@@ -547,7 +532,7 @@
def crschema_relations_values(crschema):
values = _ervalues(crschema)
- values['rule'] = text_type(crschema.rule)
+ values['rule'] = crschema.rule
# XXX why oh why?
del values['final']
relations = ['X %s %%(%s)s' % (attr, attr) for attr in sorted(values)]
@@ -593,8 +578,6 @@
value = bool(value)
elif prop == 'ordernum':
value = int(value)
- elif PY2 and isinstance(value, str):
- value = unicode(value)
if value is not None and prop == 'default':
value = Binary.zpickle(value)
values[amap.get(prop, prop)] = value
@@ -606,7 +589,7 @@
def constraints2rql(cstrtypemap, constraints, rdefeid=None):
for constraint in constraints:
values = {'ct': cstrtypemap[constraint.type()],
- 'value': text_type(constraint.serialize()),
+ 'value': constraint.serialize(),
'x': rdefeid} # when not specified, will have to be set by the caller
yield 'INSERT CWConstraint X: X value %(value)s, X cstrtype CT, EDEF constrained_by X WHERE \
CT eid %(ct)s, EDEF eid %(x)s', values
@@ -625,7 +608,7 @@
# may occurs when modifying persistent schema
continue
for group_or_rqlexpr in grantedto:
- if isinstance(group_or_rqlexpr, string_types):
+ if isinstance(group_or_rqlexpr, str):
# group
try:
yield ('SET X %s_permission Y WHERE Y eid %%(g)s, X eid %%(x)s' % action,
@@ -639,9 +622,9 @@
rqlexpr = group_or_rqlexpr
yield ('INSERT RQLExpression E: E expression %%(e)s, E exprtype %%(t)s, '
'E mainvars %%(v)s, X %s_permission E WHERE X eid %%(x)s' % action,
- {'e': text_type(rqlexpr.expression),
- 'v': text_type(','.join(sorted(rqlexpr.mainvars))),
- 't': text_type(rqlexpr.__class__.__name__)})
+ {'e': rqlexpr.expression,
+ 'v': ','.join(sorted(rqlexpr.mainvars)),
+ 't': rqlexpr.__class__.__name__})
# update functions
@@ -653,7 +636,7 @@
def updaterschema2rql(rschema, eid):
if rschema.rule:
yield ('SET X rule %(r)s WHERE X eid %(x)s',
- {'x': eid, 'r': text_type(rschema.rule)})
+ {'x': eid, 'r': rschema.rule})
else:
relations, values = rschema_relations_values(rschema)
values['x'] = eid
--- a/cubicweb/server/serverconfig.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/serverconfig.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,15 +16,11 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""server.serverconfig definition"""
-from __future__ import print_function
-
-
+from io import StringIO
import sys
from os.path import join, exists
-from six.moves import StringIO
-
import logilab.common.configuration as lgconfig
from logilab.common.decorators import cached
--- a/cubicweb/server/serverctl.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/serverctl.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,18 +16,14 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""cubicweb-ctl commands and command handlers specific to the repository"""
-from __future__ import print_function
-
# *ctl module should limit the number of import to be imported as quickly as
# possible (for cubicweb-ctl reactivity, necessary for instance for usable bash
# completion). So import locally in command helpers.
+import sched
import sys
import os
from contextlib import contextmanager
-from six import string_types
-from six.moves import input
-
from logilab.common.configuration import Configuration, merge_options
from logilab.common.shellutils import ASK, generate_password
@@ -1006,12 +1002,11 @@
def run(self, args):
from cubicweb.cwctl import init_cmdline_log_threshold
from cubicweb.server.repository import Repository
- from cubicweb.server.utils import scheduler
config = ServerConfiguration.config_for(args[0])
# Log to stdout, since the this command runs in the foreground.
config.global_set_option('log-file', None)
init_cmdline_log_threshold(config, self['loglevel'])
- repo = Repository(config, scheduler())
+ repo = Repository(config, sched.scheduler())
repo.bootstrap()
try:
repo.run_scheduler()
@@ -1095,8 +1090,7 @@
for p in ('read', 'add', 'update', 'delete'):
rule = perms.get(p)
if rule:
- perms[p] = tuple(str(x) if isinstance(x, string_types) else x
- for x in rule)
+ perms[p] = tuple(rule)
return perms, perms in defaultrelperms or perms in defaulteperms
--- a/cubicweb/server/session.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/session.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,16 +17,12 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Repository users' and internal' sessions."""
-from __future__ import print_function
-
import functools
import sys
from uuid import uuid4
from contextlib import contextmanager
from logging import getLogger
-from six import text_type
-
from logilab.common.registry import objectify_predicate
from cubicweb import QueryError, ProgrammingError, schema, server
@@ -641,7 +637,7 @@
def transaction_uuid(self, set=True):
uuid = self.transaction_data.get('tx_uuid')
if set and uuid is None:
- self.transaction_data['tx_uuid'] = uuid = text_type(uuid4().hex)
+ self.transaction_data['tx_uuid'] = uuid = uuid4().hex
self.repo.system_source.start_undoable_transaction(self, uuid)
return uuid
--- a/cubicweb/server/sources/__init__.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/sources/__init__.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,13 +17,9 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""cubicweb server sources support"""
-from __future__ import print_function
-
from time import time
from logging import getLogger
-from six import text_type
-
from logilab.common import configuration
from logilab.common.textutils import unormalize
@@ -97,7 +93,7 @@
self.uri = source_config.pop('uri')
# unormalize to avoid non-ascii characters in logger's name, this will cause decoding error
# on logging
- set_log_methods(self, getLogger('cubicweb.sources.' + unormalize(text_type(self.uri))))
+ set_log_methods(self, getLogger('cubicweb.sources.' + unormalize(self.uri)))
source_config.pop('type')
self.config = self._check_config_dict(
eid, source_config, raise_on_error=False)
@@ -155,7 +151,7 @@
except Exception as ex:
if not raise_on_error:
continue
- msg = text_type(ex)
+ msg = str(ex)
raise ValidationError(eid, {role_name('config', 'subject'): msg})
processed[optname] = value
# cw < 3.10 bw compat
--- a/cubicweb/server/sources/datafeed.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/sources/datafeed.py Fri Apr 05 17:58:19 2019 +0200
@@ -24,11 +24,10 @@
from os.path import exists
from datetime import datetime, timedelta
from functools import partial
-
-from six.moves.urllib.parse import urlparse
-from six.moves.urllib.request import Request, build_opener, HTTPCookieProcessor
-from six.moves.urllib.error import HTTPError
-from six.moves.http_cookiejar import CookieJar
+from http.cookiejar import CookieJar
+from urllib.parse import urlparse
+from urllib.request import Request, build_opener, HTTPCookieProcessor
+from urllib.error import HTTPError
from pytz import utc
from lxml import etree
--- a/cubicweb/server/sources/ldapfeed.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/sources/ldapfeed.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,8 +21,6 @@
from datetime import datetime
-from six import PY2, string_types
-
import ldap3
from logilab.common.configuration import merge_options
@@ -341,15 +339,13 @@
elif self.user_attrs.get(key) == 'modification_date':
itemdict[key] = datetime.strptime(value[0], '%Y%m%d%H%M%SZ')
else:
- if PY2 and value and isinstance(value[0], str):
- value = [unicode(val, 'utf-8', 'replace') for val in value]
if len(value) == 1:
itemdict[key] = value = value[0]
else:
itemdict[key] = value
# we expect memberUid to be a list of user ids, make sure of it
member = self.group_rev_attrs['member']
- if isinstance(itemdict.get(member), string_types):
+ if isinstance(itemdict.get(member), str):
itemdict[member] = [itemdict[member]]
return itemdict
--- a/cubicweb/server/sources/native.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/sources/native.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,21 +17,17 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Adapters for native cubicweb sources."""
-from __future__ import print_function
-
from threading import Lock
from datetime import datetime
from contextlib import contextmanager
from os.path import basename
+import pickle
import re
import itertools
import zipfile
import logging
import sys
-from six import PY2, text_type, string_types
-from six.moves import range, cPickle as pickle, zip
-
from logilab.common.decorators import cached, clear_cache
from logilab.common.configuration import Method
from logilab.common.shellutils import getlogin, ASK
@@ -121,12 +117,11 @@
class _UndoException(Exception):
"""something went wrong during undoing"""
- def __unicode__(self):
+ def __str__(self):
"""Called by the unicode builtin; should return a Unicode object
Type of _UndoException message must be `unicode` by design in CubicWeb.
"""
- assert isinstance(self.args[0], text_type)
return self.args[0]
@@ -526,7 +521,7 @@
sql, qargs, cbs = self._rql_sqlgen.generate(union, args)
self._cache[cachekey] = sql, qargs, cbs
args = self.merge_args(args, qargs)
- assert isinstance(sql, string_types), repr(sql)
+ assert isinstance(sql, str), repr(sql)
cursor = cnx.system_sql(sql, args)
results = self.process_result(cursor, cnx, cbs)
assert dbg_results(results)
@@ -581,7 +576,7 @@
self.doexec(cnx, sql, attrs)
if cnx.ertype_supports_undo(entity.cw_etype):
self._record_tx_action(cnx, 'tx_entity_actions', u'C',
- etype=text_type(entity.cw_etype), eid=entity.eid)
+ etype=entity.cw_etype, eid=entity.eid)
def update_entity(self, cnx, entity):
"""replace an entity in the source"""
@@ -590,7 +585,7 @@
if cnx.ertype_supports_undo(entity.cw_etype):
changes = self._save_attrs(cnx, entity, attrs)
self._record_tx_action(cnx, 'tx_entity_actions', u'U',
- etype=text_type(entity.cw_etype), eid=entity.eid,
+ etype=entity.cw_etype, eid=entity.eid,
changes=self._binary(pickle.dumps(changes)))
sql = self.sqlgen.update(SQL_PREFIX + entity.cw_etype, attrs,
['cw_eid'])
@@ -605,7 +600,7 @@
if (r.final or r.inlined) and r not in VIRTUAL_RTYPES]
changes = self._save_attrs(cnx, entity, attrs)
self._record_tx_action(cnx, 'tx_entity_actions', u'D',
- etype=text_type(entity.cw_etype), eid=entity.eid,
+ etype=entity.cw_etype, eid=entity.eid,
changes=self._binary(pickle.dumps(changes)))
attrs = {'cw_eid': entity.eid}
sql = self.sqlgen.delete(SQL_PREFIX + entity.cw_etype, attrs)
@@ -616,7 +611,7 @@
self._add_relations(cnx, rtype, [(subject, object)], inlined)
if cnx.ertype_supports_undo(rtype):
self._record_tx_action(cnx, 'tx_relation_actions', u'A',
- eid_from=subject, rtype=text_type(rtype), eid_to=object)
+ eid_from=subject, rtype=rtype, eid_to=object)
def add_relations(self, cnx, rtype, subj_obj_list, inlined=False):
"""add a relations to the source"""
@@ -624,7 +619,7 @@
if cnx.ertype_supports_undo(rtype):
for subject, object in subj_obj_list:
self._record_tx_action(cnx, 'tx_relation_actions', u'A',
- eid_from=subject, rtype=text_type(rtype), eid_to=object)
+ eid_from=subject, rtype=rtype, eid_to=object)
def _add_relations(self, cnx, rtype, subj_obj_list, inlined=False):
"""add a relation to the source"""
@@ -656,7 +651,7 @@
self._delete_relation(cnx, subject, rtype, object, rschema.inlined)
if cnx.ertype_supports_undo(rtype):
self._record_tx_action(cnx, 'tx_relation_actions', u'R',
- eid_from=subject, rtype=text_type(rtype), eid_to=object)
+ eid_from=subject, rtype=rtype, eid_to=object)
def _delete_relation(self, cnx, subject, rtype, object, inlined=False):
"""delete a relation from the source"""
@@ -832,7 +827,7 @@
"""add type and source info for an eid into the system table"""
assert cnx.cnxset is not None
# begin by inserting eid/type/source into the entities table
- attrs = {'type': text_type(entity.cw_etype), 'eid': entity.eid}
+ attrs = {'type': entity.cw_etype, 'eid': entity.eid}
self._handle_insert_entity_sql(cnx, self.sqlgen.insert('entities', attrs), attrs)
# insert core relations: is, is_instance_of and cw_source
@@ -907,7 +902,7 @@
# only, and with no eid specified
assert actionfilters.get('action', 'C') in 'CUD'
assert 'eid' not in actionfilters
- tearestr['etype'] = text_type(val)
+ tearestr['etype'] = val
elif key == 'eid':
# eid filter may apply to 'eid' of tx_entity_actions or to
# 'eid_from' OR 'eid_to' of tx_relation_actions
@@ -918,10 +913,10 @@
trarestr['eid_to'] = val
elif key == 'action':
if val in 'CUD':
- tearestr['txa_action'] = text_type(val)
+ tearestr['txa_action'] = val
else:
assert val in 'AR'
- trarestr['txa_action'] = text_type(val)
+ trarestr['txa_action'] = val
else:
raise AssertionError('unknow filter %s' % key)
assert trarestr or tearestr, "can't only filter on 'public'"
@@ -955,11 +950,10 @@
def tx_info(self, cnx, txuuid):
"""See :class:`cubicweb.repoapi.Connection.transaction_info`"""
- return tx.Transaction(cnx, txuuid, *self._tx_info(cnx, text_type(txuuid)))
+ return tx.Transaction(cnx, txuuid, *self._tx_info(cnx, txuuid))
def tx_actions(self, cnx, txuuid, public):
"""See :class:`cubicweb.repoapi.Connection.transaction_actions`"""
- txuuid = text_type(txuuid)
self._tx_info(cnx, txuuid)
restr = {'tx_uuid': txuuid}
if public:
@@ -1092,8 +1086,6 @@
elif eschema.destination(rtype) in ('Bytes', 'Password'):
changes[column] = self._binary(value)
edited[rtype] = Binary(value)
- elif PY2 and isinstance(value, str):
- edited[rtype] = text_type(value, cnx.encoding, 'replace')
else:
edited[rtype] = value
# This must only be done after init_entitiy_caches : defered in calling functions
@@ -1133,14 +1125,14 @@
try:
sentity, oentity, rdef = _undo_rel_info(cnx, subj, rtype, obj)
except _UndoException as ex:
- errors.append(text_type(ex))
+ errors.append(str(ex))
else:
for role, entity in (('subject', sentity),
('object', oentity)):
try:
_undo_check_relation_target(entity, rdef, role)
except _UndoException as ex:
- errors.append(text_type(ex))
+ errors.append(str(ex))
continue
if not errors:
self.repo.hm.call_hooks('before_add_relation', cnx,
@@ -1215,7 +1207,7 @@
try:
sentity, oentity, rdef = _undo_rel_info(cnx, subj, rtype, obj)
except _UndoException as ex:
- errors.append(text_type(ex))
+ errors.append(str(ex))
else:
rschema = rdef.rtype
if rschema.inlined:
--- a/cubicweb/server/sources/rql2sql.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/sources/rql2sql.py Fri Apr 05 17:58:19 2019 +0200
@@ -49,9 +49,6 @@
import threading
-from six import PY2, text_type
-from six.moves import range
-
from logilab.database import FunctionDescr, SQL_FUNCTIONS_REGISTRY
from rql import BadRQLQuery, CoercionError
@@ -1517,8 +1514,6 @@
return self.keyword_map[value]()
if constant.type == 'Substitute':
_id = value
- if PY2 and isinstance(_id, text_type):
- _id = _id.encode()
else:
_id = str(id(constant)).replace('-', '', 1)
self._query_attrs[_id] = value
--- a/cubicweb/server/sources/storages.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/sources/storages.py Fri Apr 05 17:58:19 2019 +0200
@@ -23,8 +23,6 @@
from contextlib import contextmanager
import tempfile
-from six import PY2, PY3, text_type, binary_type
-
from logilab.common import nullobject
from yams.schema import role_name
@@ -113,15 +111,8 @@
class BytesFileSystemStorage(Storage):
"""store Bytes attribute value on the file system"""
def __init__(self, defaultdir, fsencoding=_marker, wmode=0o444):
- if PY3:
- if not isinstance(defaultdir, text_type):
- raise TypeError('defaultdir must be a unicode object in python 3')
- if fsencoding is not _marker:
- raise ValueError('fsencoding is no longer supported in python 3')
- else:
- self.fsencoding = fsencoding or 'utf-8'
- if isinstance(defaultdir, text_type):
- defaultdir = defaultdir.encode(fsencoding)
+ if fsencoding is not _marker:
+ raise ValueError('fsencoding is no longer supported in python 3')
self.default_directory = defaultdir
# extra umask to use when creating file
# 0444 as in "only allow read bit in permission"
@@ -160,7 +151,7 @@
if binary is not None:
fd, fpath = self.new_fs_path(entity, attr)
# bytes storage used to store file's path
- binary_obj = Binary(fpath if PY2 else fpath.encode('utf-8'))
+ binary_obj = Binary(fpath.encode('utf-8'))
entity.cw_edited.edited_attribute(attr, binary_obj)
self._writecontent(fd, binary)
AddFileOp.get_instance(entity._cw).add_data(fpath)
@@ -204,7 +195,7 @@
entity.cw_edited.edited_attribute(attr, None)
else:
# register the new location for the file.
- binary_obj = Binary(fpath if PY2 else fpath.encode('utf-8'))
+ binary_obj = Binary(fpath.encode('utf-8'))
entity.cw_edited.edited_attribute(attr, binary_obj)
if oldpath is not None and oldpath != fpath:
# Mark the old file as useless so the file will be removed at
@@ -224,19 +215,17 @@
# available. Keeping the extension is useful for example in the case of
# PIL processing that use filename extension to detect content-type, as
# well as providing more understandable file names on the fs.
- if PY2:
- attr = attr.encode('ascii')
basename = [str(entity.eid), attr]
name = entity.cw_attr_metadata(attr, 'name')
if name is not None:
- basename.append(name.encode(self.fsencoding) if PY2 else name)
+ basename.append(name)
fd, fspath = uniquify_path(self.default_directory,
'_'.join(basename))
if fspath is None:
msg = entity._cw._('failed to uniquify path (%s, %s)') % (
self.default_directory, '_'.join(basename))
raise ValidationError(entity.eid, {role_name(attr, 'subject'): msg})
- assert isinstance(fspath, str) # bytes on py2, unicode on py3
+ assert isinstance(fspath, str)
return fd, fspath
def current_fs_path(self, entity, attr):
@@ -251,11 +240,8 @@
if rawvalue is None: # no previous value
return None
fspath = sysource._process_value(rawvalue, cu.description[0],
- binarywrap=binary_type)
- if PY3:
- fspath = fspath.decode('utf-8')
- assert isinstance(fspath, str) # bytes on py2, unicode on py3
- return fspath
+ binarywrap=bytes)
+ return fspath.decode('utf-8')
def migrate_entity(self, entity, attribute):
"""migrate an entity attribute to the storage"""
@@ -274,7 +260,7 @@
class AddFileOp(hook.DataOperationMixIn, hook.Operation):
def rollback_event(self):
for filepath in self.get_data():
- assert isinstance(filepath, str) # bytes on py2, unicode on py3
+ assert isinstance(filepath, str)
try:
unlink(filepath)
except Exception as ex:
@@ -283,7 +269,7 @@
class DeleteFileOp(hook.DataOperationMixIn, hook.Operation):
def postcommit_event(self):
for filepath in self.get_data():
- assert isinstance(filepath, str) # bytes on py2, unicode on py3
+ assert isinstance(filepath, str)
try:
unlink(filepath)
except Exception as ex:
--- a/cubicweb/server/sqlutils.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/sqlutils.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""SQL utilities functions and classes."""
-from __future__ import print_function
-
import os
import sys
import re
@@ -27,9 +25,6 @@
from logging import getLogger
from datetime import time, datetime, timedelta
-from six import string_types, text_type
-from six.moves import filter
-
from pytz import utc
from logilab import database as db, common as lgc
@@ -52,7 +47,7 @@
env = os.environ.copy()
for key, value in (extra_env or {}).items():
env.setdefault(key, value)
- if isinstance(cmd, string_types):
+ if isinstance(cmd, str):
print(cmd)
return subprocess.call(cmd, shell=True, env=env)
else:
@@ -81,7 +76,7 @@
else:
execute = cursor_or_execute
sqlstmts_as_string = False
- if isinstance(sqlstmts, string_types):
+ if isinstance(sqlstmts, str):
sqlstmts_as_string = True
sqlstmts = sqlstmts.split(delimiter)
if withpb:
@@ -475,7 +470,7 @@
for row, rowdesc in zip(rset, rset.description):
for cellindex, (value, vtype) in enumerate(zip(row, rowdesc)):
if vtype in ('TZDatetime', 'Date', 'Datetime') \
- and isinstance(value, text_type):
+ and isinstance(value, str):
found_date = True
value = value.rsplit('.', 1)[0]
try:
@@ -484,7 +479,7 @@
row[cellindex] = strptime(value, '%Y-%m-%d')
if vtype == 'TZDatetime':
row[cellindex] = row[cellindex].replace(tzinfo=utc)
- if vtype == 'Time' and isinstance(value, text_type):
+ if vtype == 'Time' and isinstance(value, str):
found_date = True
try:
row[cellindex] = strptime(value, '%H:%M:%S')
@@ -517,7 +512,7 @@
self.values.add(value)
def finalize(self):
- return ', '.join(text_type(v) for v in self.values)
+ return ', '.join(str(v) for v in self.values)
cnx.create_aggregate("GROUP_CONCAT", 1, group_concat)
--- a/cubicweb/server/ssplanner.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/ssplanner.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""plan execution of rql queries on a single source"""
-from six import text_type
-
from rql.stmts import Union, Select
from rql.nodes import Constant, Relation
@@ -55,7 +53,7 @@
value = rhs.eval(plan.args)
eschema = edef.entity.e_schema
attrtype = eschema.subjrels[rtype].objects(eschema)[0]
- if attrtype == 'Password' and isinstance(value, text_type):
+ if attrtype == 'Password' and isinstance(value, str):
value = value.encode('UTF8')
edef.edited_attribute(rtype, value)
elif str(rhs) in to_build:
--- a/cubicweb/server/test/unittest_checkintegrity.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_checkintegrity.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,15 +16,10 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
+from io import StringIO
import sys
import unittest
-from six import PY2
-if PY2:
- from StringIO import StringIO
-else:
- from io import StringIO
-
from cubicweb import devtools # noqa: E402
from cubicweb.devtools.testlib import CubicWebTC # noqa: E402
from cubicweb.server.checkintegrity import check, check_indexes, reindex_entities # noqa: E402
--- a/cubicweb/server/test/unittest_ldapsource.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_ldapsource.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
Those tests expect to have slapd, python-ldap3 and ldapscripts packages installed.
"""
-from __future__ import print_function
-
import os
import sys
import shutil
@@ -31,9 +29,6 @@
import unittest
from os.path import join
-from six import string_types
-from six.moves import range
-
from cubicweb import AuthenticationError, ValidationError
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.devtools.httptest import get_available_port
@@ -180,7 +175,7 @@
"""
modcmd = ['dn: %s' % dn, 'changetype: add']
for key, values in mods.items():
- if isinstance(values, string_types):
+ if isinstance(values, str):
values = [values]
for value in values:
modcmd.append('%s: %s' % (key, value))
@@ -200,7 +195,7 @@
modcmd = ['dn: %s' % dn, 'changetype: modify']
for (kind, key), values in mods.items():
modcmd.append('%s: %s' % (kind, key))
- if isinstance(values, string_types):
+ if isinstance(values, str):
values = [values]
for value in values:
modcmd.append('%s: %s' % (key, value))
--- a/cubicweb/server/test/unittest_migractions.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_migractions.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,6 +22,7 @@
import sys
from datetime import date
from contextlib import contextmanager
+from tempfile import TemporaryDirectory
from logilab.common import tempattr
@@ -30,7 +31,7 @@
from cubicweb import (ConfigurationError, ValidationError,
ExecutionError, Binary)
from cubicweb.devtools import startpgcluster, stoppgcluster
-from cubicweb.devtools.testlib import CubicWebTC, TemporaryDirectory
+from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.schema import constraint_name_for
from cubicweb.server.sqlutils import SQL_PREFIX
from cubicweb.server.migractions import ServerMigrationHelper
--- a/cubicweb/server/test/unittest_postgres.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_postgres.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,8 +19,6 @@
from datetime import datetime
from threading import Thread
-from six.moves import range
-
import logilab.database as lgdb
from cubicweb import ValidationError
from cubicweb.devtools import PostgresApptestConfiguration, startpgcluster, stoppgcluster
--- a/cubicweb/server/test/unittest_querier.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_querier.py Fri Apr 05 17:58:19 2019 +0200
@@ -25,8 +25,6 @@
import pytz
-from six import PY2, integer_types, binary_type, text_type
-
from rql import BadRQLQuery
from rql.utils import register_function, FunctionDescr
@@ -134,8 +132,8 @@
def assertRQLEqual(self, expected, got):
from rql import parse
- self.assertMultiLineEqual(text_type(parse(expected)),
- text_type(parse(got)))
+ self.assertMultiLineEqual(str(parse(expected)),
+ str(parse(got)))
def test_preprocess_security(self):
with self.user_groups_session('users') as cnx:
@@ -265,9 +263,6 @@
self.assertEqual(rset.description[0][0], 'Datetime')
rset = self.qexecute('Any %(x)s', {'x': 1})
self.assertEqual(rset.description[0][0], 'Int')
- if PY2:
- rset = self.qexecute('Any %(x)s', {'x': long(1)})
- self.assertEqual(rset.description[0][0], 'Int')
rset = self.qexecute('Any %(x)s', {'x': True})
self.assertEqual(rset.description[0][0], 'Boolean')
rset = self.qexecute('Any %(x)s', {'x': 1.0})
@@ -327,7 +322,7 @@
def test_typed_eid(self):
# should return an empty result set
rset = self.qexecute('Any X WHERE X eid %(x)s', {'x': '1'})
- self.assertIsInstance(rset[0][0], integer_types)
+ self.assertIsInstance(rset[0][0], int)
def test_bytes_storage(self):
feid = self.qexecute('INSERT File X: X data_name "foo.pdf", '
@@ -903,14 +898,14 @@
rset = self.qexecute('Any X, "toto" ORDERBY X WHERE X is CWGroup')
self.assertEqual(rset.rows,
[list(x) for x in zip((2,3,4,5), ('toto','toto','toto','toto',))])
- self.assertIsInstance(rset[0][1], text_type)
+ self.assertIsInstance(rset[0][1], str)
self.assertEqual(rset.description,
list(zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
('String', 'String', 'String', 'String',))))
rset = self.qexecute('Any X, %(value)s ORDERBY X WHERE X is CWGroup', {'value': 'toto'})
self.assertEqual(rset.rows,
list(map(list, zip((2,3,4,5), ('toto','toto','toto','toto',)))))
- self.assertIsInstance(rset[0][1], text_type)
+ self.assertIsInstance(rset[0][1], str)
self.assertEqual(rset.description,
list(zip(('CWGroup', 'CWGroup', 'CWGroup', 'CWGroup'),
('String', 'String', 'String', 'String',))))
@@ -1073,10 +1068,10 @@
def test_insert_4ter(self):
peid = self.qexecute("INSERT Personne X: X nom 'bidule'")[0][0]
seid = self.qexecute("INSERT Societe Y: Y nom 'toto', X travaille Y WHERE X eid %(x)s",
- {'x': text_type(peid)})[0][0]
+ {'x': str(peid)})[0][0]
self.assertEqual(len(self.qexecute('Any X, Y WHERE X travaille Y')), 1)
self.qexecute("INSERT Personne X: X nom 'chouette', X travaille Y WHERE Y eid %(x)s",
- {'x': text_type(seid)})
+ {'x': str(seid)})
self.assertEqual(len(self.qexecute('Any X, Y WHERE X travaille Y')), 2)
def test_insert_5(self):
@@ -1282,7 +1277,7 @@
rset = self.qexecute("INSERT Personne X, Societe Y: X nom 'bidule', Y nom 'toto'")
eid1, eid2 = rset[0][0], rset[0][1]
self.qexecute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s",
- {'x': text_type(eid1), 'y': text_type(eid2)})
+ {'x': str(eid1), 'y': str(eid2)})
rset = self.qexecute('Any X, Y WHERE X travaille Y')
self.assertEqual(len(rset.rows), 1)
@@ -1332,7 +1327,7 @@
eid1, eid2 = rset[0][0], rset[0][1]
rset = self.qexecute("SET X travaille Y WHERE X eid %(x)s, Y eid %(y)s, "
"NOT EXISTS(Z ecrit_par X)",
- {'x': text_type(eid1), 'y': text_type(eid2)})
+ {'x': str(eid1), 'y': str(eid2)})
self.assertEqual(tuplify(rset.rows), [(eid1, eid2)])
def test_update_query_error(self):
@@ -1379,7 +1374,7 @@
cursor = cnx.cnxset.cu
cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
% (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
- passwd = binary_type(cursor.fetchone()[0])
+ passwd = bytes(cursor.fetchone()[0])
self.assertEqual(passwd, crypt_password('toto', passwd))
rset = self.qexecute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
{'pwd': Binary(passwd)})
@@ -1396,7 +1391,7 @@
cursor = cnx.cnxset.cu
cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'"
% (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX))
- passwd = binary_type(cursor.fetchone()[0])
+ passwd = bytes(cursor.fetchone()[0])
self.assertEqual(passwd, crypt_password('tutu', passwd))
rset = cnx.execute("Any X WHERE X is CWUser, X login 'bob', X upassword %(pwd)s",
{'pwd': Binary(passwd)})
--- a/cubicweb/server/test/unittest_repository.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_repository.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,8 +22,6 @@
import logging
import unittest
-from six.moves import range
-
from yams.constraints import UniqueConstraint
from yams import register_base_type, unregister_base_type
--- a/cubicweb/server/test/unittest_rql2sql.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_rql2sql.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""unit tests for module cubicweb.server.sources.rql2sql"""
-from __future__ import print_function
import sys
import unittest
--- a/cubicweb/server/test/unittest_security.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_security.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""functional tests for server'security"""
-from six.moves import range
-
from logilab.common.testlib import unittest_main
from cubicweb.devtools.testlib import CubicWebTC
--- a/cubicweb/server/test/unittest_storage.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_storage.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""unit tests for module cubicweb.server.sources.storages"""
-from six import PY2
-
from logilab.common.testlib import unittest_main, tag, Tags
from cubicweb.devtools.testlib import CubicWebTC
@@ -79,7 +77,7 @@
def fspath(self, cnx, entity):
fspath = cnx.execute('Any fspath(D) WHERE F eid %(f)s, F data D',
{'f': entity.eid})[0][0].getvalue()
- return fspath if PY2 else fspath.decode('utf-8')
+ return fspath.decode('utf-8')
def test_bfss_wrong_fspath_usage(self):
with self.admin_access.repo_cnx() as cnx:
--- a/cubicweb/server/test/unittest_undo.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_undo.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-from six import text_type
-
from cubicweb import ValidationError
from cubicweb.devtools.testlib import CubicWebTC
from cubicweb.server.session import Connection
@@ -254,7 +252,7 @@
"%s doesn't exist anymore." % g.eid])
with self.assertRaises(ValidationError) as cm:
cnx.commit()
- cm.exception.translate(text_type)
+ cm.exception.translate(str)
self.assertEqual(cm.exception.entity, self.totoeid)
self.assertEqual(cm.exception.errors,
{'in_group-subject': u'at least one relation in_group is '
@@ -458,9 +456,9 @@
class UndoExceptionInUnicode(CubicWebTC):
# problem occurs in string manipulation for python < 2.6
- def test___unicode__method(self):
+ def test___str__method(self):
u = _UndoException(u"voilà ")
- self.assertIsInstance(text_type(u), text_type)
+ self.assertIsInstance(str(u), str)
if __name__ == '__main__':
--- a/cubicweb/server/test/unittest_utils.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/test/unittest_utils.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,6 +17,8 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Tests for cubicweb.server.utils module."""
+import sched
+
from cubicweb.devtools import testlib
from cubicweb.server import utils
@@ -40,7 +42,7 @@
self.assertEqual(utils.crypt_password('yyy', ''), '')
def test_schedule_periodic_task(self):
- scheduler = utils.scheduler()
+ scheduler = sched.scheduler()
this = []
def fill_this(x):
--- a/cubicweb/server/utils.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/server/utils.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,19 +16,12 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""Some utilities for the CubicWeb server."""
-from __future__ import print_function
-
from functools import wraps
-import sched
-import sys
import logging
from threading import Thread
from getpass import getpass
-from six import PY2, text_type
-from six.moves import input
-
from passlib.utils import handlers as uh, to_hash_str
from passlib.context import CryptContext
@@ -92,8 +85,6 @@
print(msg)
while not user:
user = input('login: ')
- if PY2:
- user = text_type(user, sys.stdin.encoding)
passwd = getpass('%s: ' % passwdmsg)
if confirm:
while True:
@@ -106,22 +97,6 @@
return user, passwd
-if PY2:
- import time # noqa
-
- class scheduler(sched.scheduler):
- """Python2 version of sched.scheduler that matches Python3 API."""
-
- def __init__(self, **kwargs):
- kwargs.setdefault('timefunc', time.time)
- kwargs.setdefault('delayfunc', time.sleep)
- # sched.scheduler is an old-style class.
- sched.scheduler.__init__(self, **kwargs)
-
-else:
- scheduler = sched.scheduler
-
-
def schedule_periodic_task(scheduler, interval, func, *args):
"""Enter a task with `func(*args)` as a periodic event in `scheduler`
executing at `interval` seconds. Once executed, the task would re-schedule
--- a/cubicweb/skeleton/cubicweb_CUBENAME/__pkginfo__.py.tmpl Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/skeleton/cubicweb_CUBENAME/__pkginfo__.py.tmpl Fri Apr 05 17:58:19 2019 +0200
@@ -20,6 +20,6 @@
classifiers = [
'Environment :: Web Environment',
'Framework :: CubicWeb',
- 'Programming Language :: Python',
+ 'Programming Language :: Python :: 3',
'Programming Language :: JavaScript',
]
--- a/cubicweb/sobjects/ldapparser.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/sobjects/ldapparser.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
unlike ldapuser source, this source is copy based and will import ldap content
(beside passwords for authentication) into the system source.
"""
-from six.moves import map, filter
-
from logilab.common.decorators import cached, cachedproperty
from logilab.common.shellutils import generate_password
--- a/cubicweb/sobjects/notification.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/sobjects/notification.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,8 +22,6 @@
from itertools import repeat
-from six import text_type
-
from logilab.common.textutils import normalize_text
from logilab.common.registry import yes
@@ -179,7 +177,7 @@
def context(self, **kwargs):
entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)
for key, val in kwargs.items():
- if val and isinstance(val, text_type) and val.strip():
+ if val and isinstance(val, str) and val.strip():
kwargs[key] = self._cw._(val)
kwargs.update({'user': self.user_data['login'],
'eid': entity.eid,
@@ -252,7 +250,7 @@
def format_value(value):
- if isinstance(value, text_type):
+ if isinstance(value, str):
return u'"%s"' % value
return value
--- a/cubicweb/sobjects/services.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/sobjects/services.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,8 +19,6 @@
import threading
-from six import text_type
-
from cubicweb.server import Service
from cubicweb.predicates import match_user_groups, match_kwargs
@@ -111,7 +109,7 @@
def call(self, login, password, email=None, groups=None, **cwuserkwargs):
cnx = self._cw
- if isinstance(password, text_type):
+ if isinstance(password, str):
# password should *always* be utf8 encoded
password = password.encode('UTF8')
cwuserkwargs['login'] = login
--- a/cubicweb/test/unittest_binary.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/test/unittest_binary.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
import os.path as osp
import pickle
-from six import PY2
-
from logilab.common.shellutils import tempdir
from cubicweb import Binary
@@ -32,10 +30,7 @@
Binary()
Binary(b'toto')
Binary(bytearray(b'toto'))
- if PY2:
- Binary(buffer('toto')) # noqa: F821
- else:
- Binary(memoryview(b'toto'))
+ Binary(memoryview(b'toto'))
with self.assertRaises((AssertionError, TypeError)):
# TypeError is raised by BytesIO if python runs with -O
Binary(u'toto')
@@ -44,10 +39,7 @@
b = Binary()
b.write(b'toto')
b.write(bytearray(b'toto'))
- if PY2:
- b.write(buffer('toto')) # noqa: F821
- else:
- b.write(memoryview(b'toto'))
+ b.write(memoryview(b'toto'))
with self.assertRaises((AssertionError, TypeError)):
# TypeError is raised by BytesIO if python runs with -O
b.write(u'toto')
--- a/cubicweb/test/unittest_cwconfig.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/test/unittest_cwconfig.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,22 +18,21 @@
"""cubicweb.cwconfig unit tests"""
import contextlib
-import compileall
import functools
import sys
import os
import pkgutil
from os.path import dirname, join
from pkg_resources import EntryPoint, Distribution
+from tempfile import TemporaryDirectory
import unittest
from mock import patch
-from six import PY3
from logilab.common.modutils import cleanup_sys_modules
from cubicweb.devtools import ApptestConfiguration
-from cubicweb.devtools.testlib import BaseTestCase, TemporaryDirectory
+from cubicweb.devtools.testlib import BaseTestCase
from cubicweb.cwconfig import (
CubicWebConfiguration, _expand_modname)
@@ -268,13 +267,6 @@
join(tempdir, 'b', 'c.py'),
join(tempdir, 'b', 'd', '__init__.py'),
):
- if not PY3:
- # ensure pyc file exists.
- # Doesn't required for PY3 since it create __pycache__
- # directory and will not import if source file doesn't
- # exists.
- compileall.compile_file(source, force=True)
- self.assertTrue(os.path.exists(source + 'c'))
# remove source file
os.remove(source)
self.assertEqual(list(_expand_modname('lib.c')), [])
--- a/cubicweb/test/unittest_cwctl.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/test/unittest_cwctl.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,11 +18,9 @@
import sys
import os
from os.path import join
-from io import StringIO, BytesIO
+from io import StringIO
import unittest
-from six import PY2
-
from mock import patch
from cubicweb.cwctl import ListCommand
@@ -38,7 +36,7 @@
tearDownClass = unittest_cwconfig.CubicWebConfigurationTC.tearDownClass
def setUp(self):
- self.stream = BytesIO() if PY2 else StringIO()
+ self.stream = StringIO()
sys.stdout = self.stream
def tearDown(self):
--- a/cubicweb/test/unittest_entity.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/test/unittest_entity.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from datetime import datetime
-from six import text_type
-
from logilab.common import tempattr
from logilab.common.decorators import clear_cache
@@ -800,11 +798,11 @@
# ambiguity test
person2 = req.create_entity('Personne', prenom=u'remi', nom=u'doe')
person.cw_clear_all_caches()
- self.assertEqual(person.rest_path(), text_type(person.eid))
- self.assertEqual(person2.rest_path(), text_type(person2.eid))
+ self.assertEqual(person.rest_path(), str(person.eid))
+ self.assertEqual(person2.rest_path(), str(person2.eid))
# unique attr with None value (nom in this case)
friend = req.create_entity('Ami', prenom=u'bob')
- self.assertEqual(friend.rest_path(), text_type(friend.eid))
+ self.assertEqual(friend.rest_path(), str(friend.eid))
# 'ref' below is created without the unique but not required
# attribute, make sur that the unique _and_ required 'ean' is used
# as the rest attribute
--- a/cubicweb/test/unittest_predicates.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/test/unittest_predicates.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from operator import eq, lt, le, gt
from contextlib import contextmanager
-from six.moves import range
-
from logilab.common.testlib import TestCase, unittest_main
from logilab.common.decorators import clear_cache
--- a/cubicweb/test/unittest_rqlrewrite.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/test/unittest_rqlrewrite.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,8 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-from six import string_types
-
from logilab.common.testlib import mock_object
from logilab.common.decorators import monkeypatch
from yams import BadSchemaDefinition
@@ -88,7 +86,7 @@
snippet_varmap[snippet].update(varmap)
continue
snippet_varmap[snippet] = varmap
- if isinstance(snippet, string_types):
+ if isinstance(snippet, str):
snippet = mock_object(snippet_rqlst=parse(u'Any X WHERE ' + snippet).children[0],
expression=u'Any X WHERE ' + snippet)
rqlexprs.append(snippet)
--- a/cubicweb/test/unittest_rset.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/test/unittest_rset.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,9 +18,8 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""unit tests for module cubicweb.rset"""
-from six import string_types
-from six.moves import cPickle as pickle
-from six.moves.urllib.parse import urlsplit
+import pickle
+from urllib.parse import urlsplit
from rql import parse
@@ -655,17 +654,17 @@
def test_str(self):
with self.admin_access.web_request() as req:
rset = req.execute('(Any X,N WHERE X is CWGroup, X name N)')
- self.assertIsInstance(str(rset), string_types)
+ self.assertIsInstance(str(rset), str)
self.assertEqual(len(str(rset).splitlines()), 1)
def test_repr(self):
with self.admin_access.web_request() as req:
rset = req.execute('(Any X,N WHERE X is CWGroup, X name N)')
- self.assertIsInstance(repr(rset), string_types)
+ self.assertIsInstance(repr(rset), str)
self.assertTrue(len(repr(rset).splitlines()) > 1)
rset = req.execute('(Any X WHERE X is CWGroup, X name "managers")')
- self.assertIsInstance(str(rset), string_types)
+ self.assertIsInstance(str(rset), str)
self.assertEqual(len(str(rset).splitlines()), 1)
def test_slice(self):
--- a/cubicweb/test/unittest_uilib.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/test/unittest_uilib.py Fri Apr 05 17:58:19 2019 +0200
@@ -23,11 +23,7 @@
import doctest
import pkg_resources
-
-try:
- from unittest import skipIf
-except ImportError:
- from unittest2 import skipIf
+from unittest import skipIf
from logilab.common.testlib import TestCase, unittest_main
--- a/cubicweb/test/unittest_utils.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/test/unittest_utils.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,13 +22,7 @@
import decimal
import doctest
import re
-try:
- from unittest2 import TestCase
-except ImportError: # Python3
- from unittest import TestCase
-
-from six import PY2
-from six.moves import range
+from unittest import TestCase
from cubicweb import Binary, Unauthorized
from cubicweb.devtools.testlib import CubicWebTC
@@ -419,9 +413,6 @@
def test_str(self):
self._test(str)
- if PY2:
- def test_unicode(self):
- self._test(unicode)
def load_tests(loader, tests, ignore):
--- a/cubicweb/toolsutils.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/toolsutils.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,8 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""some utilities for cubicweb command line tools"""
-from __future__ import print_function
-
# XXX move most of this in logilab.common (shellutils ?)
@@ -39,8 +37,6 @@
def symlink(*args):
raise NotImplementedError
-from six import add_metaclass
-
from logilab.common.clcommands import Command as BaseCommand
from logilab.common.shellutils import ASK
@@ -239,8 +235,7 @@
return cls
-@add_metaclass(metacmdhandler)
-class CommandHandler(object):
+class CommandHandler(object, metaclass=metacmdhandler):
"""configuration specific helper for cubicweb-ctl commands"""
def __init__(self, config):
--- a/cubicweb/uilib.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/uilib.py Fri Apr 05 17:58:19 2019 +0200
@@ -28,8 +28,6 @@
import re
from io import StringIO
-from six import PY2, PY3, text_type, binary_type, string_types, integer_types
-
from logilab.mtconverter import xml_escape, html_unescape
from logilab.common.date import ustrftime
@@ -64,7 +62,7 @@
return value
def print_int(value, req, props, displaytime=True):
- return text_type(value)
+ return str(value)
def print_date(value, req, props, displaytime=True):
return ustrftime(value, req.property_value('ui.date-format'))
@@ -94,7 +92,7 @@
_('%d seconds')
def print_timedelta(value, req, props, displaytime=True):
- if isinstance(value, integer_types):
+ if isinstance(value, int):
# `date - date`, unlike `datetime - datetime` gives an int
# (number of days), not a timedelta
# XXX should rql be fixed to return Int instead of Interval in
@@ -124,7 +122,7 @@
return req._('no')
def print_float(value, req, props, displaytime=True):
- return text_type(req.property_value('ui.float-format') % value) # XXX cast needed ?
+ return str(req.property_value('ui.float-format') % value) # XXX cast needed ?
PRINTERS = {
'Bytes': print_bytes,
@@ -332,11 +330,10 @@
def __init__(self, id, parent=None):
self.id = id
self.parent = parent
- def __unicode__(self):
+ def __str__(self):
if self.parent:
return u'%s.%s' % (self.parent, self.id)
- return text_type(self.id)
- __str__ = __unicode__ if PY3 else lambda self: self.__unicode__().encode('utf-8')
+ return str(self.id)
def __getattr__(self, attr):
return _JSId(attr, self)
def __call__(self, *args):
@@ -347,14 +344,13 @@
assert isinstance(args, tuple)
self.args = args
self.parent = parent
- def __unicode__(self):
+ def __str__(self):
args = []
for arg in self.args:
args.append(js_dumps(arg))
if self.parent:
return u'%s(%s)' % (self.parent, ','.join(args))
return ','.join(args)
- __str__ = __unicode__ if PY3 else lambda self: self.__unicode__().encode('utf-8')
class _JS(object):
def __getattr__(self, attr):
@@ -387,7 +383,7 @@
'img', 'area', 'input', 'col'))
def sgml_attributes(attrs):
- return u' '.join(u'%s="%s"' % (attr, xml_escape(text_type(value)))
+ return u' '.join(u'%s="%s"' % (attr, xml_escape(str(value)))
for attr, value in sorted(attrs.items())
if value is not None)
@@ -405,7 +401,7 @@
value += u' ' + sgml_attributes(attrs)
if content:
if escapecontent:
- content = xml_escape(text_type(content))
+ content = xml_escape(str(content))
value += u'>%s</%s>' % (content, tag)
else:
if tag in HTML4_EMPTY_TAGS:
@@ -434,7 +430,7 @@
stream = StringIO() #UStringIO() don't want unicode assertion
formater.format(layout, stream)
res = stream.getvalue()
- if isinstance(res, binary_type):
+ if isinstance(res, bytes):
res = res.decode('UTF8')
return res
@@ -443,16 +439,7 @@
import traceback
def exc_message(ex, encoding):
- if PY3:
- excmsg = str(ex)
- else:
- try:
- excmsg = unicode(ex)
- except Exception:
- try:
- excmsg = unicode(str(ex), encoding, 'replace')
- except Exception:
- excmsg = unicode(repr(ex), encoding, 'replace')
+ excmsg = str(ex)
exctype = ex.__class__.__name__
return u'%s: %s' % (exctype, excmsg)
@@ -464,8 +451,6 @@
res.append(u'\tFile %s, line %s, function %s' % tuple(stackentry[:3]))
if stackentry[3]:
data = xml_escape(stackentry[3])
- if PY2:
- data = data.decode('utf-8', 'replace')
res.append(u'\t %s' % data)
res.append(u'\n')
try:
@@ -501,8 +486,6 @@
xml_escape(stackentry[0]), stackentry[1], xml_escape(stackentry[2])))
if stackentry[3]:
string = xml_escape(stackentry[3])
- if PY2:
- string = string.decode('utf-8', 'replace')
strings.append(u'  %s<br/>\n' % (string))
# add locals info for each entry
try:
@@ -545,16 +528,8 @@
self.wfunc(data)
def writerow(self, row):
- if PY3:
- self.writer.writerow(row)
- return
- csvrow = []
- for elt in row:
- if isinstance(elt, text_type):
- csvrow.append(elt.encode(self.encoding))
- else:
- csvrow.append(str(elt))
- self.writer.writerow(csvrow)
+ self.writer.writerow(row)
+ return
def writerows(self, rows):
for row in rows:
@@ -570,7 +545,7 @@
def __call__(self, function):
def newfunc(*args, **kwargs):
ret = function(*args, **kwargs)
- if isinstance(ret, string_types):
+ if isinstance(ret, str):
return ret[:self.maxsize]
return ret
return newfunc
@@ -579,6 +554,6 @@
def htmlescape(function):
def newfunc(*args, **kwargs):
ret = function(*args, **kwargs)
- assert isinstance(ret, string_types)
+ assert isinstance(ret, str)
return xml_escape(ret)
return newfunc
--- a/cubicweb/utils.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/utils.py Fri Apr 05 17:58:19 2019 +0200
@@ -25,21 +25,13 @@
import random
import re
import json
-
-from six import PY3
-
from operator import itemgetter
-if PY3:
- from inspect import getfullargspec as getargspec
-else:
- from inspect import getargspec
+from inspect import getfullargspec as getargspec
from itertools import repeat
from uuid import uuid4
from threading import Lock
from logging import getLogger
-from six import text_type
-
from logilab.mtconverter import xml_escape
from logilab.common.date import ustrftime
@@ -106,7 +98,7 @@
"""
def __init__(self, w, tag, closetag=None):
self.written = False
- self.tag = text_type(tag)
+ self.tag = tag
self.closetag = closetag
self.w = w
@@ -122,7 +114,7 @@
def __exit__(self, exctype, value, traceback):
if self.written is True:
if self.closetag:
- self.w(text_type(self.closetag))
+ self.w(self.closetag)
else:
self.w(self.tag.replace('<', '</', 1))
@@ -204,8 +196,6 @@
__nonzero__ = __bool__
def write(self, value):
- assert isinstance(value, text_type), u"unicode required not %s : %s"\
- % (type(value).__name__, repr(value))
if self.tracewrites:
from traceback import format_stack
stack = format_stack(None)[:-1]
--- a/cubicweb/view.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/view.py Fri Apr 05 17:58:19 2019 +0200
@@ -24,8 +24,6 @@
from warnings import warn
from functools import partial
-from six.moves import range
-
from logilab.common.registry import yes
from logilab.mtconverter import xml_escape
--- a/cubicweb/web/__init__.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/__init__.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,11 +19,9 @@
publisher to get a full CubicWeb web application
"""
+from urllib.parse import quote as urlquote
from cubicweb import _
-
-from six.moves.urllib.parse import quote as urlquote
-
from cubicweb.web._exceptions import *
from cubicweb.utils import json_dumps
from cubicweb.uilib import eid_param
--- a/cubicweb/web/_exceptions.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/_exceptions.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,9 +18,7 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""exceptions used in the core of the CubicWeb web application"""
-
-
-from six.moves import http_client
+import http.client as http_client
from cubicweb._exceptions import *
from cubicweb.utils import json_dumps
--- a/cubicweb/web/application.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/application.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,14 +19,12 @@
import contextlib
+import http.client as http_client
import json
import sys
from time import clock, time
from contextlib import contextmanager
-from six import text_type, binary_type
-from six.moves import http_client
-
from rql import BadRQLQuery
from cubicweb import set_log_methods
@@ -316,7 +314,7 @@
# XXX ensure we don't actually serve content
if not content:
content = self.need_login_content(req)
- assert isinstance(content, binary_type)
+ assert isinstance(content, bytes)
return content
def core_handle(self, req):
@@ -481,7 +479,7 @@
if req.status_out < 400:
# don't overwrite it if it's already set
req.status_out = status
- json_dumper = getattr(ex, 'dumps', lambda: json.dumps({'reason': text_type(ex)}))
+ json_dumper = getattr(ex, 'dumps', lambda: json.dumps({'reason': str(ex)}))
return json_dumper().encode('utf-8')
# special case handling
--- a/cubicweb/web/box.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/box.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from cubicweb import _
-from six import add_metaclass
-
from logilab.mtconverter import xml_escape
from logilab.common.deprecation import class_deprecated
@@ -58,8 +56,7 @@
# old box system, deprecated ###################################################
-@add_metaclass(class_deprecated)
-class BoxTemplate(View):
+class BoxTemplate(View, metaclass=class_deprecated):
"""base template for boxes, usually a (contextual) list of possible
actions. Various classes attributes may be used to control the box
rendering.
--- a/cubicweb/web/captcha.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/captcha.py Fri Apr 05 17:58:19 2019 +0200
@@ -24,8 +24,6 @@
from random import randint, choice
from io import BytesIO
-from six.moves import range
-
from PIL import Image, ImageFont, ImageDraw, ImageFilter
--- a/cubicweb/web/component.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/component.py Fri Apr 05 17:58:19 2019 +0200
@@ -24,8 +24,6 @@
from warnings import warn
-from six import PY3, add_metaclass, text_type
-
from logilab.common.deprecation import class_deprecated, class_renamed, deprecated
from logilab.mtconverter import xml_escape
@@ -239,12 +237,9 @@
self.label = label
self.attrs = attrs
- def __unicode__(self):
+ def __str__(self):
return tags.a(self.label, href=self.href, **self.attrs)
- if PY3:
- __str__ = __unicode__
-
def render(self, w):
w(tags.a(self.label, href=self.href, **self.attrs))
@@ -455,7 +450,7 @@
@property
def domid(self):
- return domid(self.__regid__) + text_type(self.entity.eid)
+ return domid(self.__regid__) + str(self.entity.eid)
def lazy_view_holder(self, w, entity, oid, registry='views'):
"""add a holder and return a URL that may be used to replace this
@@ -528,7 +523,7 @@
args['subject'],
args['object'])
return u'[<a href="javascript: %s" class="action">%s</a>] %s' % (
- xml_escape(text_type(jscall)), label, etarget.view('incontext'))
+ xml_escape(str(jscall)), label, etarget.view('incontext'))
def related_boxitems(self, entity):
return [self.box_item(entity, etarget, 'delete_relation', u'-')
@@ -545,7 +540,7 @@
"""returns the list of unrelated entities, using the entity's
appropriate vocabulary function
"""
- skip = set(text_type(e.eid) for e in entity.related(self.rtype, role(self),
+ skip = set(str(e.eid) for e in entity.related(self.rtype, role(self),
entities=True))
skip.add(None)
skip.add(INTERNAL_FIELD_VALUE)
@@ -663,7 +658,7 @@
if maydel:
if not js_css_added:
js_css_added = self.add_js_css()
- jscall = text_type(js.ajaxBoxRemoveLinkedEntity(
+ jscall = str(js.ajaxBoxRemoveLinkedEntity(
self.__regid__, entity.eid, rentity.eid,
self.fname_remove,
self.removed_msg and _(self.removed_msg)))
@@ -678,7 +673,7 @@
if mayadd:
multiple = self.rdef.role_cardinality(self.role) in '*+'
w(u'<table><tr><td>')
- jscall = text_type(js.ajaxBoxShowSelector(
+ jscall = str(js.ajaxBoxShowSelector(
self.__regid__, entity.eid, self.fname_vocabulary,
self.fname_validate, self.added_msg and _(self.added_msg),
_(stdmsgs.BUTTON_OK[0]), _(stdmsgs.BUTTON_CANCEL[0]),
@@ -707,8 +702,7 @@
# old contextual components, deprecated ########################################
-@add_metaclass(class_deprecated)
-class EntityVComponent(Component):
+class EntityVComponent(Component, metaclass=class_deprecated):
"""abstract base class for additinal components displayed in content
headers and footer according to:
--- a/cubicweb/web/controller.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/controller.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,10 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""abstract controller classe for CubicWeb web client"""
-
-
-from six import PY2
-
from logilab.mtconverter import xml_escape
from logilab.common.registry import yes
@@ -88,8 +84,6 @@
rql = req.form.get('rql')
if rql:
req.ensure_ro_rql(rql)
- if PY2 and not isinstance(rql, unicode):
- rql = unicode(rql, req.encoding)
pp = req.vreg['components'].select_or_none('magicsearch', req)
if pp is not None:
return pp.process_query(rql)
--- a/cubicweb/web/cors.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/cors.py Fri Apr 05 17:58:19 2019 +0200
@@ -29,7 +29,7 @@
"""
-from six.moves.urllib.parse import urlsplit
+from urllib.parse import urlsplit
from cubicweb.web import LOGGER
info = LOGGER.info
--- a/cubicweb/web/facet.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/facet.py Fri Apr 05 17:58:19 2019 +0200
@@ -56,8 +56,6 @@
from copy import deepcopy
from datetime import datetime, timedelta
-from six import text_type, string_types
-
from logilab.mtconverter import xml_escape
from logilab.common.graph import has_path
from logilab.common.decorators import cached, cachedproperty
@@ -645,7 +643,7 @@
insert_attr_select_relation(
select, self.filtered_variable, self.rtype, self.role,
self.target_attr, select_target_entity=False)
- values = [text_type(x) for x, in self.rqlexec(select.as_string())]
+ values = [str(x) for x, in self.rqlexec(select.as_string())]
except Exception:
self.exception('while computing values for %s', self)
return []
@@ -696,7 +694,7 @@
if self.i18nable:
tr = self._cw._
else:
- tr = text_type
+ tr = str
if self.rql_sort:
values = [(tr(label), eid) for eid, label in rset]
else:
@@ -720,7 +718,7 @@
# XXX handle rel is None case in RQLPathFacet?
if self.restr_attr != 'eid':
self.select.set_distinct(True)
- if isinstance(value, string_types):
+ if isinstance(value, str):
# only one value selected
if value:
self.select.add_constant_restriction(
@@ -884,7 +882,7 @@
if self.i18nable:
tr = self._cw._
else:
- tr = text_type
+ tr = str
if self.rql_sort:
return [(tr(value), value) for value, in rset]
values = [(tr(value), value) for value, in rset]
@@ -1037,7 +1035,7 @@
assert self.path and isinstance(self.path, (list, tuple)), \
'path should be a list of 3-uples, not %s' % self.path
for part in self.path:
- if isinstance(part, string_types):
+ if isinstance(part, str):
part = part.split()
assert len(part) == 3, \
'path should be a list of 3-uples, not %s' % part
@@ -1090,7 +1088,7 @@
cleanup_select(select, self.filtered_variable)
varmap, restrvar = self.add_path_to_select(skiplabel=True)
select.append_selected(nodes.VariableRef(restrvar))
- values = [text_type(x) for x, in self.rqlexec(select.as_string())]
+ values = [str(x) for x, in self.rqlexec(select.as_string())]
except Exception:
self.exception('while computing values for %s', self)
return []
@@ -1113,7 +1111,7 @@
varmap = {'X': self.filtered_variable}
actual_filter_variable = None
for part in self.path:
- if isinstance(part, string_types):
+ if isinstance(part, str):
part = part.split()
subject, rtype, object = part
if skiplabel and object == self.label_variable:
@@ -1217,7 +1215,7 @@
rset = self._range_rset()
if rset:
minv, maxv = rset[0]
- return [(text_type(minv), minv), (text_type(maxv), maxv)]
+ return [(str(minv), minv), (str(maxv), maxv)]
return []
def possible_values(self):
@@ -1236,7 +1234,7 @@
def formatvalue(self, value):
"""format `value` before in order to insert it in the RQL query"""
- return text_type(value)
+ return str(value)
def infvalue(self, min=False):
if min:
@@ -1337,7 +1335,7 @@
# *list* (see rqlexec implementation)
if rset:
minv, maxv = rset[0]
- return [(text_type(minv), minv), (text_type(maxv), maxv)]
+ return [(str(minv), minv), (str(maxv), maxv)]
return []
@@ -1356,7 +1354,7 @@
skiplabel=True, skipattrfilter=True)
restrel = None
for part in self.path:
- if isinstance(part, string_types):
+ if isinstance(part, str):
part = part.split()
subject, rtype, object = part
if object == self.filter_variable:
@@ -1480,7 +1478,7 @@
if not val or val & mask])
def possible_values(self):
- return [text_type(val) for label, val in self.vocabulary()]
+ return [str(val) for label, val in self.vocabulary()]
## html widets ################################################################
@@ -1559,7 +1557,7 @@
if selected:
cssclass += ' facetValueSelected'
w(u'<div class="%s" cubicweb:value="%s">\n'
- % (cssclass, xml_escape(text_type(value))))
+ % (cssclass, xml_escape(str(value))))
# If it is overflowed one must add padding to compensate for the vertical
# scrollbar; given current css values, 4 blanks work perfectly ...
padding = u' ' * self.scrollbar_padding_factor if overflow else u''
@@ -1718,7 +1716,7 @@
imgsrc = self._cw.data_url(self.unselected_img)
imgalt = self._cw._('not selected')
w(u'<div class="%s" cubicweb:value="%s">\n'
- % (cssclass, xml_escape(text_type(self.value))))
+ % (cssclass, xml_escape(str(self.value))))
w(u'<div>')
w(u'<img src="%s" alt="%s" cubicweb:unselimg="true" /> ' % (imgsrc, imgalt))
w(u'<label class="facetTitle" cubicweb:facetName="%s">%s</label>'
--- a/cubicweb/web/form.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/form.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,9 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""abstract form classes for CubicWeb web client"""
-
-from six import add_metaclass
-
from logilab.common.decorators import iclassmethod
from cubicweb.appobject import AppObject
@@ -73,8 +70,7 @@
found
"""
-@add_metaclass(metafieldsform)
-class Form(AppObject):
+class Form(AppObject, metaclass=metafieldsform):
__registry__ = 'forms'
parent_form = None
--- a/cubicweb/web/formfields.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/formfields.py Fri Apr 05 17:58:19 2019 +0200
@@ -68,8 +68,6 @@
import pytz
-from six import PY2, text_type, string_types
-
from logilab.mtconverter import xml_escape
from logilab.common import nullobject
from logilab.common.date import ustrftime
@@ -236,15 +234,9 @@
l.append('@%#x' % id(self))
return u'%s>' % ' '.join(l)
- def __unicode__(self):
+ def __str__(self):
return self.as_string(False)
- if PY2:
- def __str__(self):
- return self.as_string(False).encode('UTF8')
- else:
- __str__ = __unicode__
-
def __repr__(self):
return self.as_string(True)
@@ -290,7 +282,7 @@
return u''
if value is True:
return u'1'
- return text_type(value)
+ return str(value)
def get_widget(self, form):
"""return the widget instance associated to this field"""
@@ -825,7 +817,7 @@
def _process_form_value(self, form):
value = form._cw.form.get(self.input_name(form))
- if isinstance(value, text_type):
+ if isinstance(value, str):
# file modified using a text widget
return Binary(value.encode(self.encoding(form)))
return super(EditableFileField, self)._process_form_value(form)
@@ -852,7 +844,7 @@
self.widget.attrs.setdefault('size', self.default_text_input_size)
def _ensure_correctly_typed(self, form, value):
- if isinstance(value, string_types):
+ if isinstance(value, str):
value = value.strip()
if not value:
return None
@@ -934,7 +926,7 @@
return self.format_single_value(req, 1.234)
def _ensure_correctly_typed(self, form, value):
- if isinstance(value, string_types):
+ if isinstance(value, str):
value = value.strip()
if not value:
return None
@@ -955,8 +947,7 @@
def format_single_value(self, req, value):
if value:
- value = format_time(value.days * 24 * 3600 + value.seconds)
- return text_type(value)
+ return format_time(value.days * 24 * 3600 + value.seconds)
return u''
def example_format(self, req):
@@ -966,7 +957,7 @@
return u'20s, 10min, 24h, 4d'
def _ensure_correctly_typed(self, form, value):
- if isinstance(value, string_types):
+ if isinstance(value, str):
value = value.strip()
if not value:
return None
@@ -996,14 +987,14 @@
return self.format_single_value(req, datetime.now())
def _ensure_correctly_typed(self, form, value):
- if isinstance(value, string_types):
+ if isinstance(value, str):
value = value.strip()
if not value:
return None
try:
value = form._cw.parse_datetime(value, self.etype)
except ValueError as ex:
- raise ProcessFormError(text_type(ex))
+ raise ProcessFormError(str(ex))
return value
@@ -1107,7 +1098,7 @@
linkedto = form.linked_to.get((self.name, self.role))
if linkedto:
buildent = form._cw.entity_from_eid
- return [(buildent(eid).view('combobox'), text_type(eid))
+ return [(buildent(eid).view('combobox'), str(eid))
for eid in linkedto]
return []
@@ -1119,7 +1110,7 @@
# vocabulary doesn't include current values, add them
if form.edited_entity.has_eid():
rset = form.edited_entity.related(self.name, self.role)
- vocab += [(e.view('combobox'), text_type(e.eid))
+ vocab += [(e.view('combobox'), str(e.eid))
for e in rset.entities()]
return vocab
@@ -1153,11 +1144,11 @@
if entity.eid in done:
continue
done.add(entity.eid)
- res.append((entity.view('combobox'), text_type(entity.eid)))
+ res.append((entity.view('combobox'), str(entity.eid)))
return res
def format_single_value(self, req, value):
- return text_type(value)
+ return str(value)
def process_form_value(self, form):
"""process posted form and return correctly typed value"""
--- a/cubicweb/web/formwidgets.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/formwidgets.py Fri Apr 05 17:58:19 2019 +0200
@@ -98,8 +98,6 @@
from functools import reduce
from datetime import date
-from six import text_type, string_types
-
from logilab.mtconverter import xml_escape
from logilab.common.date import todatetime
@@ -272,7 +270,7 @@
"""
posted = form._cw.form
val = posted.get(field.input_name(form, self.suffix))
- if isinstance(val, string_types):
+ if isinstance(val, str):
val = val.strip()
return val
@@ -463,7 +461,7 @@
options.append(u'</optgroup>')
if 'size' not in attrs:
if self._multiple:
- size = text_type(min(self.default_size, len(vocab) or 1))
+ size = str(min(self.default_size, len(vocab) or 1))
else:
size = u'1'
attrs['size'] = size
@@ -727,7 +725,7 @@
else:
value = self.value
attrs = self.attributes(form, field)
- attrs.setdefault('size', text_type(self.default_size))
+ attrs.setdefault('size', str(self.default_size))
return tags.input(name=field.input_name(form, self.suffix),
value=value, type='text', **attrs)
@@ -801,7 +799,7 @@
try:
date = todatetime(req.parse_datetime(datestr, 'Date'))
except ValueError as exc:
- raise ProcessFormError(text_type(exc))
+ raise ProcessFormError(str(exc))
timestr = req.form.get(field.input_name(form, 'time'))
if timestr:
timestr = timestr.strip()
@@ -810,7 +808,7 @@
try:
time = req.parse_datetime(timestr, 'Time')
except ValueError as exc:
- raise ProcessFormError(text_type(exc))
+ raise ProcessFormError(str(exc))
return date.replace(hour=time.hour, minute=time.minute, second=time.second)
@@ -1014,12 +1012,12 @@
req = form._cw
values = {}
path = req.form.get(field.input_name(form, 'path'))
- if isinstance(path, string_types):
+ if isinstance(path, str):
path = path.strip()
if path is None:
path = u''
fqs = req.form.get(field.input_name(form, 'fqs'))
- if isinstance(fqs, string_types):
+ if isinstance(fqs, str):
fqs = fqs.strip() or None
if fqs:
for i, line in enumerate(fqs.split('\n')):
--- a/cubicweb/web/htmlwidgets.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/htmlwidgets.py Fri Apr 05 17:58:19 2019 +0200
@@ -24,9 +24,6 @@
import random
from math import floor
-from six import add_metaclass
-from six.moves import range
-
from logilab.mtconverter import xml_escape
from logilab.common.deprecation import class_deprecated
@@ -118,8 +115,7 @@
self.w(u'</div>')
-@add_metaclass(class_deprecated)
-class SideBoxWidget(BoxWidget):
+class SideBoxWidget(BoxWidget, metaclass=class_deprecated):
"""default CubicWeb's sidebox widget"""
__deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
@@ -210,8 +206,7 @@
self.w(u'</ul></div></div>')
-@add_metaclass(class_deprecated)
-class BoxField(HTMLWidget):
+class BoxField(HTMLWidget, metaclass=class_deprecated):
"""couples label / value meant to be displayed in a box"""
__deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
def __init__(self, label, value):
@@ -224,8 +219,7 @@
% (self.label, self.value))
-@add_metaclass(class_deprecated)
-class BoxSeparator(HTMLWidget):
+class BoxSeparator(HTMLWidget, metaclass=class_deprecated):
"""a menu separator"""
__deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
@@ -233,8 +227,7 @@
self.w(u'</ul><hr class="boxSeparator"/><ul>')
-@add_metaclass(class_deprecated)
-class BoxLink(HTMLWidget):
+class BoxLink(HTMLWidget, metaclass=class_deprecated):
"""a link in a box"""
__deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
def __init__(self, href, label, _class='', title='', ident='', escape=False):
@@ -256,8 +249,7 @@
self.w(u'<li class="%s">%s</li>\n' % (self._class, link))
-@add_metaclass(class_deprecated)
-class BoxHtml(HTMLWidget):
+class BoxHtml(HTMLWidget, metaclass=class_deprecated):
"""a form in a box"""
__deprecation_warning__ = '[3.10] class %(cls)s is deprecated'
def __init__(self, rawhtml):
--- a/cubicweb/web/http_headers.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/http_headers.py Fri Apr 05 17:58:19 2019 +0200
@@ -6,9 +6,7 @@
from calendar import timegm
import base64
import re
-
-from six import string_types
-from six.moves.urllib.parse import urlparse
+from urllib.parse import urlparse
def dashCapitalize(s):
@@ -383,7 +381,7 @@
def unique(seq):
'''if seq is not a string, check it's a sequence of one element and return it'''
- if isinstance(seq, string_types):
+ if isinstance(seq, str):
return seq
if len(seq) != 1:
raise ValueError('single value required, not %s' % seq)
@@ -455,10 +453,10 @@
"""
if (value in (True, 1) or
- isinstance(value, string_types) and value.lower() == 'true'):
+ isinstance(value, str) and value.lower() == 'true'):
return 'true'
if (value in (False, 0) or
- isinstance(value, string_types) and value.lower() == 'false'):
+ isinstance(value, str) and value.lower() == 'false'):
return 'false'
raise ValueError("Invalid true/false header value: %s" % value)
--- a/cubicweb/web/request.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/request.py Fri Apr 05 17:58:19 2019 +0200
@@ -23,12 +23,10 @@
from hashlib import sha1 # pylint: disable=E0611
from calendar import timegm
from datetime import date, datetime
+import http.client
from io import BytesIO
-
-from six import PY2, text_type, string_types
-from six.moves import http_client
-from six.moves.urllib.parse import urlsplit, quote as urlquote
-from six.moves.http_cookies import SimpleCookie
+from urllib.parse import urlsplit, quote as urlquote
+from http.cookies import SimpleCookie
from rql.utils import rqlvar_maker
@@ -208,12 +206,8 @@
encoding = self.encoding
for param, val in params.items():
if isinstance(val, (tuple, list)):
- if PY2:
- val = [unicode(x, encoding) for x in val]
if len(val) == 1:
val = val[0]
- elif PY2 and isinstance(val, str):
- val = unicode(val, encoding)
if param in self.no_script_form_params and val:
val = self.no_script_form_param(param, val)
if param == '_cwmsgid':
@@ -274,7 +268,7 @@
return None
def set_message(self, msg):
- assert isinstance(msg, text_type)
+ assert isinstance(msg, str)
self.reset_message()
self._msg = msg
@@ -287,7 +281,7 @@
def set_redirect_message(self, msg):
# TODO - this should probably be merged with append_to_redirect_message
- assert isinstance(msg, text_type)
+ assert isinstance(msg, str)
msgid = self.redirect_message_id()
self.session.data[msgid] = msg
return msgid
@@ -374,7 +368,7 @@
eids = form['eid']
except KeyError:
raise NothingToEdit(self._('no selected entities'))
- if isinstance(eids, string_types):
+ if isinstance(eids, str):
eids = (eids,)
for peid in eids:
if withtype:
@@ -523,7 +517,7 @@
:param localfile: if True, the default data dir prefix is added to the
JS filename
"""
- if isinstance(jsfiles, string_types):
+ if isinstance(jsfiles, str):
jsfiles = (jsfiles,)
for jsfile in jsfiles:
if localfile:
@@ -543,7 +537,7 @@
the css inclusion. cf:
http://msdn.microsoft.com/en-us/library/ms537512(VS.85).aspx
"""
- if isinstance(cssfiles, string_types):
+ if isinstance(cssfiles, str):
cssfiles = (cssfiles,)
if ieonly:
if self.ie_browser():
@@ -613,7 +607,7 @@
lang_prefix = ''
if self.lang is not None and self.vreg.config.get('language-mode') == 'url-prefix':
lang_prefix = '%s/' % self.lang
- return lang_prefix + path
+ return lang_prefix + str(path)
def url(self, includeparams=True):
"""return currently accessed url"""
@@ -666,9 +660,9 @@
# overwrite headers_out to forge a brand new not-modified response
self.headers_out = self._forge_cached_headers()
if self.http_method() in ('HEAD', 'GET'):
- self.status_out = http_client.NOT_MODIFIED
+ self.status_out = http.client.NOT_MODIFIED
else:
- self.status_out = http_client.PRECONDITION_FAILED
+ self.status_out = http.client.PRECONDITION_FAILED
# XXX replace by True once validate_cache bw compat method is dropped
return self.status_out
# XXX replace by False once validate_cache bw compat method is dropped
--- a/cubicweb/web/schemaviewer.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/schemaviewer.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from cubicweb import _
-from six import string_types
-
from logilab.common.ureports import Section, Title, Table, Link, Span, Text
from yams.schema2dot import CARD_MAP
@@ -228,7 +226,7 @@
elif isinstance(val, (list, tuple)):
val = sorted(val)
val = ', '.join(str(v) for v in val)
- elif val and isinstance(val, string_types):
+ elif val and isinstance(val, str):
val = _(val)
else:
val = str(val)
--- a/cubicweb/web/test/data/cubicweb_file/entities.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/test/data/cubicweb_file/entities.py Fri Apr 05 17:58:19 2019 +0200
@@ -1,4 +1,3 @@
-from six import text_type
from logilab.mtconverter import guess_mimetype_and_encoding
from cubicweb.entities import AnyEntity, fetch_config
@@ -42,9 +41,9 @@
format=format, encoding=encoding,
fallbackencoding=self._cw.encoding)
if format:
- self.cw_edited['data_format'] = text_type(format)
+ self.cw_edited['data_format'] = str(format)
if encoding:
- self.cw_edited['data_encoding'] = text_type(encoding)
+ self.cw_edited['data_encoding'] = str(encoding)
class UnResizeable(Exception):
--- a/cubicweb/web/test/unittest_application.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/test/unittest_application.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,10 +18,8 @@
"""unit tests for cubicweb.web.application"""
import base64
-
-from six import text_type
-from six.moves import http_client
-from six.moves.http_cookies import SimpleCookie
+import http.client
+from http.cookies import SimpleCookie
from logilab.common.testlib import TestCase, unittest_main
from logilab.common.decorators import clear_cache
@@ -167,7 +165,7 @@
def test_publish_validation_error(self):
with self.admin_access.web_request() as req:
user = req.user
- eid = text_type(user.eid)
+ eid = str(user.eid)
req.form = {
'eid': eid,
'__type:' + eid: 'CWUser',
@@ -248,8 +246,8 @@
self.config.global_set_option('language-mode', 'http-negotiation')
orig_translations = self.config.translations.copy()
self.config.translations = {
- 'fr': (text_type, lambda x, y: text_type(y)),
- 'en': (text_type, lambda x, y: text_type(y))}
+ 'fr': (str, lambda x, y: str(y)),
+ 'en': (str, lambda x, y: str(y))}
try:
headers = {'Accept-Language': 'fr'}
with self.admin_access.web_request(headers=headers) as req:
@@ -336,8 +334,8 @@
parent_eid = parent_eid or '__cubicweb_internal_field__'
with self.admin_access.web_request() as req:
req.form = {
- 'eid': text_type(dir_eid),
- '__maineid': text_type(dir_eid),
+ 'eid': str(dir_eid),
+ '__maineid': str(dir_eid),
'__type:%s' % dir_eid: etype,
'parent-%s:%s' % (role, dir_eid): parent_eid,
}
@@ -353,8 +351,8 @@
version_eid = version_eid or '__cubicweb_internal_field__'
with self.admin_access.web_request() as req:
req.form = {
- 'eid': text_type(ticket_eid),
- '__maineid': text_type(ticket_eid),
+ 'eid': str(ticket_eid),
+ '__maineid': str(ticket_eid),
'__type:%s' % ticket_eid: 'Ticket',
'in_version-subject:%s' % ticket_eid: version_eid,
}
@@ -395,8 +393,8 @@
with self.admin_access.web_request() as req:
req.form = {
- 'eid': (text_type(topd.eid), u'B'),
- '__maineid': text_type(topd.eid),
+ 'eid': (str(topd.eid), u'B'),
+ '__maineid': str(topd.eid),
'__type:%s' % topd.eid: 'Directory',
'__type:B': 'Directory',
'parent-object:%s' % topd.eid: u'B',
@@ -569,8 +567,8 @@
cnx.commit()
with self.admin_access.web_request() as req:
- dir_eid = text_type(mydir.eid)
- perm_eid = text_type(perm.eid)
+ dir_eid = str(mydir.eid)
+ perm_eid = str(perm.eid)
req.form = {
'eid': [dir_eid, perm_eid],
'__maineid': dir_eid,
@@ -596,7 +594,7 @@
with self.admin_access.web_request(vid='test.ajax.error', url='') as req:
req.ajax_request = True
app.handle_request(req)
- self.assertEqual(http_client.INTERNAL_SERVER_ERROR,
+ self.assertEqual(http.client.INTERNAL_SERVER_ERROR,
req.status_out)
def _test_cleaned(self, kwargs, injected, cleaned):
--- a/cubicweb/web/test/unittest_form.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/test/unittest_form.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,8 +19,6 @@
import time
from datetime import datetime
-from six import text_type
-
import pytz
from lxml import html
@@ -80,19 +78,19 @@
t = req.create_entity('Tag', name=u'x')
form1 = self.vreg['forms'].select('edition', req, entity=t)
choices = [reid for rview, reid in form1.field_by_name('tags', 'subject', t.e_schema).choices(form1)]
- self.assertIn(text_type(b.eid), choices)
+ self.assertIn(str(b.eid), choices)
form2 = self.vreg['forms'].select('edition', req, entity=b)
choices = [reid for rview, reid in form2.field_by_name('tags', 'object', t.e_schema).choices(form2)]
- self.assertIn(text_type(t.eid), choices)
+ self.assertIn(str(t.eid), choices)
b.cw_clear_all_caches()
t.cw_clear_all_caches()
req.cnx.execute('SET X tags Y WHERE X is Tag, Y is BlogEntry')
choices = [reid for rview, reid in form1.field_by_name('tags', 'subject', t.e_schema).choices(form1)]
- self.assertIn(text_type(b.eid), choices)
+ self.assertIn(str(b.eid), choices)
choices = [reid for rview, reid in form2.field_by_name('tags', 'object', t.e_schema).choices(form2)]
- self.assertIn(text_type(t.eid), choices)
+ self.assertIn(str(t.eid), choices)
def test_form_field_choices_new_entity(self):
with self.admin_access.web_request() as req:
--- a/cubicweb/web/test/unittest_magicsearch.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/test/unittest_magicsearch.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,8 +21,6 @@
import sys
from contextlib import contextmanager
-from six.moves import range
-
from logilab.common.testlib import TestCase, unittest_main
from rql import BadRQLQuery, RQLSyntaxError
--- a/cubicweb/web/test/unittest_request.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/test/unittest_request.py Fri Apr 05 17:58:19 2019 +0200
@@ -4,8 +4,6 @@
import unittest
from functools import partial
-from six import text_type
-
from cubicweb.devtools.fake import FakeConfig, FakeCWRegistryStore
from cubicweb.web.request import (CubicWebRequestBase, _parse_accept_header,
@@ -84,7 +82,7 @@
vreg = FakeCWRegistryStore(FakeConfig(), initlog=False)
vreg.config['base-url'] = 'http://testing.fr/cubicweb/'
vreg.config['language-mode'] = 'url-prefix'
- vreg.config.translations['fr'] = text_type, text_type
+ vreg.config.translations['fr'] = str, str
req = CubicWebRequestBase(vreg)
# Override from_controller to avoid getting into relative_path method,
# which is not implemented in CubicWebRequestBase.
--- a/cubicweb/web/test/unittest_urlrewrite.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/test/unittest_urlrewrite.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,8 +16,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-from six import text_type
-
from logilab.common import tempattr
from cubicweb.devtools.testlib import CubicWebTC
@@ -139,8 +137,8 @@
rgx_action(r'Any X WHERE X surname %(sn)s, '
'X firstname %(fn)s',
argsgroups=('sn', 'fn'),
- transforms={'sn' : text_type.capitalize,
- 'fn' : text_type.lower,})),
+ transforms={'sn' : str.capitalize,
+ 'fn' : str.lower,})),
]
with self.admin_access.web_request() as req:
rewriter = TestSchemaBasedRewriter(req)
--- a/cubicweb/web/test/unittest_views_basecontrollers.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/test/unittest_views_basecontrollers.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,9 +18,7 @@
"""cubicweb.web.views.basecontrollers unit tests"""
import time
-
-from six import text_type
-from six.moves.urllib.parse import urlsplit, urlunsplit, urljoin, parse_qs
+from urllib.parse import urlsplit, urlunsplit, urljoin, parse_qs
import lxml
@@ -92,7 +90,7 @@
}
with self.assertRaises(ValidationError) as cm:
self.ctrl_publish(req)
- cm.exception.translate(text_type)
+ cm.exception.translate(str)
expected = {
'': u'some relations violate a unicity constraint',
'login': u'login is part of violated unicity constraint',
@@ -149,12 +147,12 @@
user = req.user
groupeids = [eid for eid, in req.execute('CWGroup G WHERE G name '
'in ("managers", "users")')]
- groups = [text_type(eid) for eid in groupeids]
- eid = text_type(user.eid)
+ groups = [str(eid) for eid in groupeids]
+ eid = str(user.eid)
req.form = {
'eid': eid, '__type:'+eid: 'CWUser',
'_cw_entity_fields:'+eid: 'login-subject,firstname-subject,surname-subject,in_group-subject',
- 'login-subject:'+eid: text_type(user.login),
+ 'login-subject:'+eid: str(user.login),
'surname-subject:'+eid: u'Th\xe9nault',
'firstname-subject:'+eid: u'Sylvain',
'in_group-subject:'+eid: groups,
@@ -172,7 +170,7 @@
self.create_user(cnx, u'user')
cnx.commit()
with self.new_access(u'user').web_request() as req:
- eid = text_type(req.user.eid)
+ eid = str(req.user.eid)
req.form = {
'eid': eid, '__maineid' : eid,
'__type:'+eid: 'CWUser',
@@ -192,12 +190,12 @@
with self.admin_access.web_request() as req:
user = req.user
groupeids = [g.eid for g in user.in_group]
- eid = text_type(user.eid)
+ eid = str(user.eid)
req.form = {
'eid': eid,
'__type:'+eid: 'CWUser',
'_cw_entity_fields:'+eid: 'login-subject,firstname-subject,surname-subject',
- 'login-subject:'+eid: text_type(user.login),
+ 'login-subject:'+eid: str(user.login),
'firstname-subject:'+eid: u'Th\xe9nault',
'surname-subject:'+eid: u'Sylvain',
}
@@ -220,7 +218,7 @@
'login-subject:X': u'adim',
'upassword-subject:X': u'toto', 'upassword-subject-confirm:X': u'toto',
'surname-subject:X': u'Di Mascio',
- 'in_group-subject:X': text_type(gueid),
+ 'in_group-subject:X': str(gueid),
'__type:Y': 'EmailAddress',
'_cw_entity_fields:Y': 'address-subject,use_email-object',
@@ -287,7 +285,7 @@
# non regression test for #3120495. Without the fix, leads to
# "unhashable type: 'list'" error
with self.admin_access.web_request() as req:
- cwrelation = text_type(req.execute('CWEType X WHERE X name "CWSource"')[0][0])
+ cwrelation = str(req.execute('CWEType X WHERE X name "CWSource"')[0][0])
req.form = {'eid': [cwrelation], '__maineid' : cwrelation,
'__type:'+cwrelation: 'CWEType',
@@ -300,7 +298,7 @@
def test_edit_multiple_linked(self):
with self.admin_access.web_request() as req:
- peid = text_type(self.create_user(req, u'adim').eid)
+ peid = str(self.create_user(req, u'adim').eid)
req.form = {'eid': [peid, 'Y'], '__maineid': peid,
'__type:'+peid: u'CWUser',
@@ -320,7 +318,7 @@
self.assertEqual(email.address, 'dima@logilab.fr')
# with self.admin_access.web_request() as req:
- emaileid = text_type(email.eid)
+ emaileid = str(email.eid)
req.form = {'eid': [peid, emaileid],
'__type:'+peid: u'CWUser',
@@ -342,7 +340,7 @@
with self.admin_access.web_request() as req:
user = req.user
req.form = {'eid': 'X',
- '__cloned_eid:X': text_type(user.eid), '__type:X': 'CWUser',
+ '__cloned_eid:X': str(user.eid), '__type:X': 'CWUser',
'_cw_entity_fields:X': 'login-subject,upassword-subject',
'login-subject:X': u'toto',
'upassword-subject:X': u'toto',
@@ -351,7 +349,7 @@
self.ctrl_publish(req)
self.assertEqual({'upassword-subject': u'password and confirmation don\'t match'},
cm.exception.errors)
- req.form = {'__cloned_eid:X': text_type(user.eid),
+ req.form = {'__cloned_eid:X': str(user.eid),
'eid': 'X', '__type:X': 'CWUser',
'_cw_entity_fields:X': 'login-subject,upassword-subject',
'login-subject:X': u'toto',
@@ -375,11 +373,11 @@
'__type:X': 'Salesterm',
'_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
'amount-subject:X': u'-10',
- 'described_by_test-subject:X': text_type(feid),
+ 'described_by_test-subject:X': str(feid),
}
with self.assertRaises(ValidationError) as cm:
self.ctrl_publish(req)
- cm.exception.translate(text_type)
+ cm.exception.translate(str)
self.assertEqual({'amount-subject': 'value -10 must be >= 0'},
cm.exception.errors)
@@ -388,11 +386,11 @@
'__type:X': 'Salesterm',
'_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
'amount-subject:X': u'110',
- 'described_by_test-subject:X': text_type(feid),
+ 'described_by_test-subject:X': str(feid),
}
with self.assertRaises(ValidationError) as cm:
self.ctrl_publish(req)
- cm.exception.translate(text_type)
+ cm.exception.translate(str)
self.assertEqual(cm.exception.errors, {'amount-subject': 'value 110 must be <= 100'})
with self.admin_access.web_request(rollbackfirst=True) as req:
@@ -400,7 +398,7 @@
'__type:X': 'Salesterm',
'_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
'amount-subject:X': u'10',
- 'described_by_test-subject:X': text_type(feid),
+ 'described_by_test-subject:X': str(feid),
}
self.expect_redirect_handle_request(req, 'edit')
# should be redirected on the created
@@ -419,7 +417,7 @@
# ensure a value that violate a constraint is properly detected
with self.admin_access.web_request(rollbackfirst=True) as req:
- req.form = {'eid': [text_type(seid)],
+ req.form = {'eid': [str(seid)],
'__type:%s'%seid: 'Salesterm',
'_cw_entity_fields:%s'%seid: 'amount-subject',
'amount-subject:%s'%seid: u'-10',
@@ -430,7 +428,7 @@
# ensure a value that comply a constraint is properly processed
with self.admin_access.web_request(rollbackfirst=True) as req:
- req.form = {'eid': [text_type(seid)],
+ req.form = {'eid': [str(seid)],
'__type:%s'%seid: 'Salesterm',
'_cw_entity_fields:%s'%seid: 'amount-subject',
'amount-subject:%s'%seid: u'20',
@@ -446,7 +444,7 @@
'__type:X': 'Salesterm',
'_cw_entity_fields:X': 'amount-subject,described_by_test-subject',
'amount-subject:X': u'0',
- 'described_by_test-subject:X': text_type(feid),
+ 'described_by_test-subject:X': str(feid),
}
# ensure a value that is modified in an operation on a modify
@@ -554,7 +552,7 @@
def test_redirect_delete_button(self):
with self.admin_access.web_request() as req:
eid = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
- req.form = {'eid': text_type(eid), '__type:%s'%eid: 'BlogEntry',
+ req.form = {'eid': str(eid), '__type:%s'%eid: 'BlogEntry',
'__action_delete': ''}
path, params = self.expect_redirect_handle_request(req, 'edit')
self.assertEqual(path, 'blogentry')
@@ -563,14 +561,14 @@
req.execute('SET X use_email E WHERE E eid %(e)s, X eid %(x)s',
{'x': req.user.eid, 'e': eid})
req.cnx.commit()
- req.form = {'eid': text_type(eid), '__type:%s'%eid: 'EmailAddress',
+ req.form = {'eid': str(eid), '__type:%s'%eid: 'EmailAddress',
'__action_delete': ''}
path, params = self.expect_redirect_handle_request(req, 'edit')
self.assertEqual(path, 'cwuser/admin')
self.assertIn('_cwmsgid', params)
eid1 = req.create_entity('BlogEntry', title=u'hop', content=u'hop').eid
eid2 = req.create_entity('EmailAddress', address=u'hop@logilab.fr').eid
- req.form = {'eid': [text_type(eid1), text_type(eid2)],
+ req.form = {'eid': [str(eid1), str(eid2)],
'__type:%s'%eid1: 'BlogEntry',
'__type:%s'%eid2: 'EmailAddress',
'__action_delete': ''}
@@ -672,13 +670,13 @@
groupeids = sorted(eid
for eid, in req.execute('CWGroup G '
'WHERE G name in ("managers", "users")'))
- groups = [text_type(eid) for eid in groupeids]
+ groups = [str(eid) for eid in groupeids]
cwetypeeid = req.execute('CWEType X WHERE X name "CWEType"')[0][0]
- basegroups = [text_type(eid)
+ basegroups = [str(eid)
for eid, in req.execute('CWGroup G '
'WHERE X read_permission G, X eid %(x)s',
{'x': cwetypeeid})]
- cwetypeeid = text_type(cwetypeeid)
+ cwetypeeid = str(cwetypeeid)
req.form = {
'eid': cwetypeeid,
'__type:'+cwetypeeid: 'CWEType',
--- a/cubicweb/web/test/unittest_views_json.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/test/unittest_views_json.py Fri Apr 05 17:58:19 2019 +0200
@@ -16,7 +16,6 @@
#
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
-from six import binary_type
from cubicweb.devtools.testlib import CubicWebTC
@@ -50,7 +49,7 @@
'rql': u'Any GN,COUNT(X) GROUPBY GN ORDERBY GN '
'WHERE X in_group G, G name GN'})
data = self.ctrl_publish(req, ctrl='jsonp')
- self.assertIsInstance(data, binary_type)
+ self.assertIsInstance(data, bytes)
self.assertEqual(req.headers_out.getRawHeaders('content-type'),
['application/javascript'])
# because jsonp anonymizes data, only 'guests' group should be found
--- a/cubicweb/web/test/unittest_viewselector.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/test/unittest_viewselector.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,7 +17,6 @@
# You should have received a copy of the GNU Lesser General Public License along
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""XXX rename, split, reorganize this"""
-from __future__ import print_function
from logilab.common.testlib import unittest_main
--- a/cubicweb/web/uihelper.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/uihelper.py Fri Apr 05 17:58:19 2019 +0200
@@ -45,8 +45,6 @@
"""
-from six import add_metaclass
-
from logilab.common.deprecation import deprecated
from cubicweb.web.views import uicfg
@@ -94,8 +92,7 @@
super(meta_formconfig, cls).__init__(name, bases, classdict)
-@add_metaclass(meta_formconfig)
-class FormConfig:
+class FormConfig(metaclass=meta_formconfig):
"""helper base class to define uicfg rules on a given entity type.
In all descriptions below, attributes list can either be a list of
--- a/cubicweb/web/views/ajaxcontroller.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/ajaxcontroller.py Fri Apr 05 17:58:19 2019 +0200
@@ -61,13 +61,9 @@
"""
-
-
+import http.client as http_client
from functools import partial
-from six import PY2, text_type
-from six.moves import http_client
-
from logilab.common.date import strptime
from logilab.common.registry import yes
@@ -151,7 +147,7 @@
if result is None:
return b''
# get unicode on @htmlize methods, encoded string on @jsonize methods
- elif isinstance(result, text_type):
+ elif isinstance(result, str):
return result.encode(self._cw.encoding)
return result
--- a/cubicweb/web/views/authentication.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/authentication.py Fri Apr 05 17:58:19 2019 +0200
@@ -17,8 +17,6 @@
# with CubicWeb. If not, see <http://www.gnu.org/licenses/>.
"""user authentication component"""
-from six import text_type
-
from logilab.common.deprecation import class_renamed
from logilab.common.textutils import unormalize
@@ -114,8 +112,8 @@
self.sessionid = make_uid(unormalize(user.login))
self.data = {}
- def __unicode__(self):
- return '<session %s (0x%x)>' % (text_type(self.user.login), id(self))
+ def __str__(self):
+ return '<session %s (0x%x)>' % (self.user.login, id(self))
@property
def anonymous_session(self):
--- a/cubicweb/web/views/autoform.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/autoform.py Fri Apr 05 17:58:19 2019 +0200
@@ -118,8 +118,6 @@
.. Controlling the generic relation fields
"""
-from six.moves import range
-
from logilab.mtconverter import xml_escape
from logilab.common.decorators import iclassmethod, cached
from logilab.common.registry import NoSelectableObject
--- a/cubicweb/web/views/basecontrollers.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/basecontrollers.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,8 +19,7 @@
object to handle publication.
"""
-from six import text_type
-from six.moves import http_client
+import http.client
from cubicweb import (NoSelectableObject, ObjectNotFound, ValidationError,
AuthenticationError, UndoTransactionException,
@@ -44,7 +43,7 @@
raise AuthenticationError()
else:
# Cookie authentication
- self._cw.status_out = http_client.FORBIDDEN
+ self._cw.status_out = http.client.FORBIDDEN
return self.appli.need_login_content(self._cw)
class LoginControllerForAuthed(Controller):
@@ -187,7 +186,7 @@
except Exception as ex:
req.cnx.rollback()
req.exception('unexpected error while validating form')
- return (False, text_type(ex), ctrl._edited_entity)
+ return (False, str(ex), ctrl._edited_entity)
return (False, '???', None)
--- a/cubicweb/web/views/baseviews.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/baseviews.py Fri Apr 05 17:58:19 2019 +0200
@@ -77,8 +77,6 @@
from cubicweb import _
-from six.moves import range
-
from logilab.mtconverter import TransformError, xml_escape
from logilab.common.registry import yes
--- a/cubicweb/web/views/boxes.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/boxes.py Fri Apr 05 17:58:19 2019 +0200
@@ -28,8 +28,6 @@
from cubicweb import _
-from six import text_type, add_metaclass
-
from logilab.mtconverter import xml_escape
from cubicweb import Unauthorized
@@ -212,7 +210,7 @@
@property
def domid(self):
- return super(RsetBox, self).domid + text_type(abs(id(self))) + text_type(abs(id(self.cw_rset)))
+ return super(RsetBox, self).domid + str(abs(id(self))) + str(abs(id(self.cw_rset)))
def render_title(self, w):
w(self.cw_extra_kwargs['title'])
--- a/cubicweb/web/views/csvexport.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/csvexport.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,9 +20,6 @@
from cubicweb import _
-from six import PY2
-from six.moves import range
-
from cubicweb.schema import display_name
from cubicweb.predicates import any_rset, empty_rset
from cubicweb.uilib import UnicodeCSVWriter
@@ -32,7 +29,7 @@
"""mixin class for CSV views"""
templatable = False
content_type = "text/comma-separated-values"
- binary = PY2 # python csv module is unicode aware in py3k
+ binary = False
csv_params = {'dialect': 'excel',
'quotechar': '"',
'delimiter': ';',
--- a/cubicweb/web/views/cwsources.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/cwsources.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,8 +21,6 @@
import logging
-from six.moves import range
-
from logilab.common.decorators import cachedproperty
from cubicweb import _
--- a/cubicweb/web/views/cwuser.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/cwuser.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,9 +22,6 @@
from hashlib import sha1 # pylint: disable=E0611
-from six import text_type
-from six.moves import range
-
from logilab.mtconverter import xml_escape
from cubicweb import tags
@@ -252,6 +249,6 @@
'group': tableview.MainEntityColRenderer(),
'nb_users': tableview.EntityTableColRenderer(
header=_('num. users'),
- renderfunc=lambda w, x: w(text_type(x.num_users())),
+ renderfunc=lambda w, x: w(str(x.num_users())),
sortfunc=lambda x: x.num_users()),
}
--- a/cubicweb/web/views/debug.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/debug.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,8 +21,6 @@
from time import strftime, localtime
-from six import text_type
-
from logilab.mtconverter import xml_escape
from cubicweb.predicates import none_rset, match_user_groups
@@ -98,7 +96,7 @@
if k.endswith('_cache_size'):
stats[k] = '%s / %s' % (stats[k]['size'], stats[k]['maxsize'])
def format_stat(sname, sval):
- return '%s %s' % (xml_escape(text_type(sval)),
+ return '%s %s' % (xml_escape(str(sval)),
sname.endswith('percent') and '%' or '')
pyvalue = [(sname, format_stat(sname, sval))
for sname, sval in sorted(stats.items())]
--- a/cubicweb/web/views/editcontroller.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/editcontroller.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,8 +22,6 @@
from datetime import datetime
-from six import text_type
-
from logilab.common.graph import ordered_nodes
from rql.utils import rqlvar_maker
@@ -201,7 +199,7 @@
if '__linkto' in req.form and 'eid' in req.form:
self.execute_linkto()
elif '__delete' not in req.form:
- raise ValidationError(None, {None: text_type(ex)})
+ raise ValidationError(None, {None: str(ex)})
# all pending inlined relations to newly created entities have been
# treated now (pop to ensure there are no attempt to add new ones)
pending_inlined = req.data.pop('pending_inlined')
@@ -234,7 +232,7 @@
autoform.delete_relations(self._cw, todelete)
self._cw.remove_pending_operations()
if self.errors:
- errors = dict((f.name, text_type(ex)) for f, ex in self.errors)
+ errors = dict((f.name, str(ex)) for f, ex in self.errors)
raise ValidationError(valerror_eid(form.get('__maineid')), errors)
def _insert_entity(self, etype, eid, rqlquery):
@@ -285,7 +283,7 @@
rqlquery.set_inlined(field.name, form_.edited_entity.eid)
if not rqlquery.canceled:
if self.errors:
- errors = dict((f.role_name(), text_type(ex)) for f, ex in self.errors)
+ errors = dict((f.role_name(), str(ex)) for f, ex in self.errors)
raise ValidationError(valerror_eid(entity.eid), errors)
if eid is None: # creation or copy
entity.eid = eid = self._insert_entity(etype, formparams['eid'], rqlquery)
--- a/cubicweb/web/views/editforms.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/editforms.py Fri Apr 05 17:58:19 2019 +0200
@@ -23,8 +23,6 @@
from copy import copy
-from six.moves import range
-
from logilab.common.registry import yes
from cubicweb import _
--- a/cubicweb/web/views/formrenderers.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/formrenderers.py Fri Apr 05 17:58:19 2019 +0200
@@ -37,8 +37,6 @@
from warnings import warn
-from six import text_type
-
from logilab.mtconverter import xml_escape
from logilab.common.registry import yes
@@ -121,7 +119,7 @@
data.insert(0, errormsg)
# NOTE: we call unicode because `tag` objects may be found within data
# e.g. from the cwtags library
- w(''.join(text_type(x) for x in data))
+ w(''.join(str(x) for x in data))
def render_content(self, w, form, values):
if self.display_progress_div:
--- a/cubicweb/web/views/forms.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/forms.py Fri Apr 05 17:58:19 2019 +0200
@@ -45,8 +45,6 @@
import time
import inspect
-from six import text_type
-
from logilab.common import dictattr, tempattr
from logilab.common.decorators import iclassmethod, cached
from logilab.common.textutils import splitstrip
@@ -286,7 +284,7 @@
except ProcessFormError as exc:
errors.append((field, exc))
if errors:
- errors = dict((f.role_name(), text_type(ex)) for f, ex in errors)
+ errors = dict((f.role_name(), str(ex)) for f, ex in errors)
raise ValidationError(None, errors)
return processed
--- a/cubicweb/web/views/ibreadcrumbs.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/ibreadcrumbs.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,8 +22,6 @@
from warnings import warn
-from six import text_type
-
from logilab.mtconverter import xml_escape
from cubicweb import tags, uilib
@@ -146,7 +144,7 @@
xml_escape(url), xml_escape(uilib.cut(title, textsize))))
else:
textsize = self._cw.property_value('navigation.short-line-size')
- w(xml_escape(uilib.cut(text_type(part), textsize)))
+ w(xml_escape(uilib.cut(str(part), textsize)))
class BreadCrumbETypeVComponent(BreadCrumbEntityVComponent):
--- a/cubicweb/web/views/idownloadable.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/idownloadable.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,8 +22,6 @@
from cubicweb import _
-from six.moves import range
-
from logilab.mtconverter import BINARY_ENCODINGS, TransformError, xml_escape
from cubicweb import tags
--- a/cubicweb/web/views/magicsearch.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/magicsearch.py Fri Apr 05 17:58:19 2019 +0200
@@ -23,8 +23,6 @@
import re
from logging import getLogger
-from six import text_type
-
from yams.interfaces import IVocabularyConstraint
from rql import RQLSyntaxError, BadRQLQuery, parse
@@ -388,7 +386,7 @@
self.processors = sorted(processors, key=lambda x: x.priority)
def process_query(self, uquery):
- assert isinstance(uquery, text_type)
+ assert isinstance(uquery, str)
try:
procname, query = uquery.split(':', 1)
proc = self.by_name[procname.strip().lower()]
--- a/cubicweb/web/views/navigation.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/navigation.py Fri Apr 05 17:58:19 2019 +0200
@@ -50,8 +50,6 @@
from datetime import datetime
-from six import text_type
-
from rql.nodes import VariableRef, Constant
from logilab.mtconverter import xml_escape
@@ -193,10 +191,10 @@
return entity.printable_value(attrname, format='text/plain')
elif col is None: # smart links disabled.
def index_display(row):
- return text_type(row)
+ return str(row)
elif self._cw.vreg.schema.eschema(rset.description[0][col]).final:
def index_display(row):
- return text_type(rset[row][col])
+ return str(rset[row][col])
else:
def index_display(row):
return rset.get_entity(row, col).view('text')
--- a/cubicweb/web/views/owl.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/owl.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,8 +21,6 @@
from cubicweb import _
-from six.moves import range
-
from logilab.mtconverter import TransformError, xml_escape
from cubicweb.view import StartupView, EntityView
--- a/cubicweb/web/views/pyviews.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/pyviews.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,10 +18,6 @@
"""Basic views for python values (eg without any result set)
"""
-
-from six import text_type
-from six.moves import range
-
from cubicweb.view import View
from cubicweb.predicates import match_kwargs
from cubicweb.web.views import tableview
@@ -41,7 +37,7 @@
w(self.empty_cell_content)
def render_cell(self, w, rownum):
- w(text_type(self.data[rownum][self.colid]))
+ w(str(self.data[rownum][self.colid]))
class PyValTableView(tableview.TableMixIn, View):
--- a/cubicweb/web/views/rdf.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/rdf.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from cubicweb import _
-from six.moves import range
-
from yams import xy
from cubicweb.schema import VIRTUAL_RTYPES
--- a/cubicweb/web/views/schema.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/schema.py Fri Apr 05 17:58:19 2019 +0200
@@ -26,8 +26,6 @@
import os, os.path as osp
import codecs
-from six import text_type
-
from logilab.common.graph import GraphGenerator, DotBackend
from logilab.common.ureports import Section, Table
from logilab.common.registry import yes
@@ -281,7 +279,7 @@
def cell_call(self, row, col):
defaultval = self.cw_rset.rows[row][col]
if defaultval is not None:
- self.w(text_type(self.cw_rset.rows[row][col].unzpickle()))
+ self.w(str(self.cw_rset.rows[row][col].unzpickle()))
class CWETypeRelationCardinalityCell(baseviews.FinalView):
__regid__ = 'etype-rel-cardinality-cell'
@@ -489,7 +487,7 @@
entity = self.cw_rset.get_entity(row, col)
rschema = self._cw.vreg.schema.rschema(entity.rtype.name)
rdef = rschema.rdefs[(entity.stype.name, entity.otype.name)]
- constraints = [xml_escape(text_type(c)) for c in getattr(rdef, 'constraints')]
+ constraints = [xml_escape(str(c)) for c in getattr(rdef, 'constraints')]
self.w(u'<br/>'.join(constraints))
class CWAttributeOptionsCell(EntityView):
--- a/cubicweb/web/views/sparql.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/sparql.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from cubicweb import _
-from six.moves import range
-
from yams import xy
from rql import TypeResolverException
--- a/cubicweb/web/views/tableview.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/tableview.py Fri Apr 05 17:58:19 2019 +0200
@@ -66,9 +66,6 @@
from copy import copy
from types import MethodType
-from six import string_types, add_metaclass, create_bound_method
-from six.moves import range
-
from logilab.mtconverter import xml_escape
from logilab.common.decorators import cachedproperty
from logilab.common.deprecation import class_deprecated
@@ -286,7 +283,7 @@
attrs = renderer.attributes.copy()
if renderer.sortable:
sortvalue = renderer.sortvalue(rownum)
- if isinstance(sortvalue, string_types):
+ if isinstance(sortvalue, str):
sortvalue = sortvalue[:self.sortvalue_limit]
if sortvalue is not None:
attrs[u'cubicweb:sortvalue'] = js_dumps(sortvalue)
@@ -717,7 +714,7 @@
for aname, member in[('renderfunc', renderfunc),
('sortfunc', sortfunc)]:
if isinstance(member, MethodType):
- member = create_bound_method(member.__func__, acopy)
+ member = MethodType(member.__func__, acopy)
setattr(acopy, aname, member)
return acopy
finally:
@@ -912,8 +909,7 @@
################################################################################
-@add_metaclass(class_deprecated)
-class TableView(AnyRsetView):
+class TableView(AnyRsetView, metaclass=class_deprecated):
"""The table view accepts any non-empty rset. It uses introspection on the
result set to compute column names and the proper way to display the cells.
@@ -1178,8 +1174,7 @@
title = _('editable-table')
-@add_metaclass(class_deprecated)
-class CellView(EntityView):
+class CellView(EntityView, metaclass=class_deprecated):
__deprecation_warning__ = '[3.14] %(cls)s is deprecated'
__regid__ = 'cell'
__select__ = nonempty_rset()
--- a/cubicweb/web/views/tabs.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/tabs.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from cubicweb import _
-from six import string_types
-
from logilab.common.deprecation import class_renamed
from logilab.mtconverter import xml_escape
@@ -116,7 +114,7 @@
active_tab = uilib.domid(default_tab)
viewsvreg = self._cw.vreg['views']
for tab in tabs:
- if isinstance(tab, string_types):
+ if isinstance(tab, str):
tabid, tabkwargs = tab, {}
else:
tabid, tabkwargs = tab
--- a/cubicweb/web/views/timetable.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/timetable.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from cubicweb import _
-from six.moves import range
-
from logilab.mtconverter import xml_escape
from logilab.common.date import ONEDAY, date_range, todatetime
--- a/cubicweb/web/views/uicfg.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/uicfg.py Fri Apr 05 17:58:19 2019 +0200
@@ -56,8 +56,6 @@
from itertools import repeat
-from six import string_types
-
from cubicweb import neg_role
from cubicweb.rtags import (RelationTags, RelationTagsBool, RelationTagsSet,
RelationTagsDict, NoTargetRelationTagsDict,
@@ -692,7 +690,7 @@
self.tag_relation((sschema, rschema, oschema, role), True)
def _tag_etype_attr(self, etype, attr, desttype='*', *args, **kwargs):
- if isinstance(attr, string_types):
+ if isinstance(attr, str):
attr, role = attr, 'subject'
else:
attr, role = attr
--- a/cubicweb/web/views/urlrewrite.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/urlrewrite.py Fri Apr 05 17:58:19 2019 +0200
@@ -19,8 +19,6 @@
import re
-from six import string_types, add_metaclass
-
from cubicweb.uilib import domid
from cubicweb.appobject import AppObject
@@ -53,8 +51,7 @@
return super(metarewriter, mcs).__new__(mcs, name, bases, classdict)
-@add_metaclass(metarewriter)
-class URLRewriter(AppObject):
+class URLRewriter(AppObject, metaclass=metarewriter):
"""Base class for URL rewriters.
Url rewriters should have a `rules` dict that maps an input URI
@@ -124,14 +121,14 @@
required_groups = None
if required_groups and not req.user.matching_groups(required_groups):
continue
- if isinstance(inputurl, string_types):
+ if isinstance(inputurl, str):
if inputurl == uri:
req.form.update(infos)
break
elif inputurl.match(uri): # it's a regexp
# XXX what about i18n? (vtitle for instance)
for param, value in infos.items():
- if isinstance(value, string_types):
+ if isinstance(value, str):
req.form[param] = inputurl.sub(value, uri)
else:
req.form[param] = value
@@ -224,7 +221,7 @@
required_groups = None
if required_groups and not req.user.matching_groups(required_groups):
continue
- if isinstance(inputurl, string_types):
+ if isinstance(inputurl, str):
if inputurl == uri:
return callback(inputurl, uri, req, self._cw.vreg.schema)
elif inputurl.match(uri): # it's a regexp
--- a/cubicweb/web/views/wdoc.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/wdoc.py Fri Apr 05 17:58:19 2019 +0200
@@ -26,8 +26,6 @@
from os.path import join
from xml.etree.ElementTree import parse
-from six import text_type
-
from logilab.common.registry import yes
from cubicweb.predicates import match_form_params
@@ -91,9 +89,9 @@
for title in node.findall('title'):
title_lang = title.attrib['{http://www.w3.org/XML/1998/namespace}lang']
if title_lang == lang:
- return text_type(title.text)
+ return title.text
if title_lang == 'en':
- fallback_title = text_type(title.text)
+ fallback_title = title.text
return fallback_title
--- a/cubicweb/web/views/workflow.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/workflow.py Fri Apr 05 17:58:19 2019 +0200
@@ -24,8 +24,6 @@
from cubicweb import _
-from six import text_type
-
from logilab.mtconverter import xml_escape
from cubicweb import Unauthorized
@@ -309,7 +307,7 @@
wf = req.entity_from_eid(wfeid)
rschema = req.vreg.schema[field.name]
param = 'toeid' if field.role == 'subject' else 'fromeid'
- return sorted((e.view('combobox'), text_type(e.eid))
+ return sorted((e.view('combobox'), str(e.eid))
for e in getattr(wf, 'reverse_%s' % wfrelation)
if rschema.has_perm(req, 'add', **{param: e.eid}))
--- a/cubicweb/web/views/xbel.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/xbel.py Fri Apr 05 17:58:19 2019 +0200
@@ -20,8 +20,6 @@
from cubicweb import _
-from six.moves import range
-
from logilab.mtconverter import xml_escape
from cubicweb.predicates import is_instance
--- a/cubicweb/web/views/xmlrss.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/views/xmlrss.py Fri Apr 05 17:58:19 2019 +0200
@@ -22,8 +22,6 @@
from base64 import b64encode
from time import timezone
-from six.moves import range
-
from logilab.mtconverter import xml_escape
from cubicweb.predicates import (is_instance, non_final_entity, one_line_rset,
--- a/cubicweb/web/webconfig.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/webconfig.py Fri Apr 05 17:58:19 2019 +0200
@@ -25,8 +25,6 @@
from uuid import uuid4
from os.path import dirname, join, exists, split, isdir
-from six import text_type
-
from logilab.common.decorators import cached, cachedproperty
from logilab.common.configuration import Method, merge_options
@@ -134,8 +132,6 @@
try:
user = self['anonymous-user'] or None
passwd = self['anonymous-password']
- if user:
- user = text_type(user)
except KeyError:
user, passwd = None, None
except UnicodeDecodeError:
@@ -301,7 +297,7 @@
def sign_text(self, text):
"""sign some text for later checking"""
# hmac.new expect bytes
- if isinstance(text, text_type):
+ if isinstance(text, str):
text = text.encode('utf-8')
# replace \r\n so we do not depend on whether a browser "reencode"
# original message using \r\n or not
--- a/cubicweb/web/webctl.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/web/webctl.py Fri Apr 05 17:58:19 2019 +0200
@@ -18,7 +18,6 @@
"""cubicweb-ctl commands and command handlers common to twisted/modpython
web configuration
"""
-from __future__ import print_function
import os
import os.path as osp
--- a/cubicweb/wfutils.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/wfutils.py Fri Apr 05 17:58:19 2019 +0200
@@ -45,8 +45,6 @@
import collections
-from six import text_type
-
from cubicweb import NoResultError
@@ -91,7 +89,6 @@
by calling :func:`cleanupworkflow`.
:return: The created/updated workflow entity
"""
- name = text_type(name)
try:
wf = cnx.find('Workflow', name=name).one()
except NoResultError:
--- a/cubicweb/wsgi/__init__.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/wsgi/__init__.py Fri Apr 05 17:58:19 2019 +0200
@@ -27,9 +27,9 @@
from email import message, message_from_string
+from http.cookies import SimpleCookie
from pprint import pformat as _pformat
-from six.moves.http_cookies import SimpleCookie
def pformat(obj):
"""pretty prints `obj` if possible"""
--- a/cubicweb/wsgi/handler.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/wsgi/handler.py Fri Apr 05 17:58:19 2019 +0200
@@ -21,8 +21,6 @@
from itertools import chain, repeat
-from six.moves import zip
-
from cubicweb import AuthenticationError
from cubicweb.web import DirectResponse
from cubicweb.web.application import CubicWebPublisher
--- a/cubicweb/wsgi/request.py Fri Apr 05 17:21:14 2019 +0200
+++ b/cubicweb/wsgi/request.py Fri Apr 05 17:58:19 2019 +0200
@@ -28,8 +28,7 @@
import tempfile
from io import BytesIO
-
-from six.moves.urllib.parse import parse_qs
+from urllib.parse import parse_qs
from cubicweb.multipart import (
copy_file, parse_form_data, parse_options_header)
--- a/debian/control Fri Apr 05 17:21:14 2019 +0200
+++ b/debian/control Fri Apr 05 17:58:19 2019 +0200
@@ -14,7 +14,6 @@
python-docutils,
python-sphinx,
python-logilab-common (>= 1.4.0),
- python-unittest2 (>= 0.7.0),
python-logilab-mtconverter,
python-markdown,
python-tz,
@@ -46,7 +45,6 @@
python-logilab-database (>= 1.15.0),
python-yams (>= 0.45.0),
python-rql (>= 0.34.0),
- python-unittest2 (>= 0.7.0),
python-lxml,
python-markdown,
python-passlib,
--- a/doc/changes/3.27.rst Fri Apr 05 17:21:14 2019 +0200
+++ b/doc/changes/3.27.rst Fri Apr 05 17:58:19 2019 +0200
@@ -25,6 +25,8 @@
* Support for legacy cubes (in the 'cubes' python namespace) has been dropped.
Use of environment variables CW_CUBES_PATH and CUBES_DIR is removed.
+* Python 2 support has been dropped.
+
Deprecated code drops
---------------------
--- a/doc/tools/mode_plan.py Fri Apr 05 17:21:14 2019 +0200
+++ b/doc/tools/mode_plan.py Fri Apr 05 17:58:19 2019 +0200
@@ -23,8 +23,6 @@
rename A010-joe.en.txt to A030-joe.en.txt
accept [y/N]?
"""
-from __future__ import print_function
-
def ren(a,b):
names = glob.glob('%s*'%a)
--- a/setup.py Fri Apr 05 17:21:14 2019 +0200
+++ b/setup.py Fri Apr 05 17:58:19 2019 +0200
@@ -63,7 +63,6 @@
package_data=package_data,
include_package_data=True,
install_requires=[
- 'six >= 1.4.0',
'logilab-common >= 1.4.0',
'logilab-mtconverter >= 0.8.0',
'rql >= 0.34.0',
@@ -73,7 +72,6 @@
'passlib',
'pytz',
'Markdown',
- 'unittest2 >= 0.7.0',
'filelock',
],
entry_points={
--- a/tox.ini Fri Apr 05 17:21:14 2019 +0200
+++ b/tox.ini Fri Apr 05 17:58:19 2019 +0200
@@ -1,12 +1,12 @@
[tox]
envlist =
check-manifest,flake8,
- py{27,3}-{server,web,misc}
+ py3-{server,web,misc}
[testenv]
+basepython=python3
deps =
-r{toxinidir}/requirements/dev.txt
- py27: backports.tempfile
misc: -r{toxinidir}/requirements/test-misc.txt
server: -r{toxinidir}/requirements/test-server.txt
web: -r{toxinidir}/requirements/test-web.txt
@@ -17,7 +17,6 @@
web: {envpython} -m pytest {posargs} {toxinidir}/cubicweb/web/test
[testenv:flake8]
-basepython=python3
skip_install = true
deps =
flake8 >= 3.6