|
| 1 | +# Code Style and Conventions |
| 2 | + |
| 3 | +## Core Development Rules |
| 4 | + |
| 5 | +### Code Quality Requirements |
| 6 | +- **Type hints required** for all code |
| 7 | +- **Public APIs must have docstrings** |
| 8 | +- **Functions must be focused and small** |
| 9 | +- **Follow existing patterns exactly** |
| 10 | +- **Line length: 120 chars maximum** |
| 11 | +- **Avoid `Any` type** - prefer typed classes inheriting from Pydantic `BaseModel` |
| 12 | + |
| 13 | +### File Organization |
| 14 | +- Every module should have files ending with `Core` and `internal` folder |
| 15 | +- **MAKE ALL properties in class private** by prepending `_` to variable name |
| 16 | +- **IF property should be public** then hide it using `_` and create a property function |
| 17 | +- **AVOID MAGIC NUMBERS** - instead create STATIC fields in class |
| 18 | + |
| 19 | +### Comment Style |
| 20 | +- **NO inline comments after code** - Never write comments on the same line as code (e.g., `x = 5 # this is bad`) |
| 21 | +- Comments should be on their own line above the code they describe |
| 22 | +- Docstrings are preferred over comments for function/class documentation |
| 23 | + |
| 24 | +### Class Design |
| 25 | +- **Classes with only static methods should not have instances created** |
| 26 | + - Mark such classes appropriately (e.g., with abstract base class or clear documentation) |
| 27 | + - Consider using module-level functions instead if appropriate |
| 28 | + |
| 29 | +### Forbidden Practices |
| 30 | +- Using `hasattr` and `getattr` by default |
| 31 | +- Use static types instead of dictionaries whenever possible and sensible |
| 32 | + |
| 33 | +### Testing Requirements |
| 34 | +- **Framework**: pytest with anyio (preferred over asyncio) |
| 35 | +- **Test file naming**: Must end in `Test` postfix (e.g., `KnowledgeSearchCoreTest.py`) |
| 36 | +- **Test classes**: Always use classes in test files |
| 37 | +- **One test file per implementation file** |
| 38 | + |
| 39 | +### Test Quality Standards - NO WEAK TESTS! |
| 40 | +Tests MUST: |
| 41 | +- **Not have any `if` statements** |
| 42 | +- **Test real values and not only shape** |
| 43 | +- **Not use `try`/`catch` for testing** (prevents false positives) |
| 44 | +- **Have hardcoded values mostly** and not ranges like `len(expression) > magic_number` |
| 45 | +- **NO MAGIC NUMBERS** - put numbers in class constants |
| 46 | + |
| 47 | +### Exception Handling |
| 48 | +- **Always use `logger.exception()` instead of `logger.error()` when catching exceptions** |
| 49 | +- Don't include the exception in the message: `logger.exception("Failed")` not `logger.exception(f"Failed: {e}")` |
| 50 | +- **Catch specific exceptions** where possible: |
| 51 | + - File ops: `except (OSError, PermissionError):` |
| 52 | + - JSON: `except json.JSONDecodeError:` |
| 53 | + - Network: `except (ConnectionError, TimeoutError):` |
| 54 | +- **Only catch `Exception` for**: |
| 55 | + - Top-level handlers that must not crash |
| 56 | + - Cleanup blocks (log at debug level) |
| 57 | + |
| 58 | +### Formatting Tools |
| 59 | +- **Ruff**: Primary linter and formatter |
| 60 | +- **Black**: Code formatting (line-length=120, target py312) |
| 61 | +- **isort**: Import sorting (black profile, line_length=120) |
| 62 | +- **MyPy**: Type checking with strict settings |
0 commit comments