diff --git a/Lib/encodings/aliases.py b/Lib/encodings/aliases.py index e5e50630f33d14d..df4c230fbf9c4e4 100644 --- a/Lib/encodings/aliases.py +++ b/Lib/encodings/aliases.py @@ -226,6 +226,12 @@ # cp949 codec '949' : 'cp949', + 'korean' : 'cp949', + 'ksc5601' : 'cp949', + 'ks_c_5601' : 'cp949', + 'ks_c_5601_1987' : 'cp949', + 'ksx1001' : 'cp949', + 'ks_x_1001' : 'cp949', 'ms949' : 'cp949', 'uhc' : 'cp949', @@ -248,12 +254,6 @@ # euc_kr codec 'euckr' : 'euc_kr', - 'korean' : 'euc_kr', - 'ksc5601' : 'euc_kr', - 'ks_c_5601' : 'euc_kr', - 'ks_c_5601_1987' : 'euc_kr', - 'ksx1001' : 'euc_kr', - 'ks_x_1001' : 'euc_kr', 'cseuckr' : 'euc_kr', # gb18030 codec diff --git a/Lib/test/test_lazy_import/__init__.py b/Lib/test/test_lazy_import/__init__.py index 321733a4fdf1705..94576a206b42caa 100644 --- a/Lib/test/test_lazy_import/__init__.py +++ b/Lib/test/test_lazy_import/__init__.py @@ -21,8 +21,10 @@ _testcapi = None -class LazyImportTests(unittest.TestCase): - """Tests for basic lazy import functionality.""" +class LazyImportTestCase(unittest.TestCase): + def setUp(self): + self.lazy_imports_filter = sys.get_lazy_imports_filter() + self.lazy_imports = sys.get_lazy_imports() def tearDown(self): """Clean up any test modules from sys.modules.""" @@ -30,10 +32,14 @@ def tearDown(self): if key.startswith('test.test_lazy_import.data'): del sys.modules[key] - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") + sys.set_lazy_imports_filter(self.lazy_imports_filter) + sys.set_lazy_imports(self.lazy_imports) sys.lazy_modules.clear() + +class LazyImportTests(LazyImportTestCase): + """Tests for basic lazy import functionality.""" + def test_basic_unused(self): """Lazy imported module should not be loaded if never accessed.""" import test.test_lazy_import.data.basic_unused @@ -162,17 +168,9 @@ def test_from_import_with_imported_module_getattr(self): assert_python_ok("-c", code) -class GlobalLazyImportModeTests(unittest.TestCase): +class GlobalLazyImportModeTests(LazyImportTestCase): """Tests for sys.set_lazy_imports() global mode control.""" - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_global_off_rejected(self): """Mode 'none' is not supported.""" with self.assertRaises(ValueError): @@ -204,17 +202,9 @@ def test_global_filter_from_true(self): self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) -class CompatibilityModeTests(unittest.TestCase): +class CompatibilityModeTests(LazyImportTestCase): """Tests for __lazy_modules__ compatibility mode.""" - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_compatibility_mode(self): """__lazy_modules__ should enable lazy imports for listed modules.""" import test.test_lazy_import.data.basic_compatibility_mode @@ -241,17 +231,9 @@ def test_compatibility_mode_relative(self): self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) -class ModuleIntrospectionTests(unittest.TestCase): +class ModuleIntrospectionTests(LazyImportTestCase): """Tests for module dict and getattr behavior with lazy imports.""" - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_modules_dict(self): """Accessing module.__dict__ should not trigger reification.""" import test.test_lazy_import.data.modules_dict @@ -268,17 +250,9 @@ def test_modules_getattr_other(self): self.assertNotIn("test.test_lazy_import.data.basic2", sys.modules) -class LazyImportTypeTests(unittest.TestCase): +class LazyImportTypeTests(LazyImportTestCase): """Tests for the LazyImportType and its resolve() method.""" - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_lazy_value_resolve(self): """resolve() method should force the lazy import to load.""" import test.test_lazy_import.data.lazy_get_value @@ -304,17 +278,9 @@ def test_lazy_import_type_attributes_accessible(self): self.assertIn(b" bool """ - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def _run_subprocess_with_modules(self, code, files): with tempfile.TemporaryDirectory() as tmpdir: for relpath, contents in files.items(): @@ -1611,17 +1497,9 @@ def my_filter(importer, name, fromlist): self.assertIn("OK", result.stdout) -class AdditionalSyntaxRestrictionTests(unittest.TestCase): +class AdditionalSyntaxRestrictionTests(LazyImportTestCase): """Additional syntax restriction tests per PEP 810.""" - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_lazy_import_inside_class_raises_syntax_error(self): """lazy import inside class body should raise SyntaxError.""" # PEP 810: "The soft keyword is only allowed at the global (module) level, @@ -1631,7 +1509,7 @@ def test_lazy_import_inside_class_raises_syntax_error(self): @support.requires_subprocess() -class MixedLazyEagerImportTests(unittest.TestCase): +class MixedLazyEagerImportTests(LazyImportTestCase): """Tests for mixing lazy and eager imports of the same module. PEP 810: "If module foo is imported both lazily and eagerly in the same @@ -1639,14 +1517,6 @@ class MixedLazyEagerImportTests(unittest.TestCase): the same module object." """ - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_eager_import_before_lazy_resolves_to_same_module(self): """Eager import before lazy should make lazy resolve to same module.""" code = textwrap.dedent(""" @@ -1692,17 +1562,9 @@ def test_lazy_import_before_eager_resolves_to_same_module(self): self.assertIn("OK", result.stdout) -class RelativeImportTests(unittest.TestCase): +class RelativeImportTests(LazyImportTestCase): """Tests for relative imports with lazy keyword.""" - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_relative_lazy_import(self): """lazy from . import submodule should work.""" from test.test_lazy_import.data import relative_lazy @@ -1727,21 +1589,13 @@ def test_relative_lazy_from_import(self): self.assertIn("test.test_lazy_import.data.basic2", sys.modules) -class LazyModulesCompatibilityFromImportTests(unittest.TestCase): +class LazyModulesCompatibilityFromImportTests(LazyImportTestCase): """Tests for __lazy_modules__ with from imports. PEP 810: "When a module is made lazy this way, from-imports using that module are also lazy" """ - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_lazy_modules_makes_from_imports_lazy(self): """__lazy_modules__ should make from imports of listed modules lazy.""" from test.test_lazy_import.data import lazy_compat_from @@ -1756,7 +1610,7 @@ def test_lazy_modules_makes_from_imports_lazy(self): @support.requires_subprocess() -class ImportStateAtReificationTests(unittest.TestCase): +class ImportStateAtReificationTests(LazyImportTestCase): """Tests for import system state at reification time. PEP 810: "Reification still calls __import__ to resolve the import, which uses @@ -1765,14 +1619,6 @@ class ImportStateAtReificationTests(unittest.TestCase): statement was evaluated." """ - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_sys_path_at_reification_time_is_used(self): """sys.path changes after lazy import should affect reification.""" code = textwrap.dedent(""" @@ -1815,17 +1661,9 @@ def test_sys_path_at_reification_time_is_used(self): @support.requires_subprocess() -class ThreadSafetyTests(unittest.TestCase): +class ThreadSafetyTests(LazyImportTestCase): """Tests for thread-safety of lazy imports.""" - def tearDown(self): - for key in list(sys.modules.keys()): - if key.startswith('test.test_lazy_import.data'): - del sys.modules[key] - - sys.set_lazy_imports_filter(None) - sys.set_lazy_imports("normal") - def test_concurrent_lazy_import_reification(self): """Multiple threads racing to reify the same lazy import should succeed.""" from test.test_lazy_import.data import basic_unused @@ -2087,11 +1925,7 @@ def test_normal_import_dis(self): @unittest.skipIf(_testcapi is None, 'need the _testcapi module') -class LazyCApiTests(unittest.TestCase): - def tearDown(self): - sys.set_lazy_imports("normal") - sys.set_lazy_imports_filter(None) - +class LazyCApiTests(LazyImportTestCase): def test_set_matches_sys(self): self.assertEqual(_testcapi.PyImport_GetLazyImportsMode(), sys.get_lazy_imports()) for mode in ("normal", "all"): diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 9ee97b922ad48e1..63c130813ec4972 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -534,7 +534,7 @@ def test_ios_ver(self): def test_libc_ver(self): if support.is_emscripten: - assert platform.libc_ver() == ("emscripten", "4.0.12") + assert platform.libc_ver() == ("emscripten", "4.0.19") return # check that libc_ver(executable) doesn't raise an exception if os.path.isdir(sys.executable) and \ diff --git a/Misc/NEWS.d/next/Library/2026-06-04-23-10-31.gh-issue-62825.BtG_yQ.rst b/Misc/NEWS.d/next/Library/2026-06-04-23-10-31.gh-issue-62825.BtG_yQ.rst new file mode 100644 index 000000000000000..95a4fb1c61d4c30 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-04-23-10-31.gh-issue-62825.BtG_yQ.rst @@ -0,0 +1,2 @@ +Encodings "KS_C_5601-1987", "KS X 1001", etc are now aliases of "CP949" +instead of "EUC-KR". diff --git a/Platforms/emscripten/config.toml b/Platforms/emscripten/config.toml index ba2dc8f4a482bfa..401e9396ddbb009 100644 --- a/Platforms/emscripten/config.toml +++ b/Platforms/emscripten/config.toml @@ -1,7 +1,7 @@ # Any data that can vary between Python versions is to be kept in this file. # This allows for blanket copying of the Emscripten build code between supported # Python versions. -emscripten-version = "4.0.12" +emscripten-version = "4.0.19" node-version = "24" test-args = [ "-m", "test", diff --git a/Platforms/emscripten/streams.mjs b/Platforms/emscripten/streams.mjs index 76ad79f9247f4cf..1b121d48d4e76c6 100644 --- a/Platforms/emscripten/streams.mjs +++ b/Platforms/emscripten/streams.mjs @@ -112,7 +112,7 @@ const prepareBuffer = (buffer, offset, length) => const TTY_OPS = { ioctl_tiocgwinsz(tty) { - return tty.devops.ioctl_tiocgwinsz?.(); + return tty.devops.ioctl_tiocgwinsz?.() ?? [24, 80]; }, }; @@ -188,6 +188,10 @@ class NodeReader { fsync() { nodeFsync(this.nodeStream.fd); } + + ioctl_tiocgwinsz() { + return [this.nodeStream.rows ?? 24, this.nodeStream.columns ?? 80]; + } } class NodeWriter {