Skip to content

Commit 13d0a6a

Browse files
refactoring
1 parent a06f683 commit 13d0a6a

9 files changed

Lines changed: 216 additions & 17 deletions

File tree

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,25 @@ hubs = [p for p, n in project.dependency_metrics.items() if n.is_hub]
7878
print(f"Key modules: {hubs}")
7979
```
8080

81+
### Organized Imports
82+
83+
```python
84+
# Core analysis
85+
from code2logic.core import ProjectInfo, ProjectAnalyzer, analyze_project
86+
87+
# Format generators
88+
from code2logic.formats import (
89+
YAMLGenerator, JSONGenerator, TOONGenerator,
90+
LogicMLGenerator, GherkinGenerator
91+
)
92+
93+
# LLM clients
94+
from code2logic.llm import get_client, BaseLLMClient
95+
96+
# Development tools
97+
from code2logic.tools import run_benchmark, CodeReviewer
98+
```
99+
81100
## 📋 Output Formats
82101

83102
### Markdown (default)

code2logic/core/__init__.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""Core analysis components.
2+
3+
Re-exports from parent package for backward compatibility.
4+
"""
5+
from ..models import (
6+
FunctionInfo, ClassInfo, TypeInfo, ModuleInfo,
7+
DependencyNode, ProjectInfo
8+
)
9+
from ..analyzer import ProjectAnalyzer, analyze_project
10+
from ..dependency import DependencyAnalyzer
11+
from ..errors import (
12+
ErrorSeverity, ErrorType, AnalysisError, AnalysisResult,
13+
ErrorHandler, create_error_handler
14+
)
15+
16+
__all__ = [
17+
'FunctionInfo', 'ClassInfo', 'TypeInfo', 'ModuleInfo',
18+
'DependencyNode', 'ProjectInfo',
19+
'ProjectAnalyzer', 'analyze_project', 'DependencyAnalyzer',
20+
'ErrorSeverity', 'ErrorType', 'AnalysisError', 'AnalysisResult',
21+
'ErrorHandler', 'create_error_handler',
22+
]

code2logic/formats/__init__.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""Output format generators.
2+
3+
Re-exports from parent package for backward compatibility.
4+
"""
5+
from ..generators import (
6+
YAMLGenerator, JSONGenerator, CompactGenerator,
7+
CSVGenerator, MarkdownGenerator
8+
)
9+
from ..gherkin import (
10+
GherkinGenerator, StepDefinitionGenerator,
11+
CucumberYAMLGenerator, csv_to_gherkin, gherkin_to_test_data
12+
)
13+
from ..markdown_format import MarkdownHybridGenerator, MarkdownSpec
14+
from ..logicml import LogicMLGenerator, LogicMLSpec
15+
from ..toon_format import TOONGenerator, TOONParser, generate_toon, parse_toon
16+
from ..file_formats import (
17+
generate_file_csv, generate_file_json, generate_file_yaml
18+
)
19+
20+
__all__ = [
21+
# Core generators
22+
'YAMLGenerator', 'JSONGenerator', 'CompactGenerator',
23+
'CSVGenerator', 'MarkdownGenerator',
24+
# Gherkin
25+
'GherkinGenerator', 'StepDefinitionGenerator',
26+
'CucumberYAMLGenerator', 'csv_to_gherkin', 'gherkin_to_test_data',
27+
# Markdown
28+
'MarkdownHybridGenerator', 'MarkdownSpec',
29+
# LogicML
30+
'LogicMLGenerator', 'LogicMLSpec',
31+
# TOON
32+
'TOONGenerator', 'TOONParser', 'generate_toon', 'parse_toon',
33+
# File formats
34+
'generate_file_csv', 'generate_file_json', 'generate_file_yaml',
35+
]
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""External integrations.
2+
3+
Re-exports from parent package for backward compatibility.
4+
"""
5+
from ..mcp_server import handle_request, call_tool, run_server
6+
7+
__all__ = ['handle_request', 'call_tool', 'run_server']

code2logic/llm/__init__.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
"""LLM client integrations.
2+
3+
Re-exports from parent package for backward compatibility.
4+
"""
5+
from ..llm_clients import (
6+
BaseLLMClient, OpenRouterClient, OllamaLocalClient,
7+
LiteLLMClient, get_client
8+
)
9+
from ..intent import EnhancedIntentGenerator
10+
11+
__all__ = [
12+
'BaseLLMClient', 'OpenRouterClient', 'OllamaLocalClient',
13+
'LiteLLMClient', 'get_client',
14+
'EnhancedIntentGenerator',
15+
]

code2logic/tools/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
"""Development tools and utilities.
2+
3+
Re-exports from parent package for backward compatibility.
4+
"""
5+
from ..benchmark import ReproductionBenchmark, run_benchmark, FormatResult, BenchmarkResult
6+
from ..code_review import (
7+
analyze_code_quality, check_security_issues,
8+
check_performance_issues, CodeReviewer
9+
)
10+
from ..refactor import (
11+
RefactoringReport, RefactoringSuggestion, DuplicateGroup,
12+
find_duplicates, suggest_refactoring, compare_codebases, quick_analyze
13+
)
14+
from ..adaptive import AdaptiveReproducer, AdaptiveResult, get_llm_capabilities, LLM_CAPABILITIES
15+
16+
__all__ = [
17+
'ReproductionBenchmark', 'run_benchmark', 'FormatResult', 'BenchmarkResult',
18+
'analyze_code_quality', 'check_security_issues',
19+
'check_performance_issues', 'CodeReviewer',
20+
'RefactoringReport', 'RefactoringSuggestion', 'DuplicateGroup',
21+
'find_duplicates', 'suggest_refactoring', 'compare_codebases', 'quick_analyze',
22+
'AdaptiveReproducer', 'AdaptiveResult', 'get_llm_capabilities', 'LLM_CAPABILITIES',
23+
]

docs/04-python-api.md

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,29 @@
44
55
[← README](../README.md) | [← CLI Reference](03-cli-reference.md) | [Output Formats →](05-output-formats.md)
66

7+
## Package Structure
8+
9+
Code2Logic is organized into subpackages for cleaner imports:
10+
11+
| Package | Contents |
12+
|---------|----------|
13+
| `code2logic.core` | Models, Analyzer, Errors |
14+
| `code2logic.formats` | All generators (YAML, JSON, TOON, etc.) |
15+
| `code2logic.llm` | LLM clients and intent extraction |
16+
| `code2logic.tools` | Benchmark, Review, Refactor |
17+
| `code2logic.integrations` | MCP server |
18+
19+
```python
20+
# Traditional imports (still work)
21+
from code2logic import analyze_project, YAMLGenerator
22+
23+
# Organized imports
24+
from code2logic.core import ProjectInfo, ProjectAnalyzer
25+
from code2logic.formats import TOONGenerator, LogicMLGenerator
26+
from code2logic.llm import get_client
27+
from code2logic.tools import run_benchmark
28+
```
29+
730
## Core Functions
831

932
### analyze_project
@@ -88,10 +111,20 @@ class ClassInfo:
88111

89112
## Generators
90113

114+
All generators are available from `code2logic.formats`:
115+
116+
```python
117+
from code2logic.formats import (
118+
MarkdownGenerator, JSONGenerator, YAMLGenerator,
119+
CSVGenerator, CompactGenerator, GherkinGenerator,
120+
TOONGenerator, LogicMLGenerator
121+
)
122+
```
123+
91124
### MarkdownGenerator
92125

93126
```python
94-
from code2logic.generators import MarkdownGenerator
127+
from code2logic.formats import MarkdownGenerator
95128

96129
gen = MarkdownGenerator()
97130
output = gen.generate(project, detail='standard')
@@ -101,7 +134,7 @@ output = gen.generate(project, detail='standard')
101134
### JSONGenerator
102135

103136
```python
104-
from code2logic.generators import JSONGenerator
137+
from code2logic.formats import JSONGenerator
105138

106139
gen = JSONGenerator()
107140
output = gen.generate(project, flat=False, detail='standard')
@@ -111,16 +144,36 @@ output = gen.generate(project, flat=False, detail='standard')
111144
### YAMLGenerator
112145

113146
```python
114-
from code2logic.generators import YAMLGenerator
147+
from code2logic.formats import YAMLGenerator
115148

116149
gen = YAMLGenerator()
117150
output = gen.generate(project, flat=False, detail='standard')
118151
```
119152

153+
### TOONGenerator
154+
155+
```python
156+
from code2logic.formats import TOONGenerator
157+
158+
gen = TOONGenerator(use_tabs=False)
159+
output = gen.generate(project, detail='standard')
160+
# TOON: Token-Oriented Object Notation (6x smaller than JSON)
161+
```
162+
163+
### LogicMLGenerator
164+
165+
```python
166+
from code2logic.formats import LogicMLGenerator
167+
168+
gen = LogicMLGenerator()
169+
spec = gen.generate(project)
170+
output = spec.content # LogicMLSpec has .content attribute
171+
```
172+
120173
### CSVGenerator
121174

122175
```python
123-
from code2logic.generators import CSVGenerator
176+
from code2logic.formats import CSVGenerator
124177

125178
gen = CSVGenerator()
126179
output = gen.generate(project, detail='standard')
@@ -129,7 +182,7 @@ output = gen.generate(project, detail='standard')
129182
### CompactGenerator
130183

131184
```python
132-
from code2logic.generators import CompactGenerator
185+
from code2logic.formats import CompactGenerator
133186

134187
gen = CompactGenerator()
135188
output = gen.generate(project)
@@ -139,7 +192,7 @@ output = gen.generate(project)
139192
### GherkinGenerator
140193

141194
```python
142-
from code2logic.gherkin import GherkinGenerator
195+
from code2logic.formats import GherkinGenerator
143196

144197
gen = GherkinGenerator()
145198
output = gen.generate(project, detail='standard')
@@ -157,12 +210,33 @@ output = gen.generate(project)
157210

158211
## LLM Clients
159212

160-
### OllamaClient
213+
All LLM clients are available from `code2logic.llm`:
161214

