Skip to content

Commit 8bbc01c

Browse files
GeneAIclaude
andcommitted
fix: Prepare package for PyPI publication
Python 3.10+ compatibility: - Add tomli backport for Python < 3.11 (tomllib not available) - Make numpy imports lazy in search.py (only for embeddings feature) Code quality improvements: - Remove unused tree-sitter imports in symbol_extractor.py - Fix importlib usage in empathy_sync.py for module checking - Clean up linting issues (down from 29 to 16 minor style issues) Package successfully builds and installs on Python 3.10, 3.11, and 3.12. All core commands work without optional dependencies. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 0127bf3 commit 8bbc01c

7 files changed

Lines changed: 46 additions & 31 deletions

File tree

memdocs/exceptions.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,10 @@ def validate_file_path(path: Path, must_exist: bool = True) -> None:
184184
raise FileNotFoundError(path)
185185

186186

187-
def validate_config_version(version: int, supported: list[int] = [1]) -> None:
187+
def validate_config_version(version: int, supported: list[int] = None) -> None:
188188
"""Validate configuration version."""
189+
if supported is None:
190+
supported = [1]
189191
if version not in supported:
190192
raise ConfigurationError(
191193
f"Unsupported configuration version: {version}. "

memdocs/extract.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,25 @@
99

1010
import json
1111
import re
12-
import tomllib
12+
import sys
1313
from dataclasses import dataclass
1414
from pathlib import Path
1515

1616
import git
1717
from pygments import lexers
1818
from pygments.util import ClassNotFound
1919

20+
# Python 3.11+ has tomllib built-in, earlier versions need tomli
21+
if sys.version_info >= (3, 11):
22+
import tomllib
23+
else:
24+
try:
25+
import tomli as tomllib
26+
except ImportError:
27+
tomllib = None # type: ignore
28+
2029
from memdocs.schemas import Symbol, SymbolKind
21-
from memdocs.security import InputValidator, ConfigValidator
30+
from memdocs.security import InputValidator
2231

2332
# Configuration constants
2433
MAX_FILE_SIZE_MB = 10 # Maximum file size to process (10MB)

memdocs/search.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
from pathlib import Path
1010
from typing import Any, cast
1111

12-
import numpy as np
13-
1412

1513
class LocalVectorSearch:
1614
"""Local vector similarity search using FAISS.
@@ -80,6 +78,14 @@ def add_embeddings(
8078
if not embeddings:
8179
return []
8280

81+
# Import numpy (only needed for embeddings feature)
82+
try:
83+
import numpy as np
84+
except ImportError:
85+
raise ImportError(
86+
"numpy not installed. " "Install with: pip install 'memdocs[embeddings]'"
87+
) from None
88+
8389
# Convert to numpy array
8490
vectors = np.array(embeddings).astype("float32")
8591

@@ -89,7 +95,7 @@ def add_embeddings(
8995

9096
# Store metadata
9197
indices = list(range(start_idx, start_idx + len(embeddings)))
92-
for idx, doc in zip(indices, documents):
98+
for idx, doc in zip(indices, documents, strict=False):
9399
self.metadata[str(idx)] = doc
94100

95101
# Save to disk (git-committable)
@@ -116,6 +122,14 @@ def search(
116122
if self.index.ntotal == 0:
117123
return []
118124

125+
# Import numpy (only needed for embeddings feature)
126+
try:
127+
import numpy as np
128+
except ImportError:
129+
raise ImportError(
130+
"numpy not installed. " "Install with: pip install 'memdocs[embeddings]'"
131+
) from None
132+
119133
# Convert to numpy array
120134
query = np.array([query_embedding]).astype("float32")
121135

@@ -129,7 +143,7 @@ def search(
129143

130144
# Build results
131145
results = []
132-
for idx, similarity in zip(indices[0], similarities):
146+
for idx, similarity in zip(indices[0], similarities, strict=False):
133147
if idx == -1: # FAISS returns -1 for empty slots
134148
continue
135149

memdocs/summarize.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
ReferenceSummary,
1919
ScopeInfo,
2020
)
21-
from memdocs.security import InputValidator, RateLimiter, ConfigValidator
21+
from memdocs.security import InputValidator, RateLimiter
2222

2323
# Configuration constants
2424
DEFAULT_MAX_TOKENS = 4096 # Default max tokens for Claude API response (schema default)

memdocs/symbol_extractor.py

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -383,16 +383,9 @@ def _extract_typescript_symbols(self, code: str) -> list[ExtractedSymbol]:
383383
Returns:
384384
List of ExtractedSymbol objects
385385
"""
386-
try:
387-
from tree_sitter import Language, Parser
388-
389-
# Try to load TypeScript language
390-
# This requires tree-sitter-typescript to be built
391-
# TODO: Add tree-sitter setup instructions
392-
return []
393-
except ImportError:
394-
# tree-sitter not installed - return empty list
395-
return []
386+
# TODO: Implement TypeScript extraction with tree-sitter
387+
# Requires: tree-sitter-typescript to be built
388+
return []
396389

397390
def _extract_javascript_symbols(self, code: str) -> list[ExtractedSymbol]:
398391
"""
@@ -406,13 +399,9 @@ def _extract_javascript_symbols(self, code: str) -> list[ExtractedSymbol]:
406399
Returns:
407400
List of ExtractedSymbol objects
408401
"""
409-
try:
410-
from tree_sitter import Language, Parser
411-
412-
# TODO: Implement JavaScript extraction
413-
return []
414-
except ImportError:
415-
return []
402+
# TODO: Implement JavaScript extraction with tree-sitter
403+
# Requires: tree-sitter-javascript to be built
404+
return []
416405

417406

418407
def extract_symbols_for_memdocs(

memdocs/wizards/empathy_sync.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,11 @@ async def analyze_module(
159159
def _is_local_empathy(self) -> bool:
160160
"""Check if Empathy Framework is available locally."""
161161
try:
162-
# Try to import EmpathyService
163-
from app.backend.services.empathy_service import EmpathyService
164-
165-
return True
166-
except ImportError:
162+
# Check if EmpathyService module is available
163+
import importlib.util
164+
spec = importlib.util.find_spec("app.backend.services.empathy_service")
165+
return spec is not None
166+
except (ImportError, ModuleNotFoundError):
167167
return False
168168

169169
async def _analyze_local(
@@ -362,7 +362,7 @@ async def main():
362362
# Execute based on mode
363363
if args.file:
364364
print(f"Analyzing file: {args.file}")
365-
result = await wizard.analyze_file(args.file, args.language, args.wizard, args.tier)
365+
await wizard.analyze_file(args.file, args.language, args.wizard, args.tier)
366366
print("✓ Analysis complete. Stored in .memdocs/")
367367

368368
elif args.module:

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ dependencies = [
4242
"tiktoken>=0.7.0", # Token counting
4343
"python-dotenv>=1.0.0", # Environment variables
4444
"rich>=13.0.0", # Beautiful terminal formatting
45+
"tomli>=2.0.0; python_version < '3.11'", # TOML parsing (backport)
4546
]
4647

4748
[project.optional-dependencies]

0 commit comments

Comments
 (0)