gh-99482: remove jython compatibility parts from stdlib and tests (#99484)

This commit is contained in:
Nikita Sobolev 2022-12-23 23:17:24 +03:00 committed by GitHub
parent c5726b727e
commit 745545b5bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 134 additions and 232 deletions

View file

@ -955,6 +955,9 @@ Removed
``SSTATE_INTERNED_IMMORTAL`` macro. ``SSTATE_INTERNED_IMMORTAL`` macro.
(Contributed by Victor Stinner in :gh:`85858`.) (Contributed by Victor Stinner in :gh:`85858`.)
* Remove ``Jython`` compatibility hacks from several stdlib modules and tests.
(Contributed by Nikita Sobolev in :gh:`99482`.)
* Remove ``_use_broken_old_ctypes_structure_semantics_`` flag * Remove ``_use_broken_old_ctypes_structure_semantics_`` flag
from :mod:`ctypes` module. from :mod:`ctypes` module.
(Contributed by Nikita Sobolev in :gh:`99285`.) (Contributed by Nikita Sobolev in :gh:`99285`.)

View file

@ -56,11 +56,6 @@ class Error(Exception):
pass pass
error = Error # backward compatibility error = Error # backward compatibility
try:
from org.python.core import PyStringMap
except ImportError:
PyStringMap = None
__all__ = ["Error", "copy", "deepcopy"] __all__ = ["Error", "copy", "deepcopy"]
def copy(x): def copy(x):
@ -120,9 +115,6 @@ d[dict] = dict.copy
d[set] = set.copy d[set] = set.copy
d[bytearray] = bytearray.copy d[bytearray] = bytearray.copy
if PyStringMap is not None:
d[PyStringMap] = PyStringMap.copy
del d, t del d, t
def deepcopy(x, memo=None, _nil=[]): def deepcopy(x, memo=None, _nil=[]):
@ -231,8 +223,6 @@ def _deepcopy_dict(x, memo, deepcopy=deepcopy):
y[deepcopy(key, memo)] = deepcopy(value, memo) y[deepcopy(key, memo)] = deepcopy(value, memo)
return y return y
d[dict] = _deepcopy_dict d[dict] = _deepcopy_dict
if PyStringMap is not None:
d[PyStringMap] = _deepcopy_dict
def _deepcopy_method(x, memo): # Copy instance methods def _deepcopy_method(x, memo): # Copy instance methods
return type(x)(x.__func__, deepcopy(x.__self__, memo)) return type(x)(x.__func__, deepcopy(x.__self__, memo))
@ -301,4 +291,4 @@ def _reconstruct(x, memo, func, args,
y[key] = value y[key] = value
return y return y
del types, weakref, PyStringMap del types, weakref

View file

@ -98,12 +98,6 @@ class _Stop(Exception):
def __init__(self, value): def __init__(self, value):
self.value = value self.value = value
# Jython has PyStringMap; it's a dict subclass with string keys
try:
from org.python.core import PyStringMap
except ImportError:
PyStringMap = None
# Pickle opcodes. See pickletools.py for extensive docs. The listing # Pickle opcodes. See pickletools.py for extensive docs. The listing
# here is in kind-of alphabetical order of 1-character pickle code. # here is in kind-of alphabetical order of 1-character pickle code.
# pickletools groups them by purpose. # pickletools groups them by purpose.
@ -972,8 +966,6 @@ class _Pickler:
self._batch_setitems(obj.items()) self._batch_setitems(obj.items())
dispatch[dict] = save_dict dispatch[dict] = save_dict
if PyStringMap is not None:
dispatch[PyStringMap] = save_dict
def _batch_setitems(self, items): def _batch_setitems(self, items):
# Helper to batch up SETITEMS sequences; proto >= 1 only # Helper to batch up SETITEMS sequences; proto >= 1 only

View file

@ -1290,7 +1290,7 @@ def platform(aliased=0, terse=0):
else: else:
platform = _platform(system, release, version, csd) platform = _platform(system, release, version, csd)
elif system in ('Linux',): elif system == 'Linux':
# check for libc vs. glibc # check for libc vs. glibc
libcname, libcversion = libc_ver() libcname, libcversion = libc_ver()
platform = _platform(system, release, machine, processor, platform = _platform(system, release, machine, processor,

View file

@ -404,11 +404,6 @@ def setquit():
def setcopyright(): def setcopyright():
"""Set 'copyright' and 'credits' in builtins""" """Set 'copyright' and 'credits' in builtins"""
builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright) builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright)
if sys.platform[:4] == 'java':
builtins.credits = _sitebuiltins._Printer(
"credits",
"Jython is maintained by the Jython developers (www.jython.org).")
else:
builtins.credits = _sitebuiltins._Printer("credits", """\ builtins.credits = _sitebuiltins._Printer("credits", """\
Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
for supporting Python development. See www.python.org for more information.""") for supporting Python development. See www.python.org for more information.""")

View file

@ -505,6 +505,7 @@ def requires_debug_ranges(reason='requires co_positions / debug_ranges'):
requires_legacy_unicode_capi = unittest.skipUnless(unicode_legacy_string, requires_legacy_unicode_capi = unittest.skipUnless(unicode_legacy_string,
'requires legacy Unicode C API') 'requires legacy Unicode C API')
# Is not actually used in tests, but is kept for compatibility.
is_jython = sys.platform.startswith('java') is_jython = sys.platform.startswith('java')
is_android = hasattr(sys, 'getandroidapilevel') is_android = hasattr(sys, 'getandroidapilevel')
@ -736,8 +737,6 @@ def gc_collect():
""" """
import gc import gc
gc.collect() gc.collect()
if is_jython:
time.sleep(0.1)
gc.collect() gc.collect()
gc.collect() gc.collect()

View file

@ -11,10 +11,6 @@ import warnings
# Filename used for testing # Filename used for testing
if os.name == 'java':
# Jython disallows @ in module names
TESTFN_ASCII = '$test'
else:
TESTFN_ASCII = '@test' TESTFN_ASCII = '@test'
# Disambiguate TESTFN for parallel testing, while letting it remain a valid # Disambiguate TESTFN for parallel testing, while letting it remain a valid

View file

@ -100,7 +100,6 @@ class AllTest(unittest.TestCase):
'__future__', '__future__',
]) ])
if not sys.platform.startswith('java'):
# In case _socket fails to build, make this test fail more gracefully # In case _socket fails to build, make this test fail more gracefully
# than an AttributeError somewhere deep in CGIHTTPServer. # than an AttributeError somewhere deep in CGIHTTPServer.
import _socket import _socket

