osis-python 0.5.0__tar.gz → 0.5.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. {osis_python-0.5.0/src/osis_python.egg-info → osis_python-0.5.1}/PKG-INFO +1 -1
  2. {osis_python-0.5.0 → osis_python-0.5.1/src/osis_python.egg-info}/PKG-INFO +1 -1
  3. {osis_python-0.5.0 → osis_python-0.5.1}/src/osis_python.egg-info/SOURCES.txt +2 -2
  4. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/__init__.py +1 -1
  5. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/apdl_sync.py +53 -11
  6. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/sync_apdl_cli.py +7 -19
  7. osis_python-0.5.0/src/pyosis/transfer/sync_exec.py → osis_python-0.5.1/src/pyosis/transfer/out_to_python.py +13 -117
  8. {osis_python-0.5.0 → osis_python-0.5.1}/LICENSE +0 -0
  9. {osis_python-0.5.0 → osis_python-0.5.1}/README.md +0 -0
  10. {osis_python-0.5.0 → osis_python-0.5.1}/pyproject.toml +0 -0
  11. {osis_python-0.5.0 → osis_python-0.5.1}/setup.cfg +0 -0
  12. {osis_python-0.5.0 → osis_python-0.5.1}/src/osis_python.egg-info/dependency_links.txt +0 -0
  13. {osis_python-0.5.0 → osis_python-0.5.1}/src/osis_python.egg-info/requires.txt +0 -0
  14. {osis_python-0.5.0 → osis_python-0.5.1}/src/osis_python.egg-info/top_level.txt +0 -0
  15. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/boundary/__init__.py +0 -0
  16. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/boundary/interface.py +0 -0
  17. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/boundary/manager.py +0 -0
  18. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/__init__.py +0 -0
  19. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/control.py +0 -0
  20. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/io.py +0 -0
  21. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/manager.py +0 -0
  22. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/control/nonlinear.py +0 -0
  23. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/__init__.py +0 -0
  24. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/all_func.py +0 -0
  25. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/basic_manager.py +0 -0
  26. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/build.py +0 -0
  27. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/client.py +0 -0
  28. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/command.py +0 -0
  29. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/core/engine.py +0 -0
  30. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/__init__.py +0 -0
  31. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/load_to_mass.py +0 -0
  32. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/manager.py +0 -0
  33. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/modal.py +0 -0
  34. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/dynamic/seismic.py +0 -0
  35. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/element/__init__.py +0 -0
  36. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/element/interface.py +0 -0
  37. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/element/manager.py +0 -0
  38. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/general/__init__.py +0 -0
  39. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/general/interface.py +0 -0
  40. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/geometry/__init__.py +0 -0
  41. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/geometry/interface.py +0 -0
  42. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/geometry/manager.py +0 -0
  43. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/__init__.py +0 -0
  44. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/analysis.py +0 -0
  45. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/grade.py +0 -0
  46. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/lane.py +0 -0
  47. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/live/manager.py +0 -0
  48. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/__init__.py +0 -0
  49. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/loadcase.py +0 -0
  50. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/manager.py +0 -0
  51. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/static.py +0 -0
  52. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/load/tendon.py +0 -0
  53. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/material/__init__.py +0 -0
  54. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/material/interface.py +0 -0
  55. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/material/manager.py +0 -0
  56. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/node/__init__.py +0 -0
  57. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/node/interface.py +0 -0
  58. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/node/manager.py +0 -0
  59. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/__init__.py +0 -0
  60. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/combine.py +0 -0
  61. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/design_check.py +0 -0
  62. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/display.py +0 -0
  63. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/post/manager.py +0 -0
  64. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/project/__init__.py +0 -0
  65. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/project/interface.py +0 -0
  66. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/project/manager.py +0 -0
  67. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/__init__.py +0 -0
  68. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/component_thickness.py +0 -0
  69. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/coordinate.py +0 -0
  70. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/creep_shrink.py +0 -0
  71. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/damping.py +0 -0
  72. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/manager.py +0 -0
  73. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/property/pu_curve.py +0 -0
  74. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/quick_building/__init__.py +0 -0
  75. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/quick_building/interface.py +0 -0
  76. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/__init__.py +0 -0
  77. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/check.py +0 -0
  78. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/env.py +0 -0
  79. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/loadcase.py +0 -0
  80. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/manager.py +0 -0
  81. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/result/result.py +0 -0
  82. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/__init__.py +0 -0
  83. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/common.py +0 -0
  84. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/composite.py +0 -0
  85. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/manager.py +0 -0
  86. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/numeric.py +0 -0
  87. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/param.py +0 -0
  88. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/rebar.py +0 -0
  89. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/rib.py +0 -0
  90. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/section/steel.py +0 -0
  91. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/settlement/__init__.py +0 -0
  92. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/settlement/interface.py +0 -0
  93. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/settlement/manager.py +0 -0
  94. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stability/__init__.py +0 -0
  95. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stability/buckling.py +0 -0
  96. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stability/manager.py +0 -0
  97. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stage/__init__.py +0 -0
  98. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stage/define.py +0 -0
  99. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stage/manager.py +0 -0
  100. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/stage/overall.py +0 -0
  101. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/thickness/__init__.py +0 -0
  102. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/thickness/interface.py +0 -0
  103. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/thickness/manager.py +0 -0
  104. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/__init__.py +0 -0
  105. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/generator.py +0 -0
  106. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/matrix.py +0 -0
  107. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/parser.py +0 -0
  108. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/routes.py +0 -0
  109. {osis_python-0.5.0 → osis_python-0.5.1}/src/pyosis/transfer/split.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: osis-python
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: A Python client library for Osis APDL
5
5
  Author-email: "CCCC Highway Consultant Co. Ltd." <support@osisbim.com>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: osis-python
