Skip to main content

py-geometry-utils

Provides utilities for working with coordinates, rectangles, and grids.

[!WARNING] This library is still in beta, breaking changes between releases are likely for 0.x versions.

Initially part of a different project, I wanted to use it in a few other projects so I decided to separate it out into its own package.

PyPI: https://pypi.org/project/py-geometry-utils/

Documentation: https://py-geometry-utils.readthedocs.io/en/latest/

Changelog: https://github.com/svioletg/py-geometry-utils/blob/main/CHANGELOG.md

Usage

Install with pip or include as a dependency as py-geometry-utils, the package will be available as the geometry module.

Construct a 2D coordinate: Coord2(1, 2)

Construct a rectangle: Rect(0, 0, 10, 10)

Construct a 2D grid: Grid2(-10, -10, 10, 10, step=(1, 1), origin=(0, 0)) (step and origin optional, defaults to Coord2(1, 1) and the center coordinate of the rectangle respectively)

Features

Immutability

All geometry classes are immutable by default, meaning their attributes (such as x and y) cannot be reassigned after constructing the instance.

p = Coord2(0, 0)
p.x = 1
# TypeError: Cannot modify attribute of immutable Coord2 instance

r = Rect(0, 0, 10, 10)
r.x1 = 1
# TypeError: Cannot modify attribute of immutable Rect instance

g = Grid2(-10, -10, 10, 10, step=(1, 1), origin=(0, 0))
g.step = Coord2(2, 2)
# TypeError: Cannot modify attribute of immutable Coord2 instance

To make them mutable, mut=True must be passed to their constructors:

p = Coord2(0, 0, mut=True)
p.x = 1
assert p.x == 1

r = Rect(0, 0, 10, 10, mut=True)
r.x1 = 1
assert r.x1 == 1

g = Grid2(-10, -10, 10, 10, step=(1, 1), origin=(0, 0), mut=True)
g.step = Coord2(2, 2)
assert g.step == Coord2(2, 2)

When Grid2 is constructed with mut=False, the passed step and origin values are always copied as new immutable Coord2 instances. Otherwise, the objects are used as-is if they are already Coord2 instances (meaning in Grid2(..., step=Coord2(1, 1, mut=False), mut=True) the step value will maintain its immutability); if they're tuples, they are converted to new mutable Coord2 objects.

Type coercion

All Coord2 and Rect methods which take a second coordinate or rectangle as an argument will also accept their respective tuple of values. If a method's argument takes Coord2, it will also accept tuple[float, float]; if it takes Rect, it will accept tuple[float, float, float, float].

assert Coord2(0, 0).distance(Coord2(10, 10)) == 20
assert Coord2(0, 0).distance((10, 10)) == 20

Grid2.step and Grid2.origin's setters will accept a plain tuple of two numbers in addition to a Coord2 instance, those values being converted to Coord2 implicitly:

g = Grid2(-10, -10, 10, 10, mut=True)
g.step = (10, 10)
# g.step == Coord2(10, 10)

Math & other combining operations

Coord2 supports the operators +, -, *, /, //, %, and ** between either other Coord2 instances, tuple[float, float], or single numbers (which gets treated as (n, n)).

assert Coord2(1, 1) + 1 == Coord2(2, 2)
assert Coord2(1, 1) + (1, 2) == Coord2(2, 4)
assert Coord2(1, 1) + Coord2(1, 2) == Coord2(2, 4)

assert Coord2(1, 1) - 1 == Coord2(0, 0)
assert Coord2(1, 1) - (1, 2) == Coord2(0, -1)
assert Coord2(1, 1) - Coord2(1, 2) == Coord2(0, -1)

# and so on...

You can also use the Coord2.zip_with() method to combine two coordinates together using a given function, where a new Coord2 instance is constructed using the result of applying fn to both original coordinates' x and y values individually:

assert Coord2(0, 1).zip_with(max, (1, 0)) == Coord2(1, 1)

Coord2.map() returns a new Coord2 applying a function to the original coordinates' values:

assert Coord2(1, 2).map(lambda n: (n * 10) if n % 2 == 0 else (n / 10)) == Coord2(0.1, 20)

Coord2.as_tuple() by default returns the x and y values of a coordinate as a simple tuple, but can optionally take a function argument to transform those values before returning it:

assert Coord2(1, 2).as_tuple() == (1, 2)
assert Coord2(1, 2).as_tuple(str) == ('1', '2')

Rect and Grid2 also have as_tuple, map, and zip_with methods that behave the same way with their respective classes. Grid2 is a subclass of Rect and so simply inherits the former two methods, but has its own implementation of zip_with which allows specifying the step and origin values to set for the returned new instance.

Copying

Coord2, Rect, and Grid2 all implement __copy__ by having it return a new instance with the same coordinate values, with Grid2.__copy__() also copying the step and origin values (which are Coord2 instances, so Coord2.__copy__() is invoked for them).

Iteration & other magic method implementations

Coord2, Rect, and Grid2 all support both __iter__ and __getitem__. __iter__ yields the coordinate values for the class, meaning x and y for Coord2, and x1, y1, x2, and y2 for Rect and Grid2. This is also the order of attributes returned for as_tuple() on each of these classes. __getitem__ acts as a shortcut for .as_tuple()[n].

Comparing

All classes support ==, comparing each instance's coordinate values. They can also be compared with tuples:

assert Coord2(1, 2) == Coord2(1, 2)
assert Coord2(1, 2) == (1, 2)

assert Rect(0, 0, 10, 10) == Rect(0, 0, 10, 10)
assert Rect(0, 0, 10, 10) == (0, 0, 10, 10)

[!NOTE] Comparing two Grid2 instances will not take into account their step and origin values.

Coord2 additionally supports the >=, >, <=, and < operators, comparing it and another coordinate's values the same way that tuples are compared (e.g. Coord2(x, y) > Coord2(x, y) will always equal the outcome of (x, y) > (x, y)).

Release files for py-geometry-utils 0.8.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 py-geometry-utils 0.8.0
File Size Uploaded
py_geometry_utils-0.8.0.tar.gz 71.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for py-geometry-utils 0.8.0
File Interpreter ABI Platform
py_geometry_utils-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 85.0 kB

Release files / py_geometry_utils-0.8.0.tar.gz

Download URL py_geometry_utils-0.8.0.tar.gz
Size 71.2 kB
Tags Source
SHA-256 checksum
How to use checksums
46cbd4a78c77c8362db4bcd7733fa80e848cf7793a8461ac2a5793ee642eec63
BLAKE2b-256 checksum
How to use checksums
d2fcc22180731474331f445e10455eb8713bb11aac82824cfef9c87993ac78dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Release files / py_geometry_utils-0.8.0-py3-none-any.whl

Download URL py_geometry_utils-0.8.0-py3-none-any.whl
Size 13.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
939d5f1e92347923241aff51943bd2c79b133b375ca52e7e978fee8b78902071
BLAKE2b-256 checksum
How to use checksums
1328f5d53ba638299eac6a94ec69839a8bd776382196f429bba16310ee0f5674
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

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