View file

@ -2,45 +2,16 @@
Test cases for codeop.py Test cases for codeop.py
Nick Mathewson Nick Mathewson
""" """
import sys
import unittest import unittest
import warnings import warnings
from test import support
from test.support import warnings_helper from test.support import warnings_helper
from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT
import io
if support.is_jython:
def unify_callables(d):
for n,v in d.items():
if hasattr(v, '__call__'):
d[n] = True
return d
class CodeopTests(unittest.TestCase): class CodeopTests(unittest.TestCase):
def assertValid(self, str, symbol='single'): def assertValid(self, str, symbol='single'):
'''succeed iff str is a valid piece of code''' '''succeed iff str is a valid piece of code'''
if support.is_jython:
code = compile_command(str, "<input>", symbol)
self.assertTrue(code)
if symbol == "single":
d,r = {},{}
saved_stdout = sys.stdout
sys.stdout = io.StringIO()
try:
exec(code, d)
exec(compile(str,"<input>","single"), r)
finally:
sys.stdout = saved_stdout
elif symbol == 'eval':
ctx = {'a': 2}
d = { 'value': eval(code,ctx) }
r = { 'value': eval(str,ctx) }
self.assertEqual(unify_callables(r),unify_callables(d))
else:
expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT) expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT)
self.assertEqual(compile_command(str, "<input>", symbol), expected) self.assertEqual(compile_command(str, "<input>", symbol), expected)
@ -62,16 +33,12 @@ class CodeopTests(unittest.TestCase):
av = self.assertValid av = self.assertValid
# special case # special case
if not support.is_jython:
self.assertEqual(compile_command(""), self.assertEqual(compile_command(""),
compile("pass", "<input>", 'single', compile("pass", "<input>", 'single',
PyCF_DONT_IMPLY_DEDENT)) PyCF_DONT_IMPLY_DEDENT))
self.assertEqual(compile_command("\n"), self.assertEqual(compile_command("\n"),
compile("pass", "<input>", 'single', compile("pass", "<input>", 'single',
PyCF_DONT_IMPLY_DEDENT)) PyCF_DONT_IMPLY_DEDENT))
else:
av("")
av("\n")
av("a = 1") av("a = 1")
av("\na = 1") av("\na = 1")

