rangeslib 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. rangeslib-0.6.0/LICENSE +21 -0
  2. rangeslib-0.6.0/MANIFEST.in +7 -0
  3. rangeslib-0.6.0/PKG-INFO +205 -0
  4. rangeslib-0.6.0/README.md +166 -0
  5. rangeslib-0.6.0/docs/api.rst +27 -0
  6. rangeslib-0.6.0/docs/architecture.md +281 -0
  7. rangeslib-0.6.0/docs/changelog.md +151 -0
  8. rangeslib-0.6.0/docs/conf.py +28 -0
  9. rangeslib-0.6.0/docs/contributing.md +228 -0
  10. rangeslib-0.6.0/docs/cpp-comparison.md +59 -0
  11. rangeslib-0.6.0/docs/index.rst +28 -0
  12. rangeslib-0.6.0/docs/migration.md +55 -0
  13. rangeslib-0.6.0/docs/publishing.md +40 -0
  14. rangeslib-0.6.0/docs/roadmap.md +34 -0
  15. rangeslib-0.6.0/docs/usage.md +164 -0
  16. rangeslib-0.6.0/playground.py +37 -0
  17. rangeslib-0.6.0/pyproject.toml +82 -0
  18. rangeslib-0.6.0/requirements.txt +2 -0
  19. rangeslib-0.6.0/scripts/benchmark.py +47 -0
  20. rangeslib-0.6.0/scripts/check.sh +22 -0
  21. rangeslib-0.6.0/scripts/check_all.sh +14 -0
  22. rangeslib-0.6.0/scripts/check_package.sh +37 -0
  23. rangeslib-0.6.0/scripts/format.sh +15 -0
  24. rangeslib-0.6.0/scripts/generate_docs.sh +9 -0
  25. rangeslib-0.6.0/scripts/run_playground.sh +8 -0
  26. rangeslib-0.6.0/scripts/run_tests.sh +8 -0
  27. rangeslib-0.6.0/scripts/typecheck.sh +15 -0
  28. rangeslib-0.6.0/setup.cfg +4 -0
  29. rangeslib-0.6.0/src/rangeslib/__init__.py +8 -0
  30. rangeslib-0.6.0/src/rangeslib/_adaptors.py +396 -0
  31. rangeslib-0.6.0/src/rangeslib/_core.py +98 -0
  32. rangeslib-0.6.0/src/rangeslib/_generators.py +42 -0
  33. rangeslib-0.6.0/src/rangeslib/py.typed +0 -0
  34. rangeslib-0.6.0/src/rangeslib/ranges.py +32 -0
  35. rangeslib-0.6.0/src/rangeslib/views.py +349 -0
  36. rangeslib-0.6.0/src/rangeslib.egg-info/PKG-INFO +205 -0
  37. rangeslib-0.6.0/src/rangeslib.egg-info/SOURCES.txt +42 -0
  38. rangeslib-0.6.0/src/rangeslib.egg-info/dependency_links.txt +1 -0
  39. rangeslib-0.6.0/src/rangeslib.egg-info/requires.txt +19 -0
  40. rangeslib-0.6.0/src/rangeslib.egg-info/top_level.txt +1 -0
  41. rangeslib-0.6.0/tests/test_public_api.py +255 -0
  42. rangeslib-0.6.0/tests/test_range.py +334 -0
  43. rangeslib-0.6.0/tests/test_range_collection.py +66 -0
  44. rangeslib-0.6.0/tests/typecheck/public_api.py +37 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aaryan Banerjee
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ include LICENSE
2
+ include README.md
3
+ include requirements.txt
4
+ include playground.py
5
+ recursive-include scripts *.py *.sh
6
+ recursive-include docs *.md *.rst *.py
7
+ recursive-include tests *.py
@@ -0,0 +1,205 @@
1
+ Metadata-Version: 2.4
2
+ Name: rangeslib
3
+ Version: 0.6.0
4
+ Summary: Composable, typed Python ranges and iterable adaptors
5
+ Author: Aaryan Banerjee
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/TheUltimateOrion/RangesLib
8
+ Project-URL: Documentation, https://theultimateorion.github.io/RangesLib/
9
+ Project-URL: Repository, https://github.com/TheUltimateOrion/RangesLib.git
10
+ Project-URL: Issues, https://github.com/TheUltimateOrion/RangesLib/issues
11
+ Keywords: ranges,iterables,pipelines,functional,typing
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Typing :: Typed
19
+ Requires-Python: >=3.12
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Provides-Extra: docs
23
+ Requires-Dist: myst-parser>=4; extra == "docs"
24
+ Requires-Dist: sphinx>=8; extra == "docs"
25
+ Requires-Dist: sphinx-autodoc-typehints>=3; extra == "docs"
26
+ Provides-Extra: test
27
+ Requires-Dist: coverage[toml]>=7.6; extra == "test"
28
+ Provides-Extra: dev
29
+ Requires-Dist: build>=1.2; extra == "dev"
30
+ Requires-Dist: coverage[toml]>=7.6; extra == "dev"
31
+ Requires-Dist: mypy>=1.15; extra == "dev"
32
+ Requires-Dist: myst-parser>=4; extra == "dev"
33
+ Requires-Dist: pre-commit>=4.0; extra == "dev"
34
+ Requires-Dist: pyright>=1.1.400; extra == "dev"
35
+ Requires-Dist: ruff>=0.9; extra == "dev"
36
+ Requires-Dist: sphinx>=8; extra == "dev"
37
+ Requires-Dist: sphinx-autodoc-typehints>=3; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # rangeslib
41
+
42
+ [![Tests and quality](https://github.com/TheUltimateOrion/RangesLib/actions/workflows/tests.yml/badge.svg)](https://github.com/TheUltimateOrion/RangesLib/actions/workflows/tests.yml)
43
+ [![Documentation](https://github.com/TheUltimateOrion/RangesLib/actions/workflows/docs.yml/badge.svg)](https://theultimateorion.github.io/RangesLib/)
44
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue)](https://www.python.org/)
45
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
46
+
47
+ `rangeslib` is a typed Python library for eager, C++-inspired range pipelines.
48
+ The public API is intentionally small:
49
+
50
+ ```python
51
+ from rangeslib import ranges, views
52
+ ```
53
+
54
+ The mental model is:
55
+
56
+ ```text
57
+ ranges creates values
58
+ views transforms values
59
+ views.to converts the final result
60
+ ```
61
+
62
+ ## Quick Start
63
+
64
+ ```python
65
+ from rangeslib import ranges, views
66
+
67
+ result = (
68
+ ranges.iota(1, 11)
69
+ | views.filter(lambda value: value % 2 == 0)
70
+ | views.transform(lambda value: value * 10)
71
+ | views.take(3)
72
+ | views.to(list)
73
+ )
74
+
75
+ assert result == [20, 40, 60]
76
+ ```
77
+
78
+ `Range` values are eager and reusable. Most adaptors return another `Range`; the
79
+ terminal `views.to(...)` adaptor returns whatever collection or factory you ask
80
+ for.
81
+
82
+ ## Existing Iterables
83
+
84
+ Ordinary Python iterables can start pipelines too:
85
+
86
+ ```python
87
+ from rangeslib import views
88
+
89
+ text = "abcdef" | views.take(3) | views.to("".join)
90
+ assert text == "abc"
91
+
92
+ chars = "abc" | views.all()
93
+ assert list(chars) == ["a", "b", "c"]
94
+ ```
95
+
96
+ `views.all()` is the eager Python counterpart to C++ `views::all`: it adapts an
97
+ existing iterable into a reusable `Range`.
98
+
99
+ ## Reusable Pipelines
100
+
101
+ Adaptors can be composed before data is supplied:
102
+
103
+ ```python
104
+ from rangeslib import views
105
+
106
+ first_three_even = views.filter(lambda value: value % 2 == 0) | views.take(3)
107
+
108
+ assert list([1, 2, 3, 4, 5, 6] | first_three_even) == [2, 4, 6]
109
+ assert list([10, 11, 12, 14] | first_three_even) == [10, 12, 14]
110
+ ```
111
+
112
+ ## Sources And Views
113
+
114
+ The `ranges` facade creates source ranges:
115
+
116
+ ```python
117
+ from rangeslib import ranges
118
+
119
+ ranges.empty()
120
+ ranges.single("value")
121
+ ranges.iota(1, 5)
122
+ ranges.indices(3)
123
+ ranges.repeat("x", 3)
124
+ ```
125
+
126
+ The `views` facade contains transformations such as:
127
+
128
+ ```text
129
+ all, reverse, filter, transform, take, drop, counted,
130
+ elements, keys, values, enumerate, concat, zip, cartesian_product,
131
+ adjacent, pairwise, chunk, slide, stride, join, split, to
132
+ ```
133
+
134
+ See [docs/usage.md](docs/usage.md) for the full API catalog.
135
+
136
+ ## C++ Ranges Correspondence
137
+
138
+ `rangeslib` borrows naming and broad behavior from C++20/23/26 ranges, but it
139
+ is not a lazy C++ view implementation. The most important differences are:
140
+
141
+ - Python iterables replace C++ iterator/sentinel pairs.
142
+ - `Range` stores eager values instead of reference-like lazy views.
143
+ - Tuple results are ordinary Python tuples, not tuples of references.
144
+ - Python type checking is useful but cannot express every C++ tuple-like rule.
145
+
146
+ See [docs/cpp-comparison.md](docs/cpp-comparison.md) for details.
147
+
148
+ ## Installation
149
+
150
+ Python 3.12 or newer is required.
151
+
152
+ ```bash
153
+ python -m pip install .
154
+ ```
155
+
156
+ For development:
157
+
158
+ ```bash
159
+ python -m pip install -e ".[dev]"
160
+ ```
161
+
162
+ `rangeslib` has no runtime dependencies.
163
+
164
+ ## Development
165
+
166
+ Useful commands live in `scripts/`:
167
+
168
+ ```bash
169
+ ./scripts/run_tests.sh # tests only
170
+ ./scripts/typecheck.sh # mypy + Pyright
171
+ ./scripts/check.sh # Ruff, typing, tests, coverage
172
+ ./scripts/check_all.sh # check.sh + strict Sphinx docs
173
+ ./scripts/check_package.sh # sdist/wheel build and install smoke test
174
+ ./scripts/run_playground.sh # manual playground
175
+ ```
176
+
177
+ Before a release commit, run:
178
+
179
+ ```bash
180
+ ./scripts/check_all.sh
181
+ ./scripts/check_package.sh
182
+ ```
183
+
184
+ ## Documentation
185
+
186
+ Build the Sphinx site with:
187
+
188
+ ```bash
189
+ ./scripts/generate_docs.sh
190
+ ```
191
+
192
+ Generated HTML is written to `docs/_build/html/` and published to GitHub Pages
193
+ after CI succeeds on `main`.
194
+
195
+ ## Releases
196
+
197
+ Changing `[project].version` in `pyproject.toml` on `main` automatically runs
198
+ the complete quality and package checks, then creates the matching Git tag and
199
+ GitHub Release. Published GitHub Releases trigger PyPI publishing through
200
+ Trusted Publishing after the PyPI project is configured.
201
+
202
+ For future work, prefer opening or collecting issues before adding more adaptors
203
+ immediately. See [docs/roadmap.md](docs/roadmap.md).
204
+
205
+ See [docs/publishing.md](docs/publishing.md) for the PyPI setup checklist.
@@ -0,0 +1,166 @@
1
+ # rangeslib
2
+
3
+ [![Tests and quality](https://github.com/TheUltimateOrion/RangesLib/actions/workflows/tests.yml/badge.svg)](https://github.com/TheUltimateOrion/RangesLib/actions/workflows/tests.yml)
4
+ [![Documentation](https://github.com/TheUltimateOrion/RangesLib/actions/workflows/docs.yml/badge.svg)](https://theultimateorion.github.io/RangesLib/)
5
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue)](https://www.python.org/)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE)
7
+
8
+ `rangeslib` is a typed Python library for eager, C++-inspired range pipelines.
9
+ The public API is intentionally small:
10
+
11
+ ```python
12
+ from rangeslib import ranges, views
13
+ ```
14
+
15
+ The mental model is:
16
+
17
+ ```text
18
+ ranges creates values
19
+ views transforms values
20
+ views.to converts the final result
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```python
26
+ from rangeslib import ranges, views
27
+
28
+ result = (
29
+ ranges.iota(1, 11)
30
+ | views.filter(lambda value: value % 2 == 0)
31
+ | views.transform(lambda value: value * 10)
32
+ | views.take(3)
33
+ | views.to(list)
34
+ )
35
+
36
+ assert result == [20, 40, 60]
37
+ ```
38
+
39
+ `Range` values are eager and reusable. Most adaptors return another `Range`; the
40
+ terminal `views.to(...)` adaptor returns whatever collection or factory you ask
41
+ for.
42
+
43
+ ## Existing Iterables
44
+
45
+ Ordinary Python iterables can start pipelines too:
46
+
47
+ ```python
48
+ from rangeslib import views
49
+
50
+ text = "abcdef" | views.take(3) | views.to("".join)
51
+ assert text == "abc"
52
+
53
+ chars = "abc" | views.all()
54
+ assert list(chars) == ["a", "b", "c"]
55
+ ```
56
+
57
+ `views.all()` is the eager Python counterpart to C++ `views::all`: it adapts an
58
+ existing iterable into a reusable `Range`.
59
+
60
+ ## Reusable Pipelines
61
+
62
+ Adaptors can be composed before data is supplied:
63
+
64
+ ```python
65
+ from rangeslib import views
66
+
67
+ first_three_even = views.filter(lambda value: value % 2 == 0) | views.take(3)
68
+
69
+ assert list([1, 2, 3, 4, 5, 6] | first_three_even) == [2, 4, 6]
70
+ assert list([10, 11, 12, 14] | first_three_even) == [10, 12, 14]
71
+ ```
72
+
73
+ ## Sources And Views
74
+
75
+ The `ranges` facade creates source ranges:
76
+
77
+ ```python
78
+ from rangeslib import ranges
79
+
80
+ ranges.empty()
81
+ ranges.single("value")
82
+ ranges.iota(1, 5)
83
+ ranges.indices(3)
84
+ ranges.repeat("x", 3)
85
+ ```
86
+
87
+ The `views` facade contains transformations such as:
88
+
89
+ ```text
90
+ all, reverse, filter, transform, take, drop, counted,
91
+ elements, keys, values, enumerate, concat, zip, cartesian_product,
92
+ adjacent, pairwise, chunk, slide, stride, join, split, to
93
+ ```
94
+
95
+ See [docs/usage.md](docs/usage.md) for the full API catalog.
96
+
97
+ ## C++ Ranges Correspondence
98
+
99
+ `rangeslib` borrows naming and broad behavior from C++20/23/26 ranges, but it
100
+ is not a lazy C++ view implementation. The most important differences are:
101
+
102
+ - Python iterables replace C++ iterator/sentinel pairs.
103
+ - `Range` stores eager values instead of reference-like lazy views.
104
+ - Tuple results are ordinary Python tuples, not tuples of references.
105
+ - Python type checking is useful but cannot express every C++ tuple-like rule.
106
+
107
+ See [docs/cpp-comparison.md](docs/cpp-comparison.md) for details.
108
+
109
+ ## Installation
110
+
111
+ Python 3.12 or newer is required.
112
+
113
+ ```bash
114
+ python -m pip install .
115
+ ```
116
+
117
+ For development:
118
+
119
+ ```bash
120
+ python -m pip install -e ".[dev]"
121
+ ```
122
+
123
+ `rangeslib` has no runtime dependencies.
124
+
125
+ ## Development
126
+
127
+ Useful commands live in `scripts/`:
128
+
129
+ ```bash
130
+ ./scripts/run_tests.sh # tests only
131
+ ./scripts/typecheck.sh # mypy + Pyright
132
+ ./scripts/check.sh # Ruff, typing, tests, coverage
133
+ ./scripts/check_all.sh # check.sh + strict Sphinx docs
134
+ ./scripts/check_package.sh # sdist/wheel build and install smoke test
135
+ ./scripts/run_playground.sh # manual playground
136
+ ```
137
+
138
+ Before a release commit, run:
139
+
140
+ ```bash
141
+ ./scripts/check_all.sh
142
+ ./scripts/check_package.sh
143
+ ```
144
+
145
+ ## Documentation
146
+
147
+ Build the Sphinx site with:
148
+
149
+ ```bash
150
+ ./scripts/generate_docs.sh
151
+ ```
152
+
153
+ Generated HTML is written to `docs/_build/html/` and published to GitHub Pages
154
+ after CI succeeds on `main`.
155
+
156
+ ## Releases
157
+
158
+ Changing `[project].version` in `pyproject.toml` on `main` automatically runs
159
+ the complete quality and package checks, then creates the matching Git tag and
160
+ GitHub Release. Published GitHub Releases trigger PyPI publishing through
161
+ Trusted Publishing after the PyPI project is configured.
162
+
163
+ For future work, prefer opening or collecting issues before adding more adaptors
164
+ immediately. See [docs/roadmap.md](docs/roadmap.md).
165
+
166
+ See [docs/publishing.md](docs/publishing.md) for the PyPI setup checklist.
@@ -0,0 +1,27 @@
1
+ API reference
2
+ =============
3
+
4
+ The supported application-facing API consists of :class:`rangeslib.Range`,
5
+ :mod:`rangeslib.ranges`, and :mod:`rangeslib.views`. Modules beginning with an
6
+ underscore are private implementation details.
7
+
8
+ Core container
9
+ --------------
10
+
11
+ .. autoclass:: rangeslib.Range
12
+ :members: copy, is_empty
13
+ :show-inheritance:
14
+
15
+ Generator facade
16
+ ----------------
17
+
18
+ .. automodule:: rangeslib.ranges
19
+ :members:
20
+ :undoc-members:
21
+
22
+ View facade
23
+ -----------
24
+
25
+ .. automodule:: rangeslib.views
26
+ :members:
27
+ :undoc-members: