diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index bd6c036a..00000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -matrix: - include: - - os: linux - language: python - python: 3.6 - - os: linux - dist: xenial # or later - language: python - python: 3.7 - - os: linux - dist: xenial # or later - language: python - python: 3.8 - - os: linux - dist: xenial # or later - language: python - python: 3.9 - - os: linux - dist: bionic # or later - language: python - python: 3.10.1 # 3.10 doesn't currently work. - - os: linux - dist: xenial - language: java - jdk: openjdk8 - - os: linux - language: java - jdk: openjdk11 - - os: linux - language: java - jdk: openjdk17 - - os: osx - language: generic - -script: python3 ./setup.py test - diff --git a/README.rst b/README.rst index 7834cbb9..7c6ae933 100644 --- a/README.rst +++ b/README.rst @@ -48,7 +48,7 @@ environment such as enabling numpy specific behavior if numpy is installed. Dependencies ------------ -* Python >= 3.6 +* Python >= 3.10 * Java >= 1.8 * NumPy >= 1.7 (optional) diff --git a/appveyor.yml b/appveyor.yml index 9ac61c2b..39925d8e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -3,14 +3,6 @@ image: Visual Studio 2019 environment: matrix: - - PYTHON: "C:\\Python37-x64" - JAVA_HOME: "C:\\Program Files\\Java\\jdk1.8.0" - - PYTHON: "C:\\Python37-x64" - JAVA_HOME: "C:\\Program Files\\Java\\jdk11" - - PYTHON: "C:\\Python38-x64" - JAVA_HOME: "C:\\Program Files\\Java\\jdk11" - - PYTHON: "C:\\Python39-x64" - JAVA_HOME: "C:\\Program Files\\Java\\jdk11" - PYTHON: "C:\\Python310-x64" JAVA_HOME: "C:\\Program Files\\Java\\jdk11" - PYTHON: "C:\\Python310-x64" diff --git a/release_notes/4.3-notes.rst b/release_notes/4.3-notes.rst new file mode 100644 index 00000000..014ee467 --- /dev/null +++ b/release_notes/4.3-notes.rst @@ -0,0 +1,4 @@ +Jep 4.3 Release Notes +********************* +This release drops support for versions of Python older than 3.10. + diff --git a/setup.py b/setup.py index a81e6880..6f7de21a 100755 --- a/setup.py +++ b/setup.py @@ -100,10 +100,6 @@ def read_file(name): 'Topic :: Software Development', 'Programming Language :: Java', 'Programming Language :: Python', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', diff --git a/src/main/c/Include/pyjbuffer.h b/src/main/c/Include/pyjbuffer.h index 2d553c35..fd85562e 100644 --- a/src/main/c/Include/pyjbuffer.h +++ b/src/main/c/Include/pyjbuffer.h @@ -37,9 +37,6 @@ #ifndef _Included_pyjbuffer #define _Included_pyjbuffer -extern PyTypeObject PyJBuffer_Type; - -#define PyJBuffer_Check(pyobj) \ - PyObject_TypeCheck(pyobj, &PyJBuffer_Type) +extern PyType_Spec PyJBuffer_Spec; #endif // ndef pyjbuffer diff --git a/src/main/c/Jep/convert_j2p.c b/src/main/c/Jep/convert_j2p.c index af8d62e9..ae23c919 100644 --- a/src/main/c/Jep/convert_j2p.c +++ b/src/main/c/Jep/convert_j2p.c @@ -105,11 +105,7 @@ static PyObject* pyjobject_convert_pyobject(PyObject* pyjob) PyObject* topy = PyObject_GetAttrString(pyjob, "_to_python"); if (topy != NULL) { Py_DECREF(pyjob); -#if PY_MAJOR_VERSION > 3 || PY_MINOR_VERSION >= 9 result = PyObject_CallNoArgs(topy); -#else - result = PyObject_CallObject(topy, NULL); -#endif Py_DECREF(topy); } else { /* This is exactly what is done in PyObject_HasAttr. */ diff --git a/src/main/c/Jep/pyembed.c b/src/main/c/Jep/pyembed.c index 775f6b78..d2a3f94e 100644 --- a/src/main/c/Jep/pyembed.c +++ b/src/main/c/Jep/pyembed.c @@ -301,14 +301,6 @@ static int pyjtypes_ready(void) if (PyType_Ready(&PyJClass_Type) < 0) { return -1; } - - if (!PyJBuffer_Type.tp_base) { - PyJBuffer_Type.tp_base = &PyJObject_Type; - } - if (PyType_Ready(&PyJBuffer_Type) < 0) { - return -1; - } - return 0; } @@ -382,10 +374,6 @@ void pyembed_startup(JNIEnv *env, jobjectArray sharedModulesArgv) Py_Initialize(); -#if PY_MAJOR_VERSION < 4 && PY_MINOR_VERSION < 7 - PyEval_InitThreads(); -#endif - if (pyjtypes_ready()) { handle_startup_exception(env, "Failed to initialize PyJTypes"); return; @@ -1386,10 +1374,8 @@ static void pyembed_run_pyc(JepThread *jepThread, // Python 3.3 added an extra long containing the size of the source. // https://github.com/python/cpython/commit/5136ac0ca21a05691978df8d0650f902c8ca3463 (void) PyMarshal_ReadLongFromFile(fp); -#if PY_MAJOR_VERSION > 3 || PY_MINOR_VERSION >= 7 // PEP 552 added another long (void) PyMarshal_ReadLongFromFile(fp); -#endif v = (PyObject *) (intptr_t) PyMarshal_ReadLastObjectFromFile(fp); if (v == NULL || !PyCode_Check(v)) { Py_XDECREF(v); diff --git a/src/main/c/Objects/pyjbuffer.c b/src/main/c/Objects/pyjbuffer.c index f2d6fe51..6d5eb99e 100644 --- a/src/main/c/Objects/pyjbuffer.c +++ b/src/main/c/Objects/pyjbuffer.c @@ -151,55 +151,15 @@ getbuf(PyObject* self, Py_buffer *view, int flags) return 0; } - -static PyBufferProcs buffer_as_buffer = { - (getbufferproc)getbuf, - (releasebufferproc)NULL +static PyType_Slot slots[] = { + {Py_tp_doc, "Jep java.nio.Buffer"}, + {Py_bf_getbuffer, (void*) getbuf}, + {0, NULL}, }; - - -/* - * Inherits from PyJObject_Type - */ -PyTypeObject PyJBuffer_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "java.nio.Buffer", - sizeof(PyJObject), - 0, - 0, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - &buffer_as_buffer, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - "Jep java.nio.Buffer", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, // &PyJObject_Type /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - NULL, /* tp_new */ +PyType_Spec PyJBuffer_Spec = { + .name = "java.nio.Buffer", + .basicsize = sizeof(PyJObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = slots }; diff --git a/src/main/c/Objects/pyjtype.c b/src/main/c/Objects/pyjtype.c index 716ec42c..2ad8e58b 100644 --- a/src/main/c/Objects/pyjtype.c +++ b/src/main/c/Objects/pyjtype.c @@ -73,16 +73,7 @@ static PyTypeObject* addCustomTypeToTypeDict(JNIEnv *env, PyObject* fqnToPyType, static PyTypeObject* addSpecToTypeDict(JNIEnv *env, PyObject* fqnToPyType, jclass class, PyType_Spec *spec, PyTypeObject *base) { - /* TODO Starting in 3.10 bases can be a single type so there will be no need to make a tuple. */ - PyObject *bases = NULL; - if (base) { - bases = PyTuple_Pack(1, base); - if (!bases) { - return NULL; - } - } - PyTypeObject *type = (PyTypeObject*) PyType_FromSpecWithBases(spec, bases); - Py_XDECREF(bases); + PyTypeObject *type = (PyTypeObject*) PyType_FromSpecWithBases(spec, (PyObject*) base); if (!type) { return NULL; } @@ -134,20 +125,17 @@ static int populateCustomTypeDict(JNIEnv *env, PyObject* fqnToPyType) &PyJObject_Type)) { return -1; } + if (!addSpecToTypeDict(env, fqnToPyType, JBUFFER_TYPE, &PyJBuffer_Spec, + &PyJObject_Type)) { + return -1; + } + if (staticTypesInitialized) { - if (PyDict_SetItemString(fqnToPyType, PyJBuffer_Type.tp_name, - (PyObject * ) &PyJBuffer_Type)) { - return -1; - } if (PyDict_SetItemString(fqnToPyType, PyJObject_Type.tp_name, (PyObject * ) &PyJObject_Type)) { return -1; } } else { - /* TODO In python 3.8 buffer protocol was added to spec so pybuffer type can use a spec */ - if (!addCustomTypeToTypeDict(env, fqnToPyType, JBUFFER_TYPE, &PyJBuffer_Type)) { - return -1; - } if (!addCustomTypeToTypeDict(env, fqnToPyType, JOBJECT_TYPE, &PyJObject_Type)) { return -1; } diff --git a/src/test/python/test_allow_python_enquirer.py b/src/test/python/test_allow_python_enquirer.py index 2118b6fe..e4847c2e 100644 --- a/src/test/python/test_allow_python_enquirer.py +++ b/src/test/python/test_allow_python_enquirer.py @@ -1,4 +1,3 @@ -import sys import unittest from jep_pipe import jep_pipe @@ -6,7 +5,5 @@ class TestAllowPythonEnquirer(unittest.TestCase): - @unittest.skipIf(sys.version_info.major == 3 and sys.version_info.minor < 7, - "Test needs re.Pattern which was added in Python 3.7") def test_allow_python_enquirer(self): jep_pipe(build_java_process_cmd('jep.test.TestAllowPythonEnquirer')) diff --git a/src/test/python/test_types.py b/src/test/python/test_types.py index aa2d60b6..da98d804 100644 --- a/src/test/python/test_types.py +++ b/src/test/python/test_types.py @@ -1,6 +1,5 @@ import unittest from math import isnan -import sys import jep TestMethodTypes = jep.findClass('jep.test.types.TestMethodTypes') TestStaticMethodTypes = jep.findClass('jep.test.types.TestStaticMethodTypes') @@ -785,8 +784,7 @@ def test_int_array(self): v = memoryview(a) v = v[::2] examples.append(v) - if sys.version_info.major > 3 or sys.version_info.minor > 7: - examples.append(v.toreadonly()) + examples.append(v.toreadonly()) for l in examples: self.assertSequenceEqual(l, self.methods.intArray(l)) self.assertSequenceEqual(l, self.staticMethods.intArray(l)) @@ -829,9 +827,8 @@ def test_byte_array(self): v = v[::2] bb = ByteBuffer.wrap(v) self.assertSequenceEqual(bb.array(), v) - if sys.version_info.major > 3 or sys.version_info.minor > 7: - bb = ByteBuffer.wrap(v.toreadonly()) - self.assertSequenceEqual(bb.array(), v) + bb = ByteBuffer.wrap(v.toreadonly()) + self.assertSequenceEqual(bb.array(), v) with self.assertRaises(TypeError): ByteBuffer.wrap(array.array('f', [1,2,3,4])) self.assertSequenceEqual(self.methods.object(b'binary'), b'binary') @@ -847,9 +844,8 @@ def test_float_array(self): v = v[::2] fb = FloatBuffer.wrap(v) self.assertSequenceEqual(fb.array(), v) - if sys.version_info.major > 3 or sys.version_info.minor > 7: - fb = FloatBuffer.wrap(v.toreadonly()) - self.assertSequenceEqual(fb.array(), v) + fb = FloatBuffer.wrap(v.toreadonly()) + self.assertSequenceEqual(fb.array(), v) with self.assertRaises(TypeError): FloatBuffer.wrap(array.array('i', [1,2,3,4])) @@ -864,9 +860,8 @@ def test_long_array(self): v = v[::2] lb = LongBuffer.wrap(v) self.assertSequenceEqual(lb.array(), v) - if sys.version_info.major > 3 or sys.version_info.minor > 7: - lb = LongBuffer.wrap(v.toreadonly()) - self.assertSequenceEqual(lb.array(), v) + lb = LongBuffer.wrap(v.toreadonly()) + self.assertSequenceEqual(lb.array(), v) with self.assertRaises(TypeError): LongBuffer.wrap(array.array('f', [1,2,3,4]))