View file

@ -360,7 +360,6 @@ class ExceptionTests(unittest.TestCase):
self.assertRaises(SystemError, _testcapi.raise_exception, self.assertRaises(SystemError, _testcapi.raise_exception,
InvalidException, 1) InvalidException, 1)
if not sys.platform.startswith('java'):
test_capi1() test_capi1()
test_capi2() test_capi2()
test_capi3() test_capi3()

View file

@ -20,7 +20,7 @@ from unittest import mock
from test.support import os_helper from test.support import os_helper
from test.support import ( from test.support import (
STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only, is_emscripten, STDLIB_DIR, swap_attr, swap_item, cpython_only, is_emscripten,
is_wasi) is_wasi)
from test.support.import_helper import ( from test.support.import_helper import (
forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport) forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport)
@ -163,9 +163,6 @@ class ImportTests(unittest.TestCase):
def test_with_extension(ext): def test_with_extension(ext):
# The extension is normally ".py", perhaps ".pyw". # The extension is normally ".py", perhaps ".pyw".
source = TESTFN + ext source = TESTFN + ext
if is_jython:
pyc = TESTFN + "$py.class"
else:
pyc = TESTFN + ".pyc" pyc = TESTFN + ".pyc"
with open(source, "w", encoding='utf-8') as f: with open(source, "w", encoding='utf-8') as f:

View file

@ -329,7 +329,7 @@ class PlatformTest(unittest.TestCase):
def test_java_ver(self): def test_java_ver(self):
res = platform.java_ver() res = platform.java_ver()
if sys.platform == 'java': if sys.platform == 'java': # Is never actually checked in CI
self.assertTrue(all(res)) self.assertTrue(all(res))
def test_win32_ver(self): def test_win32_ver(self):

View file

@ -54,10 +54,6 @@ class StrftimeTest(unittest.TestCase):
self.now = now self.now = now
def setUp(self): def setUp(self):
try:
import java
java.util.Locale.setDefault(java.util.Locale.US)
except ImportError:
from locale import setlocale, LC_TIME from locale import setlocale, LC_TIME
saved_locale = setlocale(LC_TIME) saved_locale = setlocale(LC_TIME)
setlocale(LC_TIME, 'C') setlocale(LC_TIME, 'C')

View file

