]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39432: Implement PEP-489 algorithm for non-ascii "PyInit_*" symbol names in distu...
authorStefan Behnel <stefan_ml@behnel.de>
Tue, 4 Feb 2020 15:24:30 +0000 (16:24 +0100)
committerGitHub <noreply@github.com>
Tue, 4 Feb 2020 15:24:30 +0000 (07:24 -0800)
Make it export the correct init symbol also on Windows.

https://bugs.python.org/issue39432

Lib/distutils/command/build_ext.py
Lib/distutils/tests/test_build_ext.py
Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst [new file with mode: 0644]

index 38bb8fd93c2781b7421d0e35ec63fccf1e271968..1a9bd1200f82358c5a758c69c433bb55621e157e 100644 (file)
@@ -689,7 +689,15 @@ class build_ext(Command):
         provided, "PyInit_" + module_name.  Only relevant on Windows, where
         the .pyd file (DLL) must export the module "PyInit_" function.
         """
-        initfunc_name = "PyInit_" + ext.name.split('.')[-1]
+        suffix = '_' + ext.name.split('.')[-1]
+        try:
+            # Unicode module name support as defined in PEP-489
+            # https://www.python.org/dev/peps/pep-0489/#export-hook-name
+            suffix.encode('ascii')
+        except UnicodeEncodeError:
+            suffix = 'U' + suffix.encode('punycode').replace(b'-', b'_').decode('ascii')
+
+        initfunc_name = "PyInit" + suffix
         if initfunc_name not in ext.export_symbols:
             ext.export_symbols.append(initfunc_name)
         return ext.export_symbols
index 52d36b2484f4147430a39aed911edb23efb81d64..7e3eafa8ef231e822dae7b2669a68f9fcc992956 100644 (file)
@@ -304,6 +304,19 @@ class BuildExtTestCase(TempdirManager,
         cmd.ensure_finalized()
         self.assertEqual(cmd.get_source_files(), ['xxx'])
 
+    def test_unicode_module_names(self):
+        modules = [
+            Extension('foo', ['aaa'], optional=False),
+            Extension('föö', ['uuu'], optional=False),
+        ]
+        dist = Distribution({'name': 'xx', 'ext_modules': modules})
+        cmd = self.build_ext(dist)
+        cmd.ensure_finalized()
+        self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo\..*')
+        self.assertRegex(cmd.get_ext_filename(modules[1].name), r'föö\..*')
+        self.assertEqual(cmd.get_export_symbols(modules[0]), ['PyInit_foo'])
+        self.assertEqual(cmd.get_export_symbols(modules[1]), ['PyInitU_f_gkaa'])
+
     def test_compiler_option(self):
         # cmd.compiler is an option and
         # should not be overridden by a compiler instance
diff --git a/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst b/Misc/NEWS.d/next/Library/2020-01-23-16-08-58.bpo-39432.Cee6mi.rst
new file mode 100644 (file)
index 0000000..21c4ba8
--- /dev/null
@@ -0,0 +1 @@
+Implement PEP-489 algorithm for non-ascii "PyInit\_..." symbol names in distutils to make it export the correct init symbol also on Windows.