162215
```python
163-
from code2logic.llm import OllamaClient
216+
from code2logic.llm import (
217+
get_client, BaseLLMClient,
218+
OpenRouterClient, OllamaLocalClient, LiteLLMClient
219+
)
220+
```
221+
222+
### get_client (Recommended)
223+
224+
```python
225+
from code2logic.llm import get_client
226+
227+
# Auto-detect best available client
228+
client = get_client()
229+
230+
# Or specify provider
231+
client = get_client(provider='ollama', model='qwen2.5-coder:7b')
232+
```
233+
234+
### OllamaLocalClient
235+
236+
```python
237+
from code2logic.llm import OllamaLocalClient
164238

165-
client = OllamaClient(
239+
client = OllamaLocalClient(
166240
model="qwen2.5-coder:7b",
167241
host="http://localhost:11434"
168242
)

tests/test_error_handling.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ def test_binary_file_detection(self, error_handler, tmp_path):
116116

117117
def test_encoding_fallback(self, error_handler, tmp_path):
118118
"""Test encoding fallback for non-UTF8 files."""
119-
# Create file with Latin-1 encoding
119+
# Create file with Latin-1 encoding (using chars valid in latin-1)
120120
latin1_file = tmp_path / "latin1.py"
121-
latin1_file.write_bytes("# Cześć świat\ndef hello(): pass".encode('latin-1'))
121+
latin1_file.write_bytes("# Caf\xe9 cr\xe8me\ndef hello(): pass".encode('latin-1'))
122122

123123
result = error_handler.safe_read_file(latin1_file)
124124

tests/test_format_comparison.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,11 @@ def test_json_generation(self, analyzed_project):
127127
def test_logicml_generation(self, analyzed_project):
128128
"""Test LogicML format generation."""
129129
gen = LogicMLGenerator()
130-
output = gen.generate(analyzed_project)
130+
spec = gen.generate(analyzed_project)
131+
output = spec.content # LogicMLSpec has .content attribute
131132

132133
assert len(output) > 0
133-
assert "<project" in output or "<module" in output
134+
assert "imports:" in output or "methods:" in output or "functions:" in output
134135

135136
def test_markdown_generation(self, analyzed_project):
136137
"""Test Markdown format generation."""
@@ -178,7 +179,8 @@ def test_format_sizes(self, analyzed_project):
178179
"""Compare output sizes across formats."""
179180
yaml_out = YAMLGenerator().generate(analyzed_project)
180181
json_out = JSONGenerator().generate(analyzed_project)
181-
logicml_out = LogicMLGenerator().generate(analyzed_project)
182+
logicml_spec = LogicMLGenerator().generate(analyzed_project)
183+
logicml_out = logicml_spec.content # LogicMLSpec has .content attribute
182184
markdown_out = MarkdownGenerator().generate(analyzed_project)
183185
toon_out = TOONGenerator().generate(analyzed_project)
184186
toon_tabs = TOONGenerator(use_tabs=True).generate(analyzed_project)
@@ -194,18 +196,19 @@ def test_format_sizes(self, analyzed_project):
194196

195197
print("\n=== Format Size Comparison ===")
196198
for fmt, size in sorted(sizes.items(), key=lambda x: x[1]):
197-
tokens = self._estimate_tokens(size)
199+
tokens = size // 4 # ~4 chars per token
198200
print(f" {fmt}: {size} chars, ~{tokens} tokens")
199201

200202
# TOON should be smaller than JSON
201203
assert sizes['TOON'] < sizes['JSON'], "TOON should be more compact than JSON"
202204

203205
def test_token_estimates(self, analyzed_project):
204206
"""Estimate token counts for each format."""
207+
logicml_spec = LogicMLGenerator().generate(analyzed_project)
205208
formats = {
206209
'YAML': YAMLGenerator().generate(analyzed_project),
207210
'JSON': JSONGenerator().generate(analyzed_project),
208-
'LogicML': LogicMLGenerator().generate(analyzed_project),
211+
'LogicML': logicml_spec.content, # LogicMLSpec has .content attribute
209212
'Markdown': MarkdownGenerator().generate(analyzed_project),
210213
'TOON': TOONGenerator().generate(analyzed_project),
211214
'TOON(tabs)': TOONGenerator(use_tabs=True).generate(analyzed_project),
@@ -351,10 +354,11 @@ class TestBenchmarkSummary:
351354

352355
def test_print_benchmark(self, analyzed_project):
353356
"""Print comprehensive benchmark."""
357+
logicml_spec = LogicMLGenerator().generate(analyzed_project)
354358
formats = {
355359
'YAML': YAMLGenerator().generate(analyzed_project, detail='full'),
356360
'JSON': JSONGenerator().generate(analyzed_project),
357-
'LogicML': LogicMLGenerator().generate(analyzed_project),
361+
'LogicML': logicml_spec.content, # LogicMLSpec has .content attribute
358362
'Markdown': MarkdownGenerator().generate(analyzed_project),
359363
'TOON': TOONGenerator().generate(analyzed_project, detail='full'),
360364
'TOON(tabs)': TOONGenerator(use_tabs=True).generate(analyzed_project, detail='full'),

0 commit comments

Comments
 (0)