@ -94,7 +94,6 @@ class UnicodeTest(string_tests.CommonTest,
self.assertNotEqual(r"\u0020", " ") self.assertNotEqual(r"\u0020", " ")
def test_ascii(self): def test_ascii(self):
if not sys.platform.startswith('java'):
# Test basic sanity of repr() # Test basic sanity of repr()
self.assertEqual(ascii('abc'), "'abc'") self.assertEqual(ascii('abc'), "'abc'")
self.assertEqual(ascii('ab\\c'), "'ab\\\\c'") self.assertEqual(ascii('ab\\c'), "'ab\\\\c'")
@ -136,7 +135,6 @@ class UnicodeTest(string_tests.CommonTest,
self.assertRaises(TypeError, ascii, WrongRepr()) self.assertRaises(TypeError, ascii, WrongRepr())
def test_repr(self): def test_repr(self):
if not sys.platform.startswith('java'):
# Test basic sanity of repr() # Test basic sanity of repr()
self.assertEqual(repr('abc'), "'abc'") self.assertEqual(repr('abc'), "'abc'")
self.assertEqual(repr('ab\\c'), "'ab\\\\c'") self.assertEqual(repr('ab\\c'), "'ab\\\\c'")
@ -684,7 +682,6 @@ class UnicodeTest(string_tests.CommonTest,
def test_isupper(self): def test_isupper(self):
super().test_isupper() super().test_isupper()
if not sys.platform.startswith('java'):
self.checkequalnofix(False, '\u1FFc', 'isupper') self.checkequalnofix(False, '\u1FFc', 'isupper')
self.assertTrue('\u2167'.isupper()) self.assertTrue('\u2167'.isupper())
self.assertFalse('\u2177'.isupper()) self.assertFalse('\u2177'.isupper())
@ -1473,7 +1470,6 @@ class UnicodeTest(string_tests.CommonTest,
self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 3.5), 'abc, abc, -1, -2.000000, 3.50') self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 3.5), 'abc, abc, -1, -2.000000, 3.50')
self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 3.57), 'abc, abc, -1, -2.000000, 3.57') self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 3.57), 'abc, abc, -1, -2.000000, 3.57')
self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 1003.57), 'abc, abc, -1, -2.000000, 1003.57') self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 1003.57), 'abc, abc, -1, -2.000000, 1003.57')
if not sys.platform.startswith('java'):
self.assertEqual("%r, %r" % (b"abc", "abc"), "b'abc', 'abc'") self.assertEqual("%r, %r" % (b"abc", "abc"), "b'abc', 'abc'")
self.assertEqual("%r" % ("\u1234",), "'\u1234'") self.assertEqual("%r" % ("\u1234",), "'\u1234'")
self.assertEqual("%a" % ("\u1234",), "'\\u1234'") self.assertEqual("%a" % ("\u1234",), "'\\u1234'")
@ -1671,7 +1667,6 @@ class UnicodeTest(string_tests.CommonTest,
# unicode(obj, encoding, error) tests (this maps to # unicode(obj, encoding, error) tests (this maps to
# PyUnicode_FromEncodedObject() at C level) # PyUnicode_FromEncodedObject() at C level)
if not sys.platform.startswith('java'):
self.assertRaises( self.assertRaises(
TypeError, TypeError,
str, str,
@ -1685,7 +1680,6 @@ class UnicodeTest(string_tests.CommonTest,
'strings are decoded to unicode' 'strings are decoded to unicode'
) )
if not sys.platform.startswith('java'):
self.assertEqual( self.assertEqual(
str( str(
memoryview(b'character buffers are decoded to unicode'), memoryview(b'character buffers are decoded to unicode'),

View file

@ -56,7 +56,6 @@ except TypeError as exc:
TracebackType = type(exc.__traceback__) TracebackType = type(exc.__traceback__)
FrameType = type(exc.__traceback__.tb_frame) FrameType = type(exc.__traceback__.tb_frame)
# For Jython, the following two types are identical
GetSetDescriptorType = type(FunctionType.__code__) GetSetDescriptorType = type(FunctionType.__code__)
MemberDescriptorType = type(FunctionType.__globals__) MemberDescriptorType = type(FunctionType.__globals__)

View file

@ -57,9 +57,7 @@ def _make_skipped_test(methodname, exception, suiteClass):
TestClass = type("ModuleSkipped", (case.TestCase,), attrs) TestClass = type("ModuleSkipped", (case.TestCase,), attrs)
return suiteClass((TestClass(methodname),)) return suiteClass((TestClass(methodname),))
def _jython_aware_splitext(path): def _splitext(path):
if path.lower().endswith('$py.class'):
return path[:-9]
return os.path.splitext(path)[0] return os.path.splitext(path)[0]
@ -315,7 +313,7 @@ class TestLoader(object):
def _get_name_from_path(self, path): def _get_name_from_path(self, path):
if path == self._top_level_dir: if path == self._top_level_dir:
return '.' return '.'
path = _jython_aware_splitext(os.path.normpath(path)) path = _splitext(os.path.normpath(path))
_relpath = os.path.relpath(path, self._top_level_dir) _relpath = os.path.relpath(path, self._top_level_dir)
assert not os.path.isabs(_relpath), "Path must be within the project" assert not os.path.isabs(_relpath), "Path must be within the project"
@ -393,13 +391,13 @@ class TestLoader(object):
else: else:
mod_file = os.path.abspath( mod_file = os.path.abspath(
getattr(module, '__file__', full_path)) getattr(module, '__file__', full_path))
realpath = _jython_aware_splitext( realpath = _splitext(
os.path.realpath(mod_file)) os.path.realpath(mod_file))
fullpath_noext = _jython_aware_splitext( fullpath_noext = _splitext(
os.path.realpath(full_path)) os.path.realpath(full_path))
if realpath.lower() != fullpath_noext.lower(): if realpath.lower() != fullpath_noext.lower():
module_dir = os.path.dirname(realpath) module_dir = os.path.dirname(realpath)
mod_name = _jython_aware_splitext( mod_name = _splitext(
os.path.basename(full_path)) os.path.basename(full_path))
expected_dir = os.path.dirname(full_path) expected_dir = os.path.dirname(full_path)
msg = ("%r module incorrectly imported from %r. Expected " msg = ("%r module incorrectly imported from %r. Expected "

View file

@ -60,11 +60,7 @@ if _false:
import os, sys import os, sys
if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ: if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ:
default_parser_list = os.environ["PY_SAX_PARSER"].split(",") default_parser_list = os.environ["PY_SAX_PARSER"].split(",")
del os del os, sys
_key = "python.xml.sax.parser"
if sys.platform[:4] == "java" and sys.registry.containsKey(_key):
default_parser_list = sys.registry.getProperty(_key).split(",")
def make_parser(parser_list=()): def make_parser(parser_list=()):
@ -93,15 +89,6 @@ def make_parser(parser_list=()):
# --- Internal utility methods used by make_parser # --- Internal utility methods used by make_parser
if sys.platform[ : 4] == "java":
def _create_parser(parser_name):
from org.python.core import imp
drv_module = imp.importName(parser_name, 0, globals())
return drv_module.create_parser()
else:
def _create_parser(parser_name): def _create_parser(parser_name):
drv_module = __import__(parser_name,{},{},['create_parser']) drv_module = __import__(parser_name,{},{},['create_parser'])
return drv_module.create_parser() return drv_module.create_parser()
del sys

View file

@ -1,8 +1,4 @@
"""Different kinds of SAX Exceptions""" """Different kinds of SAX Exceptions"""
import sys
if sys.platform[:4] == "java":
from java.lang import Exception
del sys
# ===== SAXEXCEPTION ===== # ===== SAXEXCEPTION =====

View file

@ -12,12 +12,6 @@ from xml.sax.handler import feature_external_ges, feature_external_pes
from xml.sax.handler import feature_string_interning from xml.sax.handler import feature_string_interning
from xml.sax.handler import property_xml_string, property_interning_dict from xml.sax.handler import property_xml_string, property_interning_dict
# xml.parsers.expat does not raise ImportError in Jython
import sys
if sys.platform[:4] == "java":
raise SAXReaderNotAvailable("expat not available in Java", None)
del sys
try: try:
from xml.parsers import expat from xml.parsers import expat
except ImportError: except ImportError:

View file

@ -0,0 +1 @@
Remove ``Jython`` partial compatibility code from several stdlib modules.