3
- Version: 0.5.0
3
+ Version: 0.5.1
4
4
  Summary: A Python client library for Osis APDL
5
5
  Author-email: "CCCC Highway Consultant Co. Ltd." <support@osisbim.com>
6
6
  License-Expression: MIT
@@ -101,7 +101,7 @@ src/pyosis/thickness/manager.py
101
101
  src/pyosis/transfer/__init__.py
102
102
  src/pyosis/transfer/generator.py
103
103
  src/pyosis/transfer/matrix.py
104
+ src/pyosis/transfer/out_to_python.py
104
105
  src/pyosis/transfer/parser.py
105
106
  src/pyosis/transfer/routes.py
106
- src/pyosis/transfer/split.py
107
- src/pyosis/transfer/sync_exec.py
107
+ src/pyosis/transfer/split.py
@@ -7,7 +7,7 @@ A library for extending OSIS functionality.
7
7
  A library that allows users to use CAE with great flexibility.
8
8
  """
9
9
 
10
- __version__ = "0.5.0"
10
+ __version__ = "0.5.1"
11
11
  __author__ = "CCCC Highway Consultant Co. Ltd." # 中交公路规划设计院 - 工程技术研究中心 - lzh - wjh - myf
12
12
 
13
13
  from .core.engine import OSISEngine
@@ -21,17 +21,24 @@ from dataclasses import dataclass
21
21
  from pathlib import Path
22
22
  from typing import TYPE_CHECKING
23
23
 
24
+ from ..transfer import parse_text
25
+ from ..transfer.out_to_python import write_prep_outputs
26
+
24
27
  if TYPE_CHECKING:
25
28
  from .engine import OSISEngine
26
29
 
27
30
  SYNC_STATE_FILE = ".apdl_sync.json"
28
31
 
32
+ # 默认 .out 文件名(位于项目根目录)
33
+ DEFAULT_EXPORT_NAME = "_pyosis_sync.out"
34
+
29
35
  # 忽略 TIME: 行,避免时间戳导致 MD5 每次不同
30
36
  _TIME_LINE_PATTERN = re.compile(
31
37
  r"^//-+ TIME:.*//\s*$",
32
38
  re.MULTILINE | re.IGNORECASE,
33
39
  )
34
40
 
41
+
35
42
  @dataclass
36
43
  class ApdlSyncResult:
37
44
  """APDL 同步结果。"""
@@ -107,6 +114,49 @@ def _save_persisted_hash(state_path: Path, out_path: Path, file_hash: str) -> No
107
114
  )
108
115
 
109
116
 
117
+ # 解析项目目录
118
+ def _get_project_dir(engine: "OSISEngine") -> Path | None:
119
+ try:
120
+ proj_dir = engine.project.get_directory()
121
+ except RuntimeError:
122
+ return None
123
+ if not proj_dir:
124
+ return None
125
+ return Path(proj_dir)
126
+
127
+
128
+ # 解析 (out_path, prep_dir)
129
+ def _resolve_project_paths(engine: "OSISEngine") -> tuple[Path, Path]:
130
+ """返回 (默认 out_path, prep_dir)。prep_dir 不存在会自动创建。"""
131
+ proj_dir = _get_project_dir(engine)
132
+ if proj_dir is None:
133
+ raise RuntimeError("无法获取 OSIS 项目目录")
134
+ prep_dir = proj_dir / "py" / "prep"
135
+ prep_dir.mkdir(parents=True, exist_ok=True)
136
+ return proj_dir / DEFAULT_EXPORT_NAME, prep_dir
137
+
138
+
139
+ # 确保 .out 文件存在
140
+ def _ensure_out_file(
141
+ engine: "OSISEngine",
142
+ out_path: Path,
143
+ *,
144
+ force_export: bool,
145
+ ) -> Path:
146
+ """确保 .out 存在;不存在或 force_export 时调用 engine.export_apdl。"""
147
+ if out_path.is_file() and not force_export:
148
+ return out_path
149
+
150
+ out_path.parent.mkdir(parents=True, exist_ok=True)
151
+ print(f"执行 export_apdl → {out_path}")
152
+ engine.export_apdl(str(out_path))
153
+
154
+ if not out_path.is_file() or out_path.stat().st_size == 0:
155
+ raise FileNotFoundError(f"导出失败或未生成有效 .out 文件: {out_path}")
156
+
157
+ return out_path
158
+
159
+
110
160
  # 执行 APDL 同步
111
161
  def perform_apdl_sync(
112
162
  engine: "OSISEngine",
@@ -118,22 +168,14 @@ def perform_apdl_sync(
118
168
 
119
169
  无项目路径时返回 None。
120
170
  """
