immlib 1.0.0.dev2__tar.gz → 1.0.0rc2__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.
- {immlib-1.0.0.dev2/src/immlib.egg-info → immlib-1.0.0rc2}/PKG-INFO +48 -13
- immlib-1.0.0rc2/README.md +58 -0
- immlib-1.0.0rc2/pyproject.toml +95 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/__init__.py +22 -30
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/_version.py +70 -56
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/iolib/__init__.py +3 -9
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/iolib/_core.py +133 -66
- immlib-1.0.0rc2/src/immlib/math/__init__.py +348 -0
- immlib-1.0.0rc2/src/immlib/math/_core.py +3253 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/pathlib/__init__.py +0 -5
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/pathlib/_cache.py +23 -15
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/pathlib/_core.py +88 -87
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/pathlib/_osf.py +94 -42
- immlib-1.0.0rc2/src/immlib/py.typed +0 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/test/__init__.py +3 -2
- immlib-1.0.0rc2/src/immlib/test/concurrency/__init__.py +8 -0
- immlib-1.0.0rc2/src/immlib/test/concurrency/test_threads.py +537 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/test/iolib/__init__.py +2 -2
- immlib-1.0.0rc2/src/immlib/test/iolib/test_core.py +539 -0
- immlib-1.0.0rc2/src/immlib/test/math/__init__.py +9 -0
- immlib-1.0.0rc2/src/immlib/test/math/test_math.py +1089 -0
- immlib-1.0.0rc2/src/immlib/test/math/test_rules.py +552 -0
- immlib-1.0.0rc2/src/immlib/test/pathlib/__init__.py +12 -0
- immlib-1.0.0rc2/src/immlib/test/pathlib/_osf_fixture.py +98 -0
- immlib-1.0.0rc2/src/immlib/test/pathlib/test_cache.py +244 -0
- immlib-1.0.0rc2/src/immlib/test/pathlib/test_core.py +347 -0
- immlib-1.0.0rc2/src/immlib/test/pathlib/test_osf.py +225 -0
- immlib-1.0.0rc2/src/immlib/test/test_version.py +197 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/test/util/__init__.py +3 -0
- immlib-1.0.0rc2/src/immlib/test/util/test_arrayindex.py +139 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/test/util/test_core.py +29 -1
- immlib-1.0.0rc2/src/immlib/test/util/test_docs.py +211 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/test/util/test_numeric.py +122 -14
- immlib-1.0.0rc2/src/immlib/test/util/test_pint.py +136 -0
- immlib-1.0.0rc2/src/immlib/test/util/test_quantity.py +2675 -0
- immlib-1.0.0rc2/src/immlib/test/workflow/test_core.py +933 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/test/workflow/test_plantype.py +37 -6
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/util/__init__.py +24 -12
- immlib-1.0.0.dev2/src/immlib/types/_core.py → immlib-1.0.0rc2/src/immlib/util/_arrayindex.py +42 -158
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/util/_core.py +240 -194
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/util/_numeric.py +397 -344
- immlib-1.0.0rc2/src/immlib/util/_quantity.py +3415 -0
- immlib-1.0.0rc2/src/immlib/util/_url.py +242 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/workflow/__init__.py +6 -5
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/workflow/_core.py +475 -81
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/workflow/_plantype.py +22 -9
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2/src/immlib.egg-info}/PKG-INFO +48 -13
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib.egg-info/SOURCES.txt +15 -9
- immlib-1.0.0rc2/src/immlib.egg-info/requires.txt +25 -0
- immlib-1.0.0.dev2/README.md +0 -26
- immlib-1.0.0.dev2/pyproject.toml +0 -48
- immlib-1.0.0.dev2/src/immlib/_init.py +0 -108
- immlib-1.0.0.dev2/src/immlib/doc/__init__.py +0 -38
- immlib-1.0.0.dev2/src/immlib/doc/_core.py +0 -311
- immlib-1.0.0.dev2/src/immlib/test/doc/__init__.py +0 -6
- immlib-1.0.0.dev2/src/immlib/test/doc/test_core.py +0 -91
- immlib-1.0.0.dev2/src/immlib/test/iolib/test_core.py +0 -81
- immlib-1.0.0.dev2/src/immlib/test/pathlib/__init__.py +0 -11
- immlib-1.0.0.dev2/src/immlib/test/pathlib/test_core.py +0 -146
- immlib-1.0.0.dev2/src/immlib/test/pathlib/test_osf.py +0 -54
- immlib-1.0.0.dev2/src/immlib/test/types/__init__.py +0 -5
- immlib-1.0.0.dev2/src/immlib/test/types/test_core.py +0 -110
- immlib-1.0.0.dev2/src/immlib/test/util/test_quantity.py +0 -218
- immlib-1.0.0.dev2/src/immlib/test/workflow/test_core.py +0 -418
- immlib-1.0.0.dev2/src/immlib/types/__init__.py +0 -29
- immlib-1.0.0.dev2/src/immlib/util/_quantity.py +0 -523
- immlib-1.0.0.dev2/src/immlib/util/_url.py +0 -114
- immlib-1.0.0.dev2/src/immlib.egg-info/requires.txt +0 -19
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/LICENSE +0 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/setup.cfg +0 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/test/__main__.py +0 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/test/util/test_url.py +0 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib/test/workflow/__init__.py +0 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib.egg-info/dependency_links.txt +0 -0
- {immlib-1.0.0.dev2 → immlib-1.0.0rc2}/src/immlib.egg-info/top_level.txt +0 -0
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: immlib
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: A library of
|
|
3
|
+
Version: 1.0.0rc2
|
|
4
|
+
Summary: A library of utilities for immutable scientific data.
|
|
5
5
|
Author-email: "Noah C. Benson" <nben@uw.edu>
|
|
6
|
-
License: MIT
|
|
6
|
+
License-Expression: MIT
|
|
7
7
|
Project-URL: homepage, https://github.com/noahbenson/immlib
|
|
8
8
|
Project-URL: documentation, https://github.com/noahbenson/immlib
|
|
9
9
|
Project-URL: repository, https://github.com/noahbenson/immlib
|
|
10
10
|
Keywords: persistent,immutable,functional,scientific,workflow
|
|
11
11
|
Classifier: Intended Audience :: Science/Research
|
|
12
12
|
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
14
13
|
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
17
14
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
15
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
19
|
Classifier: Topic :: Software Development
|
|
22
20
|
Classifier: Topic :: Software Development :: Libraries
|
|
23
21
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
@@ -27,25 +25,30 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
27
25
|
Classifier: Operating System :: POSIX
|
|
28
26
|
Classifier: Operating System :: Unix
|
|
29
27
|
Classifier: Operating System :: MacOS
|
|
30
|
-
Requires-Python: >=3.
|
|
28
|
+
Requires-Python: >=3.10
|
|
31
29
|
Description-Content-Type: text/markdown
|
|
32
30
|
License-File: LICENSE
|
|
33
|
-
Requires-Dist: pcollections>=0.
|
|
31
|
+
Requires-Dist: pcollections>=1.0.0rc1
|
|
34
32
|
Requires-Dist: numpy>=1.24.0
|
|
35
|
-
Requires-Dist: scipy>=1.
|
|
36
|
-
Requires-Dist: pint
|
|
37
|
-
Requires-Dist:
|
|
33
|
+
Requires-Dist: scipy>=1.8.0
|
|
34
|
+
Requires-Dist: pint<0.27,>=0.24.0
|
|
35
|
+
Requires-Dist: docshare>=0.2.0
|
|
38
36
|
Requires-Dist: joblib>=1.3.0
|
|
39
|
-
Requires-Dist: cloudpathlib[azure,gs,s3]
|
|
37
|
+
Requires-Dist: cloudpathlib[azure,gs,s3]<0.26,>=0.18.0
|
|
40
38
|
Requires-Dist: pyyaml>=6.0
|
|
41
39
|
Provides-Extra: dev
|
|
42
40
|
Requires-Dist: torch>=2.2.0; extra == "dev"
|
|
41
|
+
Requires-Dist: pandas>=1.5.0; extra == "dev"
|
|
42
|
+
Requires-Dist: mypy>=1.8; extra == "dev"
|
|
43
43
|
Provides-Extra: test
|
|
44
44
|
Requires-Dist: torch>=2.2.0; extra == "test"
|
|
45
|
+
Requires-Dist: pandas>=1.5.0; extra == "test"
|
|
46
|
+
Provides-Extra: pandas
|
|
47
|
+
Requires-Dist: pandas>=1.5.0; extra == "pandas"
|
|
45
48
|
Provides-Extra: docs
|
|
46
49
|
Requires-Dist: torch>=2.2.0; extra == "docs"
|
|
47
|
-
Requires-Dist: jupyter-book>=1.0.0; extra == "docs"
|
|
48
50
|
Requires-Dist: matplotlib>=3.4.0; extra == "docs"
|
|
51
|
+
Requires-Dist: jupyter-book>=2; extra == "docs"
|
|
49
52
|
Dynamic: license-file
|
|
50
53
|
|
|
51
54
|

