Serialization (codex)

koskari.serialize

Spec-driven .kio read/write and incremental adapters. Use compile_ki_file_to_kio(..., source_filename=...) when the path stored for runtime tracebacks should differ from the build-time ki_path (same source bytes required).

class koskari.serialize.KioFile(header: KioHeader, meta: KioMeta, codes: list, pool: list = None)

Bases: object

Semantic representation of a .kio file

build_pool_and_code_records()
codes: list
encode_sections()
classmethod from_bytes(data, allocator=None)

Decode a .kio image. Function code recorded as placed in an arena is placed into allocator when one is given; bodies and all other code are built on the heap

Parameters:
  • data – the .kio bytes

  • allocator – CodeAllocator, or None

Returns:

KioFile

Raises:

ValueError – see validate

classmethod from_codes(codes, soft_meta=None, header=None, meta=None)
header: KioHeader
meta: KioMeta
pool: list = None
classmethod read(source, allocator=None)
classmethod read_meta(source)

The META of a .kio without decoding its pool or bodies

Parameters:

source – file path, bytes, or readable binary stream

Returns:

KioMeta

Raises:

ValueError – a structural fault, bad magic, or a bytecode ABI this interpreter does not run (see validate)

to_bytes()
classmethod validate(source)

Check that a .kio is structurally sound without decoding its pool or bodies. Returns the header and the section map, or raises ValueError naming the first problem found

Checked, in order: the buffer holds a whole header; the magic and bytecode ABI match this interpreter; the section directory lies inside the file; every entry names a known tag, lies inside the file after the header, and appears once; the POOL, CODE, and META sections are all present; a stamped META is long enough to hold its stamp

Parameters:

source – file path, bytes, or readable binary stream

Returns:

(KioHeader, dict of SectionTag to (offset, length))

Raises:

ValueError – describing the first structural fault

write(dest)
class koskari.serialize.KioHeader(magic: bytes, abi_major: int, abi_minor: int, abi_micro: int, abi_patch: int, flags: int, section_dir_offset: int, section_dir_count: int)

Bases: object

Semantic fixed-size file header

abi_major: int
abi_micro: int
abi_minor: int
abi_patch: int
classmethod default()
flags: int
classmethod from_bytes(buf)
magic: bytes
section_dir_count: int
section_dir_offset: int
to_bytes()
validate_runtime()
class koskari.serialize.KioMeta(soft_meta: bytes = b'', source_mtime_ns: int = None, source_size: int = None)

Bases: object

META section payload

A leading flag byte says whether a source stamp follows: the mtime in nanoseconds and the size in bytes of the .ki the file was compiled from, as recorded when it was compiled. The loader compares the stamp against a sibling .ki and loads the source when they differ or when no stamp was recorded. Any bytes after the stamp are soft_meta, opaque to the runtime. An empty section is a file with no stamp and no soft_meta.

STAMPED = 1
classmethod default(soft_meta=None)
classmethod for_source(path, soft_meta=None)

A META stamped from the .ki at path as it is on disk now

classmethod from_buffer(buf, off, length)

Read META body of exactly length bytes at off

soft_meta: bytes = b''
source_mtime_ns: int = None
source_size: int = None
property stamped
to_bytes()
koskari.serialize.compile_ki_file_to_kio(ki_path, kio_dest, mod_name=None, source_filename=None)

Read each top-level form from a .ki file, compile to expression Code, and write a single .kio containing one CODEP body per form.

The module is compiled under the name an import of ki_path would give it (module_identity()), with the directory above its package root on sys.path for the build and its parent package imported first, so the package pragma in force and a relative import in the body are the ones a source load sees. mod_name overrides the derived name; its parent package is the part before the last dot, and no directory is added for it.

Source bytes are always read from ki_path. Each body stores a filename string used when the .kio is loaded so Code.filename and native tracebacks refer to that path. By default this is ki_path. If source_filename is set (for example a stable path for distributed packages), it is stored instead; line and column metadata still refer to the same text as ki_path, so that file must have identical contents at runtime for linecache and traceback source lines to resolve. Relative paths depend on the process current working directory.

Parameters:
  • ki_path – path to Koskari source file to open and compile

  • kio_dest – output .kio path or writable binary stream

  • mod_name – module name to compile under, or None to derive it from the path

  • source_filename – optional string stored per body as the logical source path for diagnostics when it differs from ki_path

koskari.serialize.compile_ki_source_to_kio(source_text, kio_dest, mod_name='__kio_compile__', source_filename=None)

Compile Koskari source text to a single .kio with one CODEP body per form.

Same semantics as compile_ki_file_to_kio except input is a string. The logical filename for diagnostics and embedded Code.filename is source_filename when set, otherwise a placeholder string. No source stamp is recorded, so the loader treats the file as stale beside a sibling .ki.

Parameters:
  • source_text – Koskari source string

  • kio_dest – output .kio path or writable binary stream

  • mod_name – synthetic module name for compiled fragments

  • source_filename – logical path for errors and stored filenames

koskari.serialize.dump_kio(dest, codes, soft_meta=None)

Write a .kio file from a list of Code objects.

Parameters:
  • dest – output file path or writable binary stream

  • codes – list of Code objects in evaluation order

  • soft_meta – optional bytes for META tail

koskari.serialize.load_kio(source)

Load a .kio file and return a KioFile.

Parameters:

source – file path, bytes, or readable binary stream

Returns:

decoded KioFile