Skip to main content

The Swiss army knife of Python projects.

Project description

pelutils

Ruff basedpyright checks Coverage Status PyPi Python versions image

The Swiss army knife of Python projects.

  • A simple and powerful logger with colourful printing, stacktraces, and log file rotation.
  • Parsing for combining config files and command-line arguments - especially useful developing algorithms with many parameters.
  • A timer inspired by Matlab's tic and toc.
  • Simple, near-zero cost performance profiler.
  • An extension to the built-in dataclass for saving and loading data.
  • Table formatting with built-in LaTeX support.
  • Miscellaneous standalone functions - see pelutils/__init__.py.
  • Data-science submodule with extra utilities for statistics, plotting with matplotlib, and machine learning using PyTorch.
  • unique function in the style of numpy.unique which runs in linear time, making it significantly.

pelutils supports Python 3.9+.

To install, simply run pip install pelutils. A small subset of the functionality requires PyTorch, which has to be installed separately.

Timing and Code Profiling

Simple time taker inspired by Matlab Tic, Toc, which also has profiling tooling.

from pelutils import TT, TickTock

# Time a task
TT.tick()
<some task>
seconds_used = TT.tock()

# Profile a for loop
for i in range(100):
    with TT.profile("Repeated code"):
    <some task>
    with TT.profile("Subtask"):
        <some subtask>
print(TT)  # Print a table view of profiled code sections

# When using multiprocessing, it can be useful to simulate multiple hits of the same profile
with mp.Pool() as p, TT.profile("Processing 100 items on multiple threads", hits=100):
    p.map(100 items)
# Similar for very quick loops
a = 0
with TT.profile("Adding 1 to a", hits=100):
    for _ in range(100):
        a += 1

# To use the TickTock instance as a timer to trigger events, do
while True:
    if TT.do_at_interval(60, "task1"):  # Do task 1 every 60 seconds
        <task 1>
    if TT.do_at_interval(30, "task2"):  # Do task 2 every 30 seconds
        <task 2>
    time.sleep(0.01)

Data Serialisation

The DataStorage2 class is an extension of pydantic.BaseModel that incluces save and load functionality. It supports any data type, storing all data to a pretty JSON file. A class should simply inherit from DataStorage2. The stored JSON will be a dictionary-like structure with the whole nested structure. Any nested BaseModel is automatically converted to a dictionary. If a data type is reached which is not JSON serialisable (e.g. normal classes, pandas DataFramas, numpy arrays), they are encoded with pickle and base64. Inside the JSON file, a record is kept of the original type.

Very long lists utilise the full allowed line length before splitting, preventing the common JSON issue of having either very long lines (no indents) or excessively many lines with a single element on each.

Because the class inherits from pydantic.BaseModel, type checking is built directly into it.

class BasederClass(BaseModel):
    based_string: str

# Define the structure
class BasedClass(DataStorage2):
    nice: float
    long_tuple_of_ints: tuple[int, ...]
    array: FloatArray
    baseder: BasederClass

# Create an instance
based = BasedClass(
    nice=69.69,
    long_tuple_of_ints=tuple(range(500)),
    array=np.arange(5, dtype=np.float16),
    baseder=BasederClass(based_string="Hello there")
)
# Save it to a file
based.save(".")
# Save it to a file
based.save("directory/to/save/in")

# Load it again
based = BasedClass.load("directory/to/save/in")

This will produce directory/to/save/in/BasedClass.json with the following contents:

{
  "nice": 69.69,
  "long_tuple_of_ints": [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
    37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
    71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
    104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130,
    131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157,
    158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
    185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211,
    212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238,
    239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265,
    266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292,
    293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319,
    320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346,
    347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373,
    374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400,
    401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427,
    428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454,
    455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481,
    482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499
  ],
  "array": "__pickled_b64__:numpy.ndarray:gAWVfQAAAAAAAACMEm51bXB5LmNvcmUubnVtZXJpY5SMC19mcm9tYnVmZmVylJOUKJYKAAAAAAAAAAAAADwAQABCAESUjAVudW1weZSMBWR0eXBllJOUjAJmMpSJiIeUUpQoSwOMATyUTk5OSv////9K/////0sAdJRiSwWFlIwBQ5R0lFKULg==",
  "baseder": {"based_string": "Hello there"}
}

The class is built on top of the also provided pretty_json which does the exact same as the built-in json.dumps but with prettier formatting of the JSON string.

Config and Command-line Argument Parsing

Python has built-in support for both config files (the ArgumentParser and ConfigParser, respectively), but nothing for parsing both. The Pelutils Parser supports both, while also allowing for much stricter checking of types and presence of arguments. It is useful for any application relying on config files where one may want to overwrite certain arguments from the command-line. It's prime usecase, though, is for development of parametric algorithms, such as machine learning engineering.

Consider the execution of a file main.py with the command line call

python main.py path/to/output -c path/to/config/file.ini --data-path path/to/data

The config file could contain

[DEFAULT]
learning-rate=1e-4
fp16

[LOWLR]
learning-rate=1e-5

[NOFP16]
fp16=False

where main.py contains

options = [
    # Mandatory argument with set abbreviation -p
    Argument("data-path", help="Path to where data is located", abbrv"-p"),
    # Optional argument with auto-generated abbreviation -l
    Option("learning-rate", default=1e-5, help="Learning rate to use for gradient descent steps"),
    # Boolean flag with auto-generated abbreviation -f
    Flag("fp16", help="Use mixed precision for training"),
]
parser = Parser(*options, multiple_jobs=True)  # Two jobs are specified in the config file, so multiple_jobs=True
location = parser.location  # Experiments are stored here. In this case path/to/output
job_descriptions = parser.parse_args()
# Run each experiment
for job in job_descriptions:
    # Get the job as a dictionary
    job_dict = job.todict()
    # Clear directory where job is located and put a documentation file there
    job.prepare_directory()
    # Get location of this job as job.location
    run_experiment(job)

This could then by run by python main.py data/my-big-experiment --learning-rate 1e-5 or by python main.py data/my-big-experiment --config cfg.ini or using a combination where CLI args takes precedence: python main.py data/my-big-experiment --config cfg.ini --learning-rate 1e-5 where cfg.ini could contain

Logging

The logging submodule contains a simple yet feature-rich logger which fits common needs. Can be imported from pelutils directly, e.g. from pelutils import log.

from pelutils import log, Logger

# Configure logger for the script
log.configure("path/to/save/log.log")

# Start logging
for i in range(70):  # Nice
    log("Execution %i" % i)

# Sections
log.section("New section in the logfile")

# Adjust logging levels
log.warning("Will be logged")
with log.level(LogLevels.ERROR):  # Only log at ERROR level or above
    log.warning("Will not be logged")
with log.no_log:
    log.section("I will not be logged")

# Rotation
# Start a new log file every hour (or day, month, or year)
log.configure("path/to/save/log.log", rotation="hour")
# Start a new log file when the current one reaches a certain size
log.configure("path/to/save/log.log", rotation="5 MB")

# Error handling
# The zero-division error and stacktrace is logged
with log.log_errors:
    0 / 0
# Entire chained stacktrace is logged
with log.log_errors:
    try:
        0 / 0
    except ZeroDivisionError as e:
        raise ValueError("Denominator must be non-zero") from e

# User input - acts like built-in input but logs both prompt and user input
inp = log.input("Continue [Y/n]? ")
# Parse yes/no user input
cont = log.parse_bool_input(inp, default=True)

# Log all logs from a function at the same time
# This is especially useful when using multiple threads so logging does not get mixed up
def fun():
    with log.collect:
        log("Hello there")
        log("General Kenobi!")
with mp.Pool() as p:
    p.map(fun, args)

# It is also possible to create multiple loggers by importing the Logger class, e.g.
log2 = Logger()
log2.configure("path/to/save/log2.log")

Types

A few different numpy types are defined for the convenience of not having to remember what data types your arrays are - and also to satisfy your nasty type checkers.

from pelutils.types import AnyArray, FloatArray, IntArray


def function_which_takes_np_types(
    any_array: AnyArray,  # np.ndarray with arbitrary data type
    float_array: FloatArray,  # np.ndarray with any floating point data type (e.g. float, np.float16, and np.float64)
    int_array: IntArray,  # np.ndarray with any integer data type (e.g. int, np.uint8, and np.int32)
):
    ...

Data Science

This submodule contains various utility functions for data science, statistics, plotting, and machine learning.

Statistics

Includes various commonly used statistical functions. There are also wrappers around a number of scipy distributions reparametrized as in Jim Pitman's "Probability", instead of using scale and loc, which can be quite unintuitive for many distributions.

from pelutils.ds.stats import z, corr_zi
from pelutils.ds.distributions import expon

# Get one sided z value for exponential(lambda=2) distribution with a significance level of 1 %
zval = z(alpha=0.01, two_sided=False, distribution=expon(2))

# Get correlation, confidence interval, and p value for two vectors
a, b = np.random.randn(100), np.random.randn(100)
r, lower_r, upper_r, p = corr_ci(a, b, alpha=0.01)

