passmaker 0.1.2__tar.gz → 0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,24 +1,26 @@
1
- name: Python package
1
+ name: Publish new package version
2
2
 
3
3
  on:
4
4
  push:
5
5
  # On version pushes
6
6
  tags:
7
7
  - 'v[0-9]+.[0-9]+.[0-9]+'
8
+ - 'v[0-9]+.[0-9]+'
8
9
 
9
10
  workflow_dispatch:
10
11
 
11
- permissions:
12
- contents: write
13
-
14
12
  jobs:
15
13
  verify-checks:
16
- uses: ./.github/workflows/static-checks.yaml
14
+ uses: ./.github/workflows/quality-assurance.yaml
17
15
 
18
16
  publish:
19
17
  name: Build and publish Python Package
20
18
  needs: verify-checks
21
19
  runs-on: ubuntu-latest
20
+ permissions:
21
+ id-token: write
22
+ contents: write
23
+ environment: release
22
24
 
23
25
  steps:
24
26
  - uses: actions/checkout@v4
@@ -41,7 +43,7 @@ jobs:
41
43
  shell: bash
42
44
  run: |
43
45
  VERSION="$(hatchling version)"
44
- if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
46
+ if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ && ! "$VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then
45
47
  echo "::error::Expected a pure release version, got: $VERSION"
46
48
  exit 1
47
49
  fi
@@ -52,8 +54,6 @@ jobs:
52
54
  uv build
53
55
 
54
56
  - name: Publish package to PyPI
55
- env:
56
- UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
57
57
  run: |
58
58
  uv publish
59
59
 
@@ -63,5 +63,5 @@ jobs:
63
63
  VERSION: ${{ env.VERSION }}
64
64
  run: |
65
65
  gh release create "v$VERSION" \
