dependence 1.0.4__py3-none-any.whl → 1.1.0__py3-none-any.whl

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.
dependence/upgrade.py ADDED
@@ -0,0 +1,220 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import sys
5
+ from itertools import chain
6
+ from typing import TYPE_CHECKING
7
+
8
+ from dependence._utilities import (
9
+ check_output,
10
+ iter_configuration_files,
11
+ iter_parse_delimited_values,
12
+ )
13
+ from dependence.freeze import get_frozen_requirements
14
+ from dependence.update import update
15
+
16
+ if TYPE_CHECKING:
17
+ from collections.abc import Iterable
18
+
19
+
20
+ def upgrade(
21
+ requirements: Iterable[str],
22
+ *,
23
+ ignore_update: Iterable[str] = (),
24
+ all_extra_name: str = "",
25
+ include_pointers: tuple[str, ...] = (),
26
+ exclude_pointers: tuple[str, ...] = (),
27
+ exclude: Iterable[str] = (),
28
+ exclude_recursive: Iterable[str] = (),
29
+ depth: int | None = None,
30
+ ) -> None:
31
+ """
32
+ This function obtains a list of dependencies for the specified
33
+ `requirements` using `dependence.update.get_frozen_requirements()`,
34
+ upgrades all of these dependencies in the current environment,
35
+ then updates version specifiers for all requirements/dependencies
36
+ in any or the `requirements` which are project config files
37
+ to align with the newly installed package versions (using
38
+ `dependence.update.update()`).
39
+
40
+ Parameters:
41
+ requirements: One or more requirement specifiers (for example:
42
+ "requirement-name[extra-a,extra-b]" or ".[extra-a, extra-b]) and/or
43
+ paths to a setup.py, setup.cfg, pyproject.toml, tox.ini or
44
+ requirements.txt file.
45
+ ignore_update: One or more project names to ignore (leave as-is)
46
+ when updating a dependency's requirement specifier in the
47
+ provided pyproject.toml/setup.cfg/requirements.txt/tox.ini
48
+ file(s). Note that this does not prevent the package from being
49
+ upgraded—for that you need to pass the package name in
50
+ `exclude` or `exclude_recursive`.
51
+ all_extra_name: If provided, an extra which consolidates
52
+ the requirements for all other extras will be added/updated to
53
+ pyproject.toml or setup.cfg (this argument is ignored for
54
+ requirements.txt and tox.ini files).
55
+ include_pointers: A tuple of JSON pointers indicating elements to
56
+ include (defaults to all elements). This applies only to TOML
57
+ files (including pyproject.toml), and is ignored for all other
58
+ file types.
59
+ exclude_pointers: A tuple of JSON pointers indicating elements to
60
+ exclude (defaults to no exclusions). This applies only to TOML
61
+ files (including pyproject.toml), and is ignored for all other
62
+ file types.
63
+ exclude: One or more distributions to exclude when upgrading packages.
64
+ exclude_recursive: One or more distributions to exclude when
65
+ upgrading packages. Recursive dependency discovery is also
66
+ halted for these distributions, unlike those passed to `exclude`.
67
+ depth: The maximum recursion depth to traverse when discovering
68
+ dependencies. If `None` (the default), all dependencies are
69
+ discovered.
70
+ """
71
+ frozen_requirements: tuple[str, ...] = get_frozen_requirements(
72
+ requirements,
73
+ exclude=exclude,
74
+ exclude_recursive=exclude_recursive,
75
+ no_version="*",
76
+ depth=depth,
77
+ include_pointers=include_pointers,
78
+ exclude_pointers=exclude_pointers,
79
+ )
80
+ command: tuple[str, ...] = (
81
+ sys.executable,
82
+ "-m",
83
+ "pip",
84
+ "install",
85
+ "--upgrade",
86
+ *frozen_requirements,
87
+ )
88
+ check_output(command)
89
+ configuration_files: tuple[str, ...] = tuple(
90
+ chain(
91
+ *map(iter_configuration_files, requirements) # type: ignore
92
+ )
93
+ )
94
+ if configuration_files:
95
+ update(
96
+ configuration_files,
97
+ ignore=ignore_update,
98
+ all_extra_name=all_extra_name,
99
+ include_pointers=include_pointers,
100
+ exclude_pointers=exclude_pointers,
101
+ )
102
+
103
+
104
+ def main() -> None:
105
+ parser: argparse.ArgumentParser = argparse.ArgumentParser(
106
+ prog="dependence upgrade",
107
+ description=(
108
+ "Upgrade all dependencies for specified packages/projects, "
109
+ "then upgrade version specifiers in the project files "
110
+ "to align with newly installed versions of each distribution."
111
+ ),
112
+ )
113
+ parser.add_argument(
114
+ "-iu",
115
+ "--ignore-update",
116
+ default=[],
117
+ type=str,
118
+ action="append",
119
+ help=(
120
+ "A comma-separated list of distributions to ignore (leave "
121
+ "any requirements pertaining to the package as-is) when "
122
+ "updating project files"
123
+ ),
124
+ )
125
+ parser.add_argument(
126
+ "-aen",
127
+ "--all-extra-name",
128
+ default="",
129
+ type=str,
130
+ help=(
131
+ "If provided, an extra which consolidates the requirements "
132
+ "for all other extras will be added/updated to pyproject.toml "
133
+ "or setup.cfg (this argument is ignored for "
134
+ "requirements.txt files and other TOML files)"
135
+ ),
136
+ )
137
+ parser.add_argument(
138
+ "--include-pointer",
139
+ default=[],
140
+ type=str,
141
+ action="append",
142
+ help=(
143
+ "One or more JSON pointers of elements to *include* "
144
+ "(applies to TOML files only)"
145
+ ),
146
+ )
147
+ parser.add_argument(
148
+ "--exclude-pointer",
149
+ default=[],
150
+ type=str,
151
+ action="append",
152
+ help=(
153
+ "One or more JSON pointers of elements to *exclude* "
154
+ "(applies to TOML files only)"
155
+ ),
156
+ )
157
+ parser.add_argument(
158
+ "-e",
159
+ "--exclude",
160
+ default=[],
161
+ type=str,
162
+ action="append",
163
+ help=(
164
+ "A distribution (or comma-separated list of distributions) to "
165
+ "exclude when performing upgrades"
166
+ ),
167
+ )
168
+ parser.add_argument(
169
+ "-er",
170
+ "--exclude-recursive",
171
+ default=[],
172
+ type=str,
173
+ action="append",
174
+ help=(
175
+ "A distribution (or comma-separated list of distributions) to "
176
+ "exclude when performing upgrades. Unlike -e / --exclude, "
177
+ "this argument also precludes recursive requirement discovery "
178
+ "for the specified packages, thereby excluding all of the "
179
+ "excluded package's requirements which are not required by "
180
+ "another (non-excluded) distribution from the upgrade."
181
+ ),
182
+ )
183
+ parser.add_argument(
184
+ "-d",
185
+ "--depth",
186
+ default=None,
187
+ type=int,
188
+ help="Depth of recursive requirement discovery",
189
+ )
190
+ parser.add_argument(
191
+ "requirement",
192
+ nargs="+",
193
+ type=str,
194
+ help=(
195
+ "One or more requirement specifiers (for example: "
196
+ '"requirement-name", "requirement-name[extra-a,extra-b]", '
197
+ '".[extra-a, extra-b]" or '
198
+ '"../other-editable-package-directory[extra-a, extra-b]) '
199
+ "and/or paths to a setup.py, setup.cfg, pyproject.toml, "
200
+ "tox.ini or requirements.txt file"
201
+ ),
202
+ )
203
+ namespace: argparse.Namespace = parser.parse_args()
204
+ upgrade(
205
+ requirements=namespace.requirement,
206
+ exclude=tuple(iter_parse_delimited_values(namespace.exclude)),
207
+ exclude_recursive=tuple(
208
+ iter_parse_delimited_values(namespace.exclude_recursive)
209
+ ),
210
+ ignore_update=tuple(
211
+ iter_parse_delimited_values(namespace.ignore_update)
212
+ ),
213
+ all_extra_name=namespace.all_extra_name,
214
+ include_pointers=tuple(namespace.include_pointer),
215
+ exclude_pointers=tuple(namespace.exclude_pointer),
216
+ )
217
+
218
+
219
+ if __name__ == "__main__":
220
+ main()
@@ -1,18 +1,18 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: dependence
3
- Version: 1.0.4
3
+ Version: 1.1.0
4
4
  Summary: A dependency management tool for python projects