Plotting

pelutils provides plotting utilities based on matplotlib. Most notable is the Figure context class, which attempts to remedy some of the common grievances with matplotlib, e.g. having to remember the correct kwargs and rcParams for setting font sizes, legend edge colour etc.

from pelutils.ds.plots import Figure

# The following makes a plot and saves it to `plot.png`.
# The seaborn is style is used for demonstration, but if the `style` argument
# is not given, the default matplotlib style is used.
# The figure and font size are also given for demonstration, but their default
# values are increased compared to matplotlib's default, as these are generally
# too small for finished plots.
with Figure("plot.png", figsize=(20, 10), style="seaborn", fontsize=20):
    plt.scatter(x, y, label="Data")
    plt.grid()
    plt.title("Very nice plot")
# The figure is automatically saved to `plot.png` and closed, such that
# plt.plot can be used again from here.
# Figure changes `matplotlib.rcParams`, but these changes are also undone
# after the end of the `with statement`.

The plotting utilies also include binning functions for creating nice histograms. The histogram function produces bins based on a binning function, of which three are provided:

  • linear_binning: Bins are spaced evenly from the lowest to the largest value of the data.
  • log_binning: Bins are log-spaced from the lowest to the largest value of the data, which is assumed to be positive.
  • normal_binning: Bins are distributed according to the distribution of the data, such there are more bins closer to the center of the data. This is useful if the data somewhat resembles a normal distribution, as the resolution will be the greatest where there is the most data.

It is also possible to provide custom binning functions.

histogram provide both x and y coordinates, making it simple to use with argument unpacking:

import matplotlib.pyplot as plt
import numpy as np
from pelutils.ds.plots import histogram, normal_binning

# Generate normally distributed data
x = np.random.randn(100)
# Plot distribution
plt.plot(*histogram(x, binning_fn=normal_binning))

Finally, different smoothing functions are provided. The two most common are moving_avg and exponential_avg which smooth the data using a moving average and exponential smoothing, respectively.

The double_moving_avg is special in that the number of smoothed data points do not depend on the number of given data points but is instead based on a given number of samples, which allows the resulting smoothed curve to not by jagged as happens with the other smoothing functions. It also has two smoothness parameters, which allows a large degree of smoothness control.

Apart from smoothness parameters, all smoothness functions have the same call signature:

from pelutils.ds.plots import double_moving_avg

# Generate noisy data
n = 100
x = np.linspace(-1, 1, n)
y = np.random.randn(n)

# Plot data along with smoothed curve
plt.plot(*double_moving_avg(x, y))
# If x is not given, it is assumed to go from 0 to n-1 in steps of 1
plt.plot(*double_moving_avg(y))

Examples of all the plotting utilities are shown in the examples directory.

Supported platforms

Precompiled wheels are provided for most common platforms. Notably, they are not provided for 32-bit systems. If no wheel is provided, pip should attempt a source install. If all else fails, it is possible to install from source by pointing pip to Github directly:

pip install git+https://github.com/peleiden/pelutils.git@release#egg=pelutils

It is also possible to install from source using pip's --no-binary option.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pelutils-3.8.0.tar.gz (85.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pelutils-3.8.0-cp314-cp314-win_amd64.whl (91.4 kB view details)

Uploaded CPython 3.14Windows x86-64

