-
-
Notifications
You must be signed in to change notification settings - Fork 569
Expand file tree
/
Copy pathpyproject.toml
More file actions
294 lines (243 loc) Β· 11.2 KB
/
Copy pathpyproject.toml
File metadata and controls
294 lines (243 loc) Β· 11.2 KB
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
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# Β©AngelaMos | 2026
# pyproject.toml
#
# This file is the "instruction manual" for our Python project. Every
# modern Python project has one. It tells tools like uv, pip, pytest,
# ruff, mypy, and pylint:
#
# - What our project is called
# - Which third-party libraries we depend on
# - How to build and install it
# - How to lint, type-check, and test it
#
# The file format is called TOML β a simple, human-readable config
# language. Square brackets like [project] start a "table" (a section).
# Lines like name = "..." are key-value pairs inside that table.
#
# Read this top-to-bottom. Each section has a short comment explaining
# what it does and why it is here.
# =============================================================================
# [project] β the metadata that describes WHAT this project is
# =============================================================================
# This section is standardized across the whole Python ecosystem (PEP 621).
# Anyone who runs `pip install` or `uv sync` reads from here.
[project]
# The name people will install this package under.
# Must be unique on PyPI if we ever publish there.
name = "password-vault"
# Semantic version: MAJOR.MINOR.PATCH.
# 1.0.0 means "first stable release."
# When we add features β bump MINOR (1.1.0). When we break things β MAJOR.
version = "1.0.0"
# One-line description that shows up in `pip show` and on PyPI.
description = "Beginner-friendly encrypted password manager (Argon2id + AES-256-GCM)"
# The minimum Python version this project supports.
# >=3.13 means "Python 3.13 or anything newer."
# We need 3.13 because we use modern type-hint syntax (X | None).
requires-python = ">=3.13"
# Who wrote it. Shows up in package metadata.
authors = [
{name = "CarterPerez-dev", email = "support@certgames.com"}
]
# The README file is shown on PyPI and in `pip show`.
readme = "README.md"
# AGPL-3.0 means: anyone can use it, but if they modify and run it as a
# service, they must publish their changes. It protects the project
# from being privatized.
license = {text = "AGPL-3.0-or-later"}
# -----------------------------------------------------------------------------
# dependencies β third-party libraries we MUST have at runtime
# -----------------------------------------------------------------------------
# When a user runs `pip install password-vault`, these get installed too.
# The string format is "<name><operator><version>". We use ranges so we
# get bug fixes (>=) but never an incompatible major version (<).
dependencies = [
# argon2-cffi: implements Argon2id, the modern password-hashing
# algorithm we use to turn the master password into an encryption key.
"argon2-cffi>=25.1.0",
# cryptography: provides AES-256-GCM, the actual encryption that
# scrambles vault contents. Maintained by the Python Cryptographic
# Authority β the gold-standard library, audited and trusted.
"cryptography>=48.0.0",
# typer: builds nice CLIs from regular Python functions.
# Lets us write `add`, `get`, `list` commands with auto-generated help.
"typer>=0.25.1",
# rich: pretty terminal output β colors, tables, panels, prompts.
# Makes the CLI pleasant to use without writing a bunch of formatting.
"rich>=15.0.0",
]
# -----------------------------------------------------------------------------
# optional-dependencies β extra libraries that are NOT needed at runtime
# -----------------------------------------------------------------------------
# These only matter to developers (testing, linting, formatting). End users
# don't install them. Activated with: `uv sync --extra dev` or `--all-extras`.
[project.optional-dependencies]
dev = [
# pytest β runs our test suite (the test_*.py files in tests/).
"pytest>=9.0.3",
# pytest-cov β measures how much of our code the tests actually
# exercise. "Coverage" β high coverage means well-tested code.
"pytest-cov>=7.1.0",
# ruff β extremely fast linter and formatter. Catches bugs, style
# issues, dead imports. Modern replacement for flake8/black/isort.
"ruff>=0.15.12",
# mypy β static type checker. Reads our type hints and tells us if
# we passed a string where an int was expected, BEFORE running the code.
"mypy>=2.1.0",
# pylint β second linter that catches deeper logic issues ruff misses.
"pylint>=4.0.5",
# yapf β code formatter (Google's). Keeps every file looking identical.
"yapf>=0.43.0,<1.0.0",
]
# -----------------------------------------------------------------------------
# project.urls β links shown on PyPI / package pages
# -----------------------------------------------------------------------------
[project.urls]
Homepage = "https://github.com/CarterPerez-dev/Cybersecurity-Projects"
Repository = "https://github.com/CarterPerez-dev/Cybersecurity-Projects/tree/main/PROJECTS/foundations/password-manager"
# -----------------------------------------------------------------------------
# project.scripts β command-line entry points
# -----------------------------------------------------------------------------
# These create real shell commands when the package is installed. After
# `uv sync`, the user can type `pv add github` instead of
# `python -m password_manager add github`. The right-hand side is
# "<module>:<function>" β the function gets called when the command runs.
[project.scripts]
pv = "password_manager.main:app"
password-vault = "password_manager.main:app"
# =============================================================================
# [build-system] β how to BUILD this project into an installable package
# =============================================================================
# Required by PEP 517. Tools like uv read this to know which builder
# to use. We chose hatchling β modern, fast, zero-config for our case.
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
# Tell hatchling where the actual Python code lives. Without this, it
# guesses β and guesses wrong when the layout is src/<package>/.
[tool.hatch.build.targets.wheel]
packages = ["src/password_manager"]
# =============================================================================
# [tool.ruff] β linter / formatter configuration
# =============================================================================
# Ruff is the FAST one. It runs in milliseconds and catches 90% of issues.
[tool.ruff]
# Target Python version β ruff adjusts which warnings apply.
target-version = "py313"
# Wrap lines at 88 characters (PEP 8 says 79, but 88 is the modern norm).
line-length = 88
# Tell ruff "the source code lives in src/" so imports resolve correctly.
src = ["src"]
# Don't lint these directories.
exclude = [
".git",
".venv",
"__pycache__",
"venv",
"build",
"dist",
]
# -----------------------------------------------------------------------------
# Which lint rules to enable. Each "code" is a category of check.
# -----------------------------------------------------------------------------
[tool.ruff.lint]
select = [
"E", # pycodestyle errors β basic PEP 8 spacing/indent rules
"F", # Pyflakes β unused imports, undefined names, real bugs
"W", # pycodestyle warnings β softer style issues
"B", # Bugbear β sneaky bugs (mutable default args, etc.)
"C4", # Comprehensions β encourages cleaner list/dict comprehensions
"UP", # Pyupgrade β flags old syntax we should modernize
"SIM", # Simplify β suggests cleaner equivalents
]
# Some rules we deliberately ignore.
ignore = [
# Line length is handled by yapf, not ruff. Avoids double-flagging.
"E501",
]
# =============================================================================
# [tool.mypy] β static type checker configuration
# =============================================================================
# Mypy reads our type hints (the `: int`, `-> str` parts) and verifies them
# without running the code. Catches whole categories of bugs at edit time.
[tool.mypy]
python_version = "3.13"
# Treat anything returning Any as a warning β Any is a type-system escape
# hatch and we want to know when we're using it.
warn_return_any = true
# Warn if our config has unused settings (typos, etc.).
warn_unused_configs = true
# Require type annotations on every function. STRICT mode β appropriate
# for a security-critical project where bugs = leaked passwords.
disallow_untyped_defs = true
disallow_incomplete_defs = true
# Don't auto-add Optional just because a default is None. Be explicit.
no_implicit_optional = true
# Warn if we cast a value to a type it already has (dead code).
warn_redundant_casts = true
# Warn if a function might fall off the end without returning.
warn_no_return = true
# Pretty error output β helps when reading mypy output.
show_error_codes = true
show_column_numbers = true
pretty = true
exclude = [
".venv",
"venv",
"tests", # tests use fixtures and don't need strict typing
]
# -----------------------------------------------------------------------------
# Per-module overrides β silence missing stubs for argon2.
# argon2-cffi doesn't ship type hints, so mypy can't check it. That's fine.
# -----------------------------------------------------------------------------
[[tool.mypy.overrides]]
module = ["argon2.*"]
ignore_missing_imports = true
# =============================================================================
# [tool.pylint] β second-opinion linter
# =============================================================================
# Slower than ruff but catches different things β class design issues,
# dead variables, complex code patterns.
[tool.pylint.main]
py-version = "3.13"
jobs = 4 # run in parallel across 4 cores
persistent = true # cache results between runs
ignore = [
"venv",
".venv",
"__pycache__",
"build",
"dist",
".git",
"tests",
]
# Specific pylint warnings we deliberately turn off.
[tool.pylint.messages_control]
disable = [
"R0903", # too-few-public-methods β small data classes are fine
"C0103", # invalid-name β we use short names like `kdf` on purpose
"C0325", # superfluous-parens β fights with yapf formatting
]
# Override pylint's default complexity limits where they're too strict.
[tool.pylint.design]
max-args = 8 # default is 5; we sometimes need a few more
max-attributes = 10 # default is 7
# Foundation-tier modules carry heavy teaching comments and multi-
# paragraph docstrings, which push a single self-contained module
# above the default 1000-line ceiling. The right answer is not to
# split the module artificially β keeping vault.py as one place to
# read end-to-end is the pedagogical point β so we lift the cap.
[tool.pylint.format]
max-module-lines = 1500
# =============================================================================
# [tool.pytest.ini_options] β test runner configuration
# =============================================================================
[tool.pytest.ini_options]
# Where the test files live.
testpaths = ["tests"]
# Files that match this pattern are treated as test modules.
python_files = ["test_*.py"]
# Default flags every `pytest` invocation gets:
# -v β verbose, show each test name
# --tb=short β short tracebacks on failure (less wall of text)
addopts = "-v --tb=short"