121
- from ..transfer import parse_text
122
- from ..transfer.sync_exec import (
123
- get_project_dir_optional,
124
- resolve_out_file,
125
- resolve_project_paths,
126
- write_prep_outputs,
127
- )
128
-
129
- if get_project_dir_optional(engine) is None:
171
+ if _get_project_dir(engine) is None:
130
172
  return None
131
173
 
132
174
  session: ApdlSessionStore = engine._apdl_session
133
175
 
134
- default_out, prep_dir = resolve_project_paths(engine)
176
+ default_out, prep_dir = _resolve_project_paths(engine)
135
177
  out_path = Path(path) if path is not None else default_out
136
- out_path = resolve_out_file(engine, out_path, force_export=force_export)
178
+ out_path = _ensure_out_file(engine, out_path, force_export=force_export)
137
179
 
138
180
  text = _read_out_text(out_path)
139
181
  file_hash = _text_hash(text)
@@ -1,4 +1,7 @@
1
1
  """OSIS 界面操作后触发 pyosis APDL 同步的 CLI 入口。
2
+
3
+ 仅负责触发 perform_apdl_sync;prep 模块的执行不在本模块职责范围内。
4
+
2
5
  用法:
3
6
  python -m pyosis.core.sync_apdl_cli
4
7
  退出码:
@@ -9,30 +12,15 @@
9
12
  from __future__ import annotations
10
13
 
11
14
  import sys
12
- from typing import TYPE_CHECKING
13
15
 
16
+ from .apdl_sync import perform_apdl_sync
14
17
  from .engine import OSISEngine
15
18
 
16
- if TYPE_CHECKING:
17
- from .apdl_sync import ApdlSyncResult
18
-
19
-
20
- def _print_result(result: ApdlSyncResult) -> None:
21
-
22
- if result.changed:
23
- print("命令流有变化,已重新生成并执行 prep")
24
- else:
25
- print("命令流未变化,已 export,未重新执行 prep")
26
-
27
- summary = result.summary()
28
- if summary:
29
- print(f"摘要: {summary}")
30
-
31
-
32
19
 
33
20
  def main() -> int:
21
+ engine = OSISEngine()
34
22
  try:
35
- result = OSISEngine().sync_apdl()
23
+ result = perform_apdl_sync(engine)
36
24
  except Exception as exc:
37
25
  print(f"sync_apdl 失败: {exc}", file=sys.stderr)
38
26
  return 1
@@ -41,7 +29,7 @@ def main() -> int:
41
29
  print("跳过:未获取到项目路径")
42
30
  return 0
43
31
 
44
- # _print_result(result)
32
+ print(result.summary())
45
33
  return 0
46
34
 
47
35
 
@@ -1,29 +1,22 @@
1
- """transfer 同步链路的共享工具:路径解析、写 prep、执行 prep。
1
+ """transfer 同步链路的纯文本处理工具:把 .out 文本转换为 pyosis prep 模块。
2
2
 
3
- apdl_sync(export → 写 prep)与 sync_test(执行 prep)使用。
3
+ 只负责文本解析与 Python 代码生成:
4
+ - 解析 OSIS 导出的命令流(parse_text)
5
+ - 按模块分桶并生成 prep 模块(_1_control.py … _10_stage.py + main.py)
4
6
 
5
- 路径约定(与 build / apdl_sync 一致):
6
- {项目目录}/_pyosis_sync.out
7
- {项目目录}/py/prep/_0_engine.py _10_stage.py
7
+ 不负责:
8
+ - .out 文件的获取(export_apdl) —— 由调用方管理
9
+ - prep 模块的执行(import + builder 调用) —— 由调用方管理
8
10
  """
