MCPcopy Create free account
hub / github.com/BasisResearch/lean.py / _build_callable

Function _build_callable

lean_py/library.py:189–269  ·  view source on GitHub ↗

Build a Python wrapper around an `@[export]`'d Lean function. Conventions for the C ABI of Lean-exported functions: * Most parameter types are `lean_object*`. Exceptions: scalar value types (Bool, UInt8/16/32/64, USize, Float) are passed as their natural C types, but induc

(lib: ctypes.CDLL, finfo: FuncInfo, marshaller: Marshaller)

Source from the content-addressed store, hash-verified

187 return LeanInductiveValue(self._ti.name, self._ctor.name, self._ctor.tag, tuple(args))
188
189
190# Optional runtime validation of arguments against their Lean `TypeRepr`.
191# Off by default (the marshaller is intentionally lenient); enable it for
192# clearer errors during development. See `set_argument_typechecking`.
193_argument_typechecking = False
194
195
196def set_argument_typechecking(enabled: bool) -> None:
197 """Enable/disable runtime validation of arguments to `@[python]` functions.
198
199 When enabled, each argument is checked against the same `TypeRepr` that
200 drives marshalling (:meth:`lean_py.registry.TypeRepr.check`), raising a
201 clear ``TypeError`` before the value crosses the FFI boundary. Applies to
202 functions bound after — and calls made while — it is enabled.
203 """
204 global _argument_typechecking
205 _argument_typechecking = bool(enabled)
206
207
208# ============================================================================
209# Generated function wrappers
210# ============================================================================
211
212
213def _build_callable(lib: ctypes.CDLL, finfo: FuncInfo, marshaller: Marshaller) -> Callable:
214 """Build a Python wrapper around an `@[export]`'d Lean function.
215
216 Conventions for the C ABI of Lean-exported functions:
217 * Most parameter types are `lean_object*`. Exceptions: scalar value
218 types (Bool, UInt8/16/32/64, USize, Float) are passed as their
219 natural C types, but inductive parameters are pointer-shaped.
220 * IO-returning functions take a trailing `lean_io.RealWorld` arg
221 (just `lean_box(0)`); the result is a tagged Result object.
222 """
223 try:
224 cfn = getattr(lib, finfo.exportName)
225 except AttributeError as e:
226 raise RuntimeError(
227 f"Symbol {finfo.exportName} not found in library "
228 f"(declared in registry but missing from dylib)"
229 ) from e
230
231 ret = finfo.returnType
232 is_io = ret.kind == "io"
233
234 pwraps: list[TypeWrapper] = [marshaller.wrapper_for(p) for p in finfo.params]
235 rwrap: TypeWrapper = marshaller.wrapper_for(ret)
236
237 # We use `c_void_p` for any pointer-shaped argument or return value
238 # to sidestep a ctypes oddity on macOS where storing a returned
239 # `POINTER(struct)` and then passing it to another C function
240 # corrupts the pointer in some configurations.
241 def _ctype_for_call(ct):
242 # Pointer-shaped: collapse to c_void_p.
243 if isinstance(ct, type) and issubclass(ct, ctypes._Pointer):
244 return c_void_p
245 return ct
246

Callers 1

__init__Method · 0.85

Calls 5

get_structsFunction · 0.90
_ctype_for_callFunction · 0.85
get_lean_ffiFunction · 0.85
wrapper_forMethod · 0.80
shortMethod · 0.80

Tested by

no test coverage detected