|
4 | 4 | for the Distutils compiler abstraction model."""
|
5 | 5 |
|
6 | 6 | import os
|
| 7 | +import pathlib |
7 | 8 | import re
|
8 | 9 | import sys
|
9 | 10 | import types
|
@@ -969,27 +970,33 @@ def out_extensions(self):
|
969 | 970 | return dict.fromkeys(self.src_extensions, self.obj_extension)
|
970 | 971 |
|
971 | 972 | def _make_out_path(self, output_dir, strip_dir, src_name):
|
972 |
| - base, ext = os.path.splitext(src_name) |
973 |
| - base = self._make_relative(base) |
| 973 | + return self._make_out_path_exts( |
| 974 | + output_dir, strip_dir, src_name, self.out_extensions |
| 975 | + ) |
| 976 | + |
| 977 | + @classmethod |
| 978 | + def _make_out_path_exts(cls, output_dir, strip_dir, src_name, extensions): |
| 979 | + r""" |
| 980 | + >>> exts = {'.c': '.o'} |
| 981 | + >>> CCompiler._make_out_path_exts('.', False, '/foo/bar.c', exts).replace('\\', '/') |
| 982 | + './foo/bar.o' |
| 983 | + >>> CCompiler._make_out_path_exts('.', True, '/foo/bar.c', exts).replace('\\', '/') |
| 984 | + './bar.o' |
| 985 | + """ |
| 986 | + src = pathlib.PurePath(src_name) |
| 987 | + # Ensure base is relative to honor output_dir (python/cpython#37775). |
| 988 | + base = cls._make_relative(src) |
974 | 989 | try:
|
975 |
| - new_ext = self.out_extensions[ext] |
| 990 | + new_ext = extensions[src.suffix] |
976 | 991 | except LookupError:
|
977 |
| - raise UnknownFileError(f"unknown file type '{ext}' (from '{src_name}')") |
| 992 | + raise UnknownFileError(f"unknown file type '{src.suffix}' (from '{src}')") |
978 | 993 | if strip_dir:
|
979 |
| - base = os.path.basename(base) |
980 |
| - return os.path.join(output_dir, base + new_ext) |
| 994 | + base = pathlib.PurePath(base.name) |
| 995 | + return os.path.join(output_dir, base.with_suffix(new_ext)) |
981 | 996 |
|
982 | 997 | @staticmethod
|
983 |
| - def _make_relative(base): |
984 |
| - """ |
985 |
| - In order to ensure that a filename always honors the |
986 |
| - indicated output_dir, make sure it's relative. |
987 |
| - Ref python/cpython#37775. |
988 |
| - """ |
989 |
| - # Chop off the drive |
990 |
| - no_drive = os.path.splitdrive(base)[1] |
991 |
| - # If abs, chop off leading / |
992 |
| - return no_drive[os.path.isabs(no_drive) :] |
| 998 | + def _make_relative(base: pathlib.Path): |
| 999 | + return base.relative_to(base.anchor) |
993 | 1000 |
|
994 | 1001 | def shared_object_filename(self, basename, strip_dir=False, output_dir=''):
|
995 | 1002 | assert output_dir is not None
|
|
0 commit comments