pelutils-3.8.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (108.6 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pelutils-3.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (110.0 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pelutils-3.8.0-cp314-cp314-macosx_11_0_arm64.whl (90.3 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

pelutils-3.8.0-cp313-cp313-win_amd64.whl (91.2 kB view details)

Uploaded CPython 3.13Windows x86-64

pelutils-3.8.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (108.6 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pelutils-3.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (110.0 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pelutils-3.8.0-cp313-cp313-macosx_11_0_arm64.whl (90.3 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

pelutils-3.8.0-cp312-cp312-win_amd64.whl (91.2 kB view details)

Uploaded CPython 3.12Windows x86-64

pelutils-3.8.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (108.5 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pelutils-3.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (110.0 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pelutils-3.8.0-cp312-cp312-macosx_11_0_arm64.whl (90.3 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

pelutils-3.8.0-cp311-cp311-win_amd64.whl (91.2 kB view details)

Uploaded CPython 3.11Windows x86-64

pelutils-3.8.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (108.4 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pelutils-3.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (109.8 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pelutils-3.8.0-cp311-cp311-macosx_11_0_arm64.whl (90.3 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

pelutils-3.8.0-cp310-cp310-win_amd64.whl (91.2 kB view details)

Uploaded CPython 3.10Windows x86-64

pelutils-3.8.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (108.4 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pelutils-3.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (109.8 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pelutils-3.8.0-cp310-cp310-macosx_11_0_arm64.whl (90.3 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

pelutils-3.8.0-cp39-cp39-win_amd64.whl (91.2 kB view details)

Uploaded CPython 3.9Windows x86-64

pelutils-3.8.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (108.2 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

pelutils-3.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (109.7 kB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

pelutils-3.8.0-cp39-cp39-macosx_11_0_arm64.whl (90.3 kB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

File details

Details for the file pelutils-3.8.0.tar.gz.

File metadata

  • Download URL: pelutils-3.8.0.tar.gz
  • Upload date:
  • Size: 85.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pelutils-3.8.0.tar.gz
Algorithm Hash digest
SHA256 27ad882a478124211789e2655b7f62f9abec3d47627a3fd6263e55e067bda6b1
MD5 8940dd324815e5ae15adbd9bab07de3b
BLAKE2b-256 2f93687dad4f34259999ee4fcef203c1f75f84afe686e840c962f8634f1a9f2a

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: pelutils-3.8.0-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 91.4 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pelutils-3.8.0-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 fe3eb39f9c5fc3ac34a5396b420b32d2f5f8e40a5ef70b0395f17a801b4d8b6c
MD5 32860bb27f72f56ab8afbf9fdcb6c22d
BLAKE2b-256 6bc932be102bc63af10977d573614b7e206c7d7b707c38806cc22df624f690a0

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 cc0f0e2afb2eacc111492b8114d7268cf85b0014a29b80fb73a747458fadac20
MD5 3fdc72b9eaf8216a816577c31733edda
BLAKE2b-256 40cbde94b6162c6b285b2e1abc77e8d6ffac6debfad8e734fc9c84fc337b316e

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 936c3691363ee0f9fc5e554fcf4f7d2f9a3beb30862465873ff9aa2feadc95bd
MD5 b98142089ea481fcbc4c3b52e01e0177
BLAKE2b-256 0ae8db8d6d3bdfe1df7d11ef8a6cba1040b120a98a74c638a5d7a93739fb8484

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1a57c159daee20c1726ee85ea8455340ea2c684d14498e390a52f1b8c2f92d6a
MD5 cecdf1eb821fbbf543d37e418aef6d15
BLAKE2b-256 bdfb73255e51df639b1e0f8eda12494bf347a366b1f57554b1d6cbed36765e40

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: pelutils-3.8.0-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 91.2 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pelutils-3.8.0-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 e4a8acc4fb533819010672d9bf81a3697386f6a171342eb60b0de60455d8925e
MD5 2ba2ee7e263c2fa5e1f8644b2c72d4c4
BLAKE2b-256 284260cbfd0c8b3db30be5e4ff203f301eef905751d472d5eab232e07dc749a1

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d2cd45935d31bc7fc2937724bd158555deb64aba9677197c62a30f061e5d981c
MD5 dac66cedb28a5b08160a25839ba06a3f
BLAKE2b-256 8d130b6844ff244302f69e651a727f1512b9834352e0141bdf38307f48561e2c

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0aa3c1ac2e01aa132ff9556dd5a9bc1aac09ecb961f1c64ba839e3cfc6e22a55
MD5 03306efbc99af2b5be46ef0e136a7fef
BLAKE2b-256 cba73add7a9e2cad8ab246e8390362eb59db7f4ff78843d2ad415712f4f4bfff

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0e936966c90f7cfbc24c2c1a9cbf7632b025629d5c6e067d23a4f35287178e24
MD5 608d2c1858f4a53ae39c8fc2c6005dcd
BLAKE2b-256 23f7f79cd6e3ce07e23520a3daa693c078deaf31898220ece7085693a01e5712

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pelutils-3.8.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 91.2 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pelutils-3.8.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 b4f3b0e4f735e6bbfad5118a8fffc0818e03fd8148d6ca2609ca6cd6653c805a
MD5 60684f6e3a66641ee9b33e3e562f0b15
BLAKE2b-256 642c01875f9f25e34200d5be6e2f4a756395ad3961161225c345d65c328931d4

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a16d96f1651e1d3f98edddf78feba6adde9ddbf90938d7df3e89a8db51794bd6
MD5 d0cdad305fba41b0d222031334bf9b23
BLAKE2b-256 944ed7b0ee2586068b83d2d082dfa9be0c7e22f829e20590dd6d8d1020e2434d

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 be7679c924b0672dbfe4cdec58b5b30599de9b9838b56e8dbdd489cd4dbacbb0
MD5 4ab8f73d81c07ad4cf28804ced6cd16a
BLAKE2b-256 af08ed3f12abb77f892b1abe7dfa932603cae26296b17a3a36d2d9c6515279ab

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 1d8e0fdad72051358e0a476763997480b86522ee7a8c41ee7cc5dfc257121d9e
MD5 867fcf169e97a9678b79708dabf00367
BLAKE2b-256 c4b6a117df12c2bfaa2310728631ff105433723eea3fc827b1903fef283d1445

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: pelutils-3.8.0-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 91.2 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pelutils-3.8.0-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 4ffbd2c41fd3b2184b5ea408f6be0e5eaaaf32420cba2eb4779ee34aa5000913
MD5 277e11fbfe395f661b49e8d1c6543427
BLAKE2b-256 696326a3761281dfdb1ffe595dbac519d48732b7246d6356a40ccfac3b27506b

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 2f277a181defc86187ef27702041248e8fed17d6b2c7b6f798269d86e73ce3f5
MD5 dd2be78d4645567746c3e45650f9838d
BLAKE2b-256 174b767aaa1ac453e1d3a08ca12231de5eaa24d696227bb9db4b4baa5e4eff54

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 a300ab5894216c2253ec64eb6f0ea02db1d66053206a11f338e9a5adbecf17f5
MD5 5ffac81a78ed0800e336436cc9013c8a
BLAKE2b-256 09d96d724233b99dc204bda9b26f16b3e474707a1140650511a49bffc713e3c5

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 40500e8dc3fe255ce38f998f1be1f3023b5fd7f9b3d6e2bd626d30074146c1c8
MD5 28a1440caa2cd5776cb05ae611063d77
BLAKE2b-256 dc9e9e160896c43c39dd3849b3c9e50f6ced8367eb100922335f4f3c7268afbf

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: pelutils-3.8.0-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 91.2 kB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pelutils-3.8.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 43630f7dbed813ba9a16333b601cc69994a2733ece379cd2b1c3661b1671ec86
MD5 23f5b0ca0e1962e7fb6ff4ef1e45685d
BLAKE2b-256 e5910a459bde0dee40932d75f0f4b58aa13b08f1e03512ace8beb229548d852f

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 a2fe8481bfd89a787817aa14623b6110963981bbb857966aab62d72158522507
MD5 083b7926e5b27db509c6845f413cb797
BLAKE2b-256 9f98c6c1dcd30e8c154c78d0063a99879cb5cfdf205882c8b33037e9d77ed2e1

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 42181069e76d3bb3ce318993282659a987389eda62b33c9661dd5ccac0e758df
MD5 3d3cd5a2515799f0f7049c0334f9222b
BLAKE2b-256 9f16c76be681c70264b49d5641b3a91bff7a337e0b2291ec50468f112eda0b4c

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 81f700bad3258a502a6ecd0e610b463f903d5e0dc2982cd748268ddf1b43d80c
MD5 23b055c35b60aa6b4eed6e706c5fbbb6
BLAKE2b-256 3cf583fc6cbcd78d8ee1c59c29cc5b534f3ce94591a44fa0a49f144b555a5cb1

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: pelutils-3.8.0-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 91.2 kB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pelutils-3.8.0-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 664b2451d4d7a4aba3671c2714d82e22b7b30f34c5a88d73fbe980bf11ad7190
MD5 df6bfebc3aecbddda78be8f9215a7e06
BLAKE2b-256 b15d873a3c1a5bd80e3f3cc6da8a75f2f4b9779f4430738c43c50f72e1be8c2b

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 71fc318b7463b0f1320154d2f58ef86b35f7424dbf69dd4f4ad93b86586f5149
MD5 66f8988c1afa282644ec658223805a7e
BLAKE2b-256 5d12c4596d5665d9ee48c580b65f5c895e24bfe8e04b5436e9d568a91fcb3033

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 4a28dea62926034fb384931847281f59a6d975fcf4cd3e7c54126638e1bebfdb
MD5 7fd5e19c8064f4b75afb8f8df15432e8
BLAKE2b-256 985151d4cf660e00edfbe38fa53c0bbd7be1825b167e8b91c5174db875fbb23e

See more details on using hashes here.

File details

Details for the file pelutils-3.8.0-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for pelutils-3.8.0-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a864d7b3c402a60a5dea4ffa3bdbbb1bdaba1c9b0e523a0a36d9b9997d88b4b5
MD5 5f9d8096064fb51569aa5fd2bbfb053e
BLAKE2b-256 2640c2c0113ec7081ce32050095759b9616452298e4cddda27634e5556988697

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page