The Swiss army knife of Python projects
Project description
pelutils
The Swiss army knife of Python projects
Every project, experiment, or one-off script inevitably ends up reinventing much of
the same plumbing: some way to time a loop, saving and loading data to and from disk
in a convenient and human-readable manner, a decent logger, parsing a config file, a readable table.
pelutils bundles the good versions of these so you can get straight to the actual
work. It has no required dependencies beyond the scientific-Python staples, ships
type hints (including py.typed), and is easy to start using.
📖 Full documentation: pelutils.readthedocs.io
Highlights
- Logger — easy-to-use, colourful console output, log files with rotation, automatic stacktrace capture, and safe logging from multiple processes.
- Timer & profiler — a Matlab-style
tick/tocktimer and a near-zero-overhead profiler that prints a readable breakdown of where your time goes. UniversalJsonModel— apydantic.BaseModelthat can save any attribute to a human-readable JSON file (numpy arrays, tensors, and other unserialisable types are pickled transparently) and load it straight back.JobParser— one parser that unifies command-line arguments and config files, with support for running many jobs from a single config and auto-documenting them.unique— a linear-time drop-in fornumpy.unique, dramatically faster on large arrays (backed by a small C extension).- Data-science helpers — a
matplotlibFigurecontext manager with improved default settings overmatplotlib, histogram binning, reparametrised scipy distributions,z_score, LaTeX-ready tables, and numpy type aliases.
Installation
pip install pelutils
pelutils supports Python 3.11+. A small subset of functionality can additionally
make use of PyTorch, which must be installed separately.
Importing: every feature lives in its own submodule and must be imported from there — e.g.
from pelutils.logging import log. Only__version__is exported at the top level. See the docs for the full API.
Logging
Python's built-in logging is powerful but fiddly to set up, and a bare print gives
you no importance levels, no timestamps, and nothing on disk to look at afterwards. This logger hits
the sweet spot: one configure call and you get colour-coded, timestamped output to both
the console and a log file, with severity levels, log rotation, one-line exception logging,
and multiprocessing-safe collection.
from pelutils.logging import log, LogLevels
# Set up the logger by giving it the file to write to
# Omit the path to only print, never write a file
log.configure("train.log")
log.section("Training run") # Highlighted section header
log(f"Loaded {len(dataset):,} samples") # Logs at INFO level
for epoch in range(epochs):
loss = train_one_epoch()
log.debug(f"Epoch {epoch}: loss {loss:.4f}") # Logs at DEBUG level - by default, only saved to the log file, but not printed to the console
if loss > 1e3:
log.warning("Loss is diverging") # Logs at WARNING level
log.debug("Final weights", model.state_dict().keys())
# If an exeption occurs in a piece of code, log it with its full (chained) stacktrace, then re-raise
with log.log_errors:
save_checkpoint(model)
# Temporarily change or silence the log level
with log.level(LogLevels.ERROR):
log.warning("Suppressed")
# Rotate the log file by time or size
log.configure("train.log", rotation="day") # or "1 GB", "hour", ...
When using multiprocessing, wrap a worker in with log.collect: so its lines are
written together instead of interleaving with other processes. See the
logging docs for input helpers, multiple loggers,
and more.
Timing and profiling
When you want to know where a script spends its time, cProfile gives you a wall of
function-level numbers, and manual time.perf_counter() calls quickly turn into
bookkeeping. TickTock sits in between: wrap the sections you care about in named,
nestable context managers and print a readable table of totals, hit counts, averages,
and each section's share of its parent's time. The per-profile overhead is tiny, so it
happily lives inside hot loops and long-running jobs.
from pelutils.ticktock import TT
# Time a single block, Matlab style
TT.tick()
model = train_model(data)
print(f"Training took {TT.tock():.1f} s")
# Profile named sections across a loop, nesting them however you like
for image in images:
with TT.profile("Process image"):
with TT.profile("Load"):
img = load(image)
with TT.profile("Resize"):
img = resize(img, (224, 224))
with TT.profile("Inference"):
predict(model, img)
# Print a table of hits, total time, and average time for each section
print(TT)
with TT.profile("name", hits=n): records n hits at once, which is handy for very
tight loops or for a block that processes n items in parallel. TT.do_at_interval(...)
turns the same instance into a throttle for periodic tasks. The default TT is a
shared instance; construct your own with TickTock() when you need isolation — most
importantly one per thread, as profiling is not thread-safe.
Serialisation
UniversalJsonModel extends pydantic.BaseModel with save/load methods and can
serialise attributes that pydantic cannot — numpy arrays, tensors, and arbitrary
objects are base64-pickled inline, everything else stays plain, human-readable JSON.
Long lists are wrapped to the line-length limit instead of one element per line.
import numpy as np
from pydantic import BaseModel
from pelutils.serialization import UniversalJsonModel
from pelutils.types import FloatArray
class Nested(BaseModel):
label: str
class Result(UniversalJsonModel):
accuracy: float
predictions: FloatArray # numpy arrays are handled automatically
meta: Nested
result = Result(
accuracy=0.97,
predictions=np.arange(5, dtype=np.float16),
meta=Nested(label="run-1"),
)
result.save("results/run-1.json")
result = Result.load("results/run-1.json")
Use to_json_dict() / from_json_dict(...) to convert to and from a plain dict
without touching the filesystem — useful for nesting inside other structures. The
pretty_json helper function is also available on its own. The serialization
module also includes JSONL read/write helpers (jsonl_dump, jsonl_load, ...)
with largely the same interface as is provided by the built-in json module.
Config and command-line argument parsing
JobParser combines typed command-line options with INI config files. CLI values
override config values, which override defaults. Declare RequiredArg for values
every job must provide, OptionalArg for values with defaults, and Flag for
booleans. Names are --kebab-case on the command line and snake_case attributes on
the resulting job.
from pathlib import Path
from pelutils.job_parser import Flag, JobParser, OptionalArg, RequiredArg
parser = JobParser(
RequiredArg("data-path", help="Training data directory"),
OptionalArg("learning-rate", default=1e-4, type=float, help="Optimizer learning rate"),
Flag("fp16", help="Use mixed precision"),
multiple_jobs=True,
)
for job in parser.parse_jobs():
print(job.name, job.data_path, job.learning_rate, job.fp16)
job.write_documentation(Path("runs") / job.name / "arguments.ini")
# ... run your application with the resolved job values
A single config file can define several named jobs (with a shared [DEFAULT]
section), and one CLI override applies to all of them:
python main.py --config-file config.ini --learning-rate 5e-5
For a single job, drop multiple_jobs=True and call parse_job() instead. A config
path can target one section directly, e.g. --config-file config.ini:low-lr. See the
job parser docs for auto-documentation details.
Fast unique
A linear-time alternative to numpy.unique, significantly faster on large arrays. It
also accepts torch tensors and pandas series. The returned elements are unsorted.
import numpy as np
from pelutils.misc import unique
x = np.random.randint(0, 100, size=10_000_000)
values = unique(x)
values, index, inverse, counts = unique(
x, return_index=True, return_inverse=True, return_counts=True,
)
Data science
Statistics
Common statistical helpers, plus wrappers around scipy distributions reparametrised
as in Jim Pitman's Probability (rather than scipy's loc/scale, which are
unintuitive for many distributions).
from pelutils.stats import z_score
from pelutils.stats import expon
# 95 % confidence interval half-width for a standard normal (defaults give ~1.96)
half_width = std * z_score()
# One-sided z value for an Exponential(λ=2) at the 1 % significance level
zval = z_score(alpha=0.01, two_sided=False, distribution=expon(lambda_=2))
Plotting
The Figure context manager fixes common matplotlib annoyances — sensible default
figure and font sizes, easy styling — and saves and closes the figure for you while
restoring rcParams afterwards.
import matplotlib.pyplot as plt
from pelutils.plots import Figure, histogram, normal_binning
with Figure("plot.png", figsize=(20, 10), fontsize=20):
plt.scatter(x, y, label="Data")
plt.grid()
plt.title("Very nice plot")
# Saved to plot.png and closed here
# histogram returns x and y coordinates ready for unpacking
plt.plot(*histogram(data, binning_fn=normal_binning))
Three binning functions are provided — linear_binning, log_binning, and
normal_binning (more resolution near the centre of roughly-normal data) — and custom
binning functions are supported. See the
plotting docs.
Numpy type aliases
Type aliases so you (and your type checker) do not have to track array dtypes by hand.
from pelutils.types import FloatArray, IntArray, BoolArray
def process(features: FloatArray, labels: IntArray, mask: BoolArray): ...
Also included
pelutils.misc.Table— build aligned text tables which can also be easily export to LaTeX withTable.to_latex().pelutils.misc.hardware_info/OS— describe the machine the code runs on.pelutils.misc.git_repo_info— the repo and commit the code is executing in.- Assorted file and dict helpers (
reverse_line_iterator,except_keys, ...). pelutils.tests— pytest helpers: aUnitTestCollectionbase class with a managed temp directory, and arestore_argvdecorator.
Supported platforms
Precompiled wheels are provided for most common platforms (not 32-bit systems). If no
wheel matches, pip builds from source which requires <Python.h> — install it with
sudo apt install python3-dev (Ubuntu) or sudo dnf install python3-devel (Fedora).
Updating and releasing
pelutils uses the master branch as a stable development branch.
The release branch contains the latest version on PyPI.
New features should be made in feature branches from master that can be merged into master once ready.
When a new release is ready, update pelutils/__version__.py and rebase master onto release.
Then push a new tag from release named vX.Y.Z.
When new code is merged into master, a number of checks are run.
These can be tested locally with the following commands.
# Linting and formatting
ruff format pelutils tests
ruff check pelutils tests
# Type checking
basedpyright pelutils
# Unit tests
python -m pytest tests --cov pelutils
# Build docs
# Once build, open docs/build/html/index.html in your browser to see them
make -C docs html
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pelutils-4.0.0a2.tar.gz.
File metadata
- Download URL: pelutils-4.0.0a2.tar.gz
- Upload date:
- Size: 64.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b6e3962b50b0c7325b0ee269fed1352cc6991f3766e910de87a5f11ac310798
|
|
| MD5 |
7e0e5cb24c856481217966dfeff01e6b
|
|
| BLAKE2b-256 |
cbcbfd6e2eafa93d99875cfd318f6e54673f85711e4f65fcb9bde3301a5b7d2f
|
File details
Details for the file pelutils-4.0.0a2-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 68.7 kB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a3ea8575790b45b1c60e8b057aab1758806f06f70b1f6560db0a6aa16a7020d
|
|
| MD5 |
03ba8f17eddbc81240393af0ae34edc9
|
|
| BLAKE2b-256 |
6669f776f2f903a24dc673f732f0a9b8e1ae83ecf90fb2dfdadc87d3b4e61318
|
File details
Details for the file pelutils-4.0.0a2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 87.5 kB
- Tags: CPython 3.14, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ee7bacc04656969eed97074dae7a894e4b53a0d05c401da7a5b8de8d1ac7166
|
|
| MD5 |
e7ce4b009b4986b8f13563b6a8eb4162
|
|
| BLAKE2b-256 |
8e7a279bb8161abce25fce74921b0417f9d4b9e325b3af499734720ea251de5e
|
File details
Details for the file pelutils-4.0.0a2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 88.9 kB
- Tags: CPython 3.14, manylinux: glibc 2.17+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6558dc95cc2744ecbe7c478feb4b60bc04dce7bae8c0fd3b22c7ff1f2f7c001b
|
|
| MD5 |
579631e345b6ecf7d827d2873c7094f8
|
|
| BLAKE2b-256 |
b5899255052d033729e45a5318da524e9d70ad6596e4a71979f89d04824445fc
|
File details
Details for the file pelutils-4.0.0a2-cp314-cp314-macosx_11_0_arm64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp314-cp314-macosx_11_0_arm64.whl
- Upload date:
- Size: 69.5 kB
- Tags: CPython 3.14, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
200d74a7ab75ce831acbb2b49a276ce8a209b6f2e2400d9d410b8ac1560fb42f
|
|
| MD5 |
74e0a3140989e5d153338304e4337a82
|
|
| BLAKE2b-256 |
3a946b5c3a4433d7b8735df96437cf6becb9cff46cd774617edac0380a334ac5
|
File details
Details for the file pelutils-4.0.0a2-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 68.6 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d9ac6691780447d397a9cc879800332a87a9dc1f7bcfc1ebb27dac2b1a009ef0
|
|
| MD5 |
aca7ad060ad263e556dd21ec79774a6c
|
|
| BLAKE2b-256 |
061b0746170321998090532b2477618592fc0b28c8baaa61a35591a633a261c7
|
File details
Details for the file pelutils-4.0.0a2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 87.5 kB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2bbd128fa817bddaae95879c2c3405472e35d1017bef9a54eb0044cf9bab2ee0
|
|
| MD5 |
adc4912ea49520265cebb1063903c961
|
|
| BLAKE2b-256 |
5e008eac82930d613442e4865f5c5105d6faae22131f118dcd5190f00c0625ad
|
File details
Details for the file pelutils-4.0.0a2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 88.9 kB
- Tags: CPython 3.13, manylinux: glibc 2.17+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91c68fe40067faf45cd6b95a17b379dc1841dd47694063cc6af530841c3e1a16
|
|
| MD5 |
36bc0da61ee2ab1d2172724ee1d5a2e3
|
|
| BLAKE2b-256 |
87f018851d5b2234a33ac4c4f8ce57caa5f992c18ee51d31324b469444346824
|
File details
Details for the file pelutils-4.0.0a2-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 69.4 kB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a295e4affc3e84a48b129553bff82fe55d7b474526d2ca1d3666732bbc905b38
|
|
| MD5 |
d4d711c373dcfc90c50116862a88e171
|
|
| BLAKE2b-256 |
de44afc778fb221aed5e51b350b0e1657720f1f4c2f6edf66254aaffe1fb0665
|
File details
Details for the file pelutils-4.0.0a2-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 68.6 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c962ec7a2cfb60e5319d27afef964c4e48d8bea3c1fdae4bcc59816bc6374d2f
|
|
| MD5 |
6a6070177a6e7fb7f7bb080b437cabc0
|
|
| BLAKE2b-256 |
89d67a95e20418a6528ab55e693dd156d8b68ada3e9ed37ed656e74a1d773ce7
|
File details
Details for the file pelutils-4.0.0a2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 87.4 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
baeaea09b57d98d86d9d36bdba539f1ad787666af94a313468dd4fcb9849842c
|
|
| MD5 |
85525fe0ba4ec47b1e1c9e0318f8c40f
|
|
| BLAKE2b-256 |
4fe9eb2a7082e5869ab061524f0af6ea841534d13a9eda5681f51e52b4cc6ac7
|
File details
Details for the file pelutils-4.0.0a2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 88.9 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b1278371b11e3f04907771b0d7e413258f4330d7339852fe84d44329a9ec968
|
|
| MD5 |
82a7d003f70fce9aae9b0785f2080a0f
|
|
| BLAKE2b-256 |
fb15c2af7fb28be74bd05938890484f362905d9ffc7329ea554158547d6d3b39
|
File details
Details for the file pelutils-4.0.0a2-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 69.4 kB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6c4e76bbfdd652b909444bc1aea1645d87e5c8131529744d76209be2211a5f50
|
|
| MD5 |
9fc187640f4fc0238e7ef860d030b00d
|
|
| BLAKE2b-256 |
2ec3e756213e2da4b5a3677484fec437c7c0efebfafe0d602f83256ea63b3abb
|
File details
Details for the file pelutils-4.0.0a2-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 68.6 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ec17c84770e051d92977bf1afe0bcec48087c6dcc9a8c824565aeb6c6d84412
|
|
| MD5 |
917f74b188d3a875fbf4e428541df6b1
|
|
| BLAKE2b-256 |
90bed33210fe0e15f190be67202e4e406d6b17719c1f5a7fe81bdd2abd989e29
|
File details
Details for the file pelutils-4.0.0a2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 87.3 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b34b52cc608df0eb375ae19afb5e6b786d3ef1a58bbafc7d286014281b95a29
|
|
| MD5 |
82205f8796341d68c2c946a6c09f732d
|
|
| BLAKE2b-256 |
917b9e1e3f15ecaec0675f1d69261eca10b5efa17c45bf025e34ca9a2002ab6e
|
File details
Details for the file pelutils-4.0.0a2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 88.7 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4b2fd753b526ca0714010720731694b77a5b539e5789621e2aac751b6b53775
|
|
| MD5 |
c7d1e08076a587730d72b8b1a5320222
|
|
| BLAKE2b-256 |
e69a86e289de017a5f3426afe53146c32938c71494b003413eabc87f40d0d9eb
|
File details
Details for the file pelutils-4.0.0a2-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: pelutils-4.0.0a2-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 69.4 kB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
807f8b470f19862edfde4946b1e52e163deed4ecdc80c38e20444efa1d7a609a
|
|
| MD5 |
d4fe7d4d602ad3ce995c302097a510ff
|
|
| BLAKE2b-256 |
444e39f0a4a62d924f4b095e82c373f20d27fad067651bcae32dacb12334e145
|