hashcheck 0.1.3__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.
- hashcheck-0.1.3/.github/workflows/ci.yml +45 -0
- hashcheck-0.1.3/.gitignore +10 -0
- hashcheck-0.1.3/.python-version +1 -0
- hashcheck-0.1.3/CLAUDE.md +22 -0
- hashcheck-0.1.3/PKG-INFO +84 -0
- hashcheck-0.1.3/README.md +76 -0
- hashcheck-0.1.3/hashcheck/__init__.py +0 -0
- hashcheck-0.1.3/hashcheck/main.py +38 -0
- hashcheck-0.1.3/main.py +4 -0
- hashcheck-0.1.3/pyproject.toml +21 -0
- hashcheck-0.1.3/tests/test_hashcheck.py +113 -0
- hashcheck-0.1.3/uv.lock +107 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
tags: ["v*"]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout code
|
|
15
|
+
uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v5
|
|
19
|
+
with:
|
|
20
|
+
enable-cache: true
|
|
21
|
+
|
|
22
|
+
- name: Set up Python 3.13
|
|
23
|
+
shell: bash
|
|
24
|
+
run: uv python install 3.13
|
|
25
|
+
|
|
26
|
+
- run: uv sync --frozen
|
|
27
|
+
- run: uv run pytest
|
|
28
|
+
|
|
29
|
+
publish:
|
|
30
|
+
if: startsWith(github.ref, 'refs/tags/v')
|
|
31
|
+
needs: test
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
environment: pypi
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write # required for trusted publishing
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- uses: astral-sh/setup-uv@v5
|
|
40
|
+
with:
|
|
41
|
+
enable-cache: true
|
|
42
|
+
|
|
43
|
+
- run: uv build
|
|
44
|
+
|
|
45
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
`hash-checker` is a Python 3.13 CLI tool (currently in early development). Entry point is `main.py:main()`.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
This project uses `uv` for dependency and environment management.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Run the project
|
|
15
|
+
uv run python main.py
|
|
16
|
+
|
|
17
|
+
# Add a dependency
|
|
18
|
+
uv add <package>
|
|
19
|
+
|
|
20
|
+
# Install dependencies
|
|
21
|
+
uv sync
|
|
22
|
+
```
|
hashcheck-0.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hashcheck
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Simple file hash checker
|
|
5
|
+
Requires-Python: >=3.13
|
|
6
|
+
Requires-Dist: cloup>=3.0.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# hash-checker
|
|
10
|
+
|
|
11
|
+
A CLI tool for computing and comparing MD5 hashchecks.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv tool install .
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Get the MD5 hash of a file
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
hashcheck <filepath>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
$ hashcheck photo.jpg
|
|
29
|
+
d8e8fca2dc0f896fd7cb4cb0031ba249 photo.jpg
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Compare files
|
|
33
|
+
|
|
34
|
+
Pass two or more files — hashes are always printed, and the exit code indicates whether they match.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
hashcheck <file1> <file2> [file3 ...]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
$ hashcheck file_a.zip file_b.zip
|
|
42
|
+
d8e8fca2dc0f896fd7cb4cb0031ba249 file_a.zip
|
|
43
|
+
d8e8fca2dc0f896fd7cb4cb0031ba249 file_b.zip
|
|
44
|
+
All files match.
|
|
45
|
+
|
|
46
|
+
$ hashcheck original.zip modified.zip
|
|
47
|
+
d8e8fca2dc0f896fd7cb4cb0031ba249 original.zip
|
|
48
|
+
aabbcc112233445566778899aabbcc11 modified.zip
|
|
49
|
+
Files do not match.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Releasing
|
|
53
|
+
|
|
54
|
+
Releases are published to PyPI automatically by the CI workflow when a version tag is pushed.
|
|
55
|
+
|
|
56
|
+
**1. Bump the version in `pyproject.toml`**
|
|
57
|
+
|
|
58
|
+
```toml
|
|
59
|
+
[project]
|
|
60
|
+
version = "0.2.0"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**2. Commit the version bump**
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git add pyproject.toml
|
|
67
|
+
git commit -m "chore: bump version to 0.2.0"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**3. Tag and push**
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
git tag v0.2.0
|
|
74
|
+
git push origin main --tags
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The `publish` job in CI will build the package and upload it to PyPI once all tests pass.
|
|
78
|
+
|
|
79
|
+
> **First-time setup:** PyPI Trusted Publishing must be configured before the first release.
|
|
80
|
+
> Go to your PyPI project → *Manage* → *Publishing* and add a trusted publisher:
|
|
81
|
+
> - Publisher: GitHub
|
|
82
|
+
> - Repository: `<owner>/hash-checker`
|
|
83
|
+
> - Workflow: `ci.yml`
|
|
84
|
+
> - Environment: `pypi`
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# hash-checker
|
|
2
|
+
|
|
3
|
+
A CLI tool for computing and comparing MD5 hashchecks.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
uv tool install .
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Get the MD5 hash of a file
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
hashcheck <filepath>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
$ hashcheck photo.jpg
|
|
21
|
+
d8e8fca2dc0f896fd7cb4cb0031ba249 photo.jpg
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Compare files
|
|
25
|
+
|
|
26
|
+
Pass two or more files — hashes are always printed, and the exit code indicates whether they match.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
hashcheck <file1> <file2> [file3 ...]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
$ hashcheck file_a.zip file_b.zip
|
|
34
|
+
d8e8fca2dc0f896fd7cb4cb0031ba249 file_a.zip
|
|
35
|
+
d8e8fca2dc0f896fd7cb4cb0031ba249 file_b.zip
|
|
36
|
+
All files match.
|
|
37
|
+
|
|
38
|
+
$ hashcheck original.zip modified.zip
|
|
39
|
+
d8e8fca2dc0f896fd7cb4cb0031ba249 original.zip
|
|
40
|
+
aabbcc112233445566778899aabbcc11 modified.zip
|
|
41
|
+
Files do not match.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Releasing
|
|
45
|
+
|
|
46
|
+
Releases are published to PyPI automatically by the CI workflow when a version tag is pushed.
|
|
47
|
+
|
|
48
|
+
**1. Bump the version in `pyproject.toml`**
|
|
49
|
+
|
|
50
|
+
```toml
|
|
51
|
+
[project]
|
|
52
|
+
version = "0.2.0"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**2. Commit the version bump**
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git add pyproject.toml
|
|
59
|
+
git commit -m "chore: bump version to 0.2.0"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**3. Tag and push**
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git tag v0.2.0
|
|
66
|
+
git push origin main --tags
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The `publish` job in CI will build the package and upload it to PyPI once all tests pass.
|
|
70
|
+
|
|
71
|
+
> **First-time setup:** PyPI Trusted Publishing must be configured before the first release.
|
|
72
|
+
> Go to your PyPI project → *Manage* → *Publishing* and add a trusted publisher:
|
|
73
|
+
> - Publisher: GitHub
|
|
74
|
+
> - Repository: `<owner>/hash-checker`
|
|
75
|
+
> - Workflow: `ci.yml`
|
|
76
|
+
> - Environment: `pypi`
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
import cloup
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def md5_hash(filepath: str) -> str:
|
|
8
|
+
md5 = hashlib.md5()
|
|
9
|
+
with open(filepath, "rb") as f:
|
|
10
|
+
for chunk in iter(lambda: f.read(8192), b""):
|
|
11
|
+
md5.update(chunk)
|
|
12
|
+
return md5.hexdigest()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@cloup.command()
|
|
16
|
+
@cloup.argument("files", nargs=-1, required=True)
|
|
17
|
+
def main(files: tuple[str, ...]) -> None:
|
|
18
|
+
"""Get the MD5 hash of one or more files. Compares hashes when multiple files are given."""
|
|
19
|
+
hashes: dict[str, str] = {}
|
|
20
|
+
for filepath in files:
|
|
21
|
+
try:
|
|
22
|
+
digest = md5_hash(filepath)
|
|
23
|
+
hashes[filepath] = digest
|
|
24
|
+
print(f"{digest} {filepath}")
|
|
25
|
+
except FileNotFoundError:
|
|
26
|
+
print(f"Error: file not found: {filepath}", file=sys.stderr)
|
|
27
|
+
sys.exit(1)
|
|
28
|
+
except PermissionError:
|
|
29
|
+
print(f"Error: permission denied: {filepath}", file=sys.stderr)
|
|
30
|
+
sys.exit(1)
|
|
31
|
+
|
|
32
|
+
if len(files) > 1:
|
|
33
|
+
unique_hashes = set(hashes.values())
|
|
34
|
+
if len(unique_hashes) == 1:
|
|
35
|
+
print("All files match.")
|
|
36
|
+
else:
|
|
37
|
+
print("Files do not match.", file=sys.stderr)
|
|
38
|
+
sys.exit(1)
|
hashcheck-0.1.3/main.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "hashcheck"
|
|
3
|
+
version = "0.1.3"
|
|
4
|
+
description = "Simple file hash checker"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.13"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"cloup>=3.0.8",
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
[project.scripts]
|
|
12
|
+
hashcheck = "hashcheck.main:main"
|
|
13
|
+
|
|
14
|
+
[dependency-groups]
|
|
15
|
+
dev = [
|
|
16
|
+
"pytest>=9.0.2",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[build-system]
|
|
20
|
+
requires = ["hatchling"]
|
|
21
|
+
build-backend = "hatchling.build"
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from click.testing import CliRunner
|
|
5
|
+
|
|
6
|
+
from hashcheck.main import main, md5_hash
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture
|
|
10
|
+
def runner():
|
|
11
|
+
return CliRunner()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# --- md5_hash ---
|
|
15
|
+
|
|
16
|
+
def test_md5_hash_returns_correct_digest(tmp_path):
|
|
17
|
+
f = tmp_path / "file.txt"
|
|
18
|
+
f.write_bytes(b"hello world")
|
|
19
|
+
expected = hashlib.md5(b"hello world").hexdigest()
|
|
20
|
+
assert md5_hash(str(f)) == expected
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_md5_hash_empty_file(tmp_path):
|
|
24
|
+
f = tmp_path / "empty.txt"
|
|
25
|
+
f.write_bytes(b"")
|
|
26
|
+
expected = hashlib.md5(b"").hexdigest()
|
|
27
|
+
assert md5_hash(str(f)) == expected
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_md5_hash_raises_on_missing_file(tmp_path):
|
|
31
|
+
with pytest.raises(FileNotFoundError):
|
|
32
|
+
md5_hash(str(tmp_path / "nonexistent.txt"))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# --- hashcheck <filepath> ---
|
|
36
|
+
|
|
37
|
+
def test_main_prints_hash(runner, tmp_path):
|
|
38
|
+
f = tmp_path / "file.txt"
|
|
39
|
+
f.write_bytes(b"hello world")
|
|
40
|
+
expected = hashlib.md5(b"hello world").hexdigest()
|
|
41
|
+
|
|
42
|
+
result = runner.invoke(main, [str(f)])
|
|
43
|
+
|
|
44
|
+
assert result.exit_code == 0
|
|
45
|
+
assert f"{expected} {str(f)}" in result.output
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_main_no_args_shows_error(runner):
|
|
49
|
+
result = runner.invoke(main, [])
|
|
50
|
+
assert result.exit_code != 0
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_main_file_not_found(runner, tmp_path):
|
|
54
|
+
result = runner.invoke(main, [str(tmp_path / "missing.txt")])
|
|
55
|
+
assert result.exit_code == 1
|
|
56
|
+
assert "file not found" in result.output
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# --- hashcheck <file1> <file2> ... ---
|
|
60
|
+
|
|
61
|
+
def test_compare_matching_files(runner, tmp_path):
|
|
62
|
+
f1 = tmp_path / "a.txt"
|
|
63
|
+
f2 = tmp_path / "b.txt"
|
|
64
|
+
f1.write_bytes(b"same content")
|
|
65
|
+
f2.write_bytes(b"same content")
|
|
66
|
+
|
|
67
|
+
result = runner.invoke(main, [str(f1), str(f2)])
|
|
68
|
+
|
|
69
|
+
assert result.exit_code == 0
|
|
70
|
+
assert "All files match." in result.output
|
|
71
|
+
digest = hashlib.md5(b"same content").hexdigest()
|
|
72
|
+
assert f"{digest} {str(f1)}" in result.output
|
|
73
|
+
assert f"{digest} {str(f2)}" in result.output
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_compare_different_files(runner, tmp_path):
|
|
77
|
+
f1 = tmp_path / "a.txt"
|
|
78
|
+
f2 = tmp_path / "b.txt"
|
|
79
|
+
f1.write_bytes(b"content a")
|
|
80
|
+
f2.write_bytes(b"content b")
|
|
81
|
+
|
|
82
|
+
result = runner.invoke(main, [str(f1), str(f2)])
|
|
83
|
+
|
|
84
|
+
assert result.exit_code == 1
|
|
85
|
+
assert "do not match" in result.output
|
|
86
|
+
assert hashlib.md5(b"content a").hexdigest() in result.output
|
|
87
|
+
assert hashlib.md5(b"content b").hexdigest() in result.output
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_compare_multiple_files_all_match(runner, tmp_path):
|
|
91
|
+
files = []
|
|
92
|
+
for name in ["a.txt", "b.txt", "c.txt"]:
|
|
93
|
+
f = tmp_path / name
|
|
94
|
+
f.write_bytes(b"identical")
|
|
95
|
+
files.append(str(f))
|
|
96
|
+
|
|
97
|
+
result = runner.invoke(main, files)
|
|
98
|
+
|
|
99
|
+
assert result.exit_code == 0
|
|
100
|
+
assert "All files match." in result.output
|
|
101
|
+
digest = hashlib.md5(b"identical").hexdigest()
|
|
102
|
+
for filepath in files:
|
|
103
|
+
assert f"{digest} {filepath}" in result.output
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_compare_file_not_found(runner, tmp_path):
|
|
107
|
+
f = tmp_path / "exists.txt"
|
|
108
|
+
f.write_bytes(b"data")
|
|
109
|
+
|
|
110
|
+
result = runner.invoke(main, [str(f), str(tmp_path / "missing.txt")])
|
|
111
|
+
|
|
112
|
+
assert result.exit_code == 1
|
|
113
|
+
assert "file not found" in result.output
|
hashcheck-0.1.3/uv.lock
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 3
|
|
3
|
+
requires-python = ">=3.13"
|
|
4
|
+
|
|
5
|
+
[[package]]
|
|
6
|
+
name = "click"
|
|
7
|
+
version = "8.3.1"
|
|
8
|
+
source = { registry = "https://pypi.org/simple" }
|
|
9
|
+
dependencies = [
|
|
10
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
11
|
+
]
|
|
12
|
+
sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" }
|
|
13
|
+
wheels = [
|
|
14
|
+
{ url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" },
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[[package]]
|
|
18
|
+
name = "cloup"
|
|
19
|
+
version = "3.0.8"
|
|
20
|
+
source = { registry = "https://pypi.org/simple" }
|
|
21
|
+
dependencies = [
|
|
22
|
+
{ name = "click" },
|
|
23
|
+
]
|
|
24
|
+
sdist = { url = "https://files.pythonhosted.org/packages/46/cf/09a31f0f51b5c8ef2343baf37c35a5feb4f6dfdcbd0592a014baf837f2e4/cloup-3.0.8.tar.gz", hash = "sha256:f91c080a725196ddf74feabd6250266f466e97fc16dfe21a762cf6bc6beb3ecb", size = 229657, upload-time = "2025-08-05T02:25:02.83Z" }
|
|
25
|
+
wheels = [
|
|
26
|
+
{ url = "https://files.pythonhosted.org/packages/45/0a/494a923f90cd97cdf4fb989cfd06ac0c6745f6dfb8adcef1b7f99d3c7834/cloup-3.0.8-py2.py3-none-any.whl", hash = "sha256:6fe9474dc44fa06f8870e9c797f005de1e3ef891ddc1a9612d9b58598a038323", size = 54647, upload-time = "2025-08-05T02:25:01.536Z" },
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[[package]]
|
|
30
|
+
name = "colorama"
|
|
31
|
+
version = "0.4.6"
|
|
32
|
+
source = { registry = "https://pypi.org/simple" }
|
|
33
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
34
|
+
wheels = [
|
|
35
|
+
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[[package]]
|
|
39
|
+
name = "hashcheck"
|
|
40
|
+
version = "0.1.3"
|
|
41
|
+
source = { editable = "." }
|
|
42
|
+
dependencies = [
|
|
43
|
+
{ name = "cloup" },
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[package.dev-dependencies]
|
|
47
|
+
dev = [
|
|
48
|
+
{ name = "pytest" },
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[package.metadata]
|
|
52
|
+
requires-dist = [{ name = "cloup", specifier = ">=3.0.8" }]
|
|
53
|
+
|
|
54
|
+
[package.metadata.requires-dev]
|
|
55
|
+
dev = [{ name = "pytest", specifier = ">=9.0.2" }]
|
|
56
|
+
|
|
57
|
+
[[package]]
|
|
58
|
+
name = "iniconfig"
|
|
59
|
+
version = "2.3.0"
|
|
60
|
+
source = { registry = "https://pypi.org/simple" }
|
|
61
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
|
|
62
|
+
wheels = [
|
|
63
|
+
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
[[package]]
|
|
67
|
+
name = "packaging"
|
|
68
|
+
version = "26.0"
|
|
69
|
+
source = { registry = "https://pypi.org/simple" }
|
|
70
|
+
sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" }
|
|
71
|
+
wheels = [
|
|
72
|
+
{ url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" },
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
[[package]]
|
|
76
|
+
name = "pluggy"
|
|
77
|
+
version = "1.6.0"
|
|
78
|
+
source = { registry = "https://pypi.org/simple" }
|
|
79
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
|
80
|
+
wheels = [
|
|
81
|
+
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
[[package]]
|
|
85
|
+
name = "pygments"
|
|
86
|
+
version = "2.19.2"
|
|
87
|
+
source = { registry = "https://pypi.org/simple" }
|
|
88
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" }
|
|
89
|
+
wheels = [
|
|
90
|
+
{ url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" },
|
|
91
|
+
]
|
|
92
|
+
|
|
93
|
+
[[package]]
|
|
94
|
+
name = "pytest"
|
|
95
|
+
version = "9.0.2"
|
|
96
|
+
source = { registry = "https://pypi.org/simple" }
|
|
97
|
+
dependencies = [
|
|
98
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
99
|
+
{ name = "iniconfig" },
|
|
100
|
+
{ name = "packaging" },
|
|
101
|
+
{ name = "pluggy" },
|
|
102
|
+
{ name = "pygments" },
|
|
103
|
+
]
|
|
104
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" }
|
|
105
|
+
wheels = [
|
|
106
|
+
{ url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" },
|
|
107
|
+
]
|