bpo-39432: Implement PEP-489 algorithm for non-ascii "PyInit_*" symbol names in distutils (GH-18150) (GH-18546)

Make it export the correct init symbol also on Windows.

https://bugs.python.org/issue39432
(cherry picked from commit 9538bc9185)

Co-authored-by: Stefan Behnel <stefan_ml@behnel.de>
This commit is contained in:
Miss Islington (bot) 2020-02-18 05:14:43 -08:00 committed by GitHub
parent 9d83984085
commit 5bf58cef15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 1 deletions

View File

@ -688,7 +688,15 @@ class build_ext(Command):
provided, "PyInit_" + module_name. Only relevant on Windows, where provided, "PyInit_" + module_name. Only relevant on Windows, where
the .pyd file (DLL) must export the module "PyInit_" function. 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: if initfunc_name not in ext.export_symbols:
ext.export_symbols.append(initfunc_name) ext.export_symbols.append(initfunc_name)
return ext.export_symbols return ext.export_symbols

View File

@ -304,6 +304,19 @@ class BuildExtTestCase(TempdirManager,
cmd.ensure_finalized() cmd.ensure_finalized()
self.assertEqual(cmd.get_source_files(), ['xxx']) 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): def test_compiler_option(self):
# cmd.compiler is an option and # cmd.compiler is an option and
# should not be overridden by a compiler instance # should not be overridden by a compiler instance

View File

@ -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.