5
5
  Project-URL: Documentation, https://dependence.enorganic.org
6
6
  Project-URL: Repository, https://github.com/enorganic/dependence
7
7
  Author-email: david@belais.me
8
- License: MIT
8
+ License-Expression: MIT
9
9
  Keywords: dependencies,requirements
10
- Requires-Python: ~=3.8
10
+ Requires-Python: ~=3.9
11
11
  Requires-Dist: jsonpointer
12
12
  Requires-Dist: packaging
13
13
  Requires-Dist: pip
14
14
  Requires-Dist: setuptools>63
15
- Requires-Dist: tomli-w~=1.0
15
+ Requires-Dist: tomli-w~=1.2
16
16
  Requires-Dist: tomli~=2.2
17
17
  Description-Content-Type: text/markdown
18
18
 
@@ -21,11 +21,11 @@ Description-Content-Type: text/markdown
21
21
  [![test](https://github.com/enorganic/dependence/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/enorganic/dependence/actions/workflows/test.yml)
22
22
  [![PyPI version](https://badge.fury.io/py/dependence.svg?icon=si%3Apython)](https://badge.fury.io/py/dependence)
23
23
 
24
- Dependence provides a Command Line Interface and library for aligning
25
- a python projects' declared dependencies with the package versions
26
- installed in the environment in which `dependence` is executed, and for
27
- "freezing" recursively resolved package dependencies (like `pip freeze`, but
28
- for a package, instead of the entire environment).
24
+ Dependence provides a Command Line Interface and library for performing
25
+ dependency upgrades on a python project, aligning declared dependencies with
26
+ the package versions installed in the environment in which `dependence` is
27
+ executed, and for "freezing" recursively resolved package dependencies
28
+ (like `pip freeze`, but for a package, instead of the entire environment).
29
29
 
30
30
  - [Documentation](https://enorganic.github.io/dependence/)
31
31
  - [Contributing](https://enorganic.github.io/dependence/contributing)
@@ -38,7 +38,72 @@ You can install `dependence` with pip:
38
38
  pip3 install dependence
39
39
  ```
40
40
 
41
- ## Example Usage
41
+ ## Usage
42
+
43
+ ### Upgrading Dependencies
44
+
45
+ The `dependence upgrade` command, and the `dependence.upgrade.upgrade`
46
+ function, discover and upgrade project and environment dependencies in the
47
+ environment in which dependence is installed to their latest version
48
+ aligned with project and dependency requirements, then selectively update
49
+ requirement specifiers in any specified TOML files (such as pyproject.toml),
50
+ setup.cfg file, requirements.txt files, or tox.ini files. Because
51
+ pyproject.toml files may contain dependencies for more than one environment,
52
+ such as when using [hatch](https://hatch.pypa.io/) environments,
53
+ [JSON-style pointers](https://datatracker.ietf.org/doc/html/rfc6901) are used
54
+ to include or exclude specific parts of TOML files.
55
+
56
+ For example, in [this project's Makefile
57
+ ](https://github.com/enorganic/dependence/blob/main/Makefile#L27), we define a
58
+ `make upgrade` target as follows:
59
+
60
+ ```Makefile
61
+ SHELL := bash
62
+ PYTHON_VERSION := 3.9
63
+
64
+ upgrade:
65
+ hatch run dependence upgrade\
66
+ --include-pointer /tool/hatch/envs/default\
67
+ --include-pointer /project\
68
+ pyproject.toml && \
69
+ hatch run docs:dependence upgrade\
70
+ --include-pointer /tool/hatch/envs/docs\
71
+ --include-pointer /project\
72
+ pyproject.toml && \
73
+ hatch run hatch-static-analysis:dependence upgrade\
74
+ --include-pointer /tool/hatch/envs/docs\
75
+ --include-pointer /project\
76
+ pyproject.toml && \
77
+ hatch run hatch-test.py$(PYTHON_VERSION):dependence upgrade\
78
+ --include-pointer /tool/hatch/envs/hatch-test\
79
+ --include-pointer /project\
80
+ pyproject.toml && \
81
+ make requirements
82
+ ```
83
+
84
+ You can reference the [associated pyproject.toml file for this project
85
+ ](https://github.com/enorganic/dependence/blob/main/pyproject.toml#L21)
86
+ for reference concerning the implications of `--include-pointer`, which
87
+ uses identical syntax to [JSON pointers
88
+ ](https://datatracker.ietf.org/doc/html/rfc6901). The `--exclude-pointer`
89
+ parameter works identically, but in reverse. If both `--include-pointer`
90
+ and `--exclude-pointer` are used, only sections which match both conditions
91
+ will be updated.
92
+
93
+ You may refer to the [`dependence upgrade` CLI reference](./cli.md#dependence-upgrade)
94
+ and/or [`dependence.upgrade` API reference](./api/upgrade.md) for details
95
+ concerning this command/module, related options, and more complex use case
96
+ examples.
97
+
98
+ The `dependence upgrade` command, and the `dependence.upgrade.upgrade`
99
+ function, are simply a composite of the dependency listing and update
100
+ functionalities covered below, but which a `pip install --upgrade`
101
+ command executed in between—so please read further for additional details.
102
+ All parameters are directly passed, with the exception of
103
+ `--ignore-update`/`ignore_update`, which is translated to the
104
+ `--ignore`/`ignore` parameter for
105
+ `dependence update`/`dependence.update.update` (renamed in this operation
106
+ for clarity of purpose).
42
107
 
43
108
  ### Listing Dependencies
44
109
 
@@ -48,8 +113,8 @@ requirements.txt, pyproject.toml, setup.cfg, or tox.ini files. The output
48
113
  format matches that of `pip freeze`, but only lists dependencies of indicated
49
114
  packages and/or editable project locations.
50
115
 
51
- You may refer to the [`dependence freeze` CLI reference](https://dependence.enorganic.org/cli/#dependence-freeze)
52
- and/or [`dependence.freeze` API reference](https://dependence.enorganic.org/api/freeze/) for details
116
+ You may refer to the [`dependence freeze` CLI reference](./cli.md#dependence-freeze)
117
+ and/or [`dependence.freeze` API reference](./api/freeze.md) for details
53
118
  concerning this command/module, related options, and more complex use case
54
119
  examples.
55
120
 
@@ -157,7 +222,7 @@ $ diff pyproject_before.toml pyproject_after.toml
157
222
  ```
158
223
 
159
224
  As you can see, only the version specifier for tomli changed. We know that
160
- every dependency was upgraded, wo why was only the `tomli` version specifier
225
+ every dependency was upgraded, so why was only the `tomli` version specifier
161
226
  updated? By design. Here are the rules `dependence update` adheres to:
162
227
 
163
228
  - We only update requirements versions when they have *inclusive* specifiers.
@@ -174,7 +239,7 @@ updated? By design. Here are the rules `dependence update` adheres to:
174
239
  - If your requirement is unversioned, we don't touch it, of course. This is
175
240
  why you didn't see any change for "pip".
176
241
 
177
- You may refer to the [`dependence update` CLI reference](https://dependence.enorganic.org/cli/#dependence-update)
178
- and/or [`dependence.update` API reference](https://dependence.enorganic.org/api/update/) for details
242
+ You may refer to the [`dependence update` CLI reference](./cli.md#dependence-update)
243
+ and/or [`dependence.update` API reference](./api/update.md) for details
179
244
  concerning this command/module, related options, and more complex use
180
245
  cases/examples.
@@ -0,0 +1,11 @@
1
+ dependence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ dependence/__main__.py,sha256=zk67MINE1FpsBcXDDvRiHQwmO7_4iay_Rkq3JTPrha4,1802
3
+ dependence/_utilities.py,sha256=CxIl7BkoTqMtrOsJzq544_RDa8-QtZufKj31PazIBFI,36790
4
+ dependence/freeze.py,sha256=gZ3ZJuxphojUmlx8LoZ-qFTd-EUTPF-oM-FKFYVxoSs,15518
5
+ dependence/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ dependence/update.py,sha256=k6KtRbJORnbC7-bkDbVCDjsJkwVkGshQncLh1RjmolU,20554
7
+ dependence/upgrade.py,sha256=lNovLvKhxiczZAJj2_hHrbkDscNOTrx1xaOhmobVNSI,7747
8
+ dependence-1.1.0.dist-info/METADATA,sha256=mUjlA-89b_G0rNU0uLrgxznIqKeFGu7fQtkmMx4pGCM,8364
9
+ dependence-1.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
10
+ dependence-1.1.0.dist-info/entry_points.txt,sha256=NStO_B0D81ObVYr9zDs6LCy0whm0a8KCiiFHMmTwOVE,56
11
+ dependence-1.1.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.26.3
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,10 +0,0 @@
1
- dependence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- dependence/__main__.py,sha256=myBIBZdez2jC3_dkVSE-mOLo39yKi2cF_0NuVXcXF1E,1528
3
- dependence/_utilities.py,sha256=gUFC6lzd3T60_-3kqzqTJRmmilzM64HRHz6rxjhJd9c,33697
4
- dependence/freeze.py,sha256=t9yoavc8h5OWA5za_tNrEQIGThFHy679O-6MnXUBZmQ,14855
5
- dependence/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- dependence/update.py,sha256=ymncDTVh9UxECQwOIcU3OWIfhvCP3kdQlyKfJH34CoU,19978
7
- dependence-1.0.4.dist-info/METADATA,sha256=YQEq7pvYyjuLn23mF7yUcztYyFK-K2UbzE0l27gWEvw,5570
8
- dependence-1.0.4.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
9
- dependence-1.0.4.dist-info/entry_points.txt,sha256=NStO_B0D81ObVYr9zDs6LCy0whm0a8KCiiFHMmTwOVE,56
10
- dependence-1.0.4.dist-info/RECORD,,