9
11
 
10
12
  from __future__ import annotations
11
13
 
12
- import importlib.util
13
- import sys
14
14
  from collections import defaultdict
15
- from dataclasses import dataclass
16
15
  from pathlib import Path
17
- from typing import TYPE_CHECKING
18
16
 
19
17
  from pyosis.transfer.generator import generate_lines
20
18
  from pyosis.transfer.parser import ParsedCommand
21
19
 
22
- if TYPE_CHECKING:
23
- from pyosis.core.engine import OSISEngine
24
-
25
- DEFAULT_EXPORT_NAME = "_pyosis_sync.out"
26
-
27
20
  # 模块文件名
28
21
  MODULE_FILES = {
29
22
  "CONTROL": "_1_control.py",
@@ -55,56 +48,6 @@ MODULE_BUILDERS = {
55
48
  MODULE_ORDER = tuple(MODULE_FILES.keys())
56
49
 
57
50
 
58
- @dataclass
59
- class ExecResult:
60
- index: int
61
- line: str
62
- ok: bool
63
- error: str
64
-
65
- # 获取项目目录
66
- def get_project_dir_optional(engine: OSISEngine) -> Path | None:
67
- try:
68
- proj_dir = engine.project.get_directory()
69
- except RuntimeError:
70
- return None
71
- if not proj_dir:
72
- return None
73
- return Path(proj_dir)
74
-
75
-
76
- # 解析项目路径
77
- def resolve_project_paths(engine: OSISEngine) -> tuple[Path, Path]:
78
- """返回 (out_path, prep_dir)。"""
79
- proj_dir = get_project_dir_optional(engine)
80
- if proj_dir is None:
81
- raise RuntimeError("无法获取 OSIS 项目目录")
82
- prep_dir = proj_dir / "py" / "prep"
83
- prep_dir.mkdir(parents=True, exist_ok=True)
84
- return proj_dir / DEFAULT_EXPORT_NAME, prep_dir
85
-
86
-
87
- # 解析 .out 文件
88
- def resolve_out_file(
89
- engine: OSISEngine,
90
- out_path: Path,
91
- *,
92
- force_export: bool = False,
93
- ) -> Path:
94
- """确保 .out 存在;不存在或 force_export 时 export_apdl。"""
95
- if out_path.is_file() and not force_export:
96
- return out_path
97
-
98
- out_path.parent.mkdir(parents=True, exist_ok=True)
99
- print(f"执行 export_apdl → {out_path}")
100
- engine.export_apdl(str(out_path))
101
-
102
- if not out_path.is_file() or out_path.stat().st_size == 0:
103
- raise FileNotFoundError(f"导出失败或未生成有效 .out 文件: {out_path}")
104
-
105
- return out_path
106
-
107
-
108
51
  # 按模块分桶
109
52
  def _bucket_by_module(parsed: list[ParsedCommand]) -> dict[str, list[ParsedCommand]]:
110
53
  buckets: dict[str, list[ParsedCommand]] = defaultdict(list)
@@ -132,7 +75,7 @@ def _write_prep_module(prep_dir: Path, module: str, lines: list[str]) -> Path:
132
75
  fname = MODULE_FILES[module]
133
76
  builder = MODULE_BUILDERS[module]
134
77
  empty = not lines
135
- doc = f"由 pyosis.transfer.sync_exec 从 .out 自动生成: {module}"
78
+ doc = f"由 pyosis.transfer.out_to_python 从 .out 自动生成: {module}"
136
79
  if empty:
137
80
  doc += "(无命令)"
138
81
 
@@ -154,6 +97,7 @@ def _write_prep_module(prep_dir: Path, module: str, lines: list[str]) -> Path:
154
97
  path.write_text("\n".join(body_lines), encoding="utf-8")
155
98
  return path
156
99
 
100
+
157
101
  def _write_main_py(prep_dir: Path) -> Path:
158
102
  """写入 main.py:依次执行 _1_control … _10_stage。"""
159
103
  import_lines = [
@@ -164,7 +108,7 @@ def _write_main_py(prep_dir: Path) -> Path:
164
108
  call_lines = [f" {MODULE_BUILDERS[mod]}(eng)" for mod in MODULE_ORDER]
165
109
 
166
110
  body_lines = [
167
- '"""由 pyosis.transfer.sync_exec 自动生成:依次执行 prep 模块。"""',
111
+ '"""由 pyosis.transfer.out_to_python 自动生成:依次执行 prep 模块。"""',
168
112
  "",
169
113
  "from __future__ import annotations",
170
114
  "",
@@ -183,8 +127,9 @@ def _write_main_py(prep_dir: Path) -> Path:
183
127
  path.write_text("\n".join(body_lines), encoding="utf-8")
184
128
  return path
185
129
 
130
+
186
131
  def write_prep_outputs(parsed: list[ParsedCommand], prep_dir: Path) -> tuple[int, list[Path]]:
187
- """写入 _0_engine.py 与 _1~_10 prep 模块,返回 (代码行数, 文件列表)。
132
+ """写入 _0_engine.py 与 _1~_10 prep 模块 + main.py,返回 (代码行数, 文件路径列表)。
188
133
 
189
134
  每个标准模块都会写入文件;.out 中无对应命令时生成 pass stub,避免遗留旧 prep。
190
135
  """
@@ -204,53 +149,4 @@ def write_prep_outputs(parsed: list[ParsedCommand], prep_dir: Path) -> tuple[int
204
149
  encoding="utf-8",
205
150
  )
206
151
  prep_paths.append(_write_main_py(prep_dir))
207
- return code_line_count, prep_paths
208
-
209
-
210
- # 加载 prep 模块
211
- def _load_prep_module(prep_dir: Path, filename: str):
212
- path = prep_dir / filename
213
- if not path.is_file():
214
- return None
215
- spec = importlib.util.spec_from_file_location(path.stem, path)
216
- mod = importlib.util.module_from_spec(spec)
217
- assert spec.loader is not None
218
- spec.loader.exec_module(mod)
219
- return mod
220
-
221
-
222
- # 执行 prep 模块
223
- def execute_prep_modules(prep_dir: Path, engine: OSISEngine) -> list[ExecResult]:
224
- """按 _1_control … _10_stage 顺序执行 prep 模块。"""
225
- prep_dir = prep_dir.resolve()
226
- if str(prep_dir) not in sys.path:
227
- sys.path.insert(0, str(prep_dir))
228
-
229
- results: list[ExecResult] = []
230
- step = 0
231
-
232
- for module in MODULE_ORDER:
233
- fname = MODULE_FILES[module]
234
- builder_name = MODULE_BUILDERS[module]
235
- mod = _load_prep_module(prep_dir, fname)
236
- if mod is None:
237
- print(f"[SKIP] {fname} 不存在")
238
- continue
239
- builder = getattr(mod, builder_name, None)
240
- if builder is None:
241
- print(f"[SKIP] {fname} 无函数 {builder_name}")
242
- continue
243
-
244
- step += 1
245
- desc = f"{fname} → {builder_name}(engine)"
246
- try:
247
- builder(engine)
248
- results.append(ExecResult(step, desc, True, ""))
249
- print(f"[OK] {step}: {desc}")
250
- except Exception as exc:
251
- msg = str(exc)
252
- results.append(ExecResult(step, desc, False, msg))
253
- print(f"[FAIL] {step}: {desc}")
254
- print(f" {msg}")
255
-
256
- return results
152
+ return code_line_count, prep_paths
File without changes
File without changes
File without changes
File without changes