You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[mypyc] Make separate=True compilation work for real-world projects (sqlglot)
This is the minimal set of fixes needed for `separate=True` to build and run
correctly against sqlglot, a ~100-module project with cross-group class
inheritance, generator helper classes, non-ext subclasses with fast methods,
and mutually-dependent compiled modules. Each of the fixes below is a real
bug that was never hit by mypy itself (mypy's setup.py uses multi_file on
Windows only, never separate=True) or by the toy fixtures in mypyc's
TestRunSeparate.
1. Non-extension classes never have vtables -- short-circuit is_method_final
to True for them so codegen doesn't try to index into a vtable that
compute_vtable skipped.
2. emit_method_call: under separate=True, a method's FuncIR body may live in
another group while only its FuncDecl is visible here. Use method_decl(name)
instead of get_method(name).decl -- the decl is enough to emit a direct C
call. Split native_function_type to accept a decl too.
3. Cross-group native/Python-wrapper calls weren't routing through the
exports-table indirection at a dozen sites in emitwrapper / emitfunc /
emitclass. Added Emitter.native_function_call(decl) and
Emitter.wrapper_function_call(decl) helpers and migrated all offending
sites. Also made CPyPy_* wrapper declarations needs_export=True so those
symbols reach the exports table.
4. Defer cross-group imports to shim load time. The shared lib's exec_
function used to PyImport_ImportModule sibling groups at PyInit time,
which re-enters the enclosing package's __init__.py mid-flight and blows
up on partial-init attribute walks. Split exec_ into a self-contained
capsule-setup phase (runs in PyInit) and a deferred ensure_deps_<short>()
(runs from the shim just before per-module init). Shim uses
PyImport_ImportModuleLevel with a non-empty fromlist so the lookup
returns the leaf directly via sys.modules, and fetches capsules via
PyObject_GetAttrString instead of PyCapsule_Import (which itself performs
the same dotted attribute walk).
5. Fix broken fallback in lib-rt CPyImport_ImportFrom: the code tried
PyObject_GetItem(module, fullname) where it intended PyImport_GetModule
(comment says as much). Modules don't implement __getitem__, so the
fallback always raised TypeError. Also Py_XDECREF the potentially-NULL
package_path in the error path.
6. Incremental-mode plumbing for separate=True: compile_modules_to_ir now
syncs freshly built ClassIR/FuncIR into deser_ctx so later cache-loaded
SCCs can resolve cross-SCC references. load_type_map tolerates mypy's
synthetic TypeInfo entries (e.g. "<subclass of X and Y>") that have no
corresponding mypyc ClassIR.
Also adds three regression tests targeted to fail on TestRunSeparate
without the fixes above:
- testSeparateCrossGroupEnumMethod exercises fix#1.
- testSeparateCrossGroupGenerator exercises fix#2.
- testSeparateCrossGroupInheritedInit exercises fix#3.
0 commit comments