[build-system] requires = ["setuptools>=77.0.3"] build-backend = "setuptools.build_meta" [project] name = "UmbraEdit" authors = [{ name = "Veronica Berglyd Olsen", email = "code@vkbo.net" }] description = "A plain text editor for planning and writing novels" readme = { file = "setup/description_pypi.md", content-type = "text/markdown" } license = "GPL-3.0-or-later AND Apache-2.0 AND ISC AND MIT" license-files = ["LICENSE.md"] dynamic = ["version"] requires-python = ">=3.11" classifiers = [ "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Programming Language :: Python :: 3.15", "Programming Language :: Python :: Implementation :: CPython", "Development Status :: 5 - Production/Stable", "Operating System :: OS Independent", "Intended Audience :: End Users/Desktop", "Natural Language :: English", "Topic :: Text Editors", ] dependencies = [ "pyqt6>=6.4", "pyenchant>=3.3.0", "pyobjc-framework-Cocoa; sys_platform == 'darwin'", ] [dependency-groups] dev = [ { include-group = "build" }, { include-group = "docs" }, { include-group = "test" }, { include-group = "lint" }, ] build = ["pyyaml", "tzdata; sys_platform == 'win32'"] docs = [ "docutils>=0.17.1", "pygments>=2.7", "sphinx-book-theme", "sphinx-copybutton", "sphinx-design", "sphinx-favicon", "sphinx-intl", "sphinx>=5.0", ] test = [ "coverage>=7.16.0", "pytest-qt", "pytest-timeout", "pytest>=6.0.0", "tzdata; sys_platform == 'win32'", ] lint = ["pyright", "ruff"] [project.urls] Homepage = "https://umbratools.com/umbraedit" Documentation = "https://umbratools.com/umbraedit/docs" Repository = "https://github.com/saga-soft/UmbraEdit" Issues = "https://github.com/saga-soft/UmbraEdit/issues" [project.gui-scripts] umbraedit = "umbraedit:main" [tool.umbraedit.build] flatpak = { qt_version = "6.11", enchant_version = "2.8.19" } [tool.setuptools.dynamic] version = { attr = "umbraedit.__init__.__version__" } [tool.setuptools.packages.find] include = ["umbraedit*"] [tool.setuptools.package-data] umbraedit = ["assets/**/*"] [tool.ruff] line-length = 120 preview = false [tool.ruff.lint] # Rules: https://docs.astral.sh/ruff/rules select = [ "A", # flake8-builtins (A) "ANN", # flake8-annotations (ANN) "B", # flake8-bugbear (B) "C4", # flake8-comprehensions (C4) "CPY", # flake8-copyright (CPY) "D", # pydocstyle (D) "E", # pycodestyle (E) "F", # Pyflakes (F) "FA", # flake8-future-annotations (FA) "G", # flake8-logging-format (G) "I", # isort (I) "ISC", # flake8-implicit-str-concat (ISC) "LOG", # flake8-logging (LOG) "PERF", # Perflint (PERF) "PIE", # flake8-pie (PIE) "PLC", # Pylint Convention (PLC) "PLE", # Pylint Error (PLE) "PLR17", # Refactor (PLR) - Only PLR17xx "PLW", # Pylint Warning (PLW) "PT", # flake8-pytest-style (PT) "Q", # flake8-quotes (Q) "RET", # flake8-return (RET) "RUF", # Ruff-specific rules (RUF) "SIM", # flake8-simplify (SIM) "SLF", # flake8-self (SLF) "SLOT", # flake8-slots (SLOT) "TC", # flake8-type-checking (TC) "TID", # flake8-tidy-imports (TID) "UP", # pyupgrade (UP) "W", # pycodestyle (W) ] ignore = [ "ANN401", # any-type "D107", # undocumented-public-init "D203", # incorrect-blank-line-before-class "D205", # missing-blank-line-after-summary "D213", # multi-line-summary-second-line "PLC0415", # import-outside-top-level "PLC1901", # compare-to-empty-string "PLW0108", # unnecessary-lambda "PLW0717", # too-many-statements-in-try-clause "PLW2901", # redefined-loop-name "RET505", # superfluous-else-return "RUF015", # unnecessary-iterable-allocation-for-first-element "RUF067", # non-empty-init-module "SIM108", # if-else-block-instead-of-if-exp "UP015", # redundant-open-modes "UP030", # format-literals ] [tool.ruff.lint.per-file-ignores] "tests/*" = ["ANN201", "ANN202", "ANN204", "ANN205", "PLC2701", "RUF069", "SLF", "TC"] "utils/*" = ["SLF", "TC"] [tool.ruff.lint.pydocstyle] ignore-decorators = [ "abc.abstractmethod", "property", "PyQt6.QtCore.pyqtProperty", "typing.overload", "pytest.fixture", ] [tool.ruff.lint.isort] lines-between-types = 1 forced-separate = ["tests"] required-imports = ["from __future__ import annotations"] [tool.ruff.lint.pylint] max-nested-blocks = 10 [tool.ruff.format] quote-style = "double" preview = true [tool.pyright] include = ["umbraedit", "tests"] reportIncompatibleMethodOverride = false pythonVersion = "3.11" [tool.pytest.ini_options] addopts = "--import-mode=importlib" testpaths = ["tests"] log_level = "DEBUG" qt_api = "pyqt6" markers = [ "base: Base classes tests", "core: Core classes tests", "gui: GUI classes tests", ] [tool.coverage.run] branch = true source = ["umbraedit"] relative_files = true [tool.coverage.report] precision = 2