Skip to main content

LoopInt

PyPI version Python versions Tests Coverage License Typing Downloads Ruff Linter & Formatter basedpyright

LoopInt is a lightweight Python library that provides a cyclic integer type with precise range semantics [left; right) and natural integer-like behavior.

It behaves like a regular integer but wraps around within a fixed interval. This makes it useful for cyclic counters, circular buffers, modular arithmetic, clock-like values, and more.


🔧 Features

  • Fixed interval semantics: [left; right)
  • Modular wrap-around on +, -, +=, -=
  • Behaves like int in:
    • comparisons
    • hashing
    • indexing (__index__)
    • formatting (__format__)
    • int() conversion
  • Safe arithmetic:
    • LoopInt + int supported
    • LoopInt += int supported
    • Adding two LoopInt objects is intentionally forbidden
  • Fully typed (Python ≥ 3.12)

📦 Installation

pip install loopint

Or with uv:

uv add loopint

🚀 Usage

from loopint import LoopInt

x = LoopInt(0, right=5)

print(int(x))      # 0

x += 7
print(int(x))      # 2   (wrap-around: 7 % 5 == 2)

y = x + 10
print(int(y))      # 2   (non-mutating)

assert x == 2
assert y == x

Custom range

x = LoopInt(0, right=2, left=-1)
print(int(x))  # 0

x += 1
print(int(x))  # 1

x += 2         # wraps in [-1; 2)
print(int(x))  # 0

📚 API Overview

LoopInt(current, /, right, *, left=0)

Create a cyclic integer constrained to the interval [left; right) with modular wrap-around.

Parameters:

  • current — initial value (any integer-like object supporting __index__)
  • right — exclusive upper bound
  • left — inclusive lower bound (default: 0)

Interval semantics:

value ∈ [left; right)
span = right − left
value = left + ((current − left) mod span)

🔹 Properties

value: int

Returns the visible integer value of the LoopInt instance.

Equivalent to:

int(loopint_instance)

Example:

x = LoopInt(5, right=8, left=2)
assert x.value == 5

left: int

Returns the inclusive lower bound of the interval.

Example:

LoopInt(0, right=5, left=-2).left  # → -2

right: int

Returns the exclusive upper bound of the interval.

Example:

LoopInt(0, right=5).right  # → 5

span: int

Size of the interval:

span = right - left

Example:

LoopInt(0, right=5, left=2).span  # → 3

🔹 Methods

to_string() -> str

Return the value as a string. Equivalent to:

str(int(self))

Example:

x = LoopInt(4, right=10)
x.to_string()   # → "4"

Arithmetic

__add__(other) -> LoopInt

Non-mutating addition with wrap-around.

x + n  # returns a new LoopInt

__iadd__(other) -> Self

In-place addition (+=) with wrap-around.

x += 3

__sub__(other) -> LoopInt

Non-mutating subtraction.


__isub__(other) -> Self

In-place subtraction (-=).

__neg__() -> LoopInt

Modular negation:

int(-x) == (-int(x)) mod span

Example:

x = LoopInt(1, right=5)
y = -x      # → 4

__radd__(other) -> LoopInt

Enables: int + LoopInt.

Example:

3 + LoopInt(2, right=5)  # → 0

__rsub__(other) -> LoopInt

Implements: other - self using modular arithmetic.

other - x == -(x - other)

Example:

3 - LoopInt(1, right=5)   # → 2
0 - LoopInt(1, right=5)   # → 4

Comparison & hashing

__eq__(other)

LoopInt compares equal to anything whose integer value equals int(self).

Examples:

LoopInt(0, right=5) == 0            # True
LoopInt(3, right=10) == LoopInt(3, right=100)  # True

__hash__() -> int

Hash is consistent with int(self):

hash(LoopInt(3, right=10)) == hash(3)

🧪 Testing

pytest .

Both unit tests and property-based tests (Hypothesis) are included.


📄 License

MIT License.


🤝 Contributing

Contributions are welcome! Feel free to open issues or pull requests.

Metadata

Release files for loopint 1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for loopint 1.0
File Size Uploaded
loopint-1.0.tar.gz 5.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for loopint 1.0
File Interpreter ABI Platform
loopint-1.0-py3-none-any.whl Python 3 none any Details

Total release size: 10.4 kB

Release files / loopint-1.0.tar.gz

Download URL loopint-1.0.tar.gz
Size 5.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ce7c2299ca2b14805f05fa65b26dc7591d9010da22e73e3a05df433ce135a4df
BLAKE2b-256 checksum
How to use checksums
46010be84d2981d95ea87596c99b3579de30a5af2802ef1d24e002698e386923
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / loopint-1.0-py3-none-any.whl

Download URL loopint-1.0-py3-none-any.whl
Size 5.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
653e377ccb0eb93577bec1079253daa5dad0e500b98274fb110d7559d8ab764c
BLAKE2b-256 checksum
How to use checksums
4f486b689a29e5439bbaabc27bf275e1659e84353d4e13c04abc90501d7da8c5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.13 {"installer":{"name":"uv","version":"0.9.13"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page