-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpyproject.toml
278 lines (247 loc) · 12.3 KB
/
pyproject.toml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
[build-system]
requires = [
"setuptools>=61.0",
# "wheel"
]
build-backend = "setuptools.build_meta"
[project]
name = "streamdeck-plugin-sdk"
dynamic = ["version"]
description = "Write Streamdeck plugins using Python"
readme = "README.md"
authors = [
{ name = "strohganoff", email = "you@example.com" }
]
license = { file = "LICENSE" }
keywords = [
"python",
"sdk",
"streamdeck",
"streamdeck_sdk",
"streamdeck_plugin_sdk",
"stream deck",
"stream deck sdk",
"stream deck plugin sdk",
"streamdeck-sdk",
"streamdeck-plugin-sdk",
"stream-deck",
"stream-deck-sdk",
"stream-deck-plugin-sdk",
"elgato",
"elgato sdk",
"elgato plugin",
"elgato sdk",
"elgato stream deck",
"elgato stream deck sdk",
"elgato stream deck plugin sdk",
]
classifiers = [
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Development Status :: 4 - Beta",
"Environment :: Desktop",
"License :: OSI Approved :: MIT License",
"Topic :: CLI",
"Topic :: Stream Deck",
"Topic :: Stream Deck :: Plugin",
"Topic :: Stream Deck :: Plugin :: SDK",
"Topic :: Stream Deck :: SDK",
"Typing :: Typed",
]
requires-python = ">=3.9"
"dependencies" = [
# "jmespath >= 1.0.1", # Upcoming pattern-filtering functionality
"platformdirs >= 4.3.6",
"pydantic >= 2.9.2",
"pydantic_core >= 2.23.4",
"tomli >= 2.0.2",
"websockets >= 13.1",
]
[project.optional-dependencies]
dev = [
"polyfactory >= 2.17.0", # Used for generating fake Stream Deck event data from the Pydantic event models.
"pprintpp >= 0.4.0",
"pytest >= 8.3.3",
"pytest-cov >= 5.0.0",
"pytest-mock >= 3.14.0",
"pytest-sugar >= 1.0.0",
"tox >= 4.23.2",
]
[project.urls]
"Homepage" = "https://github.com/strohganoff/python-streamdeck-plugin-sdk"
"Repository" = "https://github.com/strohganoff/python-streamdeck-plugin-sdk"
"Documentation" = "https://docs.elgato.com/streamdeck/sdk/introduction/getting-started/"
"Issues" = "https://github.com/strohganoff/python-streamdeck-plugin-sdk/issues"
[project.scripts]
streamdeck = "streamdeck.__main__:main"
[tool.setuptools.packages.find]
include = ["streamdeck*"]
exclude = ["tests"]
[tool.setuptools.dynamic]
version = {attr = "streamdeck.utils._version.MODULE_VERSION"}
# Add type annotations to your Python programs, and use mypy to type check them.
[tool.mypy]
files = "streamdeck"
ignore_missing_imports = true
pretty = true
show_column_numbers = true
show_error_codes = true
show_error_context = true
strict = true
warn_unreachable = true
# Linting and code formatting
[tool.ruff]
src=["streamdeck"]
line-length=100 # Same as Black
indent-width = 4
target-version="py312"
[tool.ruff.lint]
preview=false
fixable=["ALL"]
select = [
"A", # flake8-builtins (redefinition of builtins)
"ANN", # flake8-annotations (type annotations are everywhere)
"ARG", # flake8-unused-arguments (unused argument in function/method/class/lambda)
"ASYNC", # flake8-async (async/await usage)
"B", # flake8-bugbear (bugs & design problems)
"BLE", # flake8-blind-except (no "except:" or "except Exception:")
"C4", # flake8-comprehensions (better list/set/dict comprehensions)
"C90", # McCabe (code complexity)
# "COM", # flake8-commas (force trailing commas) -> unelegant
# "COPY", # flake8-copyright (copyright notices)
"D", # pydocstyle (documentation style)
# "DJ", # flake8-django (practices on Django)
"DTZ", # flake8-datetimez (usage of unsafe naive datetime class)
"E", # pycodestyle (violation of PEP-8)
"EM", # flake8-errmsg (error messages)
"ERA", # eradicate (no commented-out code)
"EXE", # flake8-executable (executable permissions and shebangs)
"F", # pyflakes (invalid Python code)
"FA", # flake-8-future-annotations (future annotations)
"FBT", # flake8-boolean-trap (misusage of booleans in function declarations & calls)
"FIX", # flake8-fixme (fixme comments)
"FLY", # flynt (f-strings)
# "FURB", # refurb (refurbishing and modernizing Python codebases)
"G", # flake8-logging-format (logging format strings)
"I", # isort (import order)
"ICN", # flake8-import-conventions (how certain packages should be imported or aliased)
"INP", # flake8-no-pep420 (ban pep-420 implicit namespace packages)
"INT", # flake8-gettext (f-string resolved before function calls)
"ISC", # flake8-implicit-str-concat (string literal concatenation)
"LOG", # flake8-logging (logging)
"N", # pep88-naming (naming conventions)
# "NPY", # NumPy-specific rules (e.g. deprecated-type-alias and legacy-random)
# "PD", # pandas-vet (pandas linting)
"PERF", # PerFlint (performance linter for anti-patterns)
"PGH", # pygrep-hooks (miscellaneous lints, e.g. "use specific rule codes when using noqa")
"PIE", # flake8-pie (miscellaneous lints)
"PL", # Pylint (static code analyser)
"PT", # flake8-pytest-style (style issues or inconsistencies with pytest-based tests)
"PTH", # flake8-use-pathlib (use of functions that can be replaced by pathlib module)
"PYI", # flake8-pyi (provide specializations for type hinting stub files)
"Q", # flake8-quotes (avoid escaping quotes)
"RET", # flake8-return (check return values)
"RSE", # flake8-raise (improvements for raise statements)
"RUF", # ruff (ruff specific rules)
"S", # flake8-bandit (security)
"SIM", # flake8-simplify (tips to simplify the code)
"SLF", # flake8-self (private members)
"SLOT", # flake8-slots (slots usage)
"T10", # flake8-debugger (check for pdb; ipdb imports)
"T20", # flake8-print (no print nor pprint)
"TCH", # flake8-type-checking (move import only intended for type-checking in "if TYPE_CHECKING" blocks)
"TD", # flake8-todos (todos)
"TID", # flake8-tidy-imports (ordered imports)
"TRY", # tryceratops (exception handling AntiPatterns)
"UP", # pyupgrade (upgrade syntax for newer versions of Python)
"W", # pycodestyle (violation of PEP-8)
"YTT", # flake8-2020 (misuse of sys.version and sys.version_info)
]
ignore = [
"ANN101", # ignore missing type annotation for self
# "ANN102", # missing type annotation for cls but hinting cls all the time is useless
"ANN204", # ignore missing return type annotations for `__init__` special method
# "ANN401", # disallows Any, but some elements should be Any when they are external
"B024", # forces abstract classes to have at least one abstract method, but sometimes a class is virtually abstract
"COM", # flake8-commas (force trailing commas) -> unelegant
"CPY001", # flake8-copyright (copyright notices)
# "D105", # docstrings on magic methods, useless docstrings are well known
"E501", # ignore line size, bug-bear already sets it with a tolerance of 10% (B950)
"ISC001", # ignore for ruff format
"TD002", # missing-todo-author -> unused
"TD003", # missing-todo-link -> unused
]
unfixable = [
"ERA", # eradicat (no commented-out code) -> sometimes it is useful to comment out code
"F841", # local variable is assigned to but never used, but sometimes it is useful to assign a variable to debug
"RET504", # local variable is assigned to and returned but never used, but sometimes it is useful to assign a variable to debug
# "F401", # imported but unused, but sometimes it is useful to import a module to use its side effects
]
[tool.ruff.lint.per-file-ignores]
# "__main__.py" = [
# "FBT002", # booleans in function calls -> Some CLI options defined in Typer command functions are definitely going to be booleans.
# "B006", # don't use mutable data structures for argument defaults -> It's OK to use mutable data structures for argument defaults in a CLI Typer command function.
# "PLR0913", # too many arguments in function definition -> CLI Typer command functions may have many options. The function should hanlde calling the appropriate handler function based on the options.
# ]
"tests/*" = [
"ARG", # some arguments are unused in test functions but useful (e.g. patching fixtures)
"S101", # asserts are OK for tests
"S106", # possible hardcoded password -> in tests, we commonly hardcode fake passwords
"S311", # cryptographically weak random number generating -> we use random numbers for generating a port number, not for cryptographic
"SLF001", # accessing private memebers is OK for tests
"ANN002", # missing type annotation for *args
"ANN003", # missing type annotation for *kwargs
"ANN201", # missing-return-type-undocumented-public-function -> test functions usually don't return anything
"ANN202", # missing-return-type-undocumented-private-function -> special methods (like __init__) may be mocked by a closure function defined within a test function.
"FBT001", # booleans in function args -> sometimes we need to use booleans in test function args
"FBT002", # booleans in function callas -> sometimes we need to use booleans in test function calls
]
[tool.ruff.lint.mccabe]
max-complexity = 25
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.ruff.lint.pylint]
max-args=10
[tool.ruff.lint.isort]
known-first-party = ["app"]
lines-after-imports = 2
# required-imports = []
[tool.ruff.format]
preview = false
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
docstring-code-format = true
docstring-code-line-length = "dynamic"
[tool.pytest.ini_options]
minversion = "6.0"
addopts = "--color=yes --strict-markers --strict-config"
markers = ["unit", "integration"]
testpaths = ["tests"]
[tool.tox]
envlist = ["py39", "py310", "py311", "py312", "py313"]
[tool.tox.env_run_base]
deps = [".[dev]"]
commands = [["pytest", "tests/"]]
allowlist_externals = ["echo"]
[tool.coverage.run] # Configure coverage.py to measure branch coverage and specify source files to be measured.
branch = true # Enable branch coverage
source = ["streamdeck"] # Specify the source files for coverage.
[tool.coverage.report]
omit = ["tests/*"] # Exclude test files from the coverage report.
[tool.coverage.html]
directory = "reports/htmlcov"
[tool.coverage.xml]
output = "reports/coverage-results.xml"
skip_empty = true
# skip_covered = true
[tool.coverage.lcov]
output = "reports/lcov.info"