Drop support for EOL Python 2.6

This commit is contained in:
Hugo
2018-05-09 21:36:30 +03:00
parent 3bb46563d4
commit f6bdba65c0
11 changed files with 30 additions and 77 deletions

View File

@@ -13,7 +13,7 @@ from parso.utils import parse_version_string
collect_ignore = ["setup.py"] collect_ignore = ["setup.py"]
VERSIONS_2 = '2.6', '2.7' VERSIONS_2 = '2.7'
VERSIONS_3 = '3.3', '3.4', '3.5', '3.6', '3.7', '3.8' VERSIONS_3 = '3.3', '3.4', '3.5', '3.6', '3.7', '3.8'

View File

@@ -1,14 +1,10 @@
""" """
To ensure compatibility from Python ``2.6`` - ``3.3``, a module has been To ensure compatibility from Python ``2.7`` - ``3.3``, a module has been
created. Clearly there is huge need to use conforming syntax. created. Clearly there is huge need to use conforming syntax.
""" """
import sys import sys
import platform import platform
# Cannot use sys.version.major and minor names, because in Python 2.6 it's not
# a namedtuple.
py_version = int(str(sys.version_info[0]) + str(sys.version_info[1]))
# unicode function # unicode function
try: try:
unicode = unicode unicode = unicode
@@ -39,7 +35,7 @@ def u(string):
have to cast back to a unicode (and we know that we always deal with valid have to cast back to a unicode (and we know that we always deal with valid
unicode, because we check that in the beginning). unicode, because we check that in the beginning).
""" """
if py_version >= 30: if sys.version_info.major >= 3:
return str(string) return str(string)
if not isinstance(string, unicode): if not isinstance(string, unicode):
@@ -48,8 +44,10 @@ def u(string):
try: try:
# Python 2.7
FileNotFoundError = FileNotFoundError FileNotFoundError = FileNotFoundError
except NameError: except NameError:
# Python 3.3+
FileNotFoundError = IOError FileNotFoundError = IOError
@@ -65,39 +63,7 @@ def utf8_repr(func):
else: else:
return result return result
if py_version >= 30: if sys.version_info.major >= 3:
return func return func
else: else:
return wrapper return wrapper
try:
from functools import total_ordering
except ImportError:
# Python 2.6
def total_ordering(cls):
"""Class decorator that fills in missing ordering methods"""
convert = {
'__lt__': [('__gt__', lambda self, other: not (self < other or self == other)),
('__le__', lambda self, other: self < other or self == other),
('__ge__', lambda self, other: not self < other)],
'__le__': [('__ge__', lambda self, other: not self <= other or self == other),
('__lt__', lambda self, other: self <= other and not self == other),
('__gt__', lambda self, other: not self <= other)],
'__gt__': [('__lt__', lambda self, other: not (self > other or self == other)),
('__ge__', lambda self, other: self > other or self == other),
('__le__', lambda self, other: not self > other)],
'__ge__': [('__le__', lambda self, other: (not self >= other) or self == other),
('__gt__', lambda self, other: self >= other and not self == other),
('__lt__', lambda self, other: not self >= other)]
}
roots = set(dir(cls)) & set(convert)
if not roots:
raise ValueError('must define at least one ordering operation: < > <= >=')
root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
for opname, opfunc in convert[root]:
if opname not in roots:
opfunc.__name__ = opname
opfunc.__doc__ = getattr(int, opname).__doc__
setattr(cls, opname, opfunc)
return cls

View File

