diff options
| author | Stefan Behnel <stefan_ml@behnel.de> | 2020-02-04 16:24:30 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-04 07:24:30 -0800 |
| commit | daf18dd027a08dd318f348e12e75e9f4d8aaed0a (patch) | |
| tree | c8120fa6e04e47d31f96d9ecd845737073faf01e | |
| parent | c4419ed0099645ef3c27a617f93e9a6182962693 (diff) | |
| download | python-setuptools-git-daf18dd027a08dd318f348e12e75e9f4d8aaed0a.tar.gz | |
bpo-39432: Implement PEP-489 algorithm for non-ascii "PyInit_*" symbol names in distutils (GH-18150)
Make it export the correct init symbol also on Windows.
https://bugs.python.org/issue39432
| -rw-r--r-- | command/build_ext.py | 10 | ||||
| -rw-r--r-- | tests/test_build_ext.py | 13 |
2 files changed, 22 insertions, 1 deletions
diff --git a/command/build_ext.py b/command/build_ext.py index 38bb8fd9..1a9bd120 100644 --- a/command/build_ext.py +++ b/command/build_ext.py @@ -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 diff --git a/tests/test_build_ext.py b/tests/test_build_ext.py index 52d36b24..7e3eafa8 100644 --- a/tests/test_build_ext.py +++ b/tests/test_build_ext.py @@ -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 |
