cuid2 2.0.0__tar.gz → 2.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.
- {cuid2-2.0.0 → cuid2-2.0.2}/PKG-INFO +33 -39
- {cuid2-2.0.0 → cuid2-2.0.2}/README.md +19 -10
- cuid2-2.0.2/pyproject.toml +212 -0
- cuid2-2.0.2/pyproject.toml.orig +157 -0
- {cuid2-2.0.0 → cuid2-2.0.2}/src/cuid2/__init__.py +2 -1
- cuid2-2.0.2/src/cuid2/cli.py +24 -0
- {cuid2-2.0.0 → cuid2-2.0.2}/src/cuid2/generator.py +69 -19
- {cuid2-2.0.0 → cuid2-2.0.2}/src/cuid2/utils.py +7 -6
- cuid2-2.0.0/pyproject.toml +0 -213
- cuid2-2.0.0/src/cuid2/cli.py +0 -8
- {cuid2-2.0.0 → cuid2-2.0.2}/LICENSE +0 -0
- {cuid2-2.0.0 → cuid2-2.0.2}/src/cuid2/py.typed +0 -0
|
@@ -1,48 +1,32 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: cuid2
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: Next generation GUIDs. Collision-resistant ids optimized for horizontal scaling and performance.
|
|
5
|
-
Keywords: crypt
|
|
6
|
-
Author
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
-
in the Software without restriction, including without limitation the rights
|
|
14
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
-
furnished to do so, subject to the following conditions:
|
|
17
|
-
|
|
18
|
-
The above copyright notice and this permission notice shall be included in all
|
|
19
|
-
copies or substantial portions of the Software.
|
|
20
|
-
|
|
21
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
-
SOFTWARE.
|
|
5
|
+
Keywords: crypt,security,uuid,guid,cuid,cryptography
|
|
6
|
+
Author: Will Gordon
|
|
7
|
+
Author-email: Will Gordon <dev@gordoncode.dev>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
28
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
29
11
|
Classifier: Intended Audience :: Developers
|
|
30
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
31
12
|
Classifier: Operating System :: OS Independent
|
|
32
13
|
Classifier: Programming Language :: Python :: 3
|
|
33
|
-
Classifier: Programming Language :: Python :: 3.
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
34
19
|
Classifier: Topic :: Security :: Cryptography
|
|
35
20
|
Classifier: Typing :: Typed
|
|
36
|
-
|
|
37
|
-
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Project-URL: repository, https://github.com/gordon-code/cuid2/
|
|
38
23
|
Description-Content-Type: text/markdown
|
|
39
24
|
|
|
40
25
|
# cuid2
|
|
41
26
|
|
|
42
|
-
[](https://pypi.
|
|
44
|
-
[](https://pypi.
|
|
45
|
-
[](https://snyk.io/advisor/python/cuid2)
|
|
27
|
+
[](https://pypi.org/project/cuid2/)
|
|
28
|
+
[](https://pypi.org/project/cuid2/)
|
|
29
|
+
[](https://pypi.org/project/cuid2/)
|
|
46
30
|
|
|
47
31
|
CUID2 for Python 3. Next generation GUIDs. Collision-resistant ids optimized for
|
|
48
32
|
horizontal scaling and performance.
|
|
@@ -79,21 +63,24 @@ pip install cuid2
|
|
|
79
63
|
|
|
80
64
|
## Usage
|
|
81
65
|
|
|
82
|
-
You can generate CUIDs directly in the terminal with the following:
|
|
66
|
+
You can generate CUIDs directly in the terminal with the following (optionally specifying a custom length):
|
|
83
67
|
```bash
|
|
84
68
|
$ cuid2
|
|
69
|
+
$ cuid2 10
|
|
85
70
|
```
|
|
86
71
|
|
|
87
|
-
Or you can rely on a CUID wrapper if you
|
|
72
|
+
Or you can rely on a CUID wrapper if you only need default or custom-length generation:
|
|
88
73
|
```python
|
|
89
74
|
from typing import Callable
|
|
90
75
|
from cuid2 import cuid_wrapper
|
|
91
76
|
|
|
92
77
|
cuid_generator: Callable[[], str] = cuid_wrapper()
|
|
78
|
+
short_cuid_generator: Callable[[], str] = cuid_wrapper(length=10)
|
|
79
|
+
|
|
93
80
|
|
|
94
81
|
def main():
|
|
95
|
-
|
|
96
|
-
|
|
82
|
+
my_cuid: str = cuid_generator()
|
|
83
|
+
short_cuid: str = short_cuid_generator()
|
|
97
84
|
```
|
|
98
85
|
|
|
99
86
|
Finally, for more explicit control of the CUID generator, you can instantiate the class directly:
|
|
@@ -102,7 +89,14 @@ from cuid2 import Cuid
|
|
|
102
89
|
|
|
103
90
|
CUID_GENERATOR: Cuid = Cuid(length=10)
|
|
104
91
|
|
|
92
|
+
|
|
105
93
|
def main():
|
|
106
|
-
|
|
107
|
-
|
|
94
|
+
my_cuid: str = CUID_GENERATOR.generate()
|
|
95
|
+
next_cuid: str = CUID_GENERATOR.generate()
|
|
96
|
+
|
|
97
|
+
# Validate CUID
|
|
98
|
+
print(Cuid.is_cuid(my_cuid)) # True
|
|
108
99
|
```
|
|
100
|
+
|
|
101
|
+
`Cuid.is_cuid` also accepts optional `min_length` and `max_length` arguments to tighten the allowed length.
|
|
102
|
+
The bounds are clamped to 2 and 98 characters, so they can narrow but never widen what is considered valid.
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# cuid2
|
|
2
2
|
|
|
3
|
-
[](https://pypi.
|
|
5
|
-
[](https://pypi.
|
|
6
|
-
[](https://snyk.io/advisor/python/cuid2)
|
|
3
|
+
[](https://pypi.org/project/cuid2/)
|
|
4
|
+
[](https://pypi.org/project/cuid2/)
|
|
5
|
+
[](https://pypi.org/project/cuid2/)
|
|
7
6
|
|
|
8
7
|
CUID2 for Python 3. Next generation GUIDs. Collision-resistant ids optimized for
|
|
9
8
|
horizontal scaling and performance.
|
|
@@ -40,21 +39,24 @@ pip install cuid2
|
|
|
40
39
|
|
|
41
40
|
## Usage
|
|
42
41
|
|
|
43
|
-
You can generate CUIDs directly in the terminal with the following:
|
|
42
|
+
You can generate CUIDs directly in the terminal with the following (optionally specifying a custom length):
|
|
44
43
|
```bash
|
|
45
44
|
$ cuid2
|
|
45
|
+
$ cuid2 10
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
Or you can rely on a CUID wrapper if you
|
|
48
|
+
Or you can rely on a CUID wrapper if you only need default or custom-length generation:
|
|
49
49
|
```python
|
|
50
50
|
from typing import Callable
|
|
51
51
|
from cuid2 import cuid_wrapper
|
|
52
52
|
|
|
53
53
|
cuid_generator: Callable[[], str] = cuid_wrapper()
|
|
54
|
+
short_cuid_generator: Callable[[], str] = cuid_wrapper(length=10)
|
|
55
|
+
|
|
54
56
|
|
|
55
57
|
def main():
|
|
56
|
-
|
|
57
|
-
|
|
58
|
+
my_cuid: str = cuid_generator()
|
|
59
|
+
short_cuid: str = short_cuid_generator()
|
|
58
60
|
```
|
|
59
61
|
|
|
60
62
|
Finally, for more explicit control of the CUID generator, you can instantiate the class directly:
|
|
@@ -63,7 +65,14 @@ from cuid2 import Cuid
|
|
|
63
65
|
|
|
64
66
|
CUID_GENERATOR: Cuid = Cuid(length=10)
|
|
65
67
|
|
|
68
|
+
|
|
66
69
|
def main():
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
my_cuid: str = CUID_GENERATOR.generate()
|
|
71
|
+
next_cuid: str = CUID_GENERATOR.generate()
|
|
72
|
+
|
|
73
|
+
# Validate CUID
|
|
74
|
+
print(Cuid.is_cuid(my_cuid)) # True
|
|
69
75
|
```
|
|
76
|
+
|
|
77
|
+
`Cuid.is_cuid` also accepts optional `min_length` and `max_length` arguments to tighten the allowed length.
|
|
78
|
+
The bounds are clamped to 2 and 98 characters, so they can narrow but never widen what is considered valid.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.7.0,<0.14.0"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "cuid2"
|
|
7
|
+
version = "2.0.2"
|
|
8
|
+
description = "Next generation GUIDs. Collision-resistant ids optimized for horizontal scaling and performance."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
classifiers = [
|
|
14
|
+
"Development Status :: 5 - Production/Stable",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Topic :: Security :: Cryptography",
|
|
24
|
+
"Typing :: Typed",
|
|
25
|
+
]
|
|
26
|
+
keywords = [
|
|
27
|
+
"crypt",
|
|
28
|
+
"security",
|
|
29
|
+
"uuid",
|
|
30
|
+
"guid",
|
|
31
|
+
"cuid",
|
|
32
|
+
"cryptography",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[[project.authors]]
|
|
36
|
+
name = "Will Gordon"
|
|
37
|
+
email = "dev@gordoncode.dev"
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
repository = "https://github.com/gordon-code/cuid2/"
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
cuid2 = "cuid2.cli:main"
|
|
44
|
+
|
|
45
|
+
[tool.uv]
|
|
46
|
+
default-groups = [
|
|
47
|
+
"lint",
|
|
48
|
+
"test",
|
|
49
|
+
"tox",
|
|
50
|
+
"typing",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[tool.tox]
|
|
54
|
+
legacy_tox_ini = """
|
|
55
|
+
[tox]
|
|
56
|
+
min_version = 4
|
|
57
|
+
env_list = py3{10,11,12,13,14}, check
|
|
58
|
+
work_dir = local/.tox
|
|
59
|
+
isolated_build = True
|
|
60
|
+
|
|
61
|
+
[testenv]
|
|
62
|
+
runner = uv-venv-lock-runner
|
|
63
|
+
description = run unit tests
|
|
64
|
+
dependency_groups = test
|
|
65
|
+
commands = pytest local/tests
|
|
66
|
+
|
|
67
|
+
[testenv:check]
|
|
68
|
+
runner = uv-venv-lock-runner
|
|
69
|
+
description = run linters and typing
|
|
70
|
+
package = skip
|
|
71
|
+
dependency_groups =
|
|
72
|
+
lint
|
|
73
|
+
typing
|
|
74
|
+
test
|
|
75
|
+
commands =
|
|
76
|
+
ruff check src/ local/tests/
|
|
77
|
+
ruff format --check src/ local/tests/
|
|
78
|
+
codespell src/ local/tests/
|
|
79
|
+
pylint src/ local/tests/
|
|
80
|
+
mypy src/ local/tests/
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
[tool.ruff]
|
|
84
|
+
line-length = 120
|
|
85
|
+
src = ["src"]
|
|
86
|
+
target-version = "py310"
|
|
87
|
+
cache-dir = "local/.ruff_cache"
|
|
88
|
+
force-exclude = true
|
|
89
|
+
|
|
90
|
+
[tool.ruff.lint]
|
|
91
|
+
select = [
|
|
92
|
+
"F",
|
|
93
|
+
"E",
|
|
94
|
+
"W",
|
|
95
|
+
"C90",
|
|
96
|
+
"I",
|
|
97
|
+
"N",
|
|
98
|
+
"ASYNC",
|
|
99
|
+
"S",
|
|
100
|
+
"BLE",
|
|
101
|
+
"B",
|
|
102
|
+
"A",
|
|
103
|
+
"COM",
|
|
104
|
+
"C4",
|
|
105
|
+
"DTZ",
|
|
106
|
+
"T10",
|
|
107
|
+
"EM",
|
|
108
|
+
"FA",
|
|
109
|
+
"ISC",
|
|
110
|
+
"ICN",
|
|
111
|
+
"G",
|
|
112
|
+
"INP",
|
|
113
|
+
"PIE",
|
|
114
|
+
"T20",
|
|
115
|
+
"PT",
|
|
116
|
+
"Q",
|
|
117
|
+
"RSE",
|
|
118
|
+
"RET",
|
|
119
|
+
"SLF",
|
|
120
|
+
"SLOT",
|
|
121
|
+
"SIM",
|
|
122
|
+
"INT",
|
|
123
|
+
"ARG",
|
|
124
|
+
"PTH",
|
|
125
|
+
"PGH",
|
|
126
|
+
"PL",
|
|
127
|
+
"TRY",
|
|
128
|
+
"FLY",
|
|
129
|
+
"PERF",
|
|
130
|
+
"LOG",
|
|
131
|
+
"RUF",
|
|
132
|
+
]
|
|
133
|
+
ignore = [
|
|
134
|
+
"D100",
|
|
135
|
+
"D101",
|
|
136
|
+
"D102",
|
|
137
|
+
"D104",
|
|
138
|
+
"D205",
|
|
139
|
+
"D401",
|
|
140
|
+
"COM812",
|
|
141
|
+
"ISC001",
|
|
142
|
+
]
|
|
143
|
+
unfixable = [
|
|
144
|
+
"T201",
|
|
145
|
+
"F401",
|
|
146
|
+
"F841",
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
[tool.ruff.lint.per-file-ignores]
|
|
150
|
+
"test_*.py" = [
|
|
151
|
+
"S101",
|
|
152
|
+
"PLR2004",
|
|
153
|
+
"SLF001",
|
|
154
|
+
]
|
|
155
|
+
|
|
156
|
+
[tool.ruff.lint.isort]
|
|
157
|
+
known-first-party = ["src"]
|
|
158
|
+
section-order = [
|
|
159
|
+
"future",
|
|
160
|
+
"standard-library",
|
|
161
|
+
"third-party",
|
|
162
|
+
"first-party",
|
|
163
|
+
"local-folder",
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
[tool.ruff.lint.pydocstyle]
|
|
167
|
+
convention = "numpy"
|
|
168
|
+
|
|
169
|
+
[tool.pytest.ini_options]
|
|
170
|
+
minversion = "8.1"
|
|
171
|
+
cache_dir = "local/.pytest_cache"
|
|
172
|
+
python_files = "test_*.py"
|
|
173
|
+
testpaths = ["local/tests"]
|
|
174
|
+
|
|
175
|
+
[tool.pylint.master]
|
|
176
|
+
ignore-patterns = "test_.*.py"
|
|
177
|
+
|
|
178
|
+
[tool.pylint.format]
|
|
179
|
+
max-line-length = 120
|
|
180
|
+
|
|
181
|
+
[tool.pylint.messages_control]
|
|
182
|
+
disable = [
|
|
183
|
+
"missing-module-docstring",
|
|
184
|
+
"missing-class-docstring",
|
|
185
|
+
]
|
|
186
|
+
|
|
187
|
+
[tool.pylint.design]
|
|
188
|
+
max-parents = 13
|
|
189
|
+
max-args = 10
|
|
190
|
+
|
|
191
|
+
[tool.pylint.string]
|
|
192
|
+
check-quote-consistency = "yes"
|
|
193
|
+
|
|
194
|
+
[tool.mypy]
|
|
195
|
+
cache_dir = "local/.mypy_cache"
|
|
196
|
+
|
|
197
|
+
[dependency-groups]
|
|
198
|
+
lint = [
|
|
199
|
+
"codespell==2.4.3",
|
|
200
|
+
"pylint==4.1.2",
|
|
201
|
+
"ruff==0.16.10",
|
|
202
|
+
]
|
|
203
|
+
test = [
|
|
204
|
+
"pytest==9.1.1",
|
|
205
|
+
"pytest-mock==3.16.0",
|
|
206
|
+
"pytest-sugar==1.1.1",
|
|
207
|
+
]
|
|
208
|
+
tox = [
|
|
209
|
+
"tox==4.64.8",
|
|
210
|
+
"tox-uv==1.36.1",
|
|
211
|
+
]
|
|
212
|
+
typing = ["mypy==2.4.0"]
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.7.0,<0.14.0"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "cuid2"
|
|
7
|
+
version = "2.0.2"
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "Will Gordon", email = "dev@gordoncode.dev"},
|
|
10
|
+
]
|
|
11
|
+
description = "Next generation GUIDs. Collision-resistant ids optimized for horizontal scaling and performance."
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
license = "MIT"
|
|
15
|
+
license-files = ["LICENSE"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 5 - Production/Stable",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Programming Language :: Python :: 3.14",
|
|
26
|
+
"Topic :: Security :: Cryptography",
|
|
27
|
+
"Typing :: Typed",
|
|
28
|
+
]
|
|
29
|
+
keywords = ['crypt', 'security', 'uuid', 'guid', 'cuid', 'cryptography']
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
repository = "https://github.com/gordon-code/cuid2/"
|
|
33
|
+
|
|
34
|
+
[project.scripts]
|
|
35
|
+
cuid2 = "cuid2.cli:main"
|
|
36
|
+
|
|
37
|
+
[tool.uv]
|
|
38
|
+
default-groups = ["lint", "test", "tox", "typing"]
|
|
39
|
+
|
|
40
|
+
[dependency-groups]
|
|
41
|
+
lint = [
|
|
42
|
+
"codespell==2.4.3",
|
|
43
|
+
"pylint==4.1.2",
|
|
44
|
+
"ruff==0.16.10",
|
|
45
|
+
]
|
|
46
|
+
test = [
|
|
47
|
+
"pytest==9.1.1",
|
|
48
|
+
"pytest-mock==3.16.0",
|
|
49
|
+
"pytest-sugar==1.1.1",
|
|
50
|
+
]
|
|
51
|
+
tox = [
|
|
52
|
+
"tox==4.64.8",
|
|
53
|
+
"tox-uv==1.36.1",
|
|
54
|
+
]
|
|
55
|
+
typing = [
|
|
56
|
+
"mypy==2.4.0",
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
[tool.tox]
|
|
60
|
+
legacy_tox_ini = """
|
|
61
|
+
[tox]
|
|
62
|
+
min_version = 4
|
|
63
|
+
env_list = py3{10,11,12,13,14}, check
|
|
64
|
+
work_dir = local/.tox
|
|
65
|
+
isolated_build = True
|
|
66
|
+
|
|
67
|
+
[testenv]
|
|
68
|
+
runner = uv-venv-lock-runner
|
|
69
|
+
description = run unit tests
|
|
70
|
+
dependency_groups = test
|
|
71
|
+
commands = pytest local/tests
|
|
72
|
+
|
|
73
|
+
[testenv:check]
|
|
74
|
+
runner = uv-venv-lock-runner
|
|
75
|
+
description = run linters and typing
|
|
76
|
+
package = skip
|
|
77
|
+
dependency_groups =
|
|
78
|
+
lint
|
|
79
|
+
typing
|
|
80
|
+
test
|
|
81
|
+
commands =
|
|
82
|
+
ruff check src/ local/tests/
|
|
83
|
+
ruff format --check src/ local/tests/
|
|
84
|
+
codespell src/ local/tests/
|
|
85
|
+
pylint src/ local/tests/
|
|
86
|
+
mypy src/ local/tests/
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
[tool.ruff]
|
|
90
|
+
line-length = 120
|
|
91
|
+
src = ["src"]
|
|
92
|
+
target-version = "py310"
|
|
93
|
+
cache-dir = "local/.ruff_cache"
|
|
94
|
+
force-exclude = true
|
|
95
|
+
|
|
96
|
+
[tool.ruff.lint]
|
|
97
|
+
# https://docs.astral.sh/ruff/rules/
|
|
98
|
+
select = [
|
|
99
|
+
"F", "E", "W", "C90", "I", "N", "ASYNC",
|
|
100
|
+
"S", "BLE", "B", "A", "COM", "C4",
|
|
101
|
+
"DTZ", "T10", "EM", "FA", "ISC", "ICN",
|
|
102
|
+
"G", "INP", "PIE", "T20", "PT", "Q", "RSE",
|
|
103
|
+
"RET", "SLF", "SLOT", "SIM", "INT", "ARG",
|
|
104
|
+
"PTH", "PGH", "PL", "TRY", "FLY", "PERF",
|
|
105
|
+
"LOG", "RUF",
|
|
106
|
+
] # purposely not including "DJ", "YTT", "EXE", "PD", "NPY", "FBT" (boolean checking)
|
|
107
|
+
ignore = [
|
|
108
|
+
"D100", # Missing docstring in public module
|
|
109
|
+
"D101", # Missing docstring in public class
|
|
110
|
+
"D102", # Missing docstring in public method
|
|
111
|
+
"D104", # Missing docstring in public package
|
|
112
|
+
"D205", # Blank line required between summary line and description
|
|
113
|
+
"D401", # First line should be in imperative mood
|
|
114
|
+
"COM812", "ISC001", # Conflict with formatter
|
|
115
|
+
]
|
|
116
|
+
# Don't automatically remove `print`
|
|
117
|
+
# Stop automatically removing unused imports
|
|
118
|
+
unfixable = ["T201", "F401", "F841"]
|
|
119
|
+
|
|
120
|
+
[tool.ruff.lint.per-file-ignores]
|
|
121
|
+
# Ignore `assert` in test files (S101), magic values (PLR2004), and private member accessed (SLF001)
|
|
122
|
+
"test_*.py" = ["S101", "PLR2004", "SLF001"]
|
|
123
|
+
|
|
124
|
+
[tool.ruff.lint.isort]
|
|
125
|
+
known-first-party = ["src"]
|
|
126
|
+
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
|
|
127
|
+
|
|
128
|
+
[tool.ruff.lint.pydocstyle]
|
|
129
|
+
convention = "numpy"
|
|
130
|
+
|
|
131
|
+
[tool.pytest.ini_options]
|
|
132
|
+
minversion = "8.1"
|
|
133
|
+
cache_dir = "local/.pytest_cache"
|
|
134
|
+
python_files = "test_*.py"
|
|
135
|
+
testpaths = ["local/tests"]
|
|
136
|
+
|
|
137
|
+
[tool.pylint.master]
|
|
138
|
+
ignore-patterns = "test_.*.py"
|
|
139
|
+
|
|
140
|
+
[tool.pylint.format]
|
|
141
|
+
max-line-length = 120
|
|
142
|
+
|
|
143
|
+
[tool.pylint.messages_control]
|
|
144
|
+
disable = [
|
|
145
|
+
"missing-module-docstring",
|
|
146
|
+
"missing-class-docstring",
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
[tool.pylint.design]
|
|
150
|
+
max-parents = 13
|
|
151
|
+
max-args = 10
|
|
152
|
+
|
|
153
|
+
[tool.pylint.string]
|
|
154
|
+
check-quote-consistency = "yes"
|
|
155
|
+
|
|
156
|
+
[tool.mypy]
|
|
157
|
+
cache_dir = "local/.mypy_cache"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Next generation GUIDs. Collision-resistant ids optimized for horizontal scaling and performance."""
|
|
2
|
+
|
|
2
3
|
from .generator import DEFAULT_LENGTH, INITIAL_COUNT_MAX, Cuid, cuid_wrapper
|
|
3
4
|
|
|
4
|
-
__all__ = ["
|
|
5
|
+
__all__ = ["DEFAULT_LENGTH", "INITIAL_COUNT_MAX", "Cuid", "cuid_wrapper"]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from argparse import ArgumentParser
|
|
4
|
+
from typing import TYPE_CHECKING, Optional
|
|
5
|
+
|
|
6
|
+
from cuid2.generator import DEFAULT_LENGTH, cuid_wrapper
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from collections.abc import Sequence
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main(args: Optional[Sequence[str]] = None) -> None:
|
|
13
|
+
"""Print out a CUID generated string. Used by the CLI console script."""
|
|
14
|
+
arguments_parser = ArgumentParser()
|
|
15
|
+
arguments_parser.add_argument(
|
|
16
|
+
nargs="?",
|
|
17
|
+
dest="length",
|
|
18
|
+
help="Length of generated cuid2",
|
|
19
|
+
type=int,
|
|
20
|
+
default=DEFAULT_LENGTH,
|
|
21
|
+
)
|
|
22
|
+
cli_arguments = arguments_parser.parse_args(args)
|
|
23
|
+
|
|
24
|
+
print(cuid_wrapper(cli_arguments.length)()) # noqa: T201 (print statement)
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
1
4
|
import time
|
|
2
5
|
from math import floor
|
|
3
6
|
from secrets import SystemRandom
|
|
@@ -9,8 +12,7 @@ if TYPE_CHECKING:
|
|
|
9
12
|
from _random import Random
|
|
10
13
|
|
|
11
14
|
class FingerprintCallable(Protocol): # pylint: disable=too-few-public-methods
|
|
12
|
-
def __call__(self:
|
|
13
|
-
...
|
|
15
|
+
def __call__(self: FingerprintCallable, random_generator: Random) -> str: ...
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
# ~22k hosts before 50% chance of initial counter collision
|
|
@@ -18,15 +20,16 @@ if TYPE_CHECKING:
|
|
|
18
20
|
INITIAL_COUNT_MAX: Final[int] = 476782367
|
|
19
21
|
DEFAULT_LENGTH: Final = 24
|
|
20
22
|
MAXIMUM_LENGTH: Final = 98
|
|
23
|
+
_CUID_REGEX: Final[re.Pattern[str]] = re.compile(r"^[a-z][0-9a-z]+\Z")
|
|
21
24
|
|
|
22
25
|
|
|
23
26
|
class Cuid: # pylint: disable=too-few-public-methods
|
|
24
27
|
def __init__(
|
|
25
|
-
self:
|
|
26
|
-
random_generator: Callable[[],
|
|
28
|
+
self: Cuid,
|
|
29
|
+
random_generator: Callable[[], Random] = SystemRandom,
|
|
27
30
|
counter: Callable[[int], Callable[[], int]] = utils.create_counter,
|
|
28
31
|
length: int = DEFAULT_LENGTH,
|
|
29
|
-
fingerprint:
|
|
32
|
+
fingerprint: FingerprintCallable = utils.create_fingerprint,
|
|
30
33
|
) -> None:
|
|
31
34
|
"""Initialization function for the Cuid class that generates a universally unique,
|
|
32
35
|
base36 encoded string.
|
|
@@ -39,28 +42,31 @@ class Cuid: # pylint: disable=too-few-public-methods
|
|
|
39
42
|
counter : Callable[[int], Callable[[], int]], default=utils.create_counter
|
|
40
43
|
The `counter` parameter is a callable that creates a counter returning an incremented value each time it
|
|
41
44
|
is called. The `create_counter` function from the `utils` module is used by default.
|
|
42
|
-
length : int, default=DEFAULT_LENGTH (
|
|
45
|
+
length : int, default=DEFAULT_LENGTH (24)
|
|
43
46
|
The length parameter is an integer that determines the maximum length of the generated string.
|
|
44
|
-
It has a default value of DEFAULT_LENGTH (
|
|
45
|
-
A length value greater than `MAXIMUM_LENGTH` (98 characters) will raise a ValueError.
|
|
47
|
+
It has a default value of DEFAULT_LENGTH (24).
|
|
48
|
+
A length value less than 1 or greater than `MAXIMUM_LENGTH` (98 characters) will raise a ValueError.
|
|
46
49
|
fingerprint : "FingerprintCallable", default=utils.create_fingerprint
|
|
47
50
|
The "fingerprint" parameter is a callable function that generates a unique identifier.
|
|
48
51
|
|
|
49
52
|
Raises
|
|
50
53
|
------
|
|
51
54
|
ValueError
|
|
52
|
-
If the length parameter is greater than `MAXIMUM_LENGTH` (98 characters).
|
|
55
|
+
If the length parameter is less than 1 or greater than `MAXIMUM_LENGTH` (98 characters).
|
|
53
56
|
"""
|
|
57
|
+
if isinstance(length, bool) or length < 1:
|
|
58
|
+
msg = "Length must be at least 1 character."
|
|
59
|
+
raise ValueError(msg)
|
|
54
60
|
if length > MAXIMUM_LENGTH:
|
|
55
61
|
msg = "Length must never exceed 98 characters."
|
|
56
62
|
raise ValueError(msg)
|
|
57
63
|
|
|
58
|
-
self._random:
|
|
64
|
+
self._random: Random = random_generator()
|
|
59
65
|
self._counter: Callable[[], int] = counter(floor(self._random.random() * INITIAL_COUNT_MAX))
|
|
60
66
|
self._length: int = length
|
|
61
67
|
self._fingerprint: str = fingerprint(random_generator=self._random)
|
|
62
68
|
|
|
63
|
-
def generate(self:
|
|
69
|
+
def generate(self: Cuid, length: Optional[int] = None) -> str:
|
|
64
70
|
"""Generates a universally unique, base36 encoded string with a specified length.
|
|
65
71
|
|
|
66
72
|
Parameters
|
|
@@ -68,7 +74,7 @@ class Cuid: # pylint: disable=too-few-public-methods
|
|
|
68
74
|
length : int, optional
|
|
69
75
|
The length parameter is an optional integer value that specifies the length of the generated string.
|
|
70
76
|
If it is not provided, the default length value provided during class initialization is used.
|
|
71
|
-
A length value greater than `MAXIMUM_LENGTH` (98 characters) will raise a ValueError.
|
|
77
|
+
A length value less than 1 or greater than `MAXIMUM_LENGTH` (98 characters) will raise a ValueError.
|
|
72
78
|
|
|
73
79
|
Returns
|
|
74
80
|
-------
|
|
@@ -80,10 +86,13 @@ class Cuid: # pylint: disable=too-few-public-methods
|
|
|
80
86
|
Raises
|
|
81
87
|
------
|
|
82
88
|
ValueError
|
|
83
|
-
If the length parameter is greater than `MAXIMUM_LENGTH` (98 characters).
|
|
89
|
+
If the length parameter is less than 1 or greater than `MAXIMUM_LENGTH` (98 characters).
|
|
84
90
|
"""
|
|
85
|
-
|
|
86
|
-
if
|
|
91
|
+
resolved_length: int = self._length if length is None else length
|
|
92
|
+
if isinstance(resolved_length, bool) or resolved_length < 1:
|
|
93
|
+
msg = "Length must be at least 1 character."
|
|
94
|
+
raise ValueError(msg)
|
|
95
|
+
if resolved_length > MAXIMUM_LENGTH:
|
|
87
96
|
msg = "Length must never exceed 98 characters."
|
|
88
97
|
raise ValueError(msg)
|
|
89
98
|
|
|
@@ -92,21 +101,62 @@ class Cuid: # pylint: disable=too-few-public-methods
|
|
|
92
101
|
base36_time: str = utils.base36_encode(time.time_ns())
|
|
93
102
|
base36_count: str = utils.base36_encode(self._counter())
|
|
94
103
|
|
|
95
|
-
salt: str = utils.create_entropy(length=
|
|
104
|
+
salt: str = utils.create_entropy(length=resolved_length, random_generator=self._random)
|
|
96
105
|
hash_input: str = base36_time + salt + base36_count + self._fingerprint
|
|
97
106
|
|
|
98
|
-
return first_letter + utils.create_hash(hash_input)[1
|
|
107
|
+
return first_letter + utils.create_hash(hash_input)[1:resolved_length]
|
|
108
|
+
|
|
109
|
+
@staticmethod
|
|
110
|
+
def is_cuid(cuid_str: str, min_length: int = 2, max_length: int = MAXIMUM_LENGTH) -> bool:
|
|
111
|
+
"""Validates whether a given string is a valid CUID2 identifier.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
cuid_str : str
|
|
116
|
+
The string to validate as a CUID2 identifier.
|
|
117
|
+
min_length : int, default=2
|
|
118
|
+
The minimum allowed length of the identifier. Values below 2 have no effect, since a valid
|
|
119
|
+
identifier always has a leading letter followed by at least one more character.
|
|
120
|
+
max_length : int, default=MAXIMUM_LENGTH (98)
|
|
121
|
+
The maximum allowed length of the identifier. Values above `MAXIMUM_LENGTH` are clamped to it.
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
bool
|
|
126
|
+
True if `cuid_str` is a string starting with a lowercase ASCII letter followed by
|
|
127
|
+
lowercase base36 characters and has length between `min_length` and `max_length`
|
|
128
|
+
inclusive; False otherwise. The length bounds can only narrow the range of valid
|
|
129
|
+
lengths (2 to `MAXIMUM_LENGTH`), never widen it.
|
|
130
|
+
"""
|
|
131
|
+
max_length = min(max_length, MAXIMUM_LENGTH)
|
|
132
|
+
return (
|
|
133
|
+
isinstance(cuid_str, str)
|
|
134
|
+
and min_length <= len(cuid_str) <= max_length
|
|
135
|
+
and bool(_CUID_REGEX.match(cuid_str))
|
|
136
|
+
)
|
|
99
137
|
|
|
100
138
|
|
|
101
|
-
def cuid_wrapper() -> Callable[[], str]:
|
|
139
|
+
def cuid_wrapper(length: int = DEFAULT_LENGTH) -> Callable[[], str]:
|
|
102
140
|
"""Wrap a single Cuid class instance and return a callable that generates a CUID string.
|
|
103
141
|
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
length : int, default=DEFAULT_LENGTH (24)
|
|
145
|
+
The length parameter is an integer that determines the maximum length of the generated string.
|
|
146
|
+
It has a default value of DEFAULT_LENGTH (24).
|
|
147
|
+
A length value less than 1 or greater than `MAXIMUM_LENGTH` (98 characters) will raise a ValueError.
|
|
148
|
+
|
|
104
149
|
Returns
|
|
105
150
|
-------
|
|
106
151
|
Callable[[], str]
|
|
107
152
|
A callable that generates a CUID string.
|
|
153
|
+
|
|
154
|
+
Raises
|
|
155
|
+
------
|
|
156
|
+
ValueError
|
|
157
|
+
If the length parameter is less than 1 or greater than `MAXIMUM_LENGTH` (98 characters).
|
|
108
158
|
"""
|
|
109
|
-
cuid_generator: Cuid = Cuid()
|
|
159
|
+
cuid_generator: Cuid = Cuid(length=length)
|
|
110
160
|
|
|
111
161
|
def cuid() -> str:
|
|
112
162
|
return cuid_generator.generate()
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import os
|
|
2
4
|
import socket
|
|
3
5
|
import string
|
|
@@ -17,9 +19,8 @@ BIG_LENGTH: Final = 32
|
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
if TYPE_CHECKING:
|
|
20
|
-
from hashlib import _Hash
|
|
21
|
-
|
|
22
22
|
from _random import Random
|
|
23
|
+
from hashlib import _Hash
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
def create_counter(count: int) -> Callable[[], int]:
|
|
@@ -46,7 +47,7 @@ def create_counter(count: int) -> Callable[[], int]:
|
|
|
46
47
|
return counter
|
|
47
48
|
|
|
48
49
|
|
|
49
|
-
def create_fingerprint(random_generator:
|
|
50
|
+
def create_fingerprint(random_generator: Random, fingerprint_data: Optional[str] = "") -> str:
|
|
50
51
|
"""Creates a fingerprint, by default combining process ID, hostname, and environment variables
|
|
51
52
|
with entropy and then hashing the result.
|
|
52
53
|
|
|
@@ -76,7 +77,7 @@ def create_fingerprint(random_generator: "Random", fingerprint_data: Optional[st
|
|
|
76
77
|
return create_hash(fingerprint)[0:BIG_LENGTH]
|
|
77
78
|
|
|
78
79
|
|
|
79
|
-
def create_entropy(random_generator:
|
|
80
|
+
def create_entropy(random_generator: Random, length: int = 4) -> str:
|
|
80
81
|
"""Creates a random string of specified length using a base36 encoding.
|
|
81
82
|
|
|
82
83
|
Parameters
|
|
@@ -126,14 +127,14 @@ def create_hash(data: str = "") -> str:
|
|
|
126
127
|
Base36 encoding of the SHA-512 hash of the input string `data`, with the first character dropped.
|
|
127
128
|
|
|
128
129
|
"""
|
|
129
|
-
hashed_value:
|
|
130
|
+
hashed_value: _Hash = sha512(data.encode())
|
|
130
131
|
hashed_int: int = int.from_bytes(hashed_value.digest(), byteorder="big")
|
|
131
132
|
|
|
132
133
|
# Drop the first character because it will bias the histogram to the left.
|
|
133
134
|
return base36_encode(hashed_int)[1:]
|
|
134
135
|
|
|
135
136
|
|
|
136
|
-
def create_letter(random_generator:
|
|
137
|
+
def create_letter(random_generator: Random) -> str:
|
|
137
138
|
"""Generates a random lowercase letter using a given random number generator.
|
|
138
139
|
|
|
139
140
|
Parameters
|
cuid2-2.0.0/pyproject.toml
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = [
|
|
3
|
-
"pdm-backend",
|
|
4
|
-
]
|
|
5
|
-
build-backend = "pdm.backend"
|
|
6
|
-
|
|
7
|
-
[project]
|
|
8
|
-
name = "cuid2"
|
|
9
|
-
dynamic = []
|
|
10
|
-
authors = [
|
|
11
|
-
{ name = "Will Gordon", email = "wgordon@redhat.com" },
|
|
12
|
-
]
|
|
13
|
-
description = "Next generation GUIDs. Collision-resistant ids optimized for horizontal scaling and performance."
|
|
14
|
-
readme = "README.md"
|
|
15
|
-
requires-python = ">=3.8"
|
|
16
|
-
classifiers = [
|
|
17
|
-
"Development Status :: 5 - Production/Stable",
|
|
18
|
-
"Intended Audience :: Developers",
|
|
19
|
-
"License :: OSI Approved :: MIT License",
|
|
20
|
-
"Operating System :: OS Independent",
|
|
21
|
-
"Programming Language :: Python :: 3",
|
|
22
|
-
"Programming Language :: Python :: 3.8",
|
|
23
|
-
"Topic :: Security :: Cryptography",
|
|
24
|
-
"Typing :: Typed",
|
|
25
|
-
]
|
|
26
|
-
keywords = [
|
|
27
|
-
"crypt",
|
|
28
|
-
"security",
|
|
29
|
-
"uuid",
|
|
30
|
-
"guid",
|
|
31
|
-
"cuid",
|
|
32
|
-
"cryptography",
|
|
33
|
-
]
|
|
34
|
-
version = "2.0.0"
|
|
35
|
-
|
|
36
|
-
[project.license]
|
|
37
|
-
file = "LICENSE"
|
|
38
|
-
|
|
39
|
-
[project.urls]
|
|
40
|
-
repository = "https://github.com/gordon-code/cuid2/"
|
|
41
|
-
|
|
42
|
-
[project.scripts]
|
|
43
|
-
cuid2 = "cuid2.cli:main"
|
|
44
|
-
|
|
45
|
-
[tool.pdm.version]
|
|
46
|
-
source = "scm"
|
|
47
|
-
|
|
48
|
-
[tool.pdm.scripts]
|
|
49
|
-
black = "black {args:src/ local/tests/}"
|
|
50
|
-
ruff = "ruff check --fix --exit-zero {args:src/ local/tests/}"
|
|
51
|
-
spelling = "codespell {args:src/ local/tests/}"
|
|
52
|
-
pylint = "pylint {args:src/ local/tests/}"
|
|
53
|
-
safety = "safety check --bare"
|
|
54
|
-
typing = "mypy {args:src/ local/tests/}"
|
|
55
|
-
testing = "pytest local/tests"
|
|
56
|
-
testing-slow = "pytest local/tests --runslow"
|
|
57
|
-
tox = "tox --parallel auto"
|
|
58
|
-
|
|
59
|
-
[tool.pdm.scripts.lint-fast]
|
|
60
|
-
composite = [
|
|
61
|
-
"black",
|
|
62
|
-
"ruff",
|
|
63
|
-
]
|
|
64
|
-
|
|
65
|
-
[tool.pdm.scripts.lint-full]
|
|
66
|
-
composite = [
|
|
67
|
-
"lint-fast",
|
|
68
|
-
"spelling",
|
|
69
|
-
"pylint",
|
|
70
|
-
"typing",
|
|
71
|
-
"safety",
|
|
72
|
-
]
|
|
73
|
-
|
|
74
|
-
[tool.pdm.dev-dependencies]
|
|
75
|
-
lint = [
|
|
76
|
-
"black~=23.3.0",
|
|
77
|
-
"codespell~=2.2.4",
|
|
78
|
-
"pylint~=2.17.4",
|
|
79
|
-
"ruff~=0.0.269",
|
|
80
|
-
"safety==2.4.0b1",
|
|
81
|
-
]
|
|
82
|
-
test = [
|
|
83
|
-
"pytest~=7.3.1",
|
|
84
|
-
"pytest-mock~=3.10.0",
|
|
85
|
-
"pytest-sugar~=0.9.7",
|
|
86
|
-
]
|
|
87
|
-
tox = [
|
|
88
|
-
"tox~=4.4.12",
|
|
89
|
-
"tox-pdm~=0.6.1",
|
|
90
|
-
]
|
|
91
|
-
typing = [
|
|
92
|
-
"mypy~=1.3.0",
|
|
93
|
-
]
|
|
94
|
-
|
|
95
|
-
[tool.tox]
|
|
96
|
-
legacy_tox_ini = " [tox]\n min_version = 4\n env_list = py3{8,9,10,11}, check\n work_dir = local/.tox\n isolated_build = True\n\n [testenv]\n description = run unit tests\n groups = test\n commands = testing\n\n [testenv:check]\n description = run linters and typing\n skip_install = true\n groups = lint, typing, test\n commands = lint-full\n"
|
|
97
|
-
|
|
98
|
-
[tool.black]
|
|
99
|
-
line-length = 120
|
|
100
|
-
target_version = [
|
|
101
|
-
"py38",
|
|
102
|
-
]
|
|
103
|
-
|
|
104
|
-
[tool.ruff]
|
|
105
|
-
line-length = 120
|
|
106
|
-
src = [
|
|
107
|
-
"src",
|
|
108
|
-
]
|
|
109
|
-
target-version = "py38"
|
|
110
|
-
cache-dir = "local/.ruff_cache"
|
|
111
|
-
extend-select = [
|
|
112
|
-
"W",
|
|
113
|
-
"C90",
|
|
114
|
-
"I",
|
|
115
|
-
"N",
|
|
116
|
-
"UP",
|
|
117
|
-
"S",
|
|
118
|
-
"BLE",
|
|
119
|
-
"B",
|
|
120
|
-
"A",
|
|
121
|
-
"COM",
|
|
122
|
-
"C4",
|
|
123
|
-
"DTZ",
|
|
124
|
-
"T10",
|
|
125
|
-
"EM",
|
|
126
|
-
"ISC",
|
|
127
|
-
"ICN",
|
|
128
|
-
"G",
|
|
129
|
-
"INP",
|
|
130
|
-
"PIE",
|
|
131
|
-
"T20",
|
|
132
|
-
"PT",
|
|
133
|
-
"Q",
|
|
134
|
-
"RSE",
|
|
135
|
-
"RET",
|
|
136
|
-
"SLF",
|
|
137
|
-
"SIM",
|
|
138
|
-
"INT",
|
|
139
|
-
"ARG",
|
|
140
|
-
"PTH",
|
|
141
|
-
"PGH",
|
|
142
|
-
"PL",
|
|
143
|
-
"TRY",
|
|
144
|
-
"RUF",
|
|
145
|
-
"D",
|
|
146
|
-
"ANN",
|
|
147
|
-
"PYI",
|
|
148
|
-
"TCH",
|
|
149
|
-
"ERA",
|
|
150
|
-
]
|
|
151
|
-
extend-ignore = [
|
|
152
|
-
"D100",
|
|
153
|
-
"D101",
|
|
154
|
-
"D102",
|
|
155
|
-
"D104",
|
|
156
|
-
"D205",
|
|
157
|
-
"D401",
|
|
158
|
-
]
|
|
159
|
-
unfixable = [
|
|
160
|
-
"T201",
|
|
161
|
-
"F401",
|
|
162
|
-
"F841",
|
|
163
|
-
]
|
|
164
|
-
force-exclude = true
|
|
165
|
-
|
|
166
|
-
[tool.ruff.per-file-ignores]
|
|
167
|
-
"test_*.py" = [
|
|
168
|
-
"S101",
|
|
169
|
-
"PLR2004",
|
|
170
|
-
"SLF001",
|
|
171
|
-
]
|
|
172
|
-
|
|
173
|
-
[tool.ruff.isort]
|
|
174
|
-
known-first-party = [
|
|
175
|
-
"src",
|
|
176
|
-
]
|
|
177
|
-
section-order = [
|
|
178
|
-
"future",
|
|
179
|
-
"standard-library",
|
|
180
|
-
"third-party",
|
|
181
|
-
"first-party",
|
|
182
|
-
"local-folder",
|
|
183
|
-
]
|
|
184
|
-
|
|
185
|
-
[tool.ruff.pydocstyle]
|
|
186
|
-
convention = "numpy"
|
|
187
|
-
|
|
188
|
-
[tool.pytest.ini_options]
|
|
189
|
-
minversion = "7.3"
|
|
190
|
-
cache_dir = "local/.pytest_cache"
|
|
191
|
-
python_files = "test_*.py"
|
|
192
|
-
|
|
193
|
-
[tool.pylint.master]
|
|
194
|
-
ignore-patterns = "test_.*.py"
|
|
195
|
-
|
|
196
|
-
[tool.pylint.format]
|
|
197
|
-
max-line-length = 120
|
|
198
|
-
|
|
199
|
-
[tool.pylint.messages_control]
|
|
200
|
-
disable = [
|
|
201
|
-
"missing-module-docstring",
|
|
202
|
-
"missing-class-docstring",
|
|
203
|
-
]
|
|
204
|
-
|
|
205
|
-
[tool.pylint.design]
|
|
206
|
-
max-parents = 13
|
|
207
|
-
max-args = 10
|
|
208
|
-
|
|
209
|
-
[tool.pylint.string]
|
|
210
|
-
check-quote-consistency = "yes"
|
|
211
|
-
|
|
212
|
-
[tool.mypy]
|
|
213
|
-
cache_dir = "local/.mypy_cache"
|
cuid2-2.0.0/src/cuid2/cli.py
DELETED
|
File without changes
|
|
File without changes
|