@@ -19,7 +19,6 @@ import itertools as _itertools
from codecs import BOM_UTF8 from codecs import BOM_UTF8
from parso.python.token import PythonTokenTypes from parso.python.token import PythonTokenTypes
from parso._compatibility import py_version
from parso.utils import split_lines from parso.utils import split_lines
@@ -50,7 +49,7 @@ BOM_UTF8_STRING = BOM_UTF8.decode('utf-8')
_token_collection_cache = {} _token_collection_cache = {}
if py_version >= 30: if sys.version_info.major >= 3:
# Python 3 has str.isidentifier() to check if a char is a valid identifier # Python 3 has str.isidentifier() to check if a char is a valid identifier
is_identifier = str.isidentifier is_identifier = str.isidentifier
else: else:
@@ -86,7 +85,7 @@ def _all_string_prefixes(version_info, include_fstring=False, only_fstring=False
# and don't contain any permuations (include 'fr', but not # and don't contain any permuations (include 'fr', but not
# 'rf'). The various permutations will be generated. # 'rf'). The various permutations will be generated.
valid_string_prefixes = ['b', 'r', 'u'] valid_string_prefixes = ['b', 'r', 'u']
if version_info >= (3, 0): if version_info.major >= 3:
valid_string_prefixes.append('br') valid_string_prefixes.append('br')
result = set(['']) result = set([''])
@@ -106,7 +105,7 @@ def _all_string_prefixes(version_info, include_fstring=False, only_fstring=False
# create a list with upper and lower versions of each # create a list with upper and lower versions of each
# character # character
result.update(different_case_versions(t)) result.update(different_case_versions(t))
if version_info <= (2, 7): if version_info.major == 2:
# In Python 2 the order cannot just be random. # In Python 2 the order cannot just be random.
result.update(different_case_versions('ur')) result.update(different_case_versions('ur'))
result.update(different_case_versions('br')) result.update(different_case_versions('br'))
@@ -164,7 +163,7 @@ def _create_token_collection(version_info):
else: else:
Hexnumber = r'0[xX][0-9a-fA-F]+' Hexnumber = r'0[xX][0-9a-fA-F]+'
Binnumber = r'0[bB][01]+' Binnumber = r'0[bB][01]+'
if version_info >= (3, 0): if version_info.major >= 3:
Octnumber = r'0[oO][0-7]+' Octnumber = r'0[oO][0-7]+'
else: else:
Octnumber = '0[oO]?[0-7]+' Octnumber = '0[oO]?[0-7]+'

View File

@@ -1,6 +1,7 @@
import sys
from abc import abstractmethod, abstractproperty from abc import abstractmethod, abstractproperty
from parso._compatibility import utf8_repr, encoding, py_version from parso._compatibility import utf8_repr, encoding
from parso.utils import split_lines from parso.utils import split_lines
@@ -321,7 +322,7 @@ class BaseNode(NodeOrLeaf):
@utf8_repr @utf8_repr
def __repr__(self): def __repr__(self):
code = self.get_code().replace('\n', ' ').replace('\r', ' ').strip() code = self.get_code().replace('\n', ' ').replace('\r', ' ').strip()
if not py_version >= 30: if not sys.version_info.major >= 3:
code = code.encode(encoding, 'replace') code = code.encode(encoding, 'replace')
return "<%s: %s@%s,%s>" % \ return "<%s: %s@%s,%s>" % \
(type(self).__name__, code, self.start_pos[0], self.start_pos[1]) (type(self).__name__, code, self.start_pos[0], self.start_pos[1])

View File

@@ -2,8 +2,9 @@ from collections import namedtuple
import re import re
import sys import sys
from ast import literal_eval from ast import literal_eval
from functools import total_ordering
from parso._compatibility import unicode, total_ordering from parso._compatibility import unicode
# The following is a list in Python that are line breaks in str.splitlines, but # The following is a list in Python that are line breaks in str.splitlines, but
# not in Python. In Python only \r (Carriage Return, 0xD) and \n (Line Feed, # not in Python. In Python only \r (Carriage Return, 0xD) and \n (Line Feed,

View File

@@ -34,7 +34,6 @@ setup(name='parso',
'License :: OSI Approved :: MIT License', 'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.3',

View File

@@ -282,10 +282,7 @@ if sys.version_info >= (3, 6):
'f"s" b""', 'f"s" b""',
'b"s" f""', 'b"s" f""',
] ]
if sys.version_info >= (2, 7): FAILING_EXAMPLES.append('[a, 1] += 3')
# This is something that raises a different error in 2.6 than in the other
# versions. Just skip it for 2.6.
FAILING_EXAMPLES.append('[a, 1] += 3')
if sys.version_info[:2] == (3, 5): if sys.version_info[:2] == (3, 5):
# yields are not allowed in 3.5 async functions. Therefore test them # yields are not allowed in 3.5 async functions. Therefore test them

View File

@@ -5,9 +5,9 @@ tests of pydocstyle.
import difflib import difflib
import re import re
from functools import total_ordering
import parso import parso
from parso._compatibility import total_ordering
from parso.utils import python_bytes_to_unicode from parso.utils import python_bytes_to_unicode

View File

@@ -118,22 +118,12 @@ def _get_actual_exception(code):
assert False, "The piece of code should raise an exception." assert False, "The piece of code should raise an exception."
# SyntaxError # SyntaxError
# Python 2.6 has a bit different error messages here, so skip it.
if sys.version_info[:2] == (2, 6) and wanted == 'SyntaxError: unexpected EOF while parsing':
wanted = 'SyntaxError: invalid syntax'
if wanted == 'SyntaxError: non-keyword arg after keyword arg': if wanted == 'SyntaxError: non-keyword arg after keyword arg':
# The python 3.5+ way, a bit nicer. # The python 3.5+ way, a bit nicer.
wanted = 'SyntaxError: positional argument follows keyword argument' wanted = 'SyntaxError: positional argument follows keyword argument'
elif wanted == 'SyntaxError: assignment to keyword': elif wanted == 'SyntaxError: assignment to keyword':
return [wanted, "SyntaxError: can't assign to keyword", return [wanted, "SyntaxError: can't assign to keyword",
'SyntaxError: cannot assign to __debug__'], line_nr 'SyntaxError: cannot assign to __debug__'], line_nr
elif wanted == 'SyntaxError: assignment to None':
# Python 2.6 does has a slightly different error.
wanted = 'SyntaxError: cannot assign to None'
elif wanted == 'SyntaxError: can not assign to __debug__':
# Python 2.6 does has a slightly different error.
wanted = 'SyntaxError: cannot assign to __debug__'
elif wanted == 'SyntaxError: can use starred expression only as assignment target': elif wanted == 'SyntaxError: can use starred expression only as assignment target':
# Python 3.4/3.4 have a bit of a different warning than 3.5/3.6 in # Python 3.4/3.4 have a bit of a different warning than 3.5/3.6 in
# certain places. But in others this error makes sense. # certain places. But in others this error makes sense.

View File

@@ -4,8 +4,8 @@ import sys
from textwrap import dedent from textwrap import dedent
import pytest import pytest
import sys
from parso._compatibility import py_version
from parso.utils import split_lines, parse_version_string from parso.utils import split_lines, parse_version_string
from parso.python.token import PythonTokenTypes from parso.python.token import PythonTokenTypes
from parso.python import tokenize from parso.python import tokenize
@@ -137,7 +137,7 @@ def test_identifier_contains_unicode():
''') ''')
token_list = _get_token_list(fundef) token_list = _get_token_list(fundef)
unicode_token = token_list[1] unicode_token = token_list[1]
if py_version >= 30: if sys.version_info.major >= 3:
assert unicode_token[0] == NAME assert unicode_token[0] == NAME
else: else:
# Unicode tokens in Python 2 seem to be identified as operators. # Unicode tokens in Python 2 seem to be identified as operators.
@@ -185,19 +185,19 @@ def test_ur_literals():
assert typ == NAME assert typ == NAME
check('u""') check('u""')
check('ur""', is_literal=not py_version >= 30) check('ur""', is_literal=not sys.version_info.major >= 3)
check('Ur""', is_literal=not py_version >= 30) check('Ur""', is_literal=not sys.version_info.major >= 3)
check('UR""', is_literal=not py_version >= 30) check('UR""', is_literal=not sys.version_info.major >= 3)
check('bR""') check('bR""')
# Starting with Python 3.3 this ordering is also possible. # Starting with Python 3.3 this ordering is also possible.
if py_version >= 33: if sys.version_info.major >= 3:
check('Rb""') check('Rb""')
# Starting with Python 3.6 format strings where introduced. # Starting with Python 3.6 format strings where introduced.
check('fr""', is_literal=py_version >= 36) check('fr""', is_literal=sys.version_info >= (3, 6))
check('rF""', is_literal=py_version >= 36) check('rF""', is_literal=sys.version_info >= (3, 6))
check('f""', is_literal=py_version >= 36) check('f""', is_literal=sys.version_info >= (3, 6))
check('F""', is_literal=py_version >= 36) check('F""', is_literal=sys.version_info >= (3, 6))
def test_error_literal(): def test_error_literal():

View File

@@ -1,11 +1,11 @@
[tox] [tox]
envlist = {py26,py27,py33,py34,py35,py36,py37} envlist = {py27,py33,py34,py35,py36,py37}
[testenv] [testenv]
extras = testing extras = testing
deps = deps =
py26,py33: pytest>=3.0.7,<3.3 py33: pytest>=3.0.7,<3.3
py27,py34: pytest<5 py27,py34: pytest<5
py26,py33: setuptools<37 py33: setuptools<37
coverage: coverage coverage: coverage
setenv = setenv =
# https://github.com/tomchristie/django-rest-framework/issues/1957 # https://github.com/tomchristie/django-rest-framework/issues/1957