66
- --generate-notes \
67
- --verify-tag
66
+ --generate-notes --verify-tag \
67
+ ./dist/*.tar.gz ./dist/*.whl
@@ -1,8 +1,12 @@
1
- name: Static file checks
1
+ name: Run quality assurance checks
2
2
 
3
3
  on:
4
4
  pull_request:
5
- types: [opened, reopened, synchronize, ready_for_review]
5
+ types:
6
+ - opened
7
+ - reopened
8
+ - synchronize
9
+ - ready_for_review
6
10
 
7
11
  push:
8
12
  branches:
@@ -16,16 +20,17 @@ jobs:
16
20
  if: github.event.pull_request.draft == false
17
21
  runs-on: ubuntu-latest
18
22
  steps:
19
- - uses: actions/checkout@v4
23
+ - uses: actions/checkout@v7
20
24
 
21
25
  - name: Check formatting
22
- uses: astral-sh/ruff-action@v3
26
+ uses: astral-sh/ruff-action@v4.1.0
23
27
  with:
24
- args: format --check --diff --exclude=src/manager --exclude=src/connection
28
+ version-file: uv.lock
29
+ args: format --check --diff
25
30
 
26
31
  - name: Check linting
27
32
  run: |
28
- ruff check --output-format=github --extend-exclude=src/manager --extend-exclude=src/connection
33
+ ruff check --output-format=github
29
34
 
30
35
  type-checking:
31
36
  name: Static type checking
@@ -35,27 +40,26 @@ jobs:
35
40
  strategy:
36
41
  fail-fast: true
37
42
  matrix:
38
- python-version: ["3.14"]
43
+ python-version:
44
+ - "3.14"
39
45
 
40
46
  steps:
41
- - uses: actions/checkout@v4
47
+ - uses: actions/checkout@v7
42
48
 
43
- - uses: actions/setup-python@v4
49
+ - uses: actions/setup-python@v7
44
50
  with:
45
51
  python-version: ${{ matrix.python-version }}
46
52
 
47
53
  - name: Setup uv
48
- uses: astral-sh/setup-uv@v6
54
+ uses: astral-sh/setup-uv@v10.0.1
49
55
  with:
50
56
  activate-environment: true
51
- enable-cache: true
52
57
 
53
58
  - name: Synchronise dependencies
54
59
  run: |
55
60
  uv sync --locked --all-extras --all-groups --dev
56
61
 
57
62
  - name: Check with Pyright
58
- uses: jakebailey/pyright-action@v2
63
+ uses: jakebailey/pyright-action@v3
59
64
  with:
60
- version: latest
61
- annotate: all
65
+ version: PATH
@@ -0,0 +1,20 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: pyrefly-check
5
+ name: Pyrefly Check
6
+ entry: uv run --dev pyrefly check
7
+ language: system
8
+ pass_filenames: false
9
+
10
+ - id: ruff-check
11
+ name: Ruff Check
12
+ entry: uv run --dev ruff check
13
+ language: system
14
+ files: .*[.]py[i]?$
15
+
16
+ - id: ruff-format
17
+ name: Ruff Format
18
+ entry: uv run --dev ruff format --check
19
+ language: system
20
+ files: .*[.]py[i]?$
@@ -1,9 +1,10 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: passmaker
3
- Version: 0.1.2
3
+ Version: 0.2
4
4
  Summary: Generate strong passwords with ease and peace.
5
5
  Author-email: Soucelover <mr.ktotov@gmail.com>
6
6
  Requires-Python: >=3.14
7
+ Requires-Dist: randpal>=0.5
7
8
  Provides-Extra: cli
8
9
  Requires-Dist: click-option-group>=0.5.9; extra == 'cli'
9
10
  Requires-Dist: click>=8.3.1; extra == 'cli'
@@ -11,7 +11,9 @@ dynamic = ["version"]
11
11
  # Requirements (deps)
12
12
  # ===================
13
13
  requires-python = ">=3.14"
14
- dependencies = []
14
+ dependencies = [
15
+ "randpal>=0.5",
16
+ ]
15
17
 
16
18
  [project.optional-dependencies]
17
19
  cli = [
@@ -22,7 +24,8 @@ cli = [
22
24
  [dependency-groups]
23
25
  dev = [
24
26
  "pre-commit>=4.6.0",
25
- "pyrefly>=1.0.0",
27
+ "pyrefly>=1.2.0",
28
+ "pyright>=1.1.411",
26
29
  "ruff>=0.15.15",
27
30
  ]
28
31
 
@@ -1,4 +1,9 @@
1
- from .passgen import build_alphabet, generate_passwords, passgen
1
+ from .passgen import (
2
+ PasswordGenerator,
3
+ build_alphabet,
4
+ generate_passwords,
5
+ passgen,
6
+ )
2
7
  from .rules import (
3
8
  ALL_RULES,
4
9
  no_duplicates,
@@ -8,6 +13,7 @@ from .rules import (
8
13
 
9
14
  __all__ = [
10
15
  "ALL_RULES",
16
+ "PasswordGenerator",
11
17
  "build_alphabet",
12
18
  "generate_passwords",
13
19
  "no_duplicates",
@@ -3,6 +3,8 @@ import secrets
3
3
  import string
4
4
  from typing import TYPE_CHECKING
5
5
 
6
+ from randpal.rng import SecretsRandom
7
+
6
8
  from .rules import (
7
9
  ALL_RULES,
8
10
  no_duplicates,
@@ -11,11 +13,56 @@ from .rules import (
11
13
  )
12
14
 
13
15
  if TYPE_CHECKING:
14
- from collections.abc import Sequence
16
+ from collections.abc import Iterable
17
+
18
+ from randpal.rng import SequencesGenerator
15
19
 
16
20
  from .rules import Rule
17
21
 
18
22
 
23
+ class PasswordGenerator:
24
+ _random: SequencesGenerator
25
+ rules: tuple[Rule, ...]
26
+ alphabet: frozenset[str]
27
+
28
+ def __init__(
29
+ self,
30
+ alphabet: str | None = None,
31
+ *,
32
+ rules: Iterable[Rule] = ALL_RULES,
33
+ random_provider: SequencesGenerator | None = None,
34
+ ) -> None:
35
+ self._random = random_provider or SecretsRandom()
36
+ self.rules = tuple(rules)
37
+
38
+ if alphabet is None:
39
+ self.alphabet = frozenset(build_alphabet())
40
+ else:
41
+ self.alphabet = frozenset(alphabet)
42
+
43
+ def gen_password(self, length: int) -> str:
44
+ password = ""
45
+
46
+ for _ in range(length):
47
+ allowed_symbols = functools.reduce(
48
+ lambda alpha, rule: rule(password, alpha),
49
+ self.rules,
50
+ self.alphabet,
51
+ )
52
+ password += secrets.choice(list(allowed_symbols))
53
+
54
+ return password
55
+
56
+
57
+ def passgen(
58
+ length: int,
59
+ alphabet: str | None = None,
60
+ rules: Iterable[Rule] = ALL_RULES,
61
+ ) -> str:
62
+ generator = PasswordGenerator(alphabet, rules=rules)
63
+ return generator.gen_password(length)
64
+
65
+
19
66
  def build_alphabet(
20
67
  *,
21
68
  digits: bool = True,
@@ -39,26 +86,6 @@ def build_alphabet(
39
86
  return alphabet
40
87
 
41
88
 
42
- def passgen(
43
- length: int,
44
- alphabet: str | None = None,
45
- rules: Sequence[Rule] = ALL_RULES,
46
- ) -> str:
47
- if alphabet is None:
48
- alphabet = build_alphabet()
49
-
50
- password = ""
51
-
52
- for _ in range(length):
53
- allowed_symbols = functools.reduce(
54
- lambda alpha, rule: rule(password, alpha), rules, set(alphabet)
55
- )
56
-
57
- password += secrets.choice(list(allowed_symbols))
58
-
59
- return password
60
-
61
-
62
89
  def generate_passwords( # noqa: PLR0913
63
90
  length: int = 22,
64
91
  count: int = 5,
@@ -86,6 +113,6 @@ def generate_passwords( # noqa: PLR0913
86
113
  if use_similar:
87
114
  rules.append(no_similar_characters)
88
115
 
89
- return [
90
- passgen(length, alphabet=alphabet, rules=rules) for _ in range(count)
91
- ]
116
+ generator = PasswordGenerator(alphabet, rules=rules)
117
+
118
+ return [generator.gen_password(length) for _ in range(count)]
@@ -1,12 +1,15 @@
1
1
  import contextlib
2
2
  from collections.abc import Callable
3
+ from collections.abc import Set as AbstractSet
3
4
 
4
5
  # Rule is a filter to an alphabet
5
- type Rule = Callable[[str, set[str]], set[str]]
6
+ type Rule = Callable[[str, AbstractSet[str]], AbstractSet[str]]
6
7
  QWERTY: str = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
7
8
 
8
9
 
9
- def no_duplicates(password: str, alphabet: set[str]) -> set[str]:
10
+ def no_duplicates(
11
+ password: str, alphabet: AbstractSet[str]
12
+ ) -> AbstractSet[str]:
10
13
  """Don't use the same character more than once in a password.
11
14
 
12
15
  This rule removes from alphabet every char from password.
@@ -17,7 +20,9 @@ def no_duplicates(password: str, alphabet: set[str]) -> set[str]:
17
20
  return alphabet - set(password)
18
21
 
19
22
 
20
- def no_sequence_characters(password: str, alphabet: set[str]) -> set[str]:
23
+ def no_sequence_characters(
24
+ password: str, alphabet: AbstractSet[str]
25
+ ) -> AbstractSet[str]:
21
26
  """Don't use characters in password in a sequence, e.g. abc, 123, etc.
22
27
 
23
28
  This rule enforces that the next symbol in password cannot be from
@@ -44,7 +49,9 @@ def no_sequence_characters(password: str, alphabet: set[str]) -> set[str]:
44
49
  return alphabet - {chr(ord(password[-1]) - 1), chr(ord(password[-1]) + 1)}
45
50
 
46
51
 
47
- def no_similar_characters(password: str, alphabet: set[str]) -> set[str]:
52
+ def no_similar_characters(
53
+ password: str, alphabet: AbstractSet[str]
54
+ ) -> AbstractSet[str]:
48
55
  """Don't use similar characters in password, e.g. i, I, L, l, 1, etc.
49
56
 
50
57
  This rule removes from alphabet these characters: i1Il|, oO0, `.:
@@ -52,4 +59,8 @@ def no_similar_characters(password: str, alphabet: set[str]) -> set[str]:
52
59
  return alphabet - set("i1Il|oO0`.:")
53
60
 
54
61
 
55
- ALL_RULES = [no_duplicates, no_sequence_characters, no_similar_characters]
62
+ ALL_RULES: list[Rule] = [
63
+ no_duplicates,
64
+ no_sequence_characters,
65
+ no_similar_characters,
66
+ ]
@@ -83,6 +83,9 @@ wheels = [
83
83
  [[package]]
84
84
  name = "passmaker"
85
85
  source = { editable = "." }
86
+ dependencies = [
87
+ { name = "randpal" },
88
+ ]
86
89
 
87
90
  [package.optional-dependencies]
88
91
  cli = [
@@ -94,6 +97,7 @@ cli = [
94
97
  dev = [
95
98
  { name = "pre-commit" },
96
99
  { name = "pyrefly" },
100
+ { name = "pyright" },
97
101
  { name = "ruff" },
98
102
  ]
99
103
 
@@ -101,13 +105,15 @@ dev = [
101
105
  requires-dist = [
102
106
  { name = "click", marker = "extra == 'cli'", specifier = ">=8.3.1" },
103
107
  { name = "click-option-group", marker = "extra == 'cli'", specifier = ">=0.5.9" },
108
+ { name = "randpal", specifier = ">=0.5" },
104
109
  ]
105
110
  provides-extras = ["cli"]
106
111
 
107
112
  [package.metadata.requires-dev]
108
113
  dev = [
109
114
  { name = "pre-commit", specifier = ">=4.6.0" },
110
- { name = "pyrefly", specifier = ">=1.0.0" },
115
+ { name = "pyrefly", specifier = ">=1.2.0" },
116
+ { name = "pyright", specifier = ">=1.1.411" },
111
117
  { name = "ruff", specifier = ">=0.15.15" },
112
118
  ]
113
119
 
@@ -138,19 +144,34 @@ wheels = [
138
144
 
139
145
  [[package]]
140
146
  name = "pyrefly"
141
- version = "1.0.0"
147
+ version = "1.2.0"
148
+ source = { registry = "https://pypi.org/simple" }
149
+ sdist = { url = "https://files.pythonhosted.org/packages/89/01/a86e9f24722b095c3f88e3616132b75a21b0df53804bdc6a45314dd4d93c/pyrefly-1.2.0.tar.gz", hash = "sha256:5485f960fc2481617068c918335c39ab1507ef90b6b5bd35bf57726e60e73185", size = 6243654, upload-time = "2026-08-01T02:56:27.592Z" }
150
+ wheels = [
151
+ { url = "https://files.pythonhosted.org/packages/7d/9d/3c0ef1d4843987b22f996ed381ec9cf5a3b1273e29804db276252e4c95eb/pyrefly-1.2.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7f46d983ac49ddd2b043694960a01dc6a19a5cfd8eec609d6bd9c42866f91b4e", size = 14026305, upload-time = "2026-08-01T02:56:02.611Z" },
152
+ { url = "https://files.pythonhosted.org/packages/0a/06/03bbb78fbea54cdc65b626619f3597d5611aca4fdef11e72a4e8360e7e63/pyrefly-1.2.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:756f669b5555090f5c1a4fef30db1785fabe657764f7e4e6dc88994dfb8ca82d", size = 13463880, upload-time = "2026-08-01T02:56:04.93Z" },
153
+ { url = "https://files.pythonhosted.org/packages/13/5a/7d8bc00a38e93bbc9c3e7bd14d305f7948717e667c9bcddeab9dd42fd255/pyrefly-1.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3465812ce5ef4781fb592edbf2724547296f0a3124be115d73c7e8b2401862d", size = 13907329, upload-time = "2026-08-01T02:56:07.104Z" },
154
+ { url = "https://files.pythonhosted.org/packages/be/94/9e08b4bf799d0b8f36b55a2783c7ba5f51730cf0632a85a67b5b5ed876cd/pyrefly-1.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5de7b2ad2bba5c8055181681a84b74143eac2234a48ba5d1b7ed7e7a722b02bd", size = 15039020, upload-time = "2026-08-01T02:56:09.208Z" },
155
+ { url = "https://files.pythonhosted.org/packages/5b/bd/bca5fd0c80f4daf8ee6903a29df9f3de1feb05ff0946b8f35ec8c5096b13/pyrefly-1.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25822ea9505f589ea8a725e4268b475132fb89e038fbf092e446510443ac142a", size = 14986199, upload-time = "2026-08-01T02:56:11.924Z" },
156
+ { url = "https://files.pythonhosted.org/packages/97/f7/f07087f3d185ad2eced0c56cef89ca5474dfb4ff25f146cd50a861c97553/pyrefly-1.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90efe75e17491ef5d636e10469e9278d7d0256b3b4c5e1f4750069bf3ae0f5d1", size = 14393715, upload-time = "2026-08-01T02:56:14.143Z" },
157
+ { url = "https://files.pythonhosted.org/packages/d3/70/0d142c320e284b9e3ce35e9b1e58b8ce2ee1f578f2a7234bc30e5022b94f/pyrefly-1.2.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:368aaf7eee4f511ddc0f8e564cf14e01ab2f10b0db9105c6d5b153bf498d07bf", size = 13933008, upload-time = "2026-08-01T02:56:16.525Z" },
158
+ { url = "https://files.pythonhosted.org/packages/5d/e8/e84f11b6e1f63fd453ad3654213b9a0f6f4de8cef6b58038eef2d0d5955d/pyrefly-1.2.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d52d5da7bc65fb7675fbaa80eda879d4f8787c494f04cac21603330d3abbdbbe", size = 14431827, upload-time = "2026-08-01T02:56:18.645Z" },
159
+ { url = "https://files.pythonhosted.org/packages/0f/06/810d31380f66c75e1c0779a408d3b16117b1b368b57894f6aa66bef21686/pyrefly-1.2.0-py3-none-win32.whl", hash = "sha256:8c90751de8506d938e8f802659c74cf35bd7a0036510ee6c634a38eebb280bfa", size = 13229447, upload-time = "2026-08-01T02:56:20.921Z" },
160
+ { url = "https://files.pythonhosted.org/packages/ed/98/4dafa3c7a1caed2dc8cc708dde09ba27963c7736508f55b626fff3024113/pyrefly-1.2.0-py3-none-win_amd64.whl", hash = "sha256:8a8964c224ccc4882730130955815de21ff443c1ac3f0b90685b19bf63848170", size = 14087387, upload-time = "2026-08-01T02:56:23.188Z" },
161
+ { url = "https://files.pythonhosted.org/packages/1b/1c/df3cb0a2e5591660ded7a1836cd2f29dc48c91adb1c0a3a700a96f6d09e1/pyrefly-1.2.0-py3-none-win_arm64.whl", hash = "sha256:3a90bb8df39dfbac74b1f3b2e9d7c526b8f80568884c3944d955023a73ebf61e", size = 13430873, upload-time = "2026-08-01T02:56:25.425Z" },
162
+ ]
163
+
164
+ [[package]]
165
+ name = "pyright"
166
+ version = "1.1.411"
142
167
  source = { registry = "https://pypi.org/simple" }
143
- sdist = { url = "https://files.pythonhosted.org/packages/9f/3a/9045b0097ac58979c7c30a4fa0e673db942d4adbc7b6d439bd54ae58c441/pyrefly-1.0.0.tar.gz", hash = "sha256:5c2b810ffcebd84be71de5df1223651edee951653a66935c6f091e957c452455", size = 5677995, upload-time = "2026-05-12T20:12:46.812Z" }
168
+ dependencies = [
169
+ { name = "nodeenv" },
170
+ { name = "typing-extensions" },
171
+ ]
172
+ sdist = { url = "https://files.pythonhosted.org/packages/7e/ab/265f7dc69d28113ebba19092e57b075f41543b2ed048429c5f56e2b88eac/pyright-1.1.411.tar.gz", hash = "sha256:d885a0551f2e763b089a02702174e7f4ba77548cddabc972ab86d1f7f1b0f998", size = 4112861, upload-time = "2026-06-25T02:14:06.37Z" }
144
173
  wheels = [
145
- { url = "https://files.pythonhosted.org/packages/f4/c6/90788819bac9c61dd7bacba53b79f3c12d47ccbe5e51b3d6d89f2387e1d2/pyrefly-1.0.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e355a0908555348ed4b9585ef25c76ff566673e345c866c325f1633f44d890b6", size = 13122950, upload-time = "2026-05-12T20:12:20.711Z" },
146
- { url = "https://files.pythonhosted.org/packages/82/91/a3cf2a1e87d336eaa804a1e6fc93266faf6dc2a97eecdbc7eae289628022/pyrefly-1.0.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a7038efc3a40f8294edee339895633cf22db268c0d434cdbcbefc34f78a9ecc3", size = 12599494, upload-time = "2026-05-12T20:12:23.495Z" },
147
- { url = "https://files.pythonhosted.org/packages/cd/ab/74d1e11e737e99b1c003ecc5d7d2e846c4ea1f328966bfdbbd0ac63fad0a/pyrefly-1.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da331ca515ed1c08791da2b5f664cf9c1294c48fd802133262e7d5d51e0f4416", size = 12995507, upload-time = "2026-05-12T20:12:25.951Z" },
148
- { url = "https://files.pythonhosted.org/packages/7c/ac/2df0899f8464c97e5d995f994c97c5cb5b0f58610432aa90d26d924e1db5/pyrefly-1.0.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c74219d8f3e63cdaa5501a0b21d1c9d37011820f9606728d0ed06f09ae86a878", size = 13947693, upload-time = "2026-05-12T20:12:29.188Z" },
149
- { url = "https://files.pythonhosted.org/packages/6b/3e/b247c24321e36f04b7d51f9ccf3df93e5009e4b29939524b36ec2e17dc2a/pyrefly-1.0.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0d05543b1bb6ee6d64149eb5d6b2fb15aa72d3962d6a97abca0afaca8b0c131", size = 13925803, upload-time = "2026-05-12T20:12:31.904Z" },
150
- { url = "https://files.pythonhosted.org/packages/61/16/cfa2d61a4aa1e1f7bca48bb37acd01c6a09db4864b16a54f9587092765ff/pyrefly-1.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1382d5b1fcdb49a4de9f34d112d2bddf290a78ff93ee8149492ad5f1077ddffc", size = 13470398, upload-time = "2026-05-12T20:12:35.302Z" },
151
- { url = "https://files.pythonhosted.org/packages/cb/2b/6372c7dddb326223e24a46b17efd0d4bd7b4fe22c821e523157577eed2d2/pyrefly-1.0.0-py3-none-win32.whl", hash = "sha256:aa8b5d0e47080e3202a2547b39f7a5a61d2c781c712b3b67884f745ca2c759d2", size = 12222643, upload-time = "2026-05-12T20:12:38.618Z" },
152
- { url = "https://files.pythonhosted.org/packages/be/ad/1d23be700b6b2ddaeb362360c7145917a8edbbf7240ae428d40541772fce/pyrefly-1.0.0-py3-none-win_amd64.whl", hash = "sha256:c8abcb0f2082e83c890375128f9cff4aa4d3f210b85eea7b3046c1ae764e77f5", size = 13146369, upload-time = "2026-05-12T20:12:41.423Z" },
153
- { url = "https://files.pythonhosted.org/packages/8c/38/16589134f3012fd097a10dcc85771555f1a5fb76e04b682597180743af30/pyrefly-1.0.0-py3-none-win_arm64.whl", hash = "sha256:d150fa9e40e8392832be81c3bcfc0497c146674ce4d0f8e04e1ec29e775ffb8c", size = 12538326, upload-time = "2026-05-12T20:12:43.996Z" },
174
+ { url = "https://files.pythonhosted.org/packages/0a/49/385be530a6a5b78d1cbcd5c2e38debc8959a2fc6bdb716f4e581002979fc/pyright-1.1.411-py3-none-any.whl", hash = "sha256:dc7c72a8e2700c55baa127554040e067041ea53ccfd50bf96308cc4291c7d5d9", size = 6181526, upload-time = "2026-06-25T02:14:04.691Z" },
154
175
  ]
155
176
 
156
177
  [[package]]
@@ -192,6 +213,15 @@ wheels = [
192
213
  { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
193
214
  ]
194
215
 
216
+ [[package]]
217
+ name = "randpal"
218
+ version = "0.5"
219
+ source = { registry = "https://pypi.org/simple" }
220
+ sdist = { url = "https://files.pythonhosted.org/packages/02/10/41011d552baa59a6990424a6bf2d00b3fbbe881b98a301263967d0467fa2/randpal-0.5.tar.gz", hash = "sha256:178e85ef26ea3e322d86cf9b44ad0d2210e6cb871444548d14e896d6d1e6c395", size = 30281, upload-time = "2026-09-04T14:43:57.251Z" }
221
+ wheels = [
222
+ { url = "https://files.pythonhosted.org/packages/03/62/22326f19d18c34a6064ac29bf662950a06ff3e0c3cd6f667531ee08df931/randpal-0.5-py3-none-any.whl", hash = "sha256:2718ae64d05b51af2e01408e54c15171a3d467ab4655f3794976032a8705b574", size = 9099, upload-time = "2026-09-04T14:43:56.325Z" },
223
+ ]
224
+
195
225
  [[package]]
196
226
  name = "ruff"
197
227
  version = "0.15.15"
@@ -217,6 +247,15 @@ wheels = [
217
247
  { url = "https://files.pythonhosted.org/packages/4e/b2/920464c907b191e37469d477a1aa8bc048b8f36c4c1610dfa4ab87b39e18/ruff-0.15.15-py3-none-win_arm64.whl", hash = "sha256:3c8ceca6792f38196b8f589bc92eccd03eef286602da92e5dc05cc42ef6441b7", size = 11138498, upload-time = "2026-05-28T14:16:38.425Z" },
218
248
  ]
219
249
 
250
+ [[package]]
251
+ name = "typing-extensions"
252
+ version = "4.16.0"
253
+ source = { registry = "https://pypi.org/simple" }
254
+ sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
255
+ wheels = [
256
+ { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
257
+ ]
258
+
220
259
  [[package]]
221
260
  name = "virtualenv"
222
261
  version = "21.4.1"
@@ -1,19 +0,0 @@
1
- repos:
2
- # Ruff hooks
3
- - repo: https://github.com/astral-sh/ruff-pre-commit
4
- rev: v0.15.5
5
- hooks:
6
- # Run the linter
7
- - id: ruff-check
8
- args: [--fix]
9
- # Run the formatter
10
- - id: ruff-format
11
-
12
- # Pyrefly hook
13
- - repo: local
14
- hooks:
15
- - id: pyrefly-check
16
- name: Pyrefly (type checking via uvx)
17
- entry: uv tool run --from pyrefly pyrefly check
18
- language: system
19
- pass_filenames: false
File without changes
File without changes
File without changes