You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`infrared-protocols` is a pure-Python library (Python ≥ 3.14) that encodes infrared
4
-
remote-control protocols (e.g. NEC) to and from raw pulse/space timing sequences.
5
-
The public API surface is small and intentionally minimal.
3
+
`infrared-protocols` is a pure-Python library (Python ≥ 3.14) that encodes infrared remote-control protocols (e.g. NEC) to and from raw pulse/space timing sequences. The public API surface is small and intentionally minimal.
6
4
7
5
## Environment Setup
8
6
@@ -14,84 +12,41 @@ The public API surface is small and intentionally minimal.
14
12
15
13
-**Do NOT amend, squash, or rebase commits that have already been pushed to the PR branch after the PR is opened** - Reviewers need to follow the commit history, as well as see what changed since their last review
16
14
17
-
## Build / Lint / Test
15
+
## Lint / Format / Type-check
18
16
19
-
-`ruff` is used for linting and formatting.
20
-
-`basedpyright` is used for type checking.
21
-
-`pytest` is used for testing.
22
-
- After finishing a code session, run `prek --all-files` to check for linting and formatting issues.
23
-
24
-
### Run all lint, format, and type-check hooks (changed files only)
25
-
```bash
26
-
prek
27
-
```
28
-
29
-
### Run all hooks on every file
30
-
```bash
31
-
prek --all-files
32
-
```
17
+
- After finishing a code session, run `prek --all-files` to run all lint, format, and type-check hooks.
33
18
34
19
## Code Style
35
20
36
-
### Imports
37
-
-**Within the package:** use relative imports to the specific submodule that
38
-
defines the symbol, e.g. `from . import Command` in
39
-
`infrared_protocols/commands/nec.py` (picking up `Command` from the
40
-
`commands` package's `__init__.py`).
41
-
42
-
### Types
21
+
- Write code that reads like the surrounding code. `infrared_protocols/commands/nec.py` and `infrared_protocols/codes/lg/tv.py` are good references.
43
22
- No `Any`; avoid `cast`; prefer real type narrowing.
44
-
- Inline variable annotations where needed: `timings: list[int] = []`.
45
-
46
-
### Classes
47
-
- Abstract base classes use `abc.ABC` and `@abc.abstractmethod`.
48
-
- Immutable value objects use `@dataclass(frozen=True, slots=True)`.
49
-
- Constructor arguments should be **keyword-only** (use `*` separator) to prevent
50
-
positional-argument confusion.
23
+
- Constructor arguments are keyword-only (use the `*` separator).
24
+
- Use `# fmt: skip` on long arrays of numbers to avoid having one number per line. Break them at around 100 column length.
25
+
- Keep comments concise. Prefer one short line stating the non-obvious constraint, or no comment at all.
26
+
- Do not add comments that just restate the code on the following line(s) (e.g. `# Check if initialized` above `if self.initialized:`). Comments should only explain why (non-obvious constraints, surprising behavior, or workarounds), never what. Comments in tests that explain why a function call or assertion is made are ok.
51
27
52
-
### Docstrings
53
-
- First line: concise one-line summary.
54
-
- Multi-line: blank line after the summary, then prose description when the method is
55
-
complex or requires extra detail.
56
28
57
-
## Python Syntax Notes
29
+
## Python 3.14 Notes
58
30
59
-
- Python 3.14 and above is supported. Do not flag syntax or features that require Python 3.13 as issues, and do not suggest workarounds for older Python versions.
60
-
- Python 3.14 explicitly allows `except TypeA, TypeB:` without parentheses. Never flag this as an issue.
61
-
- Python 3.14 evaluates annotations lazily (PEP 649). Forward references in annotations do not need to be quoted — annotations can reference names defined later in the module without quoting them or using `from __future__ import annotations`. Do not flag unquoted forward references in annotations as issues.
31
+
- Do not flag Python 3.14 syntax as an issue or suggest workarounds for older versions.
32
+
-`except TypeA, TypeB:` without parentheses is valid in Python 3.14, and annotations are evaluated lazily (PEP 649), so forward references in annotations never need quoting.
62
33
63
34
## Protocol Semantics
64
35
65
-
- Do not add generic repeat (full frame copy) support to command encoders. Only
66
-
protocols with a distinct/special repeat-code frame should expose repeat handling.
36
+
- Do not add generic repeat (full frame copy) support to command encoders. Only protocols with a distinct/special repeat-code frame should expose repeat handling.
67
37
68
38
## Error Handling
69
39
70
-
- The library currently has no custom exceptions. Incorrect inputs surface as natural
- Correctness is enforced primarily through the type checker and immutable value
73
-
objects rather than defensive runtime checks.
74
-
- If you add validation, raise standard built-in exceptions with descriptive messages
75
-
rather than introducing custom exception classes unless there is a clear consumer
76
-
need.
40
+
- No custom exception classes: incorrect inputs surface as built-in exceptions (`TypeError`, `ValueError`) with descriptive messages.
41
+
- Correctness is enforced primarily through the type checker and immutable value objects rather than defensive runtime checks.
77
42
78
43
## Testing
79
44
80
-
- Use `pytest` to run tests
81
-
- When writing or modifying tests, ensure all test function parameters have type annotations.
82
-
- Prefer concrete types over `Any`.
83
-
- Prefer `@pytest.mark.usefixtures` over arguments, if the argument is not going to be used.
84
-
- Avoid using conditions/branching in tests. Instead, either split tests or adjust the test parametrization to cover all cases without branching.
85
-
- If multiple tests share most of their code, use `pytest.mark.parametrize` to merge them into a single parameterized test instead of duplicating the body. Use `pytest.param` with an `id` parameter to name the test cases clearly.
86
-
87
-
## Good practices
88
-
89
-
- Do not add comments that just restate the code on the following line(s) (e.g. `# Check if initialized` above `if self.initialized:`). Comments should only explain why — non-obvious constraints, surprising behavior, or workarounds — never what.
45
+
- Prefer `@pytest.mark.usefixtures` over arguments when the argument is not used.
46
+
- Avoid conditions/branching in tests: split tests or adjust the parametrization to cover all cases without branching.
47
+
- If multiple tests share most of their code, merge them with `pytest.mark.parametrize`, naming cases via `pytest.param` with an `id`.
90
48
91
49
## AI policy
92
50
93
51
This project follows the [Open Home Foundation AI Policy](AI_POLICY.md).
94
-
Autonomous contributions are not accepted: a human must review, understand,
95
-
and be able to explain every change before it is submitted. Do not open
96
-
issues or pull requests autonomously, and do not post comments on behalf of
97
-
a user without their review.
52
+
Autonomous contributions are not accepted: a human must review, understand, and be able to explain every change before it is submitted. Do not open issues or pull requests autonomously, and do not post comments on behalf of a user without their review.
0 commit comments