Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"
python-version: "3.13"

- name: Install dependencies
run: uv sync --all-extras --dev
run: uv sync --dev

- name: Run ruff check
run: uv run ruff check .

- name: Run ruff format check
run: uv run ruff format --check .

- name: Run mypy
run: uv run mypy metaboatrace
9 changes: 4 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,12 @@ jobs:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-dependency-glob: uv.lock
uses: astral-sh/setup-uv@v4

- name: Set up Python
run: uv python install 3.11
uses: actions/setup-python@v5
with:
python-version: "3.13"

- name: Build
run: uv build
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: "pyproject.toml"
python-version: "3.13"

- name: Install dependencies
run: uv sync --all-extras --dev
run: uv sync --dev

- name: Run tests with coverage
run: uv run pytest --cov=metaboatrace.models tests --cov-report=xml:coverage.xml
Expand Down
30 changes: 30 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
- id: check-toml
- id: check-merge-conflict
- id: debug-statements
- id: mixed-line-ending

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
hooks:
# Run the linter
- id: ruff
args: [--fix]
# Run the formatter
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.13.0
hooks:
- id: mypy
additional_dependencies: [pydantic]
args: [--config-file=pyproject.toml]
files: \.py$
exclude: (^tests/|/tests/)
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
![Coverage](https://img.shields.io/codecov/c/github/metaboatrace/models.svg)
![PyPI version](https://img.shields.io/pypi/v/metaboatrace.models.svg)
![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)
![Python version](https://img.shields.io/badge/python-3.11-blue.svg)
![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)
![Python version](https://img.shields.io/badge/python-3.13-blue.svg)
![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)

## 概要

Expand All @@ -26,3 +26,7 @@ source .venv/bin/activate
```

※ `uv` が事前にインストールされていること

## ブランチ戦略

[GitHub Flow](https://docs.github.com/en/get-started/using-github/github-flow) を採用している。
9 changes: 4 additions & 5 deletions metaboatrace/models/boat.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from datetime import date
from enum import Enum
from typing import Optional

from pydantic import BaseModel, Field, StrictInt

Expand All @@ -22,13 +21,13 @@ class BoatPerformance(BaseModel):
stadium_tel_code: StadiumTelCode
recorded_date: date
number: StrictInt = Field(..., ge=1, le=999)
quinella_rate: Optional[float] = Field(None, ge=0, le=100)
trio_rate: Optional[float] = Field(None, ge=0, le=100)
quinella_rate: float | None = Field(None, ge=0, le=100)
trio_rate: float | None = Field(None, ge=0, le=100)


class MotorPerformance(BaseModel):
stadium_tel_code: StadiumTelCode
recorded_date: date
number: StrictInt = Field(..., ge=1, le=99)
quinella_rate: Optional[float] = Field(None, ge=0, le=100)
trio_rate: Optional[float] = Field(None, ge=0, le=100)
quinella_rate: float | None = Field(None, ge=0, le=100)
trio_rate: float | None = Field(None, ge=0, le=100)
28 changes: 14 additions & 14 deletions metaboatrace/models/race.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from datetime import date, datetime
from enum import Enum
from typing import Literal, Optional
from typing import Literal

from pydantic import BaseModel, Field, StrictInt, field_validator

Expand Down Expand Up @@ -90,8 +90,8 @@ class RaceInformation(_RaceIdentifier):
class WeatherCondition(_RaceIdentifier):
in_performance: bool
weather: Weather
wavelength: Optional[float]
wind_angle: Optional[float] = Field(None, ge=0, le=360)
wavelength: float | None
wind_angle: float | None = Field(None, ge=0, le=360)
wind_velocity: float
air_temperature: float
water_temperature: float
Expand All @@ -114,25 +114,25 @@ class CircumferenceExhibitionRecord(_RaceEntryIdentifier):


class BoatSetting(_RaceEntryIdentifier):
boat_number: Optional[int] = None
motor_number: Optional[int] = None
tilt: Optional[float] = Field(None, ge=-0.5, le=3.0)
is_new_propeller: Optional[bool] = None
boat_number: int | None = None
motor_number: int | None = None
tilt: float | None = Field(None, ge=-0.5, le=3.0)
is_new_propeller: bool | None = None
motor_parts_exchanges: list[tuple[MotorParts, StrictInt]]


class Odds(_RaceIdentifier, _BettingMixin):
ratio: Optional[float] = Field(None, ge=0, le=9999.0)
ratio: float | None = Field(None, ge=0, le=9999.0)


class Payoff(_RaceIdentifier, _BettingMixin):
amount: StrictInt = Field(..., ge=100)


class RaceRecord(_RaceEntryIdentifier):
start_course: Optional[StrictInt] = Field(None, ge=1, le=6)
arrival: Optional[StrictInt] = Field(None, ge=1, le=6)
total_time: Optional[float] = None
start_time: Optional[float] = None
winning_trick: Optional[WinningTrick] = None
disqualification: Optional[Disqualification] = None
start_course: StrictInt | None = Field(None, ge=1, le=6)
arrival: StrictInt | None = Field(None, ge=1, le=6)
total_time: float | None = None
start_time: float | None = None
winning_trick: WinningTrick | None = None
disqualification: Disqualification | None = None
15 changes: 7 additions & 8 deletions metaboatrace/models/racer.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from datetime import date
from enum import Enum
from typing import Optional

from pydantic import BaseModel, StrictInt

Expand All @@ -27,13 +26,13 @@ class Racer(BaseModel):
registration_number: StrictInt
last_name: str
first_name: str = ""
gender: Optional[Gender] = None
term: Optional[StrictInt] = None
birth_date: Optional[date] = None
height: Optional[StrictInt] = None
born_prefecture: Optional[Prefecture] = None
branch: Optional[Branch] = None
current_rating: Optional[RacerRank] = None
gender: Gender | None = None
term: StrictInt | None = None
birth_date: date | None = None
height: StrictInt | None = None
born_prefecture: Prefecture | None = None
branch: Branch | None = None
current_rating: RacerRank | None = None


class RacerCondition(BaseModel):
Expand Down
7 changes: 3 additions & 4 deletions metaboatrace/models/stadium.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from datetime import date
from enum import Enum
from typing import Any, Dict, Optional
from typing import Self

from pydantic import BaseModel, Field, StrictInt, model_validator
from typing_extensions import Self


class StadiumTelCode(Enum):
Expand Down Expand Up @@ -81,9 +80,9 @@ class EventHoldingStatus(Enum):

class EventHolding(BaseModel):
stadium_tel_code: StadiumTelCode
date: Optional[date]
date: date | None
status: EventHoldingStatus
progress_day: Optional[int] = None # HACK: 最終日は-1で表現
progress_day: int | None = None # HACK: 最終日は-1で表現

@model_validator(mode="after")
def validate_status_and_progress_day(self) -> Self:
Expand Down
47 changes: 39 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "metaboatrace.models"
version = "2.3.7"
version = "2.4.0"
description = "Models of Japanese boatrace"
authors = [
{ name = "k0kishima", email = "okishimaxyz@gmail.com" }
Expand All @@ -9,16 +9,16 @@ dependencies = [
"pydantic>=2.0.3",
]
readme = "README.md"
requires-python = ">= 3.11"
requires-python = ">= 3.13"
license = "MIT"

[project.optional-dependencies]
[dependency-groups]
dev = [
"mypy>=1.10.1",
"black>=23.7.0",
"pre-commit>=4.0.0",
"pytest>=7.4.0",
"pytest-cov>=4.1.0",
"codecov>=2.1.13"
"ruff>=0.8.0",
]

[build-system]
Expand All @@ -32,7 +32,7 @@ allow-direct-references = true
packages = ["."]

[tool.mypy]
python_version = "3.11"
python_version = "3.13"
check_untyped_defs = true
ignore_missing_imports = true
warn_redundant_casts = true
Expand All @@ -41,10 +41,41 @@ strict_optional = true
disallow_any_generics = true
disallow_untyped_defs = true
no_implicit_optional = true
explicit_package_bases = true
namespace_packages = true

[tool.black]
[tool.ruff]
line-length = 100
target-version = ['py311']
target-version = "py313"

[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"ARG", # flake8-unused-arguments
"SIM", # flake8-simplify
"RUF", # Ruff-specific rules
]
ignore = [
"E501", # line too long (handled by formatter)
"RUF001", # String contains ambiguous unicode character
"RUF002", # Docstring contains ambiguous unicode character
"RUF003", # Comment contains ambiguous unicode character
]

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["ARG001", "ARG002"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

[tool.pytest.ini_options]
testpaths = ["tests",]
11 changes: 6 additions & 5 deletions tests/metaboatrace/models/test_boat.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import date
from typing import Any

import pytest
from pydantic import ValidationError
Expand All @@ -14,8 +15,8 @@
(50.0, 101.0, False), # invalid trio_rate
],
)
def test_boat_performance(quinella_rate, trio_rate, expected): # type: ignore
boat_data = {
def test_boat_performance(quinella_rate: float, trio_rate: float, expected: bool) -> None:
boat_data: dict[str, Any] = {
"stadium_tel_code": StadiumTelCode.FUKUOKA,
"recorded_date": date.today(),
"number": 1,
Expand All @@ -32,7 +33,7 @@ def test_boat_performance(quinella_rate, trio_rate, expected): # type: ignore
assert boat.trio_rate == boat_data["trio_rate"]
else:
with pytest.raises(ValidationError):
boat = BoatPerformance(**boat_data)
BoatPerformance(**boat_data)


@pytest.mark.parametrize(
Expand All @@ -44,7 +45,7 @@ def test_boat_performance(quinella_rate, trio_rate, expected): # type: ignore
],
)
def test_motor_performance(quinella_rate: float, trio_rate: float, expected: bool) -> None:
motor_data = {
motor_data: dict[str, Any] = {
"stadium_tel_code": StadiumTelCode.FUKUOKA,
"recorded_date": date.today(),
"number": 1,
Expand All @@ -61,4 +62,4 @@ def test_motor_performance(quinella_rate: float, trio_rate: float, expected: boo
assert motor.trio_rate == motor_data["trio_rate"]
else:
with pytest.raises(ValidationError):
motor = MotorPerformance(**motor_data)
MotorPerformance(**motor_data)
Loading