@@ -45,6 +45,21 @@ def __str__(self):
4545 return f"{ self .ksy_file } : { super ().__str__ ()} "
4646
4747
48+ def _fix_pkg_resources_import (python_path : Path ) -> None :
49+ """Replace deprecated pkg_resources import with packaging.version.
50+
51+ Kaitai Struct Compiler v0.9 generates code that imports parse_version from
52+ pkg_resources, which is deprecated and unavailable on Python 3.12+.
53+ """
54+ content = python_path .read_text ()
55+ if "from pkg_resources import parse_version" in content :
56+ content = content .replace (
57+ "from pkg_resources import parse_version" ,
58+ "from packaging.version import parse as parse_version"
59+ )
60+ python_path .write_text (content )
61+
62+
4863class CompiledKSY :
4964 def __init__ (self , class_name : str , python_path : Union [str , Path ], dependencies : Iterable ["CompiledKSY" ] = ()):
5065 self .class_name : str = class_name
@@ -117,17 +132,26 @@ def compile(ksy_path: Union[str, Path], output_directory: Union[str, Path], auto
117132 if "errors" in first_spec :
118133 for error in first_spec ["errors" ]:
119134 raise CompilationError (ksy_file = error ["file" ], message = error ["message" ])
135+
136+ main_python_path = output_directory / first_spec ["files" ][0 ]["fileName" ]
137+ dependencies = [
138+ CompiledKSY (
139+ class_name = compiled ["topLevelName" ],
140+ python_path = output_directory / compiled ["files" ][0 ]["fileName" ]
141+ )
142+ for spec_name , compiled in result [ksy_path ]["output" ]["python" ].items ()
143+ if spec_name != first_spec_name
144+ ]
145+
146+ # Fix deprecated pkg_resources import in all generated files
147+ _fix_pkg_resources_import (main_python_path )
148+ for dep in dependencies :
149+ _fix_pkg_resources_import (dep .python_path )
150+
120151 return CompiledKSY (
121152 class_name = first_spec ["topLevelName" ],
122- python_path = output_directory / first_spec ["files" ][0 ]["fileName" ],
123- dependencies = (
124- CompiledKSY (
125- class_name = compiled ["topLevelName" ],
126- python_path = output_directory / compiled ["files" ][0 ]["fileName" ]
127- )
128- for spec_name , compiled in result [ksy_path ]["output" ]["python" ].items ()
129- if spec_name != first_spec_name
130- )
153+ python_path = main_python_path ,
154+ dependencies = dependencies
131155 )
132156
133157
0 commit comments