LoopInt
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
intin:- comparisons
- hashing
- indexing (
__index__) - formatting (
__format__) int()conversion
- Safe arithmetic:
LoopInt + intsupportedLoopInt += intsupported- Adding two
LoopIntobjects 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 boundleft— 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)
| File | Size | Uploaded | |
|---|---|---|---|
| loopint-1.0.tar.gz | 5.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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}
|