# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project

**chardet** is a Python port of Mozilla's Universal Character Encoding Detector. It detects character encodings by analyzing byte patterns, character distributions, and coding schemes. Requires Python 3.10+. Zero runtime dependencies.

See `AGENTS.md` for extended architecture docs, common tasks (adding encodings, fixing accuracy, retraining models), and debugging tips.

## Commands

All commands must be prefixed with `uv run`. Install deps first with `uv sync`.

```bash
uv run pytest test.py                    # Run all tests (parallel via -n auto)
uv run pytest test.py -k "utf-8"         # Run tests matching keyword
uv run ruff check .                      # Lint
uv run ruff format .                     # Format
uv run pyright                           # Type check
uv run pre-commit run --all-files        # All pre-commit hooks
uv run chardetect file.txt               # CLI tool
```

Tests run in parallel (`-n auto`) with 60s timeout. The only test file is `test.py` at repo root. Test data lives in `tests/<encoding>[-<language>]/` directories. Known failures are in the `EXPECTED_FAILURES` dict in `test.py`.

## Architecture

Detection flows through `UniversalDetector` which coordinates parallel probers:

1. **BOM/binary detection** — immediate results for UTF-8-SIG, UTF-16/32 BOM, or binary files
2. **UTF1632Prober** — detects UTF-16/32 without BOM
3. **EscCharSetProber** — detects HZ, ISO-2022-JP/KR via escape sequences
4. **MBCSGroupProber** — runs multi-byte probers (UTF-8, GB18030, Big5, EUC-*, Shift-JIS, CP949, JOHAB) using `CodingStateMachine` + `CharDistributionAnalysis`
5. **SBCSGroupProber** — runs hundreds of `SingleByteCharSetProber` instances using bigram language models, plus `HebrewProber` for logical/visual Hebrew arbitration

Key abstractions:
- `CharSetProber` (base) → `CharSetGroupProber` (orchestrator) → `MBCSGroupProber` / `SBCSGroupProber`
- `MultiByteCharSetProber` uses state machines + unigram frequency analysis
- `SingleByteCharSetProber` uses bigram frequency models from `lang*model.py` files

### Generated files (do not edit manually)
- `chardet/lang*model.py` — single-byte bigram models, generated by `create_language_model.py`
- `chardet/*freq.py` — multi-byte unigram frequency tables

### Key types
- `ResultDict`: `{'encoding': Optional[str], 'confidence': float, 'language': Optional[str]}`
- `EncodingEra` (flag enum): MODERN_WEB, LEGACY_ISO, LEGACY_MAC, DOS, MAINFRAME, ALL
- `LanguageFilter` (flag enum): filtering probers by language
- `ProbingState`: DETECTING, FOUND_IT, NOT_ME
- `MachineState`: START, ERROR, ITS_ME

### API behavior
- `detect()` defaults to `encoding_era=EncodingEra.MODERN_WEB` and `should_rename_legacy=True`, mapping legacy ISO encodings to Windows equivalents
- Processes up to 200KB in 64KB chunks
- `LEGACY_MAP` in `universaldetector.py` and `ISO_WIN_MAP` in `sbcsgroupprober.py` handle encoding remapping

## Code Style

- Ruff for linting and formatting (Black-style, target Python 3.10)
- E501 (line length) is ignored
- Selected rules: E, W, F, B, I (pycodestyle, pyflakes, flake8-bugbear, isort)
- Accuracy over speed — don't sacrifice detection correctness for performance
