diff --git a/jpype/_core.py b/jpype/_core.py index a71935535..0fcfba7de 100644 --- a/jpype/_core.py +++ b/jpype/_core.py @@ -44,14 +44,6 @@ class JVMNotRunning(RuntimeError): pass -def versionTest(): - if sys.version_info < (3,): - raise ImportError("Python 2 is not supported") - - -versionTest() - - # Activate jedi tab completion try: import jedi as _jedi diff --git a/jpype/_pykeywords.py b/jpype/_pykeywords.py index 18ee2132c..295393241 100644 --- a/jpype/_pykeywords.py +++ b/jpype/_pykeywords.py @@ -16,8 +16,9 @@ # # ***************************************************************************** -# This is a super set of the keywords in Python2 and Python3. +# This is a superset of the keywords in Python. # We use this so that jpype is a bit more version independent. +# Removing keywords from this list impacts the exposed interfaces, and therefore is a breaking change. _KEYWORDS = set(( 'False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', diff --git a/jpype/imports.py b/jpype/imports.py index dfc53a167..d9a68ee81 100644 --- a/jpype/imports.py +++ b/jpype/imports.py @@ -24,8 +24,6 @@ ``net`` and ``edu``. Java symbols from these domains can be imported using the standard Python syntax. -Import customizers are supported in Python 3.6 or greater. - Forms supported: - **import [ as ]** - **import . [ as ]** @@ -36,9 +34,6 @@ For further information please read the :doc:`imports` guide. -Requires: - Python 3.6 or later - Example: .. code-block:: python diff --git a/jpype/pickle.py b/jpype/pickle.py index 34726a083..13eb97a95 100644 --- a/jpype/pickle.py +++ b/jpype/pickle.py @@ -49,9 +49,6 @@ Proxies and other JPype specific module resources cannot be pickled currently. -Requires: - Python 3.6 or later - """ from __future__ import absolute_import import _jpype @@ -89,8 +86,7 @@ def __init__(self, dispatch): # Extension dispatch table holds reduce method self._call = self.reduce - # Python2 and Python3 _Pickler use get() - + # Pure Python _Pickler uses get() def get(self, cls): if not issubclass(cls, (_jpype.JClass, _jpype.JObject)): return self._dispatch.get(cls) @@ -102,7 +98,6 @@ def __getitem__(self, cls): return self._dispatch[cls] return self._call - # For Python3 def reduce(self, obj): byte = bytes(self._encoder.pack(obj)) return (self._builder, (byte, )) diff --git a/jpype/protocol.py b/jpype/protocol.py index fc77854d0..bf447ac39 100644 --- a/jpype/protocol.py +++ b/jpype/protocol.py @@ -105,18 +105,6 @@ def _JInstantConversion(jcls, obj): return jcls.ofEpochSecond(sec, nsec) -if sys.version_info < (3, 6): # pragma: no cover - import pathlib - - @_jcustomizer.JConversion("java.nio.file.Path", instanceof=pathlib.PurePath) - def _JPathConvert(jcls, obj): - Paths = _jpype.JClass("java.nio.file.Paths") - return Paths.get(str(obj)) - - @_jcustomizer.JConversion("java.io.File", instanceof=pathlib.PurePath) - def _JFileConvert(jcls, obj): - return jcls(str(obj)) - # Types needed for SQL diff --git a/native/python/pyjp_array.cpp b/native/python/pyjp_array.cpp index 3a702e3f8..9dc53774c 100644 --- a/native/python/pyjp_array.cpp +++ b/native/python/pyjp_array.cpp @@ -160,16 +160,12 @@ static PyObject *PyJPArray_getItem(PyJPArray *self, PyObject *item) Py_ssize_t start, stop, step, slicelength; Py_ssize_t length = (Py_ssize_t) self->m_Array->getLength(); -#if PY_VERSION_HEX<0x03060100 - if (PySlice_GetIndicesEx(item, length, &start, &stop, &step, &slicelength) < 0) - return NULL; -#else if (PySlice_Unpack(item, &start, &stop, &step) < 0) return NULL; slicelength = PySlice_AdjustIndices(length, &start, &stop, step); -#endif - if (slicelength <= 0) + + if (slicelength <= 0) { // This should point to a null array so we don't hold worthless // memory, but this is a low priority @@ -231,16 +227,12 @@ static int PyJPArray_assignSubscript(PyJPArray *self, PyObject *item, PyObject * Py_ssize_t start, stop, step, slicelength; Py_ssize_t length = (Py_ssize_t) self->m_Array->getLength(); -#if PY_VERSION_HEX<0x03060100 - if (PySlice_GetIndicesEx(item, length, &start, &stop, &step, &slicelength) < 0) - return -1; -#else if (PySlice_Unpack(item, &start, &stop, &step) < 0) return -1; slicelength = PySlice_AdjustIndices(length, &start, &stop, step); -#endif - if (slicelength <= 0) + + if (slicelength <= 0) return 0; self->m_Array->setRange((jsize) start, (jsize) slicelength, (jsize) step, value); diff --git a/native/python/pyjp_class.cpp b/native/python/pyjp_class.cpp index 87fd68584..2b9bab9da 100644 --- a/native/python/pyjp_class.cpp +++ b/native/python/pyjp_class.cpp @@ -702,14 +702,10 @@ static bool PySlice_CheckFull(PyObject *item) if (!PySlice_Check(item)) return false; Py_ssize_t start, stop, step; -#if PY_VERSION_HEX<0x03060100 - int rc = PySlice_GetIndices(item, 0x7fffffff, &start, &stop, &step); - return (rc == 0)&&(start == 0)&&(step == 1)&&((int) stop == 0x7fffffff); -#elif defined(ANDROID) int rc = PySlice_Unpack(item, &start, &stop, &step); +#if defined(ANDROID) return (rc == 0)&&(start == 0)&&(step == 1)&&((int) stop >= 0x7fffffff); #else - int rc = PySlice_Unpack(item, &start, &stop, &step); return (rc == 0)&&(start == 0)&&(step == 1)&&((int) stop == -1); #endif } diff --git a/native/python/pyjp_module.cpp b/native/python/pyjp_module.cpp index 6466af8a9..90917df62 100644 --- a/native/python/pyjp_module.cpp +++ b/native/python/pyjp_module.cpp @@ -714,14 +714,6 @@ PyMODINIT_FUNC PyInit__jpype() JP_PY_TRY("PyInit__jpype"); JPContext_global = new JPContext(); -#if PY_VERSION_HEX<0x03070000 - // This is required for python versions prior to 3.7. - // It is called by the python initialization starting from 3.7, - // but is safe to call afterwards. Starting 3.9 this issues a - // deprecation warning. - PyEval_InitThreads(); -#endif - // Initialize the module (depends on python version) PyObject* module = PyModule_Create(&moduledef); // PyJPModule = module; diff --git a/setup.py b/setup.py index 1f9922f5e..f587649a7 100644 --- a/setup.py +++ b/setup.py @@ -58,7 +58,7 @@ author_email='devilwolf@users.sourceforge.net', maintainer='Luis Nell', maintainer_email='cooperate@originell.org', - python_requires=">=3.5", + python_requires=">=3.7", url='https://github.com/jpype-project/jpype', platforms=[ 'Operating System :: Microsoft :: Windows', @@ -68,10 +68,10 @@ ], classifiers=[ 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.5', - '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', 'Topic :: Software Development', 'Topic :: Scientific/Engineering', ], diff --git a/test/jpypetest/test_closeable.py b/test/jpypetest/test_closeable.py index 74a893591..d8f58a874 100644 --- a/test/jpypetest/test_closeable.py +++ b/test/jpypetest/test_closeable.py @@ -17,11 +17,6 @@ # ***************************************************************************** import jpype import common -import sys - - -def pythonNewerThan(major, minor): - return sys.version_info[0] > major or (sys.version_info[0] == major and sys.version_info[1] > minor) class CloseableTestCase(common.JPypeTestCase): @@ -38,7 +33,6 @@ def testCloseable(self): self.assertEqual(CloseableTest.printed, "hello 1") self.assertTrue(CloseableTest.closed) - @common.unittest.skipUnless(pythonNewerThan(3, 0), "requires python 3") def testCloseableFail(self): CloseableTest = jpype.JClass("jpype.closeable.CloseableTest") CloseableTest.reset() @@ -72,7 +66,6 @@ def testCloseablePyExcept(self): self.assertEqual(CloseableTest.printed, "hello 2") self.assertTrue(CloseableTest.closed) - @common.unittest.skipUnless(pythonNewerThan(2, 6), "Earlier python does not support stacked exceptions.") def testCloseablePyExceptFail(self): CloseableTest = jpype.JClass("jpype.closeable.CloseableTest") CloseableTest.reset() @@ -105,7 +98,6 @@ def testCloseableJExcept(self): self.assertEqual(CloseableTest.printed, "hello 4") self.assertTrue(CloseableTest.closed) - @common.unittest.skipUnless(pythonNewerThan(2, 6), "Earlier python does not support stacked exceptions.") def testCloseableJExceptFail(self): CloseableTest = jpype.JClass("jpype.closeable.CloseableTest") CloseableTest.reset() diff --git a/test/jpypetest/test_core.py b/test/jpypetest/test_core.py index 9bdfa74de..2cec5fbfc 100644 --- a/test/jpypetest/test_core.py +++ b/test/jpypetest/test_core.py @@ -25,14 +25,6 @@ class JCharTestCase(common.JPypeTestCase): def setUp(self): common.JPypeTestCase.setUp(self) - @mock.patch('jpype._core.sys') - def testVersion(self, mock_sys): - mock_sys.version_info = (2, 7) - with self.assertRaises(ImportError): - jpype._core.versionTest() - mock_sys.version_info = (3, 8) - jpype._core.versionTest() - def testShutdownHook(self): Thread = JClass("java.lang.Thread") Runnable = JClass("java.lang.Runnable") diff --git a/test/jpypetest/test_overloads.py b/test/jpypetest/test_overloads.py index b088b3632..7604ac7ba 100644 --- a/test/jpypetest/test_overloads.py +++ b/test/jpypetest/test_overloads.py @@ -128,7 +128,7 @@ def testVarArgsCall(self): def testPrimitive(self): test1 = self.__jp.Test1() - intexpectation = 'int' if not sys.version_info[0] > 2 and sys.maxint == 2**31 - 1 else 'long' + intexpectation = 'long' # FIXME it is not possible to determine if this is bool/char/byte currently #self.assertEqual(intexpectation, test1.testPrimitive(5)) #self.assertEqual('long', test1.testPrimitive(2**31))