Commit e233427b authored by Stefan Behnel's avatar Stefan Behnel Committed by GitHub

Merge pull request #2693 from cython/gh2692_remove_py26_support

Remove support for Py2.6 and various quirks that special-cased it
parents 5fdbfe49 da657c8e
......@@ -42,10 +42,6 @@ matrix:
dist: xenial # Required for Python 3.7
sudo: required # travis-ci/travis-ci#9069
env: BACKEND=cpp
- python: 2.6
env: BACKEND=c
- python: 2.6
env: BACKEND=cpp
# Disabled: coverage analysis takes excessively long, several times longer than without.
# - python: 3.7
# dist: xenial # Required for Python 3.7
......@@ -138,7 +134,7 @@ before_install:
install:
- python -c 'import sys; print("Python %s" % (sys.version,))'
- if [ -n "${TRAVIS_PYTHON_VERSION##*-dev}" -a -n "${TRAVIS_PYTHON_VERSION##2.6*}" ]; then pip install -r test-requirements.txt $( [ -z "${TRAVIS_PYTHON_VERSION##pypy*}" -o -z "${TRAVIS_PYTHON_VERSION##3.7*}" ] || echo " -r test-requirements-cpython.txt" ) ; fi
- if [ -n "${TRAVIS_PYTHON_VERSION##*-dev}" ]; then pip install -r test-requirements.txt $( [ -z "${TRAVIS_PYTHON_VERSION##pypy*}" -o -z "${TRAVIS_PYTHON_VERSION##3.7*}" ] || echo " -r test-requirements-cpython.txt" ) ; fi
# - CFLAGS="-O2 -ggdb -Wall -Wextra $(python -c 'import sys; print("-fno-strict-aliasing" if sys.version_info[0] == 2 else "")')" python setup.py build
before_script: ccache -s || true
......@@ -150,7 +146,7 @@ script:
else
STYLE_ARGS=--no-code-style;
if $PYTHON_DBG -V >&2; then CFLAGS="-O0 -ggdb" $PYTHON_DBG runtests.py -vv --no-code-style Debugger --backends=$BACKEND; fi;
if [ -z "${BACKEND##*cpp*}" -a -n "${TRAVIS_PYTHON_VERSION##2.6*}" ]; then pip install pythran; fi;
if [ -z "${BACKEND##*cpp*}" ]; then pip install pythran; fi;
if [ "$BACKEND" != "cpp" -a -n "${TRAVIS_PYTHON_VERSION##2*}" ]; then pip install mypy; fi;
fi
- if [ "$COVERAGE" != "1" ]; then CFLAGS="-O2 -ggdb -Wall -Wextra $(python -c 'import sys; print("-fno-strict-aliasing" if sys.version_info[0] == 2 else "")')" python setup.py build_ext -i; fi
......
......@@ -1056,31 +1056,25 @@ def cythonize(module_list, exclude=None, nthreads=0, aliases=None, quiet=False,
if N <= 1:
nthreads = 0
if nthreads:
# Requires multiprocessing (or Python >= 2.6)
import multiprocessing
pool = multiprocessing.Pool(
nthreads, initializer=_init_multiprocessing_helper)
# This is a bit more involved than it should be, because KeyboardInterrupts
# break the multiprocessing workers when using a normal pool.map().
# See, for example:
# http://noswap.com/blog/python-multiprocessing-keyboardinterrupt
try:
import multiprocessing
pool = multiprocessing.Pool(
nthreads, initializer=_init_multiprocessing_helper)
except (ImportError, OSError):
print("multiprocessing required for parallel cythonization")
nthreads = 0
else:
# This is a bit more involved than it should be, because KeyboardInterrupts
# break the multiprocessing workers when using a normal pool.map().
# See, for example:
# http://noswap.com/blog/python-multiprocessing-keyboardinterrupt
try:
result = pool.map_async(cythonize_one_helper, to_compile, chunksize=1)
pool.close()
while not result.ready():
try:
result.get(99999) # seconds
except multiprocessing.TimeoutError:
pass
except KeyboardInterrupt:
pool.terminate()
raise
pool.join()
result = pool.map_async(cythonize_one_helper, to_compile, chunksize=1)
pool.close()
while not result.ready():
try:
result.get(99999) # seconds
except multiprocessing.TimeoutError:
pass
except KeyboardInterrupt:
pool.terminate()
raise
pool.join()
if not nthreads:
for args in to_compile:
cythonize_one(*args)
......
......@@ -43,8 +43,6 @@ try:
except ImportError:
from builtins import str as basestring
KEYWORDS_MUST_BE_BYTES = sys.version_info < (2, 7)
non_portable_builtins_map = {
# builtins that have different names in different Python versions
......@@ -259,15 +257,11 @@ class UtilityCodeBase(object):
utility[1] = code
else:
all_tags = utility[2]
if KEYWORDS_MUST_BE_BYTES:
type = type.encode('ASCII')
all_tags[type] = code
if tags:
all_tags = utility[2]
for name, values in tags.items():
if KEYWORDS_MUST_BE_BYTES:
name = name.encode('ASCII')
all_tags.setdefault(name, set()).update(values)
@classmethod
......
......@@ -60,8 +60,6 @@ class CompileError(PyrexError):
self.message_only = message
self.formatted_message = format_error(message, position)
self.reported = False
# Deprecated and withdrawn in 2.6:
# self.message = message
Exception.__init__(self, self.formatted_message)
# Python Exception subclass pickling is broken,
# see http://bugs.python.org/issue1692335
......@@ -74,8 +72,6 @@ class CompileWarning(PyrexWarning):
def __init__(self, position = None, message = ""):
self.position = position
# Deprecated and withdrawn in 2.6:
# self.message = message
Exception.__init__(self, format_position(position) + message)
class InternalError(Exception):
......
......@@ -9,8 +9,8 @@ import re
import sys
import io
if sys.version_info[:2] < (2, 6) or (3, 0) <= sys.version_info[:2] < (3, 3):
sys.stderr.write("Sorry, Cython requires Python 2.6+ or 3.3+, found %d.%d\n" % tuple(sys.version_info[:2]))
if sys.version_info[:2] < (2, 7) or (3, 0) <= sys.version_info[:2] < (3, 3):
sys.stderr.write("Sorry, Cython requires Python 2.7 or 3.3+, found %d.%d\n" % tuple(sys.version_info[:2]))
sys.exit(1)
try:
......
......@@ -635,9 +635,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("#ifndef Py_PYTHON_H")
code.putln(" #error Python headers needed to compile C extensions, "
"please install development version of Python.")
code.putln("#elif PY_VERSION_HEX < 0x02060000 || "
code.putln("#elif PY_VERSION_HEX < 0x02070000 || "
"(0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)")
code.putln(" #error Cython requires Python 2.6+ or Python 3.3+.")
code.putln(" #error Cython requires Python 2.7+ or Python 3.3+.")
code.putln("#else")
code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
......
......@@ -56,13 +56,13 @@ def test_gdb():
stdout, _ = p.communicate()
try:
internal_python_version = list(map(int, stdout.decode('ascii', 'ignore').split()))
if internal_python_version < [2, 6]:
if internal_python_version < [2, 7]:
have_gdb = False
except ValueError:
have_gdb = False
if not have_gdb:
warnings.warn('Skipping gdb tests, need gdb >= 7.2 with Python >= 2.6')
warnings.warn('Skipping gdb tests, need gdb >= 7.2 with Python >= 2.7')
return have_gdb
......
......@@ -48,7 +48,7 @@ The module also extends gdb with some python-specific commands.
'''
# NOTE: some gdbs are linked with Python 3, so this file should be dual-syntax
# compatible (2.6+ and 3.0+). See #19308.
# compatible (2.7+ and 3.3+). See #19308.
from __future__ import print_function
import gdb
......@@ -1435,8 +1435,8 @@ The following code should ensure that the prettyprinter is registered
if the code is autoloaded by gdb when visiting libpython.so, provided
that this python file is installed to the same path as the library (or its
.debug file) plus a "-gdb.py" suffix, e.g:
/usr/lib/libpython2.6.so.1.0-gdb.py
/usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py
/usr/lib/libpython3.7.so.1.0-gdb.py
/usr/lib/debug/usr/lib/libpython3.7.so.1.0.debug-gdb.py
"""
def register (obj):
if obj is None:
......
......@@ -418,9 +418,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyDict_IterItems(PyObject* d) {
//////////////////// py_dict_viewkeys.proto ////////////////////
#if PY_VERSION_HEX < 0x02070000
#error This module uses dict views, which require Python 2.7 or later
#endif
static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewKeys(PyObject* d); /*proto*/
//////////////////// py_dict_viewkeys ////////////////////
......@@ -434,9 +431,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewKeys(PyObject* d) {
//////////////////// py_dict_viewvalues.proto ////////////////////
#if PY_VERSION_HEX < 0x02070000
#error This module uses dict views, which require Python 2.7 or later
#endif
static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewValues(PyObject* d); /*proto*/
//////////////////// py_dict_viewvalues ////////////////////
......@@ -450,9 +444,6 @@ static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewValues(PyObject* d) {
//////////////////// py_dict_viewitems.proto ////////////////////
#if PY_VERSION_HEX < 0x02070000
#error This module uses dict views, which require Python 2.7 or later
#endif
static CYTHON_INLINE PyObject* __Pyx_PyDict_ViewItems(PyObject* d); /*proto*/
//////////////////// py_dict_viewitems ////////////////////
......
......@@ -6,15 +6,7 @@ static CYTHON_INLINE PyObject *__pyx_capsule_create(void *p, const char *sig);
//////////////// Capsule ////////////////
static CYTHON_INLINE PyObject *
__pyx_capsule_create(void *p, CYTHON_UNUSED const char *sig)
__pyx_capsule_create(void *p, const char *sig)
{
PyObject *cobj;
#if PY_VERSION_HEX >= 0x02070000
cobj = PyCapsule_New(p, sig, NULL);
#else
cobj = PyCObject_FromVoidPtr(p, NULL);
#endif
return cobj;
return PyCapsule_New(p, sig, NULL);
}
......@@ -56,7 +56,6 @@ static void* __Pyx_FetchCommonPointer(void* pointer, const char* name);
static void* __Pyx_FetchCommonPointer(void* pointer, const char* name) {
#if PY_VERSION_HEX >= 0x02070000
PyObject* fake_module = NULL;
PyObject* capsule = NULL;
void* value = NULL;
......@@ -80,7 +79,4 @@ bad:
Py_XDECREF(capsule);
Py_DECREF(fake_module);
return value;
#else
return pointer;
#endif
}
......@@ -6,10 +6,7 @@ cdef extern from *:
int PY_VERSION_HEX
cdef object __Pyx_OrderedDict
if PY_VERSION_HEX >= 0x02070000:
from collections import OrderedDict as __Pyx_OrderedDict
else:
__Pyx_OrderedDict = dict
from collections import OrderedDict as __Pyx_OrderedDict
@cython.internal
cdef class __Pyx_EnumMeta(type):
......
......@@ -412,7 +412,6 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**
PyModule_GetName(module), funcname);
goto bad;
}
#if PY_VERSION_HEX >= 0x02070000
if (!PyCapsule_IsValid(cobj, sig)) {
PyErr_Format(PyExc_TypeError,
"C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
......@@ -420,21 +419,6 @@ static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**
goto bad;
}
tmp.p = PyCapsule_GetPointer(cobj, sig);
#else
{const char *desc, *s1, *s2;
desc = (const char *)PyCObject_GetDesc(cobj);
if (!desc)
goto bad;
s1 = desc; s2 = sig;
while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; }
if (*s1 != *s2) {
PyErr_Format(PyExc_TypeError,
"C function %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
PyModule_GetName(module), funcname, sig, desc);
goto bad;
}
tmp.p = PyCObject_AsVoidPtr(cobj);}
#endif
*f = tmp.fp;
if (!(*f))
goto bad;
......@@ -472,11 +456,7 @@ static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *s
goto bad;
}
tmp.fp = f;
#if PY_VERSION_HEX >= 0x02070000
cobj = PyCapsule_New(tmp.p, sig, 0);
#else
cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
#endif
if (!cobj)
goto bad;
if (PyDict_SetItemString(d, name, cobj) < 0)
......@@ -513,7 +493,6 @@ static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, con
PyModule_GetName(module), name);
goto bad;
}
#if PY_VERSION_HEX >= 0x02070000
if (!PyCapsule_IsValid(cobj, sig)) {
PyErr_Format(PyExc_TypeError,
"C variable %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
......@@ -521,21 +500,6 @@ static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, con
goto bad;
}
*p = PyCapsule_GetPointer(cobj, sig);
#else
{const char *desc, *s1, *s2;
desc = (const char *)PyCObject_GetDesc(cobj);
if (!desc)
goto bad;
s1 = desc; s2 = sig;
while (*s1 != '\0' && *s1 == *s2) { s1++; s2++; }
if (*s1 != *s2) {
PyErr_Format(PyExc_TypeError,
"C variable %.200s.%.200s has wrong signature (expected %.500s, got %.500s)",
PyModule_GetName(module), name, sig, desc);
goto bad;
}
*p = PyCObject_AsVoidPtr(cobj);}
#endif
if (!(*p))
goto bad;
Py_DECREF(d);
......@@ -567,11 +531,7 @@ static int __Pyx_ExportVoidPtr(PyObject *name, void *p, const char *sig) {
if (__Pyx_PyObject_SetAttrStr($module_cname, PYIDENT("$api_name"), d) < 0)
goto bad;
}
#if PY_VERSION_HEX >= 0x02070000
cobj = PyCapsule_New(p, sig, 0);
#else
cobj = PyCObject_FromVoidPtrAndDesc(p, (void *)sig, 0);
#endif
if (!cobj)
goto bad;
if (PyDict_SetItem(d, name, cobj) < 0)
......@@ -593,11 +553,7 @@ static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
/////////////// SetVTable ///////////////
static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
#if PY_VERSION_HEX >= 0x02070000
PyObject *ob = PyCapsule_New(vtable, 0, 0);
#else
PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
#endif
if (!ob)
goto bad;
if (PyDict_SetItem(dict, PYIDENT("__pyx_vtable__"), ob) < 0)
......@@ -621,11 +577,7 @@ static void* __Pyx_GetVtable(PyObject *dict) {
PyObject *ob = PyObject_GetItem(dict, PYIDENT("__pyx_vtable__"));
if (!ob)
goto bad;
#if PY_VERSION_HEX >= 0x02070000
ptr = PyCapsule_GetPointer(ob, 0);
#else
ptr = PyCObject_AsVoidPtr(ob);
#endif
if (!ptr && !PyErr_Occurred())
PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
Py_DECREF(ob);
......
......@@ -29,9 +29,7 @@
#ifndef HAVE_LONG_LONG
// CPython has required PY_LONG_LONG support for years, even if HAVE_LONG_LONG is not defined for us
#if PY_VERSION_HEX >= 0x02070000
#define HAVE_LONG_LONG
#endif
#define HAVE_LONG_LONG
#endif
#ifndef PY_LONG_LONG
......@@ -135,11 +133,7 @@
#ifndef CYTHON_USE_TYPE_SLOTS
#define CYTHON_USE_TYPE_SLOTS 1
#endif
#if PY_VERSION_HEX < 0x02070000
// looks like calling _PyType_Lookup() isn't safe in Py<=2.6/3.1
#undef CYTHON_USE_PYTYPE_LOOKUP
#define CYTHON_USE_PYTYPE_LOOKUP 0
#elif !defined(CYTHON_USE_PYTYPE_LOOKUP)
#ifndef CYTHON_USE_PYTYPE_LOOKUP
#define CYTHON_USE_PYTYPE_LOOKUP 1
#endif
#if PY_MAJOR_VERSION < 3
......@@ -148,10 +142,7 @@
#elif !defined(CYTHON_USE_ASYNC_SLOTS)
#define CYTHON_USE_ASYNC_SLOTS 1
#endif
#if PY_VERSION_HEX < 0x02070000
#undef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 0
#elif !defined(CYTHON_USE_PYLONG_INTERNALS)
#ifndef CYTHON_USE_PYLONG_INTERNALS
#define CYTHON_USE_PYLONG_INTERNALS 1
#endif
#ifndef CYTHON_USE_PYLIST_INTERNALS
......@@ -470,7 +461,7 @@ class __Pyx_FakeReference {
#define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno)
#endif
#if !CYTHON_FAST_THREAD_STATE || PY_VERSION_HEX < 0x02070000
#if !CYTHON_FAST_THREAD_STATE
#define __Pyx_PyThreadState_Current PyThreadState_GET()
#elif PY_VERSION_HEX >= 0x03060000
//#elif PY_VERSION_HEX >= 0x03050200
......@@ -1396,10 +1387,6 @@ static void __Pyx_FastGilFuncInit(void);
#define __Pyx_FastGIL_PyCapsule \
__Pyx_FastGIL_ABI_module "." __Pyx_FastGIL_PyCapsuleName
#if PY_VERSION_HEX < 0x02070000
#undef CYTHON_THREAD_LOCAL
#endif
#ifdef CYTHON_THREAD_LOCAL
#include "pythread.h"
......@@ -1492,11 +1479,7 @@ static void __Pyx_FastGilFuncInit0(void) {
#endif
static void __Pyx_FastGilFuncInit(void) {
#if PY_VERSION_HEX >= 0x02070000
struct __Pyx_FastGilVtab* shared = (struct __Pyx_FastGilVtab*)PyCapsule_Import(__Pyx_FastGIL_PyCapsule, 1);
#else
struct __Pyx_FastGilVtab* shared = NULL;
#endif
if (shared) {
__Pyx_FastGilFuncs = *shared;
} else {
......
......@@ -199,10 +199,8 @@ static CYTHON_INLINE PyObject *__Pyx_PyIter_Next2(PyObject* iterator, PyObject*
next = iternext(iterator);
if (likely(next))
return next;
#if PY_VERSION_HEX >= 0x02070000
if (unlikely(iternext == &_PyObject_NextNotImplemented))
return NULL;
#endif
#else
// Since the slot was set, assume that PyIter_Next() will likely succeed, and properly fail otherwise.
// Note: PyIter_Next() crashes in CPython if "tp_iternext" is NULL.
......@@ -1303,7 +1301,7 @@ static PyObject *__Pyx_RaiseGenericGetAttributeError(PyTypeObject *tp, PyObject
}
static CYTHON_INLINE PyObject* __Pyx_PyObject_GenericGetAttrNoDict(PyObject* obj, PyObject* attr_name) {
// Copied and adapted from _PyObject_GenericGetAttrWithDict() in CPython 2.6/3.7.
// Copied and adapted from _PyObject_GenericGetAttrWithDict() in CPython 3.6/3.7.
// To be used in the "tp_getattro" slot of extension types that have no instance dict and cannot be subclassed.
PyObject *descr;
PyTypeObject *tp = Py_TYPE(obj);
......
......@@ -412,12 +412,7 @@ EXT_EXTRAS = {
VER_DEP_MODULES = {
# tests are excluded if 'CurrentPythonVersion OP VersionTuple', i.e.
# (2,4) : (operator.lt, ...) excludes ... when PyVer < 2.4.x
(2,7) : (operator.lt, lambda x: x in ['run.withstat_py27', # multi context with statement
'run.yield_inside_lambda',
'run.test_dictviews',
'run.pyclass_special_methods',
'run.set_literals',
]),
# The next line should start (3,); but this is a dictionary, so
# we can only have one (3,) key. Since 2.7 is supposed to be the
# last 2.x release, things would have to change drastically for this
......@@ -1260,8 +1255,7 @@ class CythonRunTestCase(CythonCompileTestCase):
try:
self.success = False
ext_so_path = self.runCompileTest()
# Py2.6 lacks "_TextTestResult.skipped"
failures, errors, skipped = len(result.failures), len(result.errors), len(getattr(result, 'skipped', []))
failures, errors, skipped = len(result.failures), len(result.errors), len(result.skipped)
if not self.cython_only and ext_so_path is not None:
self.run_tests(result, ext_so_path)
if failures == len(result.failures) and errors == len(result.errors):
......@@ -1445,10 +1439,6 @@ class PartialTestResult(_TextTestResult):
_TextTestResult.__init__(
self, self._StringIO(), True,
base_result.dots + base_result.showAll*2)
try:
self.skipped
except AttributeError:
self.skipped = [] # Py2.6
def strip_error_results(self, results):
for test_case, error in results:
......@@ -1473,10 +1463,7 @@ class PartialTestResult(_TextTestResult):
if output:
result.stream.write(output)
result.errors.extend(errors)
try:
result.skipped.extend(skipped)
except AttributeError:
pass # Py2.6
result.skipped.extend(skipped)
result.failures.extend(failures)
result.testsRun += tests_run
......@@ -2209,7 +2196,7 @@ def time_stamper_thread(interval=10):
write('\n#### %s\n' % now())
thread = threading.Thread(target=time_stamper, name='time_stamper')
thread.setDaemon(True) # Py2.6 ...
thread.setDaemon(True) # Py2 ...
thread.start()
try:
yield
......
import sys
__doc__ = u""
if sys.version_info[:2] == (2, 6):
__doc__ += u"""
>>> memoryview = _memoryview
"""
__doc__ += u"""
__doc__ = u"""
>>> b1 = UserBuffer1()
>>> m1 = memoryview(b1)
>>> m1.tolist()
[0, 1, 2, 3, 4]
>>> del m1, b1
"""
__doc__ += u"""
>>> b2 = UserBuffer2()
>>> m2 = memoryview(b2)
UserBuffer2: getbuffer
......
......@@ -6,10 +6,6 @@ __doc__ = u"""
>>> call4()
"""
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"Error: (.*)exactly(.*)", u"Error: \\1at most\\2", __doc__)
# the calls:
def call2():
......
......@@ -1853,11 +1853,7 @@ def test_struct_attributes_format():
"""
cdef TestAttrs[10] array
cdef TestAttrs[:] struct_memview = array
if sys.version_info[:2] >= (2, 7):
print builtins.memoryview(struct_memview).format
else:
print "T{i:int_attrib:c:char_attrib:}"
print builtins.memoryview(struct_memview).format
# Test padding at the end of structs in the buffer support
......
import sys
def empty_float():
"""
>>> float()
......@@ -11,24 +9,20 @@ def empty_float():
x = float()
return x
def float_conjugate():
"""
>>> float_call_conjugate()
1.5
"""
if sys.version_info >= (2,6):
x = 1.5 .conjugate()
else:
x = 1.5
x = 1.5 .conjugate()
return x
def float_call_conjugate():
"""
>>> float_call_conjugate()
1.5
"""
if sys.version_info >= (2,6):
x = float(1.5).conjugate()
else:
x = 1.5
x = float(1.5).conjugate()
return x
# ticket: 236
__doc__ = ''
import sys
if sys.version_info >= (2,6):
__doc__ += '''
__doc__ = '''
>>> float_is_integer(1.0)
True
>>> float_is_integer(1.1)
......@@ -19,7 +17,6 @@ True
'''
def float_is_integer(float f):
# requires Python 2.6+
return f.is_integer()
def int_bit_length(int i):
......
......@@ -70,14 +70,8 @@ def test_as_variable_from_cython():
"""
>>> test_as_variable_from_cython()
"""
import sys
if sys.version_info >= (2, 7):
assert list(PyxEnum) == [TWO, THREE, FIVE], list(PyxEnum)
assert list(PxdEnum) == [RANK_0, RANK_1, RANK_2], list(PxdEnum)
else:
# No OrderedDict.
assert set(PyxEnum) == {TWO, THREE, FIVE}, list(PyxEnum)
assert set(PxdEnum) == {RANK_0, RANK_1, RANK_2}, list(PxdEnum)
assert list(PyxEnum) == [TWO, THREE, FIVE], list(PyxEnum)
assert list(PxdEnum) == [RANK_0, RANK_1, RANK_2], list(PxdEnum)
cdef int verify_pure_c() nogil:
cdef int x = TWO
......
......@@ -88,15 +88,13 @@ __doc__ = u"""
(1, ('a', 1), ('b', 2))
"""
import sys, re
if sys.version_info >= (2,6):
__doc__ = re.sub(u"(ELLIPSIS[^>]*Error: )[^\n]*\n", u"\\1...\n", __doc__)
cdef sorteditems(d):
l = list(d.items())
l.sort()
return tuple(l)
cdef class Silly:
def __init__(self, *a):
......
......@@ -5,7 +5,6 @@ cimport numpy as np
cimport cython
import re
import sys
def little_endian():
......@@ -20,7 +19,7 @@ def testcase(f):
def testcase_have_buffer_interface(f):
major, minor, *rest = np.__version__.split('.')
if (int(major), int(minor)) >= (1, 5) and sys.version_info[:2] >= (2, 6):
if (int(major), int(minor)) >= (1, 5):
__test__[f.__name__] = f.__doc__
return f
......
......@@ -247,16 +247,6 @@ class AsyncGenTest(unittest.TestCase):
else:
self.assertTrue(False)
if sys.version_info < (2, 7):
def assertIn(self, x, container):
self.assertTrue(x in container)
def assertIs(self, x, y):
self.assertTrue(x is y)
assertRaises = assertRaisesRegex
def compare_generators(self, sync_gen, async_gen):
def sync_iterate(g):
res = []
......
......@@ -144,17 +144,6 @@ def silence_coro_gc():
gc.collect()
def min_py27(method):
return None if sys.version_info < (2, 7) else method
def ignore_py26(manager):
@contextlib.contextmanager
def dummy():
yield
return dummy() if sys.version_info < (2, 7) else manager
@contextlib.contextmanager
def captured_stderr():
try:
......@@ -1826,7 +1815,7 @@ class CoroutineTest(unittest.TestCase):
buffer = []
async def test1():
with ignore_py26(self.assertWarnsRegex(DeprecationWarning, "legacy")):
with self.assertWarnsRegex(DeprecationWarning, "legacy"):
async for i1, i2 in AsyncIter():
buffer.append(i1 + i2)
......@@ -1840,7 +1829,7 @@ class CoroutineTest(unittest.TestCase):
buffer = []
async def test2():
nonlocal buffer
with ignore_py26(self.assertWarnsRegex(DeprecationWarning, "legacy")):
with self.assertWarnsRegex(DeprecationWarning, "legacy"):
async for i in AsyncIter():
buffer.append(i[0])
if i[0] == 20:
......@@ -1859,7 +1848,7 @@ class CoroutineTest(unittest.TestCase):
buffer = []
async def test3():
nonlocal buffer
with ignore_py26(self.assertWarnsRegex(DeprecationWarning, "legacy")):
with self.assertWarnsRegex(DeprecationWarning, "legacy"):
async for i in AsyncIter():
if i[0] > 20:
continue
......@@ -2076,7 +2065,6 @@ class CoroutineTest(unittest.TestCase):
self.assertEqual(CNT, 0)
# old-style pre-Py3.5.2 protocol - no longer supported
@min_py27
def __test_for_9(self):
# Test that DeprecationWarning can safely be converted into
# an exception (__aiter__ should not have a chance to raise
......@@ -2094,7 +2082,6 @@ class CoroutineTest(unittest.TestCase):
run_async(foo())
# old-style pre-Py3.5.2 protocol - no longer supported
@min_py27
def __test_for_10(self):
# Test that DeprecationWarning can safely be converted into
# an exception.
......
......@@ -10,7 +10,6 @@ import contextlib
import sys
IS_PY2 = sys.version_info[0] < 3
IS_PY26 = sys.version_info[:2] < (2, 7)
from Cython.Build.Inline import cython_inline
from Cython.TestUtils import CythonTest
......@@ -63,23 +62,8 @@ class TestCase(CythonTest):
first = stripped_first.decode('unicode_escape')
super(TestCase, self).assertEqual(first, second, msg)
if IS_PY26:
@contextlib.contextmanager
def assertRaises(self, exc):
try:
yield
except exc:
pass
else:
assert False, "exception '%s' not raised" % exc
def assertIn(self, value, collection):
self.assertTrue(value in collection)
def test__format__lookup(self):
if IS_PY26:
return
elif IS_PY2:
if IS_PY2:
raise unittest.SkipTest("Py3-only")
# Make sure __format__ is looked up on the type, not the instance.
......@@ -288,12 +272,11 @@ f'{a * x()}'"""
width = 10
precision = 4
value = decimal.Decimal('12.34567')
if not IS_PY26:
self.assertEqual(f'result: {value:{width}.{precision}}', 'result: 12.35')
self.assertEqual(f'result: {value:{width!r}.{precision}}', 'result: 12.35')
self.assertEqual(f'result: {value:{width:0}.{precision:1}}', 'result: 12.35')
self.assertEqual(f'result: {value:{1}{0:0}.{precision:1}}', 'result: 12.35')
self.assertEqual(f'result: {value:{ 1}{ 0:0}.{ precision:1}}', 'result: 12.35')
self.assertEqual(f'result: {value:{width}.{precision}}', 'result: 12.35')
self.assertEqual(f'result: {value:{width!r}.{precision}}', 'result: 12.35')
self.assertEqual(f'result: {value:{width:0}.{precision:1}}', 'result: 12.35')
self.assertEqual(f'result: {value:{1}{0:0}.{precision:1}}', 'result: 12.35')
self.assertEqual(f'result: {value:{ 1}{ 0:0}.{ precision:1}}', 'result: 12.35')
self.assertEqual(f'{10:#{1}0x}', ' 0xa')
self.assertEqual(f'{10:{"#"}1{0}{"x"}}', ' 0xa')
self.assertEqual(f'{-10:-{"#"}1{0}x}', ' -0xa')
......@@ -312,8 +295,7 @@ f'{a * x()}'"""
])
# CYTHON: The nesting restriction seems rather arbitrary. Ignoring it for now and instead test that it works.
if not IS_PY26:
self.assertEqual(f'result: {value:{width:{0}}.{precision:1}}', 'result: 12.35')
self.assertEqual(f'result: {value:{width:{0}}.{precision:1}}', 'result: 12.35')
#self.assertAllRaise(SyntaxError, "f-string: expressions nested too deeply",
# [# Can't nest format specifiers.
# "f'result: {value:{width:{0}}.{precision:1}}'",
......@@ -678,10 +660,9 @@ f'{a * x()}'"""
def test_conversions(self):
self.assertEqual(f'{3.14:10.10}', ' 3.14')
if not IS_PY26:
self.assertEqual(f'{3.14!s:10.10}', '3.14 ')
self.assertEqual(f'{3.14!r:10.10}', '3.14 ')
self.assertEqual(f'{3.14!a:10.10}', '3.14 ')
self.assertEqual(f'{3.14!s:10.10}', '3.14 ')
self.assertEqual(f'{3.14!r:10.10}', '3.14 ')
self.assertEqual(f'{3.14!a:10.10}', '3.14 ')
self.assertEqual(f'{"a"}', 'a')
self.assertEqual(f'{"a"!r}', "'a'")
......
......@@ -1520,24 +1520,6 @@ class GrammarTests(unittest.TestCase):
GrammarTests.assertRaisesRegex = lambda self, exc, msg: self.assertRaises(exc)
if sys.version_info < (2, 7):
def assertRaises(self, exc_type, func=None, *args, **kwargs):
if func is not None:
return unittest.TestCase.assertRaises(self, exc_type, func, *args, **kwargs)
@contextlib.contextmanager
def assertRaisesCM():
class Result(object):
exception = exc_type("unexpected EOF") # see usage above
try:
yield Result()
except exc_type:
self.assertTrue(True)
else:
self.assertTrue(False)
return assertRaisesCM()
GrammarTests.assertRaises = assertRaises
TokenTests.assertRaises = assertRaises
if not hasattr(unittest.TestCase, 'subTest'):
@contextlib.contextmanager
......@@ -1550,20 +1532,10 @@ if not hasattr(unittest.TestCase, 'subTest'):
GrammarTests.subTest = subTest
if not hasattr(unittest.TestCase, 'assertIn'):
def assertIn(self, member, container, msg=None):
self.assertTrue(member in container, msg)
TokenTests.assertIn = assertIn
# FIXME: disabling some tests for real Cython bugs here
del GrammarTests.test_comprehension_specials # iterable pre-calculation in generator expression
del GrammarTests.test_funcdef # annotation mangling
# this test is difficult to enable in Py2.6
if sys.version_info < (2,7):
del GrammarTests.test_former_statements_refer_to_builtins
if __name__ == '__main__':
unittest.main()
......@@ -87,11 +87,7 @@ __doc__ = br"""
True
>>> ustring_in_constant_tuple == ('a', u'abc', u'\\N{SNOWMAN}', u'x' * 3, u'\\N{SNOWMAN}' * 4 + u'O') or ustring_in_constant_tuple # unescaped by Python
True
"""
if sys.version_info >= (2,6,5):
# this doesn't work well in older Python versions
__doc__ += u"""\
>>> expected = u'\U00101234' # unescaped by Cython
>>> if wide_literal == expected: print(True)
... else: print(repr(wide_literal), repr(expected), sys.maxunicode)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment