otko/pyproject.toml
smillmorel 184bb4662b chore: scope ruff ignores to tests, Qt and engineering notation
RUF001-003 are ignored repo-wide: × / ≈ / ² are deliberate in the
engineering docs and formulas, which also makes the scattered inline
noqa suppressions redundant. Tests use engineering symbols (A, I, L, E),
`importorskip` before imports and capitalised test names; Qt requires
camelCase signal names and PascalCase event overrides; OpenSees material
fields (cR1, epsU) mirror the solver verbatim. N806 stays exempt only for
the numeric modules that use L / Iz / Iy as symbols.
2026-09-16 13:20:36 -04:00

147 lines
4.3 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[build-system]
requires = ["hatchling>=1.24"]
build-backend = "hatchling.build"
[project]
name = "otko"
dynamic = ["version"]
description = "OTKO — a modern, SAP2000-style desktop GUI for OpenSeesPy."
readme = "README.md"
requires-python = ">=3.10"
license = { file = "LICENSE" }
authors = [{ name = "Ozan" }]
keywords = ["opensees", "openseespy", "structural", "earthquake", "fem", "gui"]
classifiers = [
"Development Status :: 2 - Pre-Alpha",
"Intended Audience :: Science/Research",
"Topic :: Scientific/Engineering",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"License :: OSI Approved :: GNU Affero General Public License v3",
"Operating System :: OS Independent",
]
dependencies = [
# ── Headless base (core + services, no Qt required) ──────────────────────
"pydantic>=2.5",
"numpy>=1.26",
"h5py>=3.10",
"openseespy==3.8.0.0",
"openseespywin==3.8.0.0 ; sys_platform == 'win32'",
]
[project.optional-dependencies]
# ── GUI / visualization stack (desktop app only) ──────────────────────────
# Install with: pip install -e ".[gui]" (desktop)
# pip install -e ".[gui,dev]" (desktop + dev tools)
# Headless / web reuse: pip install -e . (base only, no Qt pulled in)
gui = [
"PySide6>=6.6",
"pyvista>=0.43",
"pyvistaqt>=0.11",
"vtk>=9.3",
"pyqtgraph>=0.13",
"imageio[ffmpeg]>=2.34",
]
dev = [
"pytest>=7.4",
"pytest-qt>=4.2",
"pytest-cov>=4.1",
"ruff>=0.4",
"mypy>=1.8",
"pre-commit>=3.6",
"hatch>=1.9",
"tomli>=2.0; python_version < '3.11'",
]
docs = [
"sphinx>=7.2",
"myst-parser>=2.0",
"furo>=2024.1.29",
]
[project.scripts]
otko = "otko.__main__:main"
[project.urls]
Homepage = "https://github.com/ogunc/otko"
Issues = "https://github.com/ogunc/otko/issues"
[tool.hatch.build.targets.wheel]
packages = ["src/otko"]
[tool.hatch.version]
path = "src/otko/_const.py"
# ─────────── Ruff ───────────
[tool.ruff]
line-length = 100
target-version = "py310"
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E", "W", # pycodestyle
"F", # pyflakes
"I", # isort
"B", # bugbear
"UP", # pyupgrade
"N", # pep8-naming
"SIM", # simplify
"RUF", # ruff-specific
]
ignore = [
"E501", # line-length handled by the formatter
"RUF001", # ambiguous unicode: engineering notation (×, ≈, ²) is deliberate
"RUF002",
"RUF003",
]
[tool.ruff.lint.per-file-ignores]
# Engineering symbols (A, I, L, E, P) and `importorskip`-then-import blocks
# are normal in tests.
"tests/**" = ["E402", "E741", "N802", "N806", "N815"]
# Qt requires camelCase signal names and PascalCase event overrides.
"src/otko/views/**" = ["N802", "N815"]
"src/otko/viewmodels/**" = ["N815"]
# Material fields mirror the OpenSees parameter names verbatim (cR1, epsU, ...).
"src/otko/core/materials/__init__.py" = ["N815"]
# Engineering symbols in numeric code: L (length), Iz/Iy (second moments).
"src/otko/services/section_properties.py" = ["N806"]
"src/otko/views/canvas3d/model_renderer.py" = ["N802", "N806", "N815"]
[tool.ruff.format]
quote-style = "double"
# ─────────── Mypy ───────────
[tool.mypy]
python_version = "3.10"
warn_unused_configs = true
plugins = []
[[tool.mypy.overrides]]
module = ["otko.core.*", "otko.services.*", "otko.viewmodels.*"]
strict = true
[[tool.mypy.overrides]]
module = ["openseespy.*", "pyvista.*", "pyvistaqt.*", "vtk.*", "pyqtgraph.*"]
ignore_missing_imports = true
# ─────────── Pytest ───────────
[tool.pytest.ini_options]
minversion = "7.0"
addopts = "-ra -q --strict-markers"
testpaths = ["tests"]
markers = [
"gui: marks tests that require a Qt event loop",
"slow: marks slow tests (deselect with '-m \"not slow\"')",
]
[tool.coverage.run]
branch = true
source = ["src/otko"]
omit = ["src/otko/views/*"] # GUI excluded from coverage targets
[tool.coverage.report]
exclude_lines = ["if TYPE_CHECKING:", "raise NotImplementedError"]
# Conservative floor for the headless suite; raise deliberately with evidence.
fail_under = 50