fishertools 0.2.1__py3-none-any.whl

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 (81) hide show
  1. fishertools/__init__.py +82 -0
  2. fishertools/config/__init__.py +24 -0
  3. fishertools/config/manager.py +247 -0
  4. fishertools/config/models.py +96 -0
  5. fishertools/config/parser.py +265 -0
  6. fishertools/decorators.py +93 -0
  7. fishertools/documentation/__init__.py +38 -0
  8. fishertools/documentation/api.py +242 -0
  9. fishertools/documentation/generator.py +502 -0
  10. fishertools/documentation/models.py +126 -0
  11. fishertools/documentation/visual.py +583 -0
  12. fishertools/errors/__init__.py +29 -0
  13. fishertools/errors/exceptions.py +191 -0
  14. fishertools/errors/explainer.py +303 -0
  15. fishertools/errors/formatters.py +386 -0
  16. fishertools/errors/models.py +228 -0
  17. fishertools/errors/patterns.py +119 -0
  18. fishertools/errors/recovery.py +467 -0
  19. fishertools/examples/__init__.py +22 -0
  20. fishertools/examples/models.py +118 -0
  21. fishertools/examples/repository.py +770 -0
  22. fishertools/helpers.py +116 -0
  23. fishertools/integration.py +451 -0
  24. fishertools/learn/__init__.py +18 -0
  25. fishertools/learn/examples.py +550 -0
  26. fishertools/learn/tips.py +281 -0
  27. fishertools/learning/__init__.py +32 -0
  28. fishertools/learning/core.py +349 -0
  29. fishertools/learning/models.py +112 -0
  30. fishertools/learning/progress.py +314 -0
  31. fishertools/learning/session.py +500 -0
  32. fishertools/learning/tutorial.py +626 -0
  33. fishertools/legacy/__init__.py +76 -0
  34. fishertools/legacy/deprecated.py +261 -0
  35. fishertools/legacy/deprecation.py +149 -0
  36. fishertools/safe/__init__.py +16 -0
  37. fishertools/safe/collections.py +242 -0
  38. fishertools/safe/files.py +240 -0
  39. fishertools/safe/strings.py +15 -0
  40. fishertools/utils.py +57 -0
  41. fishertools-0.2.1.dist-info/METADATA +256 -0
  42. fishertools-0.2.1.dist-info/RECORD +81 -0
  43. fishertools-0.2.1.dist-info/WHEEL +5 -0
  44. fishertools-0.2.1.dist-info/licenses/LICENSE +21 -0
  45. fishertools-0.2.1.dist-info/top_level.txt +2 -0
  46. tests/__init__.py +6 -0
  47. tests/conftest.py +25 -0
  48. tests/test_config/__init__.py +3 -0
  49. tests/test_config/test_basic_config.py +57 -0
  50. tests/test_config/test_config_error_handling.py +287 -0
  51. tests/test_config/test_config_properties.py +435 -0
  52. tests/test_documentation/__init__.py +3 -0
  53. tests/test_documentation/test_documentation_properties.py +253 -0
  54. tests/test_documentation/test_visual_documentation_properties.py +444 -0
  55. tests/test_errors/__init__.py +3 -0
  56. tests/test_errors/test_api.py +301 -0
  57. tests/test_errors/test_error_handling.py +354 -0
  58. tests/test_errors/test_explainer.py +173 -0
  59. tests/test_errors/test_formatters.py +338 -0
  60. tests/test_errors/test_models.py +248 -0
  61. tests/test_errors/test_patterns.py +270 -0
  62. tests/test_examples/__init__.py +3 -0
  63. tests/test_examples/test_example_repository_properties.py +204 -0
  64. tests/test_examples/test_specific_examples.py +303 -0
  65. tests/test_integration.py +298 -0
  66. tests/test_integration_enhancements.py +462 -0
  67. tests/test_learn/__init__.py +3 -0
  68. tests/test_learn/test_examples.py +221 -0
  69. tests/test_learn/test_tips.py +285 -0
  70. tests/test_learning/__init__.py +3 -0
  71. tests/test_learning/test_interactive_learning_properties.py +337 -0
  72. tests/test_learning/test_learning_system_properties.py +194 -0
  73. tests/test_learning/test_progress_tracking_properties.py +279 -0
  74. tests/test_legacy/__init__.py +3 -0
  75. tests/test_legacy/test_backward_compatibility.py +236 -0
  76. tests/test_legacy/test_deprecation_warnings.py +208 -0
  77. tests/test_safe/__init__.py +3 -0
  78. tests/test_safe/test_collections_properties.py +189 -0
  79. tests/test_safe/test_files.py +104 -0
  80. tests/test_structure.py +58 -0
  81. tests/test_structure_enhancements.py +115 -0
@@ -0,0 +1,502 @@
1
+ """
2
+ Main documentation generator with Sphinx integration.
3
+ """
4
+
5
+ import os
6
+ import json
7
+ from typing import List, Dict, Any
8
+ from .models import (
9
+ APIInfo, SphinxDocuments, NavigationTree,
10
+ ExampleCode, PublishResult, FunctionInfo, PublishStatus
11
+ )
12
+ from .api import APIGenerator
13
+
14
+
15
+ class DocumentationGenerator:
16
+ """
17
+ Automatic API documentation generator with ReadTheDocs integration.
18
+
19
+ Extracts API information, generates Sphinx documentation,
20
+ and publishes to ReadTheDocs automatically.
21
+ """
22
+
23
+ def __init__(self, project_name: str, output_dir: str = "docs"):
24
+ """
25
+ Initialize the documentation generator.
26
+
27
+ Args:
28
+ project_name: Name of the project
29
+ output_dir: Directory for generated documentation
30
+ """
31
+ self.project_name = project_name
32
+ self.output_dir = output_dir
33
+ self.api_generator = APIGenerator()
34
+
35
+ # Integration point for visual documentation
36
+ self._visual_docs = None
37
+
38
+ def extract_api_info(self, module_path: str) -> APIInfo:
39
+ """
40
+ Extract API information from a Python module.
41
+
42
+ Args:
43
+ module_path: Path to the Python module
44
+
45
+ Returns:
46
+ APIInfo: Extracted API information
47
+ """
48
+ return self.api_generator.parse_module(module_path)
49
+
50
+ def generate_sphinx_docs(self, api_info: APIInfo) -> SphinxDocuments:
51
+ """
52
+ Generate Sphinx documentation from API information.
53
+
54
+ Args:
55
+ api_info: API information to document
56
+
57
+ Returns:
58
+ SphinxDocuments: Generated Sphinx documentation
59
+ """
60
+ source_files = {}
61
+
62
+ # Generate main module RST file
63
+ rst_content = self.api_generator.generate_sphinx_rst(api_info)
64
+ source_files[f"{api_info.module_name}.rst"] = rst_content
65
+
66
+ # Generate index.rst
67
+ index_content = self._generate_index_rst([api_info.module_name])
68
+ source_files["index.rst"] = index_content
69
+
70
+ # Generate conf.py
71
+ config = self._generate_sphinx_config()
72
+ source_files["conf.py"] = self._config_to_python_file(config)
73
+
74
+ # Create navigation tree
75
+ navigation = NavigationTree(
76
+ name=self.project_name,
77
+ path="index.rst",
78
+ children=[
79
+ NavigationTree(
80
+ name=api_info.module_name,
81
+ path=f"{api_info.module_name}.rst"
82
+ )
83
+ ]
84
+ )
85
+
86
+ return SphinxDocuments(
87
+ source_files=source_files,
88
+ config=config,
89
+ navigation=navigation,
90
+ build_path=self.output_dir
91
+ )
92
+
93
+ def create_navigation_structure(self, modules: List[str]) -> NavigationTree:
94
+ """
95
+ Create structured navigation for documentation.
96
+
97
+ Args:
98
+ modules: List of module names to include
99
+
100
+ Returns:
101
+ NavigationTree: Hierarchical navigation structure
102
+ """
103
+ children = []
104
+ for module in modules:
105
+ children.append(NavigationTree(
106
+ name=module,
107
+ path=f"{module}.rst"
108
+ ))
109
+
110
+ return NavigationTree(
111
+ name=self.project_name,
112
+ path="index.rst",
113
+ children=children
114
+ )
115
+
116
+ def add_usage_examples(self, function: FunctionInfo) -> List[ExampleCode]:
117
+ """
118
+ Generate usage examples for a function.
119
+
120
+ Args:
121
+ function: Function information
122
+
123
+ Returns:
124
+ List[ExampleCode]: Generated usage examples
125
+ """
126
+ examples = []
127
+
128
+ # Generate basic usage example
129
+ basic_example = self._generate_basic_example(function)
130
+ if basic_example:
131
+ examples.append(basic_example)
132
+
133
+ # Generate example with error handling if applicable
134
+ error_example = self._generate_error_handling_example(function)
135
+ if error_example:
136
+ examples.append(error_example)
137
+
138
+ # Generate advanced example if function has complex parameters
139
+ if len(function.parameters) > 2:
140
+ advanced_example = self._generate_advanced_example(function)
141
+ if advanced_example:
142
+ examples.append(advanced_example)
143
+
144
+ return examples
145
+
146
+ def publish_to_readthedocs(self, docs: SphinxDocuments) -> PublishResult:
147
+ """
148
+ Publish documentation to ReadTheDocs.
149
+
150
+ Args:
151
+ docs: Sphinx documentation to publish
152
+
153
+ Returns:
154
+ PublishResult: Result of the publishing operation
155
+ """
156
+ try:
157
+ # Create output directory if it doesn't exist
158
+ os.makedirs(docs.build_path, exist_ok=True)
159
+
160
+ # Write all source files
161
+ for filename, content in docs.source_files.items():
162
+ file_path = os.path.join(docs.build_path, filename)
163
+ with open(file_path, 'w', encoding='utf-8') as f:
164
+ f.write(content)
165
+
166
+ # Create .readthedocs.yaml configuration
167
+ readthedocs_config = self._generate_readthedocs_config()
168
+ config_path = os.path.join(docs.build_path, ".readthedocs.yaml")
169
+ with open(config_path, 'w', encoding='utf-8') as f:
170
+ f.write(readthedocs_config)
171
+
172
+ # Create requirements.txt for ReadTheDocs
173
+ requirements_content = self._generate_requirements_txt()
174
+ req_path = os.path.join(docs.build_path, "requirements.txt")
175
+ with open(req_path, 'w', encoding='utf-8') as f:
176
+ f.write(requirements_content)
177
+
178
+ return PublishResult(
179
+ status=PublishStatus.SUCCESS,
180
+ url=f"https://{self.project_name.lower()}.readthedocs.io",
181
+ build_log=["Documentation files generated successfully"]
182
+ )
183
+
184
+ except Exception as e:
185
+ return PublishResult(
186
+ status=PublishStatus.FAILED,
187
+ error_message=str(e),
188
+ build_log=[f"Error: {str(e)}"]
189
+ )
190
+
191
+ def build_documentation(self, module_paths: List[str]) -> SphinxDocuments:
192
+ """
193
+ Build complete documentation for multiple modules.
194
+
195
+ Args:
196
+ module_paths: List of module paths to document
197
+
198
+ Returns:
199
+ SphinxDocuments: Complete generated documentation
200
+ """
201
+ all_modules = []
202
+ source_files = {}
203
+
204
+ # Process each module
205
+ for module_path in module_paths:
206
+ api_info = self.extract_api_info(module_path)
207
+ all_modules.append(api_info.module_name)
208
+
209
+ # Generate RST for this module
210
+ rst_content = self.api_generator.generate_sphinx_rst(api_info)
211
+ source_files[f"{api_info.module_name}.rst"] = rst_content
212
+
213
+ # Generate index.rst for all modules
214
+ index_content = self._generate_index_rst(all_modules)
215
+ source_files["index.rst"] = index_content
216
+
217
+ # Generate conf.py
218
+ config = self._generate_sphinx_config()
219
+ source_files["conf.py"] = self._config_to_python_file(config)
220
+
221
+ # Create navigation structure
222
+ navigation = self.create_navigation_structure(all_modules)
223
+
224
+ return SphinxDocuments(
225
+ source_files=source_files,
226
+ config=config,
227
+ navigation=navigation,
228
+ build_path=self.output_dir
229
+ )
230
+
231
+ def _generate_index_rst(self, modules: List[str]) -> str:
232
+ """Generate the main index.rst file."""
233
+ content = []
234
+
235
+ title = f"{self.project_name} Documentation"
236
+ content.append(title)
237
+ content.append("=" * len(title))
238
+ content.append("")
239
+ content.append("Welcome to the API documentation.")
240
+ content.append("")
241
+ content.append(".. toctree::")
242
+ content.append(" :maxdepth: 2")
243
+ content.append(" :caption: Contents:")
244
+ content.append("")
245
+
246
+ for module in modules:
247
+ content.append(f" {module}")
248
+
249
+ content.append("")
250
+ content.append("Indices and tables")
251
+ content.append("==================")
252
+ content.append("")
253
+ content.append("* :ref:`genindex`")
254
+ content.append("* :ref:`modindex`")
255
+ content.append("* :ref:`search`")
256
+
257
+ return "\n".join(content)
258
+
259
+ def _generate_sphinx_config(self) -> Dict[str, Any]:
260
+ """Generate Sphinx configuration."""
261
+ return {
262
+ 'project': self.project_name,
263
+ 'copyright': '2024, Auto-generated',
264
+ 'author': 'Auto-generated',
265
+ 'extensions': [
266
+ 'sphinx.ext.autodoc',
267
+ 'sphinx.ext.viewcode',
268
+ 'sphinx.ext.napoleon',
269
+ 'sphinx.ext.intersphinx'
270
+ ],
271
+ 'templates_path': ['_templates'],
272
+ 'exclude_patterns': ['_build', 'Thumbs.db', '.DS_Store'],
273
+ 'html_theme': 'sphinx_rtd_theme',
274
+ 'html_static_path': ['_static'],
275
+ 'autodoc_default_options': {
276
+ 'members': True,
277
+ 'undoc-members': True,
278
+ 'show-inheritance': True
279
+ },
280
+ 'napoleon_google_docstring': True,
281
+ 'napoleon_numpy_docstring': True,
282
+ 'intersphinx_mapping': {
283
+ 'python': ('https://docs.python.org/3', None)
284
+ }
285
+ }
286
+
287
+ def _config_to_python_file(self, config: Dict[str, Any]) -> str:
288
+ """Convert configuration dict to Python file content."""
289
+ lines = []
290
+ lines.append("# Configuration file for the Sphinx documentation builder.")
291
+ lines.append("# Auto-generated by fishertools DocumentationGenerator")
292
+ lines.append("")
293
+
294
+ for key, value in config.items():
295
+ if isinstance(value, str):
296
+ lines.append(f"{key} = '{value}'")
297
+ elif isinstance(value, list):
298
+ lines.append(f"{key} = {repr(value)}")
299
+ elif isinstance(value, dict):
300
+ lines.append(f"{key} = {repr(value)}")
301
+ else:
302
+ lines.append(f"{key} = {repr(value)}")
303
+
304
+ return "\n".join(lines)
305
+
306
+ def _generate_basic_example(self, function: FunctionInfo) -> ExampleCode:
307
+ """Generate a basic usage example for a function."""
308
+ # Create simple parameter values based on type hints
309
+ param_values = []
310
+ for param_name, param_type in function.parameters.items():
311
+ if param_name == 'self':
312
+ continue
313
+
314
+ if 'str' in param_type.lower():
315
+ param_values.append(f'"{param_name}_value"')
316
+ elif 'int' in param_type.lower():
317
+ param_values.append('42')
318
+ elif 'float' in param_type.lower():
319
+ param_values.append('3.14')
320
+ elif 'bool' in param_type.lower():
321
+ param_values.append('True')
322
+ elif 'list' in param_type.lower():
323
+ param_values.append('[1, 2, 3]')
324
+ elif 'dict' in param_type.lower():
325
+ param_values.append('{"key": "value"}')
326
+ else:
327
+ param_values.append('None')
328
+
329
+ # Generate function call
330
+ if param_values:
331
+ call = f"{function.name}({', '.join(param_values)})"
332
+ else:
333
+ call = f"{function.name}()"
334
+
335
+ code = f"""# Basic usage example
336
+ result = {call}
337
+ print(result)"""
338
+
339
+ return ExampleCode(
340
+ code=code,
341
+ description=f"Basic usage of {function.name}",
342
+ expected_output="# Output will depend on the function implementation"
343
+ )
344
+
345
+ def _generate_error_handling_example(self, function: FunctionInfo) -> ExampleCode:
346
+ """Generate an example with error handling."""
347
+ if not function.docstring or 'raise' not in function.docstring.lower():
348
+ return None
349
+
350
+ # Create a simple error handling example
351
+ param_values = ['invalid_input'] * len([p for p in function.parameters.keys() if p != 'self'])
352
+
353
+ if param_values:
354
+ call = f"{function.name}({', '.join(param_values)})"
355
+ else:
356
+ call = f"{function.name}()"
357
+
358
+ code = f"""# Error handling example
359
+ try:
360
+ result = {call}
361
+ print(f"Success: {{result}}")
362
+ except Exception as e:
363
+ print(f"Error: {{e}}")"""
364
+
365
+ return ExampleCode(
366
+ code=code,
367
+ description=f"Error handling with {function.name}",
368
+ expected_output="# Will show either success or error message"
369
+ )
370
+
371
+ def _generate_advanced_example(self, function: FunctionInfo) -> ExampleCode:
372
+ """Generate an advanced usage example."""
373
+ # Create more realistic parameter values
374
+ param_assignments = []
375
+ param_names = []
376
+
377
+ for param_name, param_type in function.parameters.items():
378
+ if param_name == 'self':
379
+ continue
380
+
381
+ var_name = f"{param_name}_data"
382
+ param_names.append(var_name)
383
+
384
+ if 'str' in param_type.lower():
385
+ param_assignments.append(f'{var_name} = "example_{param_name}"')
386
+ elif 'list' in param_type.lower():
387
+ param_assignments.append(f'{var_name} = ["item1", "item2", "item3"]')
388
+ elif 'dict' in param_type.lower():
389
+ param_assignments.append(f'{var_name} = {{"key1": "value1", "key2": "value2"}}')
390
+ else:
391
+ param_assignments.append(f'{var_name} = None # Replace with appropriate value')
392
+
393
+ assignments = '\n'.join(param_assignments)
394
+ call = f"{function.name}({', '.join(param_names)})"
395
+
396
+ code = f"""# Advanced usage example
397
+ {assignments}
398
+
399
+ result = {call}
400
+ print(f"Result: {{result}}")"""
401
+
402
+ return ExampleCode(
403
+ code=code,
404
+ description=f"Advanced usage of {function.name} with realistic data",
405
+ expected_output="# Output will show the processed result"
406
+ )
407
+
408
+ def _generate_readthedocs_config(self) -> str:
409
+ """Generate .readthedocs.yaml configuration."""
410
+ config = f"""# .readthedocs.yaml
411
+ # Read the Docs configuration file
412
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
413
+
414
+ version: 2
415
+
416
+ build:
417
+ os: ubuntu-22.04
418
+ tools:
419
+ python: "3.11"
420
+
421
+ sphinx:
422
+ configuration: conf.py
423
+
424
+ python:
425
+ install:
426
+ - requirements: requirements.txt
427
+ - method: pip
428
+ path: .
429
+ """
430
+ return config
431
+
432
+ def _generate_requirements_txt(self) -> str:
433
+ """Generate requirements.txt for ReadTheDocs."""
434
+ requirements = """# Documentation requirements
435
+ sphinx>=4.0.0
436
+ sphinx-rtd-theme>=1.0.0
437
+ sphinx-autodoc-typehints>=1.12.0
438
+ """
439
+ return requirements
440
+
441
+ def generate_enhanced_documentation(self, module_paths: List[str]) -> Dict[str, Any]:
442
+ """
443
+ Generate enhanced documentation with visual elements.
444
+
445
+ Args:
446
+ module_paths: List of module paths to document
447
+
448
+ Returns:
449
+ Dictionary containing documentation and visual artifacts
450
+ """
451
+ try:
452
+ # Generate standard Sphinx documentation
453
+ sphinx_docs = self.build_documentation(module_paths)
454
+
455
+ result = {
456
+ 'sphinx_docs': sphinx_docs,
457
+ 'visual_artifacts': {},
458
+ 'enhanced_files': {}
459
+ }
460
+
461
+ # Add visual elements if visual documentation is available
462
+ if self._visual_docs:
463
+ for module_path in module_paths:
464
+ try:
465
+ api_info = self.extract_api_info(module_path)
466
+
467
+ # Create architecture diagram
468
+ arch_diagram = self._visual_docs.create_architecture_diagram([api_info.module_name])
469
+ result['visual_artifacts'][f"{api_info.module_name}_architecture"] = arch_diagram
470
+
471
+ # Create enhanced RST with visual elements
472
+ enhanced_rst = self._create_enhanced_rst(api_info, arch_diagram)
473
+ result['enhanced_files'][f"{api_info.module_name}_enhanced.rst"] = enhanced_rst
474
+
475
+ except Exception as e:
476
+ logging.warning(f"Failed to create visuals for {module_path}: {e}")
477
+
478
+ return result
479
+
480
+ except Exception as e:
481
+ logging.error(f"Failed to generate enhanced documentation: {e}")
482
+ raise
483
+
484
+ def _create_enhanced_rst(self, api_info, architecture_diagram) -> str:
485
+ """Create enhanced RST file with visual elements."""
486
+ base_rst = self.api_generator.generate_sphinx_rst(api_info)
487
+
488
+ # Add architecture diagram at the beginning
489
+ enhanced_rst = f"""
490
+ {api_info.module_name} Module
491
+ {'=' * (len(api_info.module_name) + 7)}
492
+
493
+ Architecture Overview
494
+ --------------------
495
+
496
+ .. mermaid::
497
+
498
+ {architecture_diagram.content if hasattr(architecture_diagram, 'content') else 'graph TD; A[Module] --> B[Components]'}
499
+
500
+ {base_rst}
501
+ """
502
+ return enhanced_rst
@@ -0,0 +1,126 @@
1
+ """
2
+ Data models for the Documentation Generation module.
3
+ """
4
+
5
+ from dataclasses import dataclass
6
+ from typing import List, Optional, Dict, Any
7
+ from enum import Enum
8
+
9
+
10
+ class DiagramType(Enum):
11
+ """Types of diagrams that can be generated."""
12
+ ARCHITECTURE = "architecture"
13
+ DATA_FLOW = "data_flow"
14
+ FLOWCHART = "flowchart"
15
+ STRUCTURE = "structure"
16
+
17
+
18
+ class PublishStatus(Enum):
19
+ """Status of documentation publishing."""
20
+ SUCCESS = "success"
21
+ FAILED = "failed"
22
+ IN_PROGRESS = "in_progress"
23
+ PENDING = "pending"
24
+
25
+
26
+ @dataclass
27
+ class FunctionInfo:
28
+ """Information about a function for documentation."""
29
+ name: str
30
+ docstring: Optional[str]
31
+ parameters: Dict[str, str] # param_name -> type_annotation
32
+ return_type: Optional[str]
33
+ module_path: str
34
+ line_number: int
35
+ examples: List[str] = None
36
+
37
+ def __post_init__(self):
38
+ if self.examples is None:
39
+ self.examples = []
40
+
41
+
42
+ @dataclass
43
+ class APIInfo:
44
+ """Complete API information for a module."""
45
+ module_name: str
46
+ functions: List[FunctionInfo]
47
+ classes: List[Dict[str, Any]]
48
+ constants: Dict[str, Any]
49
+ imports: List[str]
50
+ docstring: Optional[str] = None
51
+
52
+
53
+ @dataclass
54
+ class NavigationTree:
55
+ """Navigation structure for documentation."""
56
+ name: str
57
+ path: str
58
+ children: List['NavigationTree'] = None
59
+
60
+ def __post_init__(self):
61
+ if self.children is None:
62
+ self.children = []
63
+
64
+
65
+ @dataclass
66
+ class ExampleCode:
67
+ """Code example with explanation."""
68
+ code: str
69
+ description: str
70
+ expected_output: Optional[str] = None
71
+ language: str = "python"
72
+
73
+
74
+ @dataclass
75
+ class SphinxDocuments:
76
+ """Generated Sphinx documentation."""
77
+ source_files: Dict[str, str] # filename -> content
78
+ config: Dict[str, Any]
79
+ navigation: NavigationTree
80
+ build_path: str
81
+
82
+
83
+ @dataclass
84
+ class PublishResult:
85
+ """Result of publishing documentation."""
86
+ status: PublishStatus
87
+ url: Optional[str] = None
88
+ error_message: Optional[str] = None
89
+ build_log: List[str] = None
90
+
91
+ def __post_init__(self):
92
+ if self.build_log is None:
93
+ self.build_log = []
94
+
95
+
96
+ @dataclass
97
+ class MermaidDiagram:
98
+ """Mermaid diagram representation."""
99
+ diagram_type: DiagramType
100
+ content: str
101
+ title: Optional[str] = None
102
+
103
+
104
+ @dataclass
105
+ class FlowDiagram:
106
+ """Data flow diagram."""
107
+ nodes: List[Dict[str, str]]
108
+ edges: List[Dict[str, str]]
109
+ title: str
110
+
111
+
112
+ @dataclass
113
+ class Flowchart:
114
+ """Algorithm flowchart."""
115
+ steps: List[Dict[str, Any]]
116
+ connections: List[Dict[str, str]]
117
+ title: str
118
+
119
+
120
+ @dataclass
121
+ class StructureDiagram:
122
+ """Data structure visualization."""
123
+ structure_type: str
124
+ data: Any
125
+ visualization: str
126
+ title: Optional[str] = None