Skip to content

Commit edf9c52

Browse files
committed
Move dependency header includes to internal header
1 parent 20f793c commit edf9c52

2 files changed

Lines changed: 65 additions & 11 deletions

File tree

mypyc/codegen/emitmodule.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -638,27 +638,29 @@ def generate_c_for_modules(self) -> list[tuple[str, str]]:
638638
ext_declarations.emit_line(f"#define MYPYC_NATIVE{self.group_suffix}_H")
639639
ext_declarations.emit_line("#include <Python.h>")
640640
ext_declarations.emit_line("#include <CPy.h>")
641+
642+
declarations = Emitter(self.context)
643+
declarations.emit_line(f"#ifndef MYPYC_LIBRT_INTERNAL{self.group_suffix}_H")
644+
declarations.emit_line(f"#define MYPYC_LIBRT_INTERNAL{self.group_suffix}_H")
645+
declarations.emit_line("#include <Python.h>")
646+
declarations.emit_line("#include <CPy.h>")
647+
641648
if self.compiler_options.depends_on_librt_internal:
642-
ext_declarations.emit_line("#include <internal/librt_internal.h>")
649+
declarations.emit_line("#include <internal/librt_internal.h>")
643650
if any(LIBRT_BASE64 in mod.dependencies for mod in self.modules.values()):
644-
ext_declarations.emit_line("#include <base64/librt_base64.h>")
651+
declarations.emit_line("#include <base64/librt_base64.h>")
645652
if any(LIBRT_STRINGS in mod.dependencies for mod in self.modules.values()):
646-
ext_declarations.emit_line("#include <strings/librt_strings.h>")
653+
declarations.emit_line("#include <strings/librt_strings.h>")
647654
if any(LIBRT_TIME in mod.dependencies for mod in self.modules.values()):
648-
ext_declarations.emit_line("#include <time/librt_time.h>")
655+
declarations.emit_line("#include <time/librt_time.h>")
649656
if any(LIBRT_VECS in mod.dependencies for mod in self.modules.values()):
650-
ext_declarations.emit_line("#include <vecs/librt_vecs.h>")
657+
declarations.emit_line("#include <vecs/librt_vecs.h>")
651658
# Include headers for conditional source files
652659
source_deps = collect_source_dependencies(self.modules)
653660
for source_dep in sorted(source_deps, key=lambda d: d.path):
654661
if header := source_dep.get_header():
655-
ext_declarations.emit_line(f'#include "{header}"')
662+
declarations.emit_line(f'#include "{header}"')
656663

657-
declarations = Emitter(self.context)
658-
declarations.emit_line(f"#ifndef MYPYC_LIBRT_INTERNAL{self.group_suffix}_H")
659-
declarations.emit_line(f"#define MYPYC_LIBRT_INTERNAL{self.group_suffix}_H")
660-
declarations.emit_line("#include <Python.h>")
661-
declarations.emit_line("#include <CPy.h>")
662664
declarations.emit_line(f'#include "__native{self.short_group_suffix}.h"')
663665
declarations.emit_line()
664666
declarations.emit_line("int CPyGlobalsInit(void);")

mypyc/test-data/run-multimodule.test

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1410,3 +1410,55 @@ from other import test
14101410

14111411
input = b'x' * 512
14121412
assert test(input) == input
1413+
1414+
[case testLibrtDependencyInImportedFile_experimental_librt]
1415+
# Test that a compiled file (other.py) that does not depend on librt can import another compiled
1416+
# file (native.py) that does. In separate compilation mode, the C extension for other.py includes
1417+
# a header file with C definitions for the imported objects from native.py but the other.py C
1418+
# extension does not include the header for the librt module. So this makes sure that the included
1419+
# C definitions are generic (PyObjects instead of actual librt types) and don't "leak" the
1420+
# dependency.
1421+
from librt.strings import BytesWriter, write_i16_le
1422+
1423+
glob = BytesWriter()
1424+
1425+
def fn_returns_librt_type(b: bytes) -> BytesWriter:
1426+
w = BytesWriter()
1427+
w.write(b)
1428+
return w
1429+
1430+
class ClassWithLibrtTypeMember:
1431+
def __init__(self, w: BytesWriter) -> None:
1432+
self.writer = w
1433+
1434+
def method_returns_librt_type(self) -> BytesWriter:
1435+
return self.writer
1436+
1437+
[file other.py]
1438+
import struct
1439+
1440+
from native import glob, fn_returns_librt_type, ClassWithLibrtTypeMember, write_i16_le
1441+
1442+
def test_global(b: bytes) -> None:
1443+
glob.write(b)
1444+
assert glob.getvalue() == b
1445+
1446+
def test_fn(b: bytes) -> None:
1447+
assert fn_returns_librt_type(b).getvalue() == b
1448+
1449+
def test_class(b: bytes) -> None:
1450+
c = ClassWithLibrtTypeMember(glob)
1451+
assert c.method_returns_librt_type().getvalue() == b
1452+
1453+
def test_reexport() -> None:
1454+
write_i16_le(glob, 42)
1455+
assert glob.getvalue()[-2:] == struct.pack("<h", 42)
1456+
1457+
[file driver.py]
1458+
from other import test_global, test_fn, test_class, test_reexport
1459+
1460+
input = b'x' * 512
1461+
test_global(input)
1462+
test_fn(input)
1463+
test_class(input)
1464+
test_reexport()

0 commit comments

Comments
 (0)