Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: use hatch for build and ruff for linting #81

Merged
merged 8 commits into from
Nov 16, 2022
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
18 changes: 4 additions & 14 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/PyCQA/autoflake
rev: v1.7.7
hooks:
- id: autoflake
args: ["--in-place", "--remove-all-unused-imports"]

- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
Expand All @@ -41,15 +35,11 @@ repos:
hooks:
- id: black

- repo: https://github.com/PyCQA/flake8
rev: 5.0.4
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.118
hooks:
- id: flake8
additional_dependencies:
- flake8-pyprojecttoml @ git+https://github.com/tlambert03/flake8-pyprojecttoml.git@main
- flake8-bugbear
- flake8-docstrings
- flake8-typing-imports
- id: ruff
args: ["--fix"]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.982
Expand Down
113 changes: 45 additions & 68 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# https://peps.python.org/pep-0517/
[build-system]
requires = ["setuptools>=45", "wheel", "setuptools-scm>=6.2"]
build-backend = "setuptools.build_meta"
requires = ["hatchling", "hatch-vcs"]
build-backend = "hatchling.build"

# https://peps.python.org/pep-0621/
[project]
Expand All @@ -13,15 +13,24 @@ license = { text = "BSD 3-Clause License" }
authors = [{ email = "talley.lambert@gmail.com" }, { name = "Talley Lambert" }]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Topic :: Desktop Environment",
"Topic :: Software Development",
"Topic :: Software Development :: User Interfaces",
]
dynamic = ["version"]
dependencies = ['psygnal', 'pydantic', 'in-n-out>=0.1.5', 'typing_extensions']
dependencies = [
"psygnal>=0.3.4",
"pydantic>=1.8",
"in-n-out>=0.1.5",
"typing_extensions",
]

# extras
# https://peps.python.org/pep-0621/#dependencies-optional-dependencies
Expand All @@ -31,12 +40,6 @@ test-qt = ["pytest-qt", "fonticon-fontawesome6"]
qt = ["qtpy", "superqt"]
dev = [
"black",
"cruft",
"flake8-bugbear",
"flake8-docstrings",
"flake8-pyprojecttoml",
"flake8-typing-imports",
"flake8",
"ipython",
"isort",
"mypy",
Expand All @@ -57,65 +60,51 @@ docs = [
"mkdocs-macros-plugin==0.7.0",
"typing_extensions>=4.0",
]

[project.urls]
homepage = "https://github.com/pyapp-kit/app-model"
repository = "https://github.com/pyapp-kit/app-model"

# same as console_scripts entry point
# [project.scripts]
# spam-cli = "spam:main_cli"

# Entry points
# https://peps.python.org/pep-0621/#entry-points
# [project.entry-points."spam.magical"]
# tomatoes = "spam:main_tomatoes"

# https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
[tool.setuptools]
zip-safe = false
include-package-data = true
packages = { find = { where = ["src"], exclude = [] } }
[tool.hatch.version]
source = "vcs"

[tool.setuptools.package-data]
"*" = ["py.typed"]
[tool.hatch.envs.test]
features = ["test"]
[tool.hatch.envs.test.scripts]
run = "pytest -v --color=yes --cov-config=pyproject.toml -W i --cov=app_model --cov-report=xml --cov-report=term-missing"

# https://github.com/pypa/setuptools_scm/#pyprojecttoml-usage
[tool.setuptools_scm]

# https://pycqa.github.io/isort/docs/configuration/options.html
[tool.isort]
profile = "black"
src_paths = ["src/app_model", "tests"]

# https://flake8.pycqa.org/en/latest/user/options.html
# https://gitlab.com/durko/flake8-pyprojecttoml
[tool.flake8]
exclude = "docs,.eggs,examples,_version.py"
max-line-length = 88
ignore = "E203"
min-python-version = "3.8.0"
docstring-convention = "all" # use numpy convention, while allowing D417
extend-ignore = """
E203 # whitespace before ':'
D107,D203,D212,D213,D402,D413,D415,D416 # numpy
D100 # missing docstring in public module
D105 # missing docstring in magic method
D401 # imperative mood
W503 # line break before binary operator
B010
"""
per-file-ignores = [
"tests/*,demo/*,docs/*: D",
"src/app_model/_registries.py,src/app_model/context/_expressions.py: D10",
]

# https://github.com/charliermarsh/ruff
[tool.ruff]
target-version = "py38"
line-length = 88
extend-select = ["D", "M001"]
extend-ignore = [
"D100",
"D107",
"D203",
"D212",
"D213",
"D402",
"D413",
"D415",
"D416",
]

# http://www.pydocstyle.org/en/stable/usage.html
[tool.pydocstyle]
match_dir = "src/app_model"
convention = "numpy"
add_select = "D402,D415,D417"
ignore = "D100,D213,D401,D413,D107"
[tool.ruff.per-file-ignores]
"tests/*.py" = ["D", "E501"]
"demo/*" = ["D"]
"docs/*" = ["D"]
"src/app_model/_registries.py" = ["D10"]
"src/app_model/context/_expressions.py" = ["D10"]
"src/app_model/types/_keys/*" = ["E501"]
"setup.py" = ["F821"]

# https://docs.pytest.org/en/6.2.x/customize.html
[tool.pytest.ini_options]
Expand Down Expand Up @@ -149,19 +138,14 @@ exclude_lines = [
"if TYPE_CHECKING:",
"@overload",
"except ImportError",
"pass",
]
skip_covered = true
show_missing = true

# https://github.com/cruft/cruft
[tool.cruft]
skip = ["tests"]

# https://github.com/mgedmin/check-manifest#configuration
[tool.check-manifest]
ignore = [
".cruft.json",
".flake8",
".github_changelog_generator",
".pre-commit-config.yaml",
"tests/**/*",
Expand All @@ -171,12 +155,5 @@ ignore = [
".readthedocs.yaml",
"mkdocs.yml",
"CHANGELOG.md",
".ruff_cache/**/*",
]

# https://python-semantic-release.readthedocs.io/en/latest/configuration.html
[tool.semantic_release]
version_source = "tag_only"
branch = "main"
changelog_sections = "feature,fix,breaking,documentation,performance,chore,:boom:,:sparkles:,:children_crossing:,:lipstick:,:iphone:,:egg:,:chart_with_upwards_trend:,:ambulance:,:lock:,:bug:,:zap:,:goal_net:,:alien:,:wheelchair:,:speech_balloon:,:mag:,:apple:,:penguin:,:checkered_flag:,:robot:,:green_apple:,Other"
# commit_parser=semantic_release.history.angular_parser
build_command = "pip install build && python -m build"
29 changes: 29 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import sys

sys.stderr.write(
"""
===============================
Unsupported installation method
===============================
app-model does not support installation with `python setup.py install`.
Please use `python -m pip install .` instead.
"""
)
sys.exit(1)


# The below code will never execute, however GitHub is particularly
# picky about where it finds Python packaging metadata.
# See: https://github.com/github/feedback/discussions/6456
#
# To be removed once GitHub catches up.

setup(
name="app-model",
install_requires=[
"psygnal>=0.3.4",
"pydantic>=1.8",
"in-n-out>=0.1.5",
"typing_extensions",
],
)
8 changes: 4 additions & 4 deletions src/app_model/backends/qt/_qmenu.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
# fmt: off
class _AcceptsMenus(Protocol):
_app: Application
def clear(self) -> None: ... # noqa: E704
def addMenu(self, menu: QMenu) -> None: ... # noqa: E704
def addAction(self, menu: QAction) -> None: ... # noqa: E704
def addSeparator(self) -> None: ... # noqa: E704
def clear(self) -> None: ...
def addMenu(self, menu: QMenu) -> None: ...
def addAction(self, menu: QAction) -> None: ...
def addSeparator(self) -> None: ...

# fmt: on

Expand Down
4 changes: 2 additions & 2 deletions src/app_model/expressions/_expressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,9 @@ class ExprTranformer(ast.NodeTransformer):

# fmt: off
@overload
def visit(self, node: ast.expr) -> Expr: ... # noqa
def visit(self, node: ast.expr) -> Expr: ...
@overload
def visit(self, node: PassedType) -> PassedType: ... # noqa
def visit(self, node: PassedType) -> PassedType: ...
# fmt: on

def visit(self, node: ast.AST) -> Optional[ast.AST]:
Expand Down
6 changes: 5 additions & 1 deletion src/app_model/registries/_commands_reg.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def __getitem__(self, id: str) -> _RegisteredCommand:
raise KeyError(f"Command {id!r} not registered")
return self._commands[id]

def execute_command(
def execute_command( # noqa: D417
self,
id: str,
*args: Any,
Expand All @@ -165,13 +165,17 @@ def execute_command(
----------
id : CommandId
ID of the command to execute
*args: Any
Positional arguments to pass to the command
execute_asychronously : bool
Whether to execute the command asynchronously in a thread,
by default `False`. Note that *regardless* of this setting,
the return value will implement the `Future` API (so it's necessary)
to call `result()` on the returned object. Eventually, this will
default to True, but we need to solve `ensure_main_thread` Qt threading
issues first
**kwargs: Any
Keyword arguments to pass to the command

Returns
-------
Expand Down
14 changes: 10 additions & 4 deletions src/app_model/types/_keys/_key_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ class ScanCode(IntEnum):
implementations to support special keyboards (such as multimedia or
legacy keyboards).
"""

UNIDENTIFIED = 0 # This value code should be used when no other value given in this specification is appropriate.

# ----------------------- Writing System Keys -----------------------
Expand Down Expand Up @@ -651,8 +652,10 @@ def __or__(


class KeyCombo(int):
"""KeyCombo is an integer combination of one or more
[`KeyMod`][app_model.types.KeyMod] and [`KeyCode`][app_model.types.KeyCode]."""
"""KeyCombo is an integer combination of one or more.

[`KeyMod`][app_model.types.KeyMod] and [`KeyCode`][app_model.types.KeyCode].
"""

def __new__(
cls: Type["KeyCombo"], modifiers: KeyMod, key: KeyCode = KeyCode.UNKNOWN
Expand All @@ -670,8 +673,11 @@ def __repr__(self) -> str:


class KeyChord(int):
"""KeyChord is an integer combination of two [`KeyCombo`][app_model.types.KeyCombo],
[`KeyCode`][app_model.types.KeyCode], or [int][]."""
"""KeyChord is an integer combination of two key combos.

It could be two [`KeyCombo`][app_model.types.KeyCombo]
[`KeyCode`][app_model.types.KeyCode], or [int][].
"""

def __new__(cls: Type["KeyChord"], first_part: int, second_part: int) -> "KeyChord":
# shift the second part 16 bits to the left
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def redo(self) -> Mock:
fixtures directory must be added to sys path during the test (as we do below)
"""
try:
from fake_module import GLOBAL_MOCK # noqa
from fake_module import GLOBAL_MOCK

return GLOBAL_MOCK
except ImportError as e:
Expand Down