https://github.com/pushfoo/python-better-sum
Python's sum, minus ugly annotations and extra arguments.
https://github.com/pushfoo/python-better-sum
python standard-library sum type-annotations
Last synced: 15 days ago
JSON representation
Python's sum, minus ugly annotations and extra arguments.
- Host: GitHub
- URL: https://github.com/pushfoo/python-better-sum
- Owner: pushfoo
- License: bsd-2-clause
- Created: 2024-07-14T19:24:35.000Z (over 1 year ago)
- Default Branch: development
- Last Pushed: 2025-07-04T03:45:28.000Z (7 months ago)
- Last Synced: 2026-01-03T08:36:00.098Z (about 1 month ago)
- Topics: python, standard-library, sum, type-annotations
- Language: Python
- Homepage:
- Size: 59.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: docs/contributing.md
- License: LICENSE
Awesome Lists containing this project
README
# better-sum
[](https://opensource.org/licenses/BSD-2-Clause)
[](https://makeapullrequest.com)


[sum]: https://docs.python.org/3/library/functions.html#sum
[mkdocs]: https://www.mkdocs.org/
[typing-extensions]: https://pypi.org/project/typing-extensions/
[decorator]: docs/usage.md#decorator
[class attribute]: docs/usage.md#a-class-attribute
Python's [sum][], minus ugly annotations and extra arguments.
## Project goals
- [x] Prototype a cleaner [sum][]
- [x] Try [mkdocs][]
## Quickstart
1. Create a virtual environment with Python 3.9+
2. `pip install better-sum`
3. Try the code below
```python
from __future__ import annotations # Allows forward references on Python < 3.11
from typing import NamedTuple
from better_sum import sum, sum_starts_at_instance
@sum_starts_at_instance(0.0, 0.0) # 1. Create & store a default instance
class Vec2(NamedTuple):
x: float = 0.0
y: float = 0.0
def __add__(self, other: tuple[float, float]) -> Vec2:
other_x, other_y = other
return self.__class__(self.x + other_x, self.y + other_y)
def __radd__(self, other: tuple[float, float]) -> Vec2:
other_x, other_y = other
return self.__class__(other_x + self.x, other_y + self.y)
# 2. better_sum.sum automatically starts at the default instance
to_sum = [Vec2(0.0, 0.0), Vec2(1.0, 1.0), Vec2(2.0, 2.0)]
print(sum(to_sum))
```
As expected, this will print:
```
Vec(x=3.0, y=3.0)
```
[release]: https://better-sum.readthedocs.io/en/latest/
[development-branch]: https://better-sum.readthedocs.io/en/development/
[Contributing]: https://better-sum.readthedocs.io/en/development/contributing/
## Documentation
| [`release` branch][release] | [`development` branch][development-branch] | [Contributing Guide][Contributing] |
|-------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------|
| [](https://better-sum.readthedocs.io/en/latest/?badge=main) | [](https://better-sum.readthedocs.io/en/development/?badge=development) | Same as `development` |
## What's wrong with Python's sum?
It complicates code.
```python
# The bad: verbose calls
sum(iterable, start_value)
# The ugly: gross type annotations
class SupportsSum:
# int is ugly
def __radd__(self, other: int | SupportsSum):
if other == 0:
return self
...
```
## What's the catch?
[pyglet]: https://pyglet.readthedocs.io/en/latest/
A potential speed hit from indirection.
If it's a concern, then one of two things is true:
1. You should be using binary-backed acceleration
2. You're writing code for one of the following:
* [pyglet][] or another pure-Python project
* fallback code for when binary acceleration isn't available