|
|
@@ -67,6 +70,38 @@ application programming interfaces (APIs) for scientific libraries. The name
|
|
|
67
70
|
immlib comes from the library’s philosophy of using immutable data to simplify
|
|
68
71
|
scientific workflows.
|
|
69
72
|
|
|
73
|
+
## What's in it
|
|
74
|
+
|
|
75
|
+
- **`immlib.workflow`** — immutable workflows built from `calc` units that are
|
|
76
|
+
assembled into `plan` DAGs. Inputs and outputs are tracked and wired up
|
|
77
|
+
automatically, results are computed lazily, and calculations can be cached in
|
|
78
|
+
memory or on disk.
|
|
79
|
+
- **`immlib.pathlib` / `immlib.iolib`** — a single `path` function that resolves
|
|
80
|
+
local and remote paths (S3, Google Storage, Azure, and OSF), downloads remote
|
|
81
|
+
data into a local cache, and `save`/`load` functions that read and write a
|
|
82
|
+
range of file formats.
|
|
83
|
+
- **quantities and units** — `immlib.Quantity` (a `pint.Quantity` that also
|
|
84
|
+
supports having no units at all) and `immlib.math`, a small common namespace
|
|
85
|
+
that operates on quantities, NumPy arrays, and PyTorch tensors alike, so the
|
|
86
|
+
two backends are interchangeable and units are tracked through the
|
|
87
|
+
arithmetic.
|
|
88
|
+
|
|
89
|
+
Alongside these are a set of utilities for testing and coercing types, handling
|
|
90
|
+
persistent and lazy collections, and working with numerical arguments.
|
|
91
|
+
|
|
92
|
+
## Requirements
|
|
93
|
+
|
|
94
|
+
`immlib` supports Python 3.10 through 3.14, including the free-threaded (no-GIL)
|
|
95
|
+
builds, and depends on NumPy, SciPy, Pint, `pcollections`, `docshare`, `joblib`,
|
|
96
|
+
`cloudpathlib`, and PyYAML.
|
|
97
|
+
|
|
98
|
+
PyTorch and pandas are optional. `immlib` never imports PyTorch at import time,
|
|
99
|
+
so it can be used without it (only operations that actually need a tensor
|
|
100
|
+
raise); pandas is needed only by the `csv`/`tsv` save/load formats. See the
|
|
101
|
+
"Stability and Compatibility" page of the
|
|
102
|
+
[documentation](https://noahbenson.github.io/immlib) for the supported version
|
|
103
|
+
ranges of each dependency and what the library promises across releases.
|
|
104
|
+
|
|
70
105
|
`immlib` is heavily based on the library
|
|
71
106
|
[`pimms`](https://github.com/noahbenson/pimms), which effectively served as a
|
|
72
107
|
prototype for `immlib`. Both libraries were motivated by a number of observations
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
[](https://codecov.io/gh/noahbenson/immlib)
|
|
5
|
+
[](https://badge.fury.io/py/immlib)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
**Author**: Noah C. Benson <[nben@uw.edu](mailto:nben@uw.edu)>
|
|
10
|
+
**License**: MIT
|
|
11
|
+
**[Documentation](https://noahbenson.github.io/immlib)**
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
`immlib` is a lightweight Python library that simplifies the design of
|
|
16
|
+
application programming interfaces (APIs) for scientific libraries. The name
|
|
17
|
+
immlib comes from the library’s philosophy of using immutable data to simplify
|
|
18
|
+
scientific workflows.
|
|
19
|
+
|
|
20
|
+
## What's in it
|
|
21
|
+
|
|
22
|
+
- **`immlib.workflow`** — immutable workflows built from `calc` units that are
|
|
23
|
+
assembled into `plan` DAGs. Inputs and outputs are tracked and wired up
|
|
24
|
+
automatically, results are computed lazily, and calculations can be cached in
|
|
25
|
+
memory or on disk.
|
|
26
|
+
- **`immlib.pathlib` / `immlib.iolib`** — a single `path` function that resolves
|
|
27
|
+
local and remote paths (S3, Google Storage, Azure, and OSF), downloads remote
|
|
28
|
+
data into a local cache, and `save`/`load` functions that read and write a
|
|
29
|
+
range of file formats.
|
|
30
|
+
- **quantities and units** — `immlib.Quantity` (a `pint.Quantity` that also
|
|
31
|
+
supports having no units at all) and `immlib.math`, a small common namespace
|
|
32
|
+
that operates on quantities, NumPy arrays, and PyTorch tensors alike, so the
|
|
33
|
+
two backends are interchangeable and units are tracked through the
|
|
34
|
+
arithmetic.
|
|
35
|
+
|
|
36
|
+
Alongside these are a set of utilities for testing and coercing types, handling
|
|
37
|
+
persistent and lazy collections, and working with numerical arguments.
|
|
38
|
+
|
|
39
|
+
## Requirements
|
|
40
|
+
|
|
41
|
+
`immlib` supports Python 3.10 through 3.14, including the free-threaded (no-GIL)
|
|
42
|
+
builds, and depends on NumPy, SciPy, Pint, `pcollections`, `docshare`, `joblib`,
|
|
43
|
+
`cloudpathlib`, and PyYAML.
|
|
44
|
+
|
|
45
|
+
PyTorch and pandas are optional. `immlib` never imports PyTorch at import time,
|
|
46
|
+
so it can be used without it (only operations that actually need a tensor
|
|
47
|
+
raise); pandas is needed only by the `csv`/`tsv` save/load formats. See the
|
|
48
|
+
"Stability and Compatibility" page of the
|
|
49
|
+
[documentation](https://noahbenson.github.io/immlib) for the supported version
|
|
50
|
+
ranges of each dependency and what the library promises across releases.
|
|
51
|
+
|
|
52
|
+
`immlib` is heavily based on the library
|
|
53
|
+
[`pimms`](https://github.com/noahbenson/pimms), which effectively served as a
|
|
54
|
+
prototype for `immlib`. Both libraries were motivated by a number of observations
|
|
55
|
+
about the design of scientific software and are an attempt to make some of these
|
|
56
|
+
problems easier to manage.
|
|
57
|
+
|
|
58
|
+
For more information, see the [documentation](https://noahbenson.github.io/immlib).
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
# PEP 639 (SPDX license expressions and license-files) requires setuptools 77;
|
|
3
|
+
# immlib requires Python 3.10, so there is no need for the older-setuptools
|
|
4
|
+
# fallback that a Python 3.8-compatible project would need.
|
|
5
|
+
requires = ["setuptools >= 77.0.3"]
|
|
6
|
+
build-backend = "setuptools.build_meta"
|
|
7
|
+
|
|
8
|
+
[project]
|
|
9
|
+
name = "immlib"
|
|
10
|
+
version = "1.0.0rc2"
|
|
11
|
+
description = """A library of utilities for immutable scientific data."""
|
|
12
|
+
authors = [{name="Noah C. Benson", email="nben@uw.edu"}]
|
|
13
|
+
license = "MIT"
|
|
14
|
+
license-files = ["LICENSE"]
|
|
15
|
+
readme = "README.md"
|
|
16
|
+
requires-python = ">=3.10"
|
|
17
|
+
keywords = ["persistent", "immutable", "functional", "scientific", "workflow"]
|
|
18
|
+
classifiers = [
|
|
19
|
+
'Intended Audience :: Science/Research',
|
|
20
|
+
'Intended Audience :: Developers',
|
|
21
|
+
'Programming Language :: Python :: 3',
|
|
22
|
+
'Programming Language :: Python :: 3.10',
|
|
23
|
+
'Programming Language :: Python :: 3.11',
|
|
24
|
+
'Programming Language :: Python :: 3.12',
|
|
25
|
+
'Programming Language :: Python :: 3.13',
|
|
26
|
+
'Programming Language :: Python :: 3.14',
|
|
27
|
+
'Topic :: Software Development',
|
|
28
|
+
'Topic :: Software Development :: Libraries',
|
|
29
|
+
'Topic :: Software Development :: Libraries :: Python Modules',
|
|
30
|
+
'Topic :: Scientific/Engineering',
|
|
31
|
+
'Topic :: Scientific/Engineering :: Information Analysis',
|
|
32
|
+
'Operating System :: Microsoft :: Windows',
|
|
33
|
+
'Operating System :: POSIX',
|
|
34
|
+
'Operating System :: Unix',
|
|
35
|
+
'Operating System :: MacOS']
|
|
36
|
+
dependencies = [
|
|
37
|
+
'pcollections >= 1.0.0rc1',
|
|
38
|
+
'numpy >= 1.24.0',
|
|
39
|
+
# The sparse *array* classes (scipy.sparse.csr_array, etc.) that
|
|
40
|
+
# immlib.util._numeric uses to describe sparse layouts were added in
|
|
41
|
+
# scipy 1.8.0.
|
|
42
|
+
'scipy >= 1.8.0',
|
|
43
|
+
# immlib.Quantity subclasses pint.Quantity and overrides some of Pint's
|
|
44
|
+
# private methods and attributes (see immlib.util._quantity), so an upper
|
|
45
|
+
# bound is kept to the minor series it has been tested against. The test
|
|
46
|
+
# suite passes against pint 0.24.4, 0.25.3, and 0.26.1 (see the "Pint
|
|
47
|
+
# contract" tests in immlib.test.util.test_pint); note that pint 0.25+
|
|
48
|
+
# requires Python 3.11 and pint 0.26+ requires Python 3.12, so a Python
|
|
49
|
+
# 3.10 install resolves to pint 0.24.x.
|
|
50
|
+
'pint >= 0.24.0, < 0.27',
|
|
51
|
+
'docshare >= 0.2.0',
|
|
52
|
+
'joblib >= 1.3.0',
|
|
53
|
+
# immlib reaches into a few cloudpathlib internals (notably the private
|
|
54
|
+
# Client._local_cache_dir, and the CloudPath._no_prefix helpers), so an
|
|
55
|
+
# upper bound is kept to the minor series it has been tested against
|
|
56
|
+
# (0.25.0).
|
|
57
|
+
'cloudpathlib[s3,gs,azure] >= 0.18.0, < 0.26',
|
|
58
|
+
'pyyaml >= 6.0']
|
|
59
|
+
|
|
60
|
+
[project.optional-dependencies]
|
|
61
|
+
dev = ["torch >= 2.2.0", "pandas >= 1.5.0", "mypy >= 1.8"]
|
|
62
|
+
# pandas is needed only by the csv/tsv formats of immlib.save/immlib.load, so
|
|
63
|
+
# it is an optional dependency of the library and a test dependency of the
|
|
64
|
+
# suite (which exercises those formats when pandas is present).
|
|
65
|
+
test = ["torch >= 2.2.0", "pandas >= 1.5.0"]
|
|
66
|
+
pandas = ["pandas >= 1.5.0"]
|
|
67
|
+
# Jupyter Book 2 builds with mystmd and uses its own myst.yml configuration
|
|
68
|
+
# (the docs were migrated from Jupyter Book 1); the API-reference pages are
|
|
69
|
+
# generated by docs/generate_api.py before the book is built.
|
|
70
|
+
docs = ["torch >= 2.2.0", "matplotlib >= 3.4.0", "jupyter-book >= 2"]
|
|
71
|
+
|
|
72
|
+
[tool.setuptools.package-data]
|
|
73
|
+
# Distribute the PEP 561 marker alongside the package, so that type checkers
|
|
74
|
+
# know immlib's inline annotations are usable.
|
|
75
|
+
immlib = ["py.typed"]
|
|
76
|
+
|
|
77
|
+
[tool.mypy]
|
|
78
|
+
# immlib is annotated progressively, so the checker is kept lenient on bodies
|
|
79
|
+
# that are not annotated yet; the point of running it in CI is to keep the
|
|
80
|
+
# annotations that do exist honest, not to require every function to have them.
|
|
81
|
+
#
|
|
82
|
+
# The target Python version is deliberately not pinned: mypy then follows the
|
|
83
|
+
# interpreter that runs it. Pinning it to an older version makes mypy parse
|
|
84
|
+
# with that version's grammar, which fails on dependency stubs that use newer
|
|
85
|
+
# syntax (numpy's stubs use PEP 695 `type` statements, which need 3.12+), and
|
|
86
|
+
# the CI matrix checks the annotations under more than one interpreter.
|
|
87
|
+
files = ["src/immlib"]
|
|
88
|
+
ignore_missing_imports = true
|
|
89
|
+
check_untyped_defs = false
|
|
90
|
+
warn_unused_ignores = false
|
|
91
|
+
|
|
92
|
+
[project.urls]
|
|
93
|
+
homepage = "https://github.com/noahbenson/immlib"
|
|
94
|
+
documentation = "https://github.com/noahbenson/immlib"
|
|
95
|
+
repository = "https://github.com/noahbenson/immlib"
|
|
@@ -33,37 +33,16 @@ submodules : tuple of str
|
|
|
33
33
|
A tuple of strings, each of which is the name of one of the submodules in
|
|
34
34
|
``immlib``. The modules are listed in load-order and all ``immlib``
|
|
35
35
|
submodules, including private submodules, are included.
|
|
36
|
-
docproc: docrep.DocstringProcessor object
|
|
37
|
-
This object is used to process all of the doc-strings in the ``immlib``
|
|
38
|
-
library; it should be used only with the ``immlib.docwrap`` decorator,
|
|
39
|
-
which can safely be applied anywhere in a sequence of decorators and which
|
|
40
|
-
correctly applies the ``wraps`` decorator to its argument. Function
|
|
41
|
-
documentation is always processed using the ``sections=('Parameters',
|
|
42
|
-
'Returns', 'Raises', 'Examples', 'Inputs', 'Outputs')`` parameter and the
|
|
43
|
-
``with_indent(4)`` decorator. The base-name for the function ``f`` is
|
|
44
|
-
``f.__module__ + '.' + f.__name__``.
|
|
45
36
|
'''
|
|
46
37
|
|
|
47
38
|
|
|
48
39
|
# Imports #####################################################################
|
|
49
40
|
|
|
50
|
-
# We always load _init first.
|
|
51
|
-
from ._init import reclaim
|
|
52
|
-
# Then the core library.
|
|
53
|
-
from .doc import *
|
|
54
41
|
from .util import *
|
|
55
42
|
from .pathlib import *
|
|
56
43
|
from .iolib import *
|
|
57
44
|
from .workflow import *
|
|
58
|
-
from .
|
|
59
|
-
# Import the Global UnitRegistry object to the global immlib scope. This is the
|
|
60
|
-
# value that gets updated when one runs `immlib.default_ureg()`, and this is
|
|
61
|
-
# the UnitRegistry that is used as the default registry for all ``immlib``
|
|
62
|
-
# functions.
|
|
63
|
-
from .util._quantity import _initial_global_ureg as units
|
|
64
|
-
# Do the same for the global DocstringProcessor (from the docrep library) from
|
|
65
|
-
# the doc subpackage.
|
|
66
|
-
from .doc._core import _initial_global_docproc as docproc
|
|
45
|
+
from . import math
|
|
67
46
|
# We want the version object from the ._version namespace; this is always last.
|
|
68
47
|
from ._version import (version, Version)
|
|
69
48
|
|
|
@@ -71,9 +50,6 @@ from ._version import (version, Version)
|
|
|
71
50
|
# Modules/Reloading ###########################################################
|
|
72
51
|
|
|
73
52
|
submodules = (
|
|
74
|
-
'immlib._init',
|
|
75
|
-
'immlib.doc._core',
|
|
76
|
-
'immlib.doc',
|
|
77
53
|
'immlib.util._core',
|
|
78
54
|
'immlib.util._numeric',
|
|
79
55
|
'immlib.util._quantity',
|
|
@@ -87,8 +63,8 @@ submodules = (
|
|
|
87
63
|
'immlib.workflow._core',
|
|
88
64
|
'immlib.workflow._plantype',
|
|
89
65
|
'immlib.workflow',
|
|
90
|
-
'immlib.
|
|
91
|
-
'immlib.
|
|
66
|
+
'immlib.math._core',
|
|
67
|
+
'immlib.math',
|
|
92
68
|
'immlib._version')
|
|
93
69
|
def reload_immlib():
|
|
94
70
|
"""Reload and return the entire ``immlib`` package.
|
|
@@ -126,6 +102,22 @@ __all__ = tuple(
|
|
|
126
102
|
if k[0] != '_'
|
|
127
103
|
if k != 'submodules'
|
|
128
104
|
if k != 'version'
|
|
129
|
-
if ('immlib.' + k) not in submodules]
|
|
130
|
-
|
|
131
|
-
|
|
105
|
+
if ('immlib.' + k) not in submodules]
|
|
106
|
+
+ ['units'])
|
|
107
|
+
# immlib.units is a property of the module: it returns the unit registry set
|
|
108
|
+
# by an enclosing immlib.default_ureg block in the current thread, if any, or
|
|
109
|
+
# the global default registry otherwise; assigning to it sets the global
|
|
110
|
+
# default registry.
|
|
111
|
+
import sys as _sys
|
|
112
|
+
import types as _types
|
|
113
|
+
class _ImmlibModule(_types.ModuleType):
|
|
114
|
+
@property
|
|
115
|
+
def units(self):
|
|
116
|
+
from .util._core import _default_ureg
|
|
117
|
+
return _default_ureg()
|
|
118
|
+
@units.setter
|
|
119
|
+
def units(self, ureg):
|
|
120
|
+
from .util._core import _global_ureg
|
|
121
|
+
_global_ureg[0] = ureg
|
|
122
|
+
_sys.modules[__name__].__class__ = _ImmlibModule
|
|
123
|
+
del _sys, _types
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
|
|
2
|
+
###############################################################################
|
|
3
3
|
# immlib/_version.py
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
# Dependencies
|
|
6
|
+
# Dependencies ################################################################
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
7
9
|
|
|
8
10
|
from ast import literal_eval
|
|
11
|
+
from typing import Iterator
|
|
9
12
|
from collections import namedtuple
|
|
10
13
|
from pathlib import Path
|
|
14
|
+
from os import PathLike
|
|
11
15
|
from warnings import warn
|
|
12
16
|
|
|
13
17
|
|
|
14
|
-
# Version Type
|
|
18
|
+
# Version Type ################################################################
|
|
15
19
|
|
|
16
20
|
VersionTuple = namedtuple(
|
|
17
21
|
'VersionTuple',
|
|
@@ -20,50 +24,53 @@ class Version(VersionTuple):
|
|
|
20
24
|
"""A type that represents a Python package version.
|
|
21
25
|
|
|
22
26
|
Python packages are represented simultaneously as version strings, version
|
|
23
|
-
tuples, and by the version components
|
|
24
|
-
|
|
27
|
+
tuples, and by the version components ``major``, ``minor``, ``micro``, and
|
|
28
|
+
``stage``.
|
|
25
29
|
|
|
26
30
|
Parameters
|
|
27
31
|
----------
|
|
28
32
|
string : str or None, optional
|
|
29
33
|
The version string to be represented. If this argument is not provided,
|
|
30
|
-
then one or both of the
|
|
31
|
-
be provided so that the version string can be obtained via the
|
|
32
|
-
version or the
|
|
34
|
+
then one or both of the ``package_name`` and ``pyproject_path`` options
|
|
35
|
+
must be provided so that the version string can be obtained via the
|
|
36
|
+
package version or the ``pyproject.toml`` file.
|
|
33
37
|
package_name : str or None, optional
|
|
34
|
-
If the first argument (
|
|
38
|
+
If the first argument (``string``) is provided, then this argument is
|
|
35
39
|
ignored; otherwise, the version string is first searched for by this
|
|
36
|
-
package name using the
|
|
37
|
-
|
|
40
|
+
package name using the ``importlib.metadata`` package. If found, then
|
|
41
|
+
this version string is represented in the
|
|
42
|
+
``Version`` object.
|
|
38
43
|
pyproject_path : path-like or None, optional
|
|
39
|
-
If the first argument (
|
|
40
|
-
not given, then the version is searched for in the
|
|
41
|
-
given by this path. In order for such a file to
|
|
42
|
-
contain a line that, when stripped of whitespace,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
section of the TOM: file pointed to by this
|
|
46
|
-
represented as the version string in the
|
|
44
|
+
If the first argument (``string``) is not given and the
|
|
45
|
+
``package_name`` is not given, then the version is searched for in the
|
|
46
|
+
``pyproject.toml`` file given by this path. In order for such a file to
|
|
47
|
+
be valid, it must contain a line that, when stripped of whitespace,
|
|
48
|
+
begins with the string ``'version='`` followed by a string
|
|
49
|
+
representation (e.g., ``'version="1.12.5"'``). If such a line is found
|
|
50
|
+
in the ``[project]`` section of the TOM: file pointed to by this
|
|
51
|
+
argument, then it is represented as the version string in the
|
|
52
|
+
``Version`` object.
|
|
47
53
|
on_error : {'warn' | 'ignore' | 'raise'}, optional
|
|
48
54
|
How to handle failures to deduce or parse the version number. If
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
default is
|
|
55
|
+
``'raise'`` is given, then the errors are allowed to be raised. If
|
|
56
|
+
``'warn'``, then a warning is raised and a null version is returned. If
|
|
57
|
+
``'ignore'``, then errors are ignored and a null version is
|
|
58
|
+
returned. The default is ``'raise'``.
|
|
59
|
+
|
|
53
60
|
tag_prefixes : tuple of str, optional
|
|
54
61
|
An optional tuple of strings that can appear as the prefixes of stage
|
|
55
|
-
tagss at the end of the version string. By default, this is
|
|
56
|
-
'b')
|
|
57
|
-
but
|
|
62
|
+
tagss at the end of the version string. By default, this is ``('rc',
|
|
63
|
+
'a', 'b')``, so version strings like ``'1.1.12a6'`` and ``'1.1.12rc6'``
|
|
64
|
+
are valid but ``'1.1.12c6'`` is not.
|
|
58
65
|
|
|
59
66
|
Attributes
|
|
60
67
|
----------
|
|
61
68
|
string : str
|
|
62
|
-
The string representing the package version. For example
|
|
63
|
-
|
|
69
|
+
The string representing the package version. For example ``"1.2.15"``
|
|
70
|
+
or ``"0.2.2.dev1"``.
|
|
64
71
|
tuple : tuple of int and str
|
|
65
|
-
The components of the version string, for example,
|
|
66
|
-
|
|
72
|
+
The components of the version string, for example, ``(1, 2, 15)`` or
|
|
73
|
+
``(0, 2, 2, 'dev1')``. Any missing component is excluded.
|
|
67
74
|
major : int
|
|
68
75
|
The major version number, typically indicates major API version.
|
|
69
76
|
minor : int
|
|
@@ -71,32 +78,33 @@ class Version(VersionTuple):
|
|
|
71
78
|
micro : int
|
|
72
79
|
The micro version number, typically indicates patch increment number.
|
|
73
80
|
stage : str
|
|
74
|
-
The development stage of the version. For example
|
|
81
|
+
The development stage of the version. For example ``'dev1'`` or
|
|
82
|
+
``'rc2'``.
|
|
75
83
|
"""
|
|
76
84
|
|
|
77
|
-
# Static Methods
|
|
78
|
-
|
|
85
|
+
# Static Methods ----------------------------------------------------------
|
|
86
|
+
@staticmethod
|
|
87
|
+
def getstring(package_name: str | None = None,
|
|
88
|
+
pyproject_path: str | PathLike[str] | None = None) -> str:
|
|
79
89
|
"""Returns the current version string for the given package name.
|
|
80
90
|
|
|
81
|
-
|
|
91
|
+
``Version.getstring(package_name)`` returns the version string of the
|
|
82
92
|
package with the given package name.
|
|
83
93
|
|
|
84
|
-
|
|
85
|
-
found in the pyproject.toml file found at the given
|
|
94
|
+
``Version.getstring(pyproject_path=path)`` returns the version string
|
|
95
|
+
found in the pyproject.toml file found at the given ``path``.
|
|
86
96
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
otherwise returns
|
|
97
|
+
``Version.getstring(package_name, path)`` returns
|
|
98
|
+
``Version.getstring(package_name)`` if the given ``package_name`` is
|
|
99
|
+
found, otherwise returns ``Version.getstring(pyproject_path=path)``.
|
|
90
100
|
"""
|
|
91
101
|
if package_name is None and pyproject_path is None:
|
|
92
102
|
raise ValueError("Version.getstring() requires 1 or 2 arguments")
|
|
93
103
|
if package_name is not None:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
from importlib_metadata import version
|
|
99
|
-
from importlib_metadata import PackageNotFoundError
|
|
104
|
+
# immlib requires Python 3.10 or later, so importlib.metadata is
|
|
105
|
+
# always available (the importlib_metadata backport is not needed).
|
|
106
|
+
from importlib.metadata import version
|
|
107
|
+
from importlib.metadata import PackageNotFoundError
|
|
100
108
|
if pyproject_path is None:
|
|
101
109
|
return version(package_name)
|
|
102
110
|
# Try to deduce the version string but don't raise if this fails.
|
|
@@ -106,13 +114,19 @@ class Version(VersionTuple):
|
|
|
106
114
|
pass
|
|
107
115
|
# Either a package name wasn't given or the package wasn't found; check
|
|
108
116
|
# the pyproject.toml if possible.
|
|
109
|
-
path = Path(pyproject_path)
|
|
117
|
+
path = Path(pyproject_path) # type: ignore[arg-type]
|
|
110
118
|
with path.open('rt') as fl:
|
|
111
119
|
toml_lines = fl.read().split('\n')
|
|
112
120
|
in_project_section = False
|
|
113
121
|
for ln in toml_lines:
|
|
114
122
|
ln = ln.strip()
|
|
115
|
-
if ln
|
|
123
|
+
if not ln or ln.startswith('#'):
|
|
124
|
+
# A blank line or a comment: neither starts a section nor
|
|
125
|
+
# declares anything. (The emptiness test must come first;
|
|
126
|
+
# ln[0] below would raise for a blank line, and every real
|
|
127
|
+
# pyproject.toml has blank lines in it.)
|
|
128
|
+
continue
|
|
129
|
+
elif ln == '[project]':
|
|
116
130
|
in_project_section = True
|
|
117
131
|
elif ln[0] == '[' and ln[-1] == ']':
|
|
118
132
|
in_project_section = False
|
|
@@ -131,7 +145,7 @@ class Version(VersionTuple):
|
|
|
131
145
|
f"Version.getstring() found no 'version = ...' line in file"
|
|
132
146
|
f" {path}")
|
|
133
147
|
|
|
134
|
-
# Construction
|
|
148
|
+
# Construction ------------------------------------------------------------
|
|
135
149
|
__slots__ = ()
|
|
136
150
|
null = None
|
|
137
151
|
def __new__(cls, string=None, /, *,
|
|
@@ -172,7 +186,7 @@ class Version(VersionTuple):
|
|
|
172
186
|
micro = '0'
|
|
173
187
|
last = minor
|
|
174
188
|
elif nss == 1:
|
|
175
|
-
major = ss
|
|
189
|
+
(major,) = ss
|
|
176
190
|
(minor, micro) = ('0', '0')
|
|
177
191
|
last = major
|
|
178
192
|
else:
|
|
@@ -203,20 +217,20 @@ class Version(VersionTuple):
|
|
|
203
217
|
minor=minor,
|
|
204
218
|
micro=micro,
|
|
205
219
|
stage=stage)
|
|
206
|
-
def __str__(self):
|
|
220
|
+
def __str__(self) -> str:
|
|
207
221
|
return self.string
|
|
208
|
-
def __repr__(self):
|
|
222
|
+
def __repr__(self) -> str:
|
|
209
223
|
return f"Version({repr(self.string)})"
|
|
210
|
-
def __iter__(self):
|
|
224
|
+
def __iter__(self) -> Iterator[object]:
|
|
211
225
|
return iter(self.tuple)
|
|
212
|
-
def __reversed__(self):
|
|
226
|
+
def __reversed__(self) -> Iterator[object]:
|
|
213
227
|
return reversed(self.tuple)
|
|
214
|
-
def __contains__(self, k):
|
|
228
|
+
def __contains__(self, k: object) -> bool:
|
|
215
229
|
if isinstance(k, str):
|
|
216
230
|
return k in self.string
|
|
217
231
|
else:
|
|
218
232
|
return k in self.tuple
|
|
219
|
-
Version.null = VersionTuple.__new__(
|
|
233
|
+
Version.null = VersionTuple.__new__( # type: ignore[assignment]
|
|
220
234
|
Version,
|
|
221
235
|
string='',
|
|
222
236
|
tuple=(),
|
|
@@ -226,7 +240,7 @@ Version.null = VersionTuple.__new__(
|
|
|
226
240
|
stage=None)
|
|
227
241
|
|
|
228
242
|
|
|
229
|
-
# Variables
|
|
243
|
+
# Variables ###################################################################
|
|
230
244
|
|
|
231
245
|
# The path of immlib's pyproject.toml file.
|
|
232
246
|
pyproject_path = Path(__file__).parent.parent.parent / 'pyproject.toml'
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
################################################################################
|
|
3
|
-
#
|
|
3
|
+
# immlib/iolib/__init__.py
|
|
4
4
|
|
|
5
|
-
"""Input/output tools managed by
|
|
5
|
+
"""Input/output tools managed by immlib; primarily the save and load functions.
|
|
6
6
|
|
|
7
|
-
The `
|
|
7
|
+
The `immlib.iolib` module contains tools for saving and loading data to/from
|
|
8
8
|
paths or streams. This functionality is primarily supported via the `save` and
|
|
9
9
|
`load` objects that behave as general (de)serializers to which formats can be
|
|
10
10
|
registered.
|
|
@@ -21,9 +21,3 @@ __all__ = (
|
|
|
21
21
|
'save',
|
|
22
22
|
'Load',
|
|
23
23
|
'load')
|
|
24
|
-
|
|
25
|
-
# Mark these as native to this module.
|
|
26
|
-
Save.__module__ = __name__
|
|
27
|
-
save.__module__ = __name__
|
|
28
|
-
Load.__module__ = __name__
|
|
29
|
-
load.__module__ = __name__
|