Compare commits
7 Commits
e5a91faac7
...
fd8d81becf
| Author | SHA1 | Date |
|---|---|---|
|
|
fd8d81becf | |
|
|
d92a687dc7 | |
|
|
75673d3d1f | |
|
|
4c6957db51 | |
|
|
c23d034935 | |
|
|
347a2d67f9 | |
|
|
b22c59e7a0 |
|
|
@ -69,13 +69,13 @@ When generating a commit message:
|
||||||
conventions from the
|
conventions from the
|
||||||
[style guide](./style-guide-reference.md).
|
[style guide](./style-guide-reference.md).
|
||||||
4. Add body only for multi-file or complex changes.
|
4. Add body only for multi-file or complex changes.
|
||||||
5. Write the message to a file in the repo's
|
5. Write the message to TWO files:
|
||||||
`.claude/` subdir with filename format:
|
- `.claude/skills/commit-msg/msgs/<timestamp>_<hash>_commit_msg.md`
|
||||||
`<timestamp>_<first-7-chars-of-last-commit-hash>_commit_msg.md`
|
* with `<timestamp>` from `date -u +%Y%m%dT%H%M%SZ`
|
||||||
where `<timestamp>` is from `date --iso-8601=seconds`.
|
or similar filesystem-safe format.
|
||||||
Also write a copy to
|
* and `<hash>` from `git log -1 --format=%h`
|
||||||
`.claude/git_commit_msg_LATEST.md`
|
first 7 chars.
|
||||||
(overwrite if exists).
|
- `.claude/git_commit_msg_LATEST.md` (overwrite)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
---
|
||||||
|
name: lint
|
||||||
|
description: >
|
||||||
|
Run ruff lint checks on piker Python files for
|
||||||
|
docstring style (D2xx) and code convention
|
||||||
|
compliance. Checks staged files by default.
|
||||||
|
user-invocable: true
|
||||||
|
argument-hint: "[--all|--fix|--stats|paths...]"
|
||||||
|
allowed-tools: Bash(python3 *), Bash(ruff *), Read, Edit
|
||||||
|
---
|
||||||
|
|
||||||
|
# Ruff Lint Checker
|
||||||
|
|
||||||
|
Run piker's ruff config against staged files,
|
||||||
|
specific paths, or the full codebase.
|
||||||
|
|
||||||
|
## Available scripts
|
||||||
|
|
||||||
|
- **`scripts/check.py`** — self-contained (PEP 723)
|
||||||
|
wrapper around `ruff check` that defaults to staged
|
||||||
|
files and uses the project's `ruff.toml`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# check staged Python files (default)
|
||||||
|
python3 scripts/check.py
|
||||||
|
|
||||||
|
# check full codebase
|
||||||
|
python3 scripts/check.py --all
|
||||||
|
|
||||||
|
# auto-fix fixable violations
|
||||||
|
python3 scripts/check.py --fix
|
||||||
|
|
||||||
|
# preview fixes without applying
|
||||||
|
python3 scripts/check.py --diff
|
||||||
|
|
||||||
|
# show per-rule violation counts
|
||||||
|
python3 scripts/check.py --stats
|
||||||
|
|
||||||
|
# check specific files
|
||||||
|
python3 scripts/check.py piker/ui/_style.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common violations
|
||||||
|
|
||||||
|
| Rule | Meaning | Fixable? |
|
||||||
|
|------|---------|----------|
|
||||||
|
| D213 | summary not on 2nd line after `'''` | yes |
|
||||||
|
| D205 | no blank line after summary | no |
|
||||||
|
| D204 | no blank line after class docstring | yes |
|
||||||
|
| D209 | closing quotes not on own line | yes |
|
||||||
|
| D200 | ignored — piker always multiline | n/a |
|
||||||
|
| W291 | trailing whitespace | yes |
|
||||||
|
|
||||||
|
## Fixing D213 (most common)
|
||||||
|
|
||||||
|
Convert this:
|
||||||
|
```python
|
||||||
|
"""Summary on first line."""
|
||||||
|
```
|
||||||
|
|
||||||
|
To piker's `'''` multiline style:
|
||||||
|
```python
|
||||||
|
'''
|
||||||
|
Summary on second line.
|
||||||
|
|
||||||
|
'''
|
||||||
|
```
|
||||||
|
|
||||||
|
For D205, insert a blank line between the summary
|
||||||
|
and description paragraphs inside the docstring.
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
# /// script
|
||||||
|
# requires-python = ">=3.12"
|
||||||
|
# dependencies = []
|
||||||
|
# ///
|
||||||
|
'''
|
||||||
|
Ruff lint checker for piker docstring and code style.
|
||||||
|
|
||||||
|
Checks staged files by default, or the full `piker/`
|
||||||
|
tree with `--all`. Uses the project's `ruff.toml`.
|
||||||
|
|
||||||
|
'''
|
||||||
|
import argparse
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def get_staged_py_files() -> list[str]:
|
||||||
|
'''
|
||||||
|
Return staged Python file paths (added/copied/modified).
|
||||||
|
|
||||||
|
'''
|
||||||
|
result = subprocess.run(
|
||||||
|
[
|
||||||
|
'git', 'diff',
|
||||||
|
'--cached',
|
||||||
|
'--name-only',
|
||||||
|
'--diff-filter=ACM',
|
||||||
|
'--', '*.py',
|
||||||
|
],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
)
|
||||||
|
return [
|
||||||
|
f for f in result.stdout.strip().split('\n')
|
||||||
|
if f
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
'''
|
||||||
|
Parse args and run `ruff check` against targets.
|
||||||
|
|
||||||
|
'''
|
||||||
|
ap = argparse.ArgumentParser(
|
||||||
|
description=(
|
||||||
|
"Run ruff check with piker's ruff.toml config.\n"
|
||||||
|
'\n'
|
||||||
|
'Default: checks staged .py files only.\n'
|
||||||
|
'Use --all for the full piker/ tree.'
|
||||||
|
),
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
)
|
||||||
|
ap.add_argument(
|
||||||
|
'paths',
|
||||||
|
nargs='*',
|
||||||
|
help='files/dirs to check (default: staged)',
|
||||||
|
)
|
||||||
|
ap.add_argument(
|
||||||
|
'--all', '-a',
|
||||||
|
action='store_true',
|
||||||
|
dest='check_all',
|
||||||
|
help='check entire piker/ directory',
|
||||||
|
)
|
||||||
|
ap.add_argument(
|
||||||
|
'--fix',
|
||||||
|
action='store_true',
|
||||||
|
help='auto-fix fixable violations',
|
||||||
|
)
|
||||||
|
ap.add_argument(
|
||||||
|
'--diff',
|
||||||
|
action='store_true',
|
||||||
|
help='preview fixes as unified diff (dry-run)',
|
||||||
|
)
|
||||||
|
ap.add_argument(
|
||||||
|
'--stats',
|
||||||
|
action='store_true',
|
||||||
|
help='show per-rule violation counts only',
|
||||||
|
)
|
||||||
|
args = ap.parse_args()
|
||||||
|
|
||||||
|
# determine check targets
|
||||||
|
if args.check_all:
|
||||||
|
targets: list[str] = ['piker/']
|
||||||
|
elif args.paths:
|
||||||
|
targets = args.paths
|
||||||
|
else:
|
||||||
|
targets = get_staged_py_files()
|
||||||
|
if not targets:
|
||||||
|
print(
|
||||||
|
'No staged Python files found.\n'
|
||||||
|
'Use --all for full codebase '
|
||||||
|
'or pass file paths.'
|
||||||
|
)
|
||||||
|
return 0
|
||||||
|
print(
|
||||||
|
f'Checking {len(targets)} staged file(s)..\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
# ensure ruff is available on PATH
|
||||||
|
if not shutil.which('ruff'):
|
||||||
|
print(
|
||||||
|
'Error: `ruff` not found on PATH.\n'
|
||||||
|
'On NixOS: add to flake.nix or '
|
||||||
|
'`nix-shell -p ruff`\n'
|
||||||
|
'Otherwise: `uv sync --group lint` or '
|
||||||
|
'`pip install ruff`'
|
||||||
|
)
|
||||||
|
return 127
|
||||||
|
|
||||||
|
# build ruff command
|
||||||
|
cmd: list[str] = ['ruff', 'check']
|
||||||
|
|
||||||
|
if args.diff:
|
||||||
|
cmd.append('--diff')
|
||||||
|
elif args.fix:
|
||||||
|
cmd.append('--fix')
|
||||||
|
|
||||||
|
if args.stats:
|
||||||
|
cmd.append('--statistics')
|
||||||
|
|
||||||
|
cmd.extend(targets)
|
||||||
|
|
||||||
|
result = subprocess.run(cmd)
|
||||||
|
return result.returncode
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sys.exit(main())
|
||||||
|
|
@ -107,6 +107,8 @@ ENV/
|
||||||
.git/
|
.git/
|
||||||
|
|
||||||
# any commit-msg gen tmp files
|
# any commit-msg gen tmp files
|
||||||
|
.claude/skills/commit-msg/msgs/
|
||||||
|
.claude/git_commit_msg_LATEST.md
|
||||||
.claude/*_commit_*.md
|
.claude/*_commit_*.md
|
||||||
.claude/*_commit*.toml
|
.claude/*_commit*.toml
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -586,7 +586,7 @@ async def open_price_feed(
|
||||||
fh,
|
fh,
|
||||||
instrument
|
instrument
|
||||||
)
|
)
|
||||||
) as (first, chan):
|
) as (chan, first):
|
||||||
yield chan
|
yield chan
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -653,7 +653,7 @@ async def open_order_feed(
|
||||||
fh,
|
fh,
|
||||||
instrument
|
instrument
|
||||||
)
|
)
|
||||||
) as (first, chan):
|
) as (chan, first):
|
||||||
yield chan
|
yield chan
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1529,7 +1529,7 @@ async def open_client_proxies() -> tuple[
|
||||||
# TODO: maybe this should be the default in tractor?
|
# TODO: maybe this should be the default in tractor?
|
||||||
key=tractor.current_actor().uid,
|
key=tractor.current_actor().uid,
|
||||||
|
|
||||||
) as (cache_hit, (clients, _)),
|
) as (cache_hit, (_, clients)),
|
||||||
|
|
||||||
AsyncExitStack() as stack
|
AsyncExitStack() as stack
|
||||||
):
|
):
|
||||||
|
|
@ -1718,7 +1718,7 @@ async def open_client_proxy(
|
||||||
open_aio_client_method_relay,
|
open_aio_client_method_relay,
|
||||||
client=client,
|
client=client,
|
||||||
event_consumers=event_table,
|
event_consumers=event_table,
|
||||||
) as (first, chan),
|
) as (chan, first),
|
||||||
|
|
||||||
trionics.collapse_eg(), # loose-ify
|
trionics.collapse_eg(), # loose-ify
|
||||||
trio.open_nursery() as relay_tn,
|
trio.open_nursery() as relay_tn,
|
||||||
|
|
|
||||||
|
|
@ -514,8 +514,8 @@ async def open_trade_event_stream(
|
||||||
recv_trade_updates,
|
recv_trade_updates,
|
||||||
client=client,
|
client=client,
|
||||||
) as (
|
) as (
|
||||||
_, # first pushed val
|
|
||||||
trade_event_stream,
|
trade_event_stream,
|
||||||
|
_, # first pushed val
|
||||||
):
|
):
|
||||||
task_status.started(trade_event_stream)
|
task_status.started(trade_event_stream)
|
||||||
# block forever to keep session trio-asyncio session
|
# block forever to keep session trio-asyncio session
|
||||||
|
|
|
||||||
|
|
@ -989,7 +989,7 @@ async def open_aio_quote_stream(
|
||||||
symbol=symbol,
|
symbol=symbol,
|
||||||
contract=contract,
|
contract=contract,
|
||||||
|
|
||||||
) as (contract, from_aio):
|
) as (from_aio, contract):
|
||||||
|
|
||||||
assert contract
|
assert contract
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -203,9 +203,8 @@ pyvnc = { git = "https://github.com/regulad/pyvnc.git" }
|
||||||
# xonsh = { git = 'https://github.com/xonsh/xonsh.git', branch = 'main' }
|
# xonsh = { git = 'https://github.com/xonsh/xonsh.git', branch = 'main' }
|
||||||
|
|
||||||
# XXX since, we're like, always hacking new shite all-the-time. Bp
|
# XXX since, we're like, always hacking new shite all-the-time. Bp
|
||||||
tractor = { git = "https://github.com/goodboy/tractor.git", branch ="piker_pin" }
|
tractor = { git = "https://github.com/goodboy/tractor.git", branch ="main" }
|
||||||
# tractor = { git = "https://pikers.dev/goodboy/tractor", branch = "piker_pin" }
|
# tractor = { git = "https://pikers.dev/goodboy/tractor", branch = "piker_pin" }
|
||||||
# tractor = { git = "https://pikers.dev/goodboy/tractor", branch = "main" }
|
|
||||||
# ------ goodboy ------
|
# ------ goodboy ------
|
||||||
# hackin dev-envs, usually there's something new he's hackin in..
|
# hackin dev-envs, usually there's something new he's hackin in..
|
||||||
# tractor = { path = "../tractor", editable = true }
|
# tractor = { path = "../tractor", editable = true }
|
||||||
|
|
|
||||||
62
ruff.toml
62
ruff.toml
|
|
@ -35,7 +35,7 @@ exclude = [
|
||||||
line-length = 88
|
line-length = 88
|
||||||
indent-width = 4
|
indent-width = 4
|
||||||
|
|
||||||
# Assume Python 3.9
|
# !XXX sync with `pyproject.toml`!
|
||||||
target-version = "py312"
|
target-version = "py312"
|
||||||
|
|
||||||
# ------ - ------
|
# ------ - ------
|
||||||
|
|
@ -44,11 +44,43 @@ target-version = "py312"
|
||||||
|
|
||||||
|
|
||||||
[lint]
|
[lint]
|
||||||
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
select = [
|
||||||
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
|
# pycodestyle error subsets (pre-existing)
|
||||||
# McCabe complexity (`C901`) by default.
|
"E4", "E7", "E9",
|
||||||
select = ["E4", "E7", "E9", "F"]
|
# pyflakes (pre-existing)
|
||||||
ignore = []
|
"F",
|
||||||
|
|
||||||
|
# -- pydocstyle: enforce piker's ''' multiline style --
|
||||||
|
# D2xx whitespace and formatting rules; most are
|
||||||
|
# auto-fixable via `ruff check --fix`.
|
||||||
|
# NOTE: D1xx (missing-docstring) rules intentionally
|
||||||
|
# excluded to avoid noise across the existing codebase.
|
||||||
|
"D2",
|
||||||
|
# D4xx content checks (cherry-picked)
|
||||||
|
"D402", # first line != function signature
|
||||||
|
"D403", # capitalize first word
|
||||||
|
"D419", # no empty docstrings
|
||||||
|
# NOTE: D3xx skipped entirely since D300 enforces
|
||||||
|
# triple-double-quotes `"""` which conflicts with
|
||||||
|
# piker's `'''` convention (the formatter's
|
||||||
|
# `quote-style = "single"` handles conversion).
|
||||||
|
|
||||||
|
# pycodestyle warnings
|
||||||
|
"W",
|
||||||
|
]
|
||||||
|
ignore = [
|
||||||
|
# -- pydocstyle ignores for piker conventions --
|
||||||
|
# piker ALWAYS uses multiline docstring style, never
|
||||||
|
# single-line, so disable the "fit on one line" rule.
|
||||||
|
"D200",
|
||||||
|
# piker uses NO blank line before class docstrings
|
||||||
|
# (D211) not 1-blank-line (D203); these conflict.
|
||||||
|
"D203",
|
||||||
|
# piker puts the summary on the SECOND line after
|
||||||
|
# an opening `'''` (D213); not on the same line as
|
||||||
|
# the opening quotes (D212); these conflict.
|
||||||
|
"D212",
|
||||||
|
]
|
||||||
ignore-init-module-imports = false
|
ignore-init-module-imports = false
|
||||||
|
|
||||||
[lint.per-file-ignores]
|
[lint.per-file-ignores]
|
||||||
|
|
@ -79,16 +111,10 @@ skip-magic-trailing-comma = false
|
||||||
# Like Black, automatically detect the appropriate line ending.
|
# Like Black, automatically detect the appropriate line ending.
|
||||||
line-ending = "auto"
|
line-ending = "auto"
|
||||||
|
|
||||||
# Enable auto-formatting of code examples in docstrings. Markdown,
|
# Auto-format code examples inside docstrings
|
||||||
# reStructuredText code/literal blocks and doctests are all supported.
|
# (>>> blocks, code fences, etc.)
|
||||||
#
|
docstring-code-format = true
|
||||||
# This is currently disabled by default, but it is planned for this
|
|
||||||
# to be opt-out in the future.
|
|
||||||
docstring-code-format = false
|
|
||||||
|
|
||||||
# Set the line length limit used when formatting code snippets in
|
# Use piker's 67-char target for code inside docstrings
|
||||||
# docstrings.
|
# (only applies when `docstring-code-format = true`).
|
||||||
#
|
docstring-code-line-length = 67
|
||||||
# This only has an effect when the `docstring-code-format` setting is
|
|
||||||
# enabled.
|
|
||||||
docstring-code-line-length = "dynamic"
|
|
||||||
|
|
|
||||||
4
uv.lock
4
uv.lock
|
|
@ -1034,7 +1034,7 @@ requires-dist = [
|
||||||
{ name = "tomli", specifier = ">=2.0.1,<3.0.0" },
|
{ name = "tomli", specifier = ">=2.0.1,<3.0.0" },
|
||||||
{ name = "tomli-w", specifier = ">=1.0.0,<2.0.0" },
|
{ name = "tomli-w", specifier = ">=1.0.0,<2.0.0" },
|
||||||
{ name = "tomlkit", git = "https://github.com/pikers/tomlkit.git?branch=piker_pin" },
|
{ name = "tomlkit", git = "https://github.com/pikers/tomlkit.git?branch=piker_pin" },
|
||||||
{ name = "tractor", git = "https://github.com/goodboy/tractor.git?branch=piker_pin" },
|
{ name = "tractor", git = "https://github.com/goodboy/tractor.git?branch=main" },
|
||||||
{ name = "trio", specifier = ">=0.27" },
|
{ name = "trio", specifier = ">=0.27" },
|
||||||
{ name = "trio-typing", specifier = ">=0.10.0" },
|
{ name = "trio-typing", specifier = ">=0.10.0" },
|
||||||
{ name = "trio-util", specifier = ">=0.7.0,<0.8.0" },
|
{ name = "trio-util", specifier = ">=0.7.0,<0.8.0" },
|
||||||
|
|
@ -1676,7 +1676,7 @@ wheels = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tractor"
|
name = "tractor"
|
||||||
version = "0.1.0a6.dev0"
|
version = "0.1.0a6.dev0"
|
||||||
source = { git = "https://github.com/goodboy/tractor.git?branch=piker_pin#566a17ba92469000a01fd18c709ea3e336e72796" }
|
source = { git = "https://github.com/goodboy/tractor.git?branch=main#e77198bb64f0467a50e251ed140daee439752354" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "bidict" },
|
{ name = "bidict" },
|
||||||
{ name = "cffi" },
|
{ name = "cffi" },
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue