Skip to content

Commit f28a8a3

Browse files
authored
Merge branch 'master' into Avoid-bare-except
2 parents 9861cf5 + 55ebdc8 commit f28a8a3

14 files changed

Lines changed: 407 additions & 371 deletions

File tree

.github/workflows/ci.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ on:
1010
- "docs/**"
1111
- ".readthedocs.yaml"
1212
- "pyproject.toml"
13-
- "setup.cfg"
13+
- "mypy.ini"
1414
- "**/*.py"
1515
pull_request:
1616
paths:
1717
- ".github/workflows/ci.yml"
1818
- "docs/**"
1919
- ".readthedocs.yaml"
2020
- "pyproject.toml"
21-
- "setup.cfg"
21+
- "mypy.ini"
2222
- "**/*.py"
2323

2424
concurrency:
@@ -28,9 +28,16 @@ concurrency:
2828
cancel-in-progress: true
2929

3030
jobs:
31+
ruff:
32+
runs-on: ubuntu-latest
33+
timeout-minutes: &timeout-minutes 5
34+
steps:
35+
- uses: actions/checkout@v6
36+
- uses: astral-sh/ruff-action@v4.0.0
37+
3138
mypy:
3239
runs-on: ${{ matrix.os }}
33-
timeout-minutes: &timeout-minutes 5
40+
timeout-minutes: *timeout-minutes
3441
strategy:
3542
# mypy is os and python-version sensitive. Test on all supported combinations
3643
matrix:

mypy.ini

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[mypy]
2+
mypy_path = src/, typings/
3+
exclude = build/, dist/
4+
strict = True
5+
6+
# Leverage type inference for function return type
7+
disallow_untyped_calls = False
8+
disallow_incomplete_defs = False
9+
disallow_untyped_defs = False
10+
11+
disable_error_code =
12+
# https://github.com/python/mypy/issues/6232 (redefinition with correct type)
13+
attr-defined, assignment,

pyproject.toml

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
[build-system]
2-
requires = ["setuptools", "setuptools-scm"]
2+
requires = ["setuptools>=77.0.3", "setuptools-scm"]
33
build-backend = "setuptools.build_meta"
44

5+
[tool.setuptools.dynamic]
6+
version = { attr = "pywinctl.__version__" } # any module attribute compatible with ast.literal_eval
7+
8+
[project.urls]
9+
Homepage = "https://github.com/Kalmat/PyWinCtl"
10+
Repository = "https://github.com/Kalmat/PyWinCtl.git"
11+
Issues = "https://github.com/Kalmat/PyWinCtl/issues"
12+
Changelog = "https://github.com/Kalmat/PyWinCtl/blob/HEAD/CHANGES.txt"
13+
Documentation = "https://pywinctl.readthedocs.io/"
14+
515
[project]
616
name = "PyWinCtl"
717
dynamic = ["version"]
@@ -10,7 +20,8 @@ authors = [
1020
{ name = "Kalmat", email = "palookjones@gmail.com" }
1121
]
1222
readme = "README.md"
13-
license = { file = "LICENSE.txt" }
23+
license = "BSD-3-Clause"
24+
license-files = ["LICENSE.txt"]
1425
requires-python = ">=3.9"
1526
keywords = [
1627
"activate",
@@ -42,7 +53,6 @@ classifiers = [
4253
"Environment :: Win32 (MS Windows)",
4354
"Environment :: X11 Applications",
4455
"Intended Audience :: Developers",
45-
"License :: OSI Approved :: BSD License",
4656
"Operating System :: OS Independent",
4757
"Programming Language :: Python",
4858
"Programming Language :: Python :: 3",
@@ -72,9 +82,9 @@ dev = [
7282
{ include-group = "docs" },
7383
"ewmhlib",
7484
"mypy>=0.990,<2",
85+
"ruff>=0.15.16",
7586
"types-python-xlib>=0.32",
7687
"types-pywin32>=305.0.0.3",
77-
"types-setuptools>=65.5",
7888
]
7989

8090
[tool.uv]
@@ -84,12 +94,3 @@ exclude-newer = "1 week"
8494
ewmhlib = false
8595
pymonctl = false
8696
pywinbox = false
87-
88-
[project.urls]
89-
Homepage = "https://github.com/Kalmat/PyWinCtl"
90-
91-
[tool.setuptools.packages.find]
92-
where = ["src"] # list of folders that contain the packages (["."] by default)
93-
94-
[tool.setuptools.dynamic]
95-
version = { attr = "pywinctl.__version__" } # any module attribute compatible with ast.literal_eval

ruff.toml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
[lint]
2+
future-annotations = true
3+
# https://docs.astral.sh/ruff/rules/
4+
extend-select = [
5+
"ANN2", # flake8-annotations: missing-return-type
6+
"PYI", # flake8-pyi
7+
"FA", # flake8-future-annotations
8+
"ICN", # flake8-import-conventions
9+
"F401", # unused-import
10+
"YTT", # flake8-2020
11+
"TC", # flake8-type-checking
12+
"TID", # flake8-tidy-imports
13+
"UP", # pyupgrade
14+
"RUF", # Ruff-specific rules
15+
"F404", # late-future-import
16+
"PGH", # pygrep-hooks (blanket-* rules)
17+
]
18+
ignore = [
19+
# Only enforce return types on public functions. Where otherwise mypy infers as Any
20+
# Still worth running `ruff check --fix --select=202` once in a while for autofixes
21+
"ANN202", # missing-return-type-private-function
22+
# Explicit is preferred
23+
"UP015", # redundant-open-modes,
24+
# Autofixes print-f style formatting to f-strings,
25+
# which is sometimes simpler, but looses template code reading semantics
26+
"UP032", # f-string
27+
# TC helps prevent circular imports, reduce runtime cost of typing symbols,
28+
# and prevent leaking implementations details into modules
29+
# However stdlib is not at risk of circular import, is clearly not public API,
30+
# and assume it's gonna be included in the import chain at some point anyway
31+
"TC003", # typing-only-standard-library-import
32+
# Typeshed doesn't want complex or non-literal defaults for maintenance and testing reasons.
33+
# This doesn't affect us, let's have more complete stubs.
34+
"PYI011", # typed-argument-default-in-stub
35+
"PYI014", # argument-default-in-stub
36+
"PYI053", # string-or-bytes-too-long
37+
38+
# TODO: Consider later
39+
"UP031", # printf-string-formatting
40+
"RUF059", # unused-unpacked-variable
41+
"E722", # bare-except
42+
]
43+
# F401 would remove imports not marked as explicit re-exports, which may break API boundaries
44+
extend-unsafe-fixes = ["F401"]
45+
46+
[lint.per-file-ignores]
47+
"**/typings/**/*.pyi" = [
48+
"PGH003", # TODO: Blanket ignores until using pyobj type stubs
49+
"F811", # Re-exports false positives
50+
# The following can't be controlled for external libraries:
51+
"A", # Shadowing builtin names
52+
"E741", # ambiguous variable name
53+
"F403", # `from . import *` used; unable to detect undefined names
54+
"FBT", # flake8-boolean-trap
55+
"ICN001", # unconventional-import-alias
56+
"N8", # Naming conventions
57+
"PLC2701", # Private name import
58+
"PLE0302", # The special method expects a given signature
59+
"PLR0904", # Too many public methods
60+
"PLR0913", # Argument count
61+
"PLR0917", # Too many positional arguments
62+
"PLW3201", # misspelled dunder method name
63+
"SLOT", # flake8-slots
64+
# Stubs can sometimes re-export entire modules.
65+
# Issues with using a star-imported name will be caught by type-checkers.
66+
"F405", # may be undefined, or defined from star imports
67+
# It's normal to be missing annotations for local stubs.
68+
# If they were complete, we'd upload them to typeshed!
69+
"ANN0",
70+
"ANN2",
71+
]
72+
73+
# https://docs.astral.sh/ruff/settings/#lintflake8-type-checking
74+
[lint.flake8-type-checking]
75+
quote-annotations = true

setup.cfg

Lines changed: 0 additions & 20 deletions
This file was deleted.

setup.py

Lines changed: 0 additions & 68 deletions
This file was deleted.

src/pywinctl/__init__.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
#!/usr/bin/python
2-
# -*- coding: utf-8 -*-
2+
from ._main import (Re, Window, checkPermissions, getActiveWindow,
3+
getActiveWindowTitle, getAllAppsNames, getAllAppsWindowsTitles,
4+
getAllTitles, getAllWindows, getAppsWithName, getWindowsWithTitle,
5+
getAllWindowsDict, getTopWindowAt, getWindowsAt, displayWindowsUnderMouse,
6+
getAllScreens, getScreenSize, getWorkArea, getMousePos
7+
)
38

4-
__all__ = [
9+
__all__ = [ # noqa: RUF022
510
"version", "Re",
611
# OS Specifics
712
"Window", "checkPermissions", "getActiveWindow", "getActiveWindowTitle", "getWindowsWithTitle",
@@ -18,9 +23,3 @@ def version(numberOnly: bool = True) -> str:
1823
return ("" if numberOnly else "PyWinCtl-")+__version__
1924

2025

21-
from ._main import (Re, Window, checkPermissions, getActiveWindow,
22-
getActiveWindowTitle, getAllAppsNames, getAllAppsWindowsTitles,
23-
getAllTitles, getAllWindows, getAppsWithName, getWindowsWithTitle,
24-
getAllWindowsDict, getTopWindowAt, getWindowsAt, displayWindowsUnderMouse,
25-
getAllScreens, getScreenSize, getWorkArea, getMousePos
26-
)

0 commit comments

Comments
 (0)