pyinfra 3.2__py2.py3-none-any.whl → 3.3__py2.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.
- pyinfra/api/arguments_typed.py +4 -5
- pyinfra/api/command.py +22 -3
- pyinfra/api/config.py +5 -2
- pyinfra/api/facts.py +3 -0
- pyinfra/api/host.py +10 -4
- pyinfra/api/operation.py +2 -1
- pyinfra/api/state.py +1 -1
- pyinfra/connectors/base.py +34 -8
- pyinfra/connectors/chroot.py +7 -2
- pyinfra/connectors/docker.py +7 -2
- pyinfra/connectors/dockerssh.py +7 -2
- pyinfra/connectors/local.py +7 -2
- pyinfra/connectors/ssh.py +9 -2
- pyinfra/connectors/sshuserclient/client.py +16 -0
- pyinfra/connectors/sshuserclient/config.py +2 -0
- pyinfra/connectors/terraform.py +1 -1
- pyinfra/connectors/util.py +13 -9
- pyinfra/context.py +9 -2
- pyinfra/facts/apk.py +5 -0
- pyinfra/facts/apt.py +9 -1
- pyinfra/facts/brew.py +13 -0
- pyinfra/facts/bsdinit.py +3 -0
- pyinfra/facts/cargo.py +5 -0
- pyinfra/facts/choco.py +6 -0
- pyinfra/facts/crontab.py +6 -1
- pyinfra/facts/deb.py +10 -0
- pyinfra/facts/dnf.py +5 -0
- pyinfra/facts/docker.py +10 -0
- pyinfra/facts/efibootmgr.py +5 -0
- pyinfra/facts/files.py +19 -1
- pyinfra/facts/flatpak.py +7 -0
- pyinfra/facts/freebsd.py +75 -0
- pyinfra/facts/gem.py +5 -0
- pyinfra/facts/git.py +9 -0
- pyinfra/facts/gpg.py +7 -0
- pyinfra/facts/hardware.py +13 -0
- pyinfra/facts/iptables.py +9 -1
- pyinfra/facts/launchd.py +5 -0
- pyinfra/facts/lxd.py +5 -0
- pyinfra/facts/mysql.py +8 -0
- pyinfra/facts/npm.py +5 -0
- pyinfra/facts/openrc.py +8 -0
- pyinfra/facts/opkg.py +12 -0
- pyinfra/facts/pacman.py +9 -1
- pyinfra/facts/pip.py +5 -0
- pyinfra/facts/pipx.py +8 -0
- pyinfra/facts/pkg.py +4 -0
- pyinfra/facts/pkgin.py +5 -0
- pyinfra/facts/podman.py +7 -0
- pyinfra/facts/postgres.py +8 -2
- pyinfra/facts/rpm.py +11 -0
- pyinfra/facts/runit.py +7 -0
- pyinfra/facts/selinux.py +16 -0
- pyinfra/facts/server.py +49 -3
- pyinfra/facts/snap.py +7 -0
- pyinfra/facts/systemd.py +5 -0
- pyinfra/facts/sysvinit.py +4 -0
- pyinfra/facts/upstart.py +5 -0
- pyinfra/facts/util/__init__.py +4 -1
- pyinfra/facts/vzctl.py +5 -0
- pyinfra/facts/xbps.py +6 -1
- pyinfra/facts/yum.py +5 -0
- pyinfra/facts/zfs.py +19 -2
- pyinfra/facts/zypper.py +5 -0
- pyinfra/operations/apt.py +10 -3
- pyinfra/operations/docker.py +48 -44
- pyinfra/operations/files.py +47 -1
- pyinfra/operations/freebsd/__init__.py +12 -0
- pyinfra/operations/freebsd/freebsd_update.py +70 -0
- pyinfra/operations/freebsd/pkg.py +219 -0
- pyinfra/operations/freebsd/service.py +116 -0
- pyinfra/operations/freebsd/sysrc.py +92 -0
- pyinfra/operations/opkg.py +5 -5
- pyinfra/operations/postgres.py +99 -16
- pyinfra/operations/server.py +6 -4
- pyinfra/operations/util/docker.py +44 -22
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/LICENSE.md +1 -1
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/METADATA +25 -24
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/RECORD +88 -82
- pyinfra_cli/exceptions.py +5 -0
- pyinfra_cli/log.py +3 -0
- pyinfra_cli/main.py +9 -8
- pyinfra_cli/prints.py +1 -1
- pyinfra_cli/virtualenv.py +1 -1
- tests/test_connectors/test_ssh.py +302 -182
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/WHEEL +0 -0
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/entry_points.txt +0 -0
- {pyinfra-3.2.dist-info → pyinfra-3.3.dist-info}/top_level.txt +0 -0
pyinfra/operations/opkg.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
Manage packages on OpenWrt using opkg
|
|
3
|
+
+ ``update`` - update local copy of package information
|
|
4
|
+
+ ``packages`` - install and remove packages
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
see https://openwrt.org/docs/guide-user/additional-software/opkg
|
|
7
|
+
OpenWrt recommends against upgrading all packages thus there is no ``opkg.upgrade`` function
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
from typing import List, Union
|
pyinfra/operations/postgres.py
CHANGED
|
@@ -56,14 +56,14 @@ def sql(
|
|
|
56
56
|
@operation()
|
|
57
57
|
def role(
|
|
58
58
|
role: str,
|
|
59
|
-
present=True,
|
|
59
|
+
present: bool = True,
|
|
60
60
|
password: str | None = None,
|
|
61
|
-
login=True,
|
|
62
|
-
superuser=False,
|
|
63
|
-
inherit=False,
|
|
64
|
-
createdb=False,
|
|
65
|
-
createrole=False,
|
|
66
|
-
replication=False,
|
|
61
|
+
login: bool = True,
|
|
62
|
+
superuser: bool = False,
|
|
63
|
+
inherit: bool = False,
|
|
64
|
+
createdb: bool = False,
|
|
65
|
+
createrole: bool = False,
|
|
66
|
+
replication: bool = False,
|
|
67
67
|
connection_limit: int | None = None,
|
|
68
68
|
# Details for speaking to PostgreSQL via `psql` CLI
|
|
69
69
|
psql_user: str | None = None,
|
|
@@ -102,7 +102,7 @@ def role(
|
|
|
102
102
|
password="somepassword",
|
|
103
103
|
superuser=True,
|
|
104
104
|
login=True,
|
|
105
|
-
|
|
105
|
+
_sudo_user="postgres",
|
|
106
106
|
)
|
|
107
107
|
|
|
108
108
|
"""
|
|
@@ -163,7 +163,47 @@ def role(
|
|
|
163
163
|
database=psql_database,
|
|
164
164
|
)
|
|
165
165
|
else:
|
|
166
|
-
|
|
166
|
+
# Check if any attributes need updating
|
|
167
|
+
current_role = roles[role]
|
|
168
|
+
should_execute = False
|
|
169
|
+
sql_bits = ['ALTER ROLE "{0}"'.format(role)]
|
|
170
|
+
if login and "login" in current_role and current_role["login"] != login:
|
|
171
|
+
sql_bits.append("LOGIN")
|
|
172
|
+
should_execute = True
|
|
173
|
+
if superuser and "superuser" in current_role and current_role["superuser"] != superuser:
|
|
174
|
+
sql_bits.append("SUPERUSER")
|
|
175
|
+
should_execute = True
|
|
176
|
+
if inherit and "inherit" in current_role and current_role["inherit"] != inherit:
|
|
177
|
+
sql_bits.append("INHERIT")
|
|
178
|
+
should_execute = True
|
|
179
|
+
if createdb and "createdb" in current_role and current_role["createdb"] != createdb:
|
|
180
|
+
sql_bits.append("CREATEDB")
|
|
181
|
+
should_execute = True
|
|
182
|
+
if createrole and "createrole" in current_role and current_role["createrole"] != createrole:
|
|
183
|
+
sql_bits.append("CREATEROLE")
|
|
184
|
+
should_execute = True
|
|
185
|
+
if (
|
|
186
|
+
connection_limit
|
|
187
|
+
and "connection_limit" in current_role
|
|
188
|
+
and roles[role]["connection_limit"] != connection_limit
|
|
189
|
+
):
|
|
190
|
+
sql_bits.append("CONNECTION LIMIT {0}".format(connection_limit))
|
|
191
|
+
should_execute = True
|
|
192
|
+
if password:
|
|
193
|
+
sql_bits.append(MaskString("PASSWORD '{0}'".format(password)))
|
|
194
|
+
should_execute = True
|
|
195
|
+
|
|
196
|
+
if should_execute:
|
|
197
|
+
yield make_execute_psql_command(
|
|
198
|
+
StringCommand(*sql_bits),
|
|
199
|
+
user=psql_user,
|
|
200
|
+
password=psql_password,
|
|
201
|
+
host=psql_host,
|
|
202
|
+
port=psql_port,
|
|
203
|
+
database=psql_database,
|
|
204
|
+
)
|
|
205
|
+
else:
|
|
206
|
+
host.noop("postgresql role {0} exists and does not need updates".format(role))
|
|
167
207
|
|
|
168
208
|
|
|
169
209
|
@operation()
|
|
@@ -199,9 +239,8 @@ def database(
|
|
|
199
239
|
+ psql_*: global module arguments, see above
|
|
200
240
|
|
|
201
241
|
Updates:
|
|
202
|
-
pyinfra will
|
|
203
|
-
|
|
204
|
-
operation will make no changes).
|
|
242
|
+
pyinfra will change existing databases - but some parameters are not
|
|
243
|
+
changeable (template, encoding, lc_collate and lc_ctype).
|
|
205
244
|
|
|
206
245
|
**Example:**
|
|
207
246
|
|
|
@@ -212,7 +251,7 @@ def database(
|
|
|
212
251
|
database="pyinfra_stuff",
|
|
213
252
|
owner="pyinfra",
|
|
214
253
|
encoding="UTF8",
|
|
215
|
-
|
|
254
|
+
_sudo_user="postgres",
|
|
216
255
|
)
|
|
217
256
|
|
|
218
257
|
"""
|
|
@@ -250,8 +289,8 @@ def database(
|
|
|
250
289
|
("OWNER", '"{0}"'.format(owner) if owner else owner),
|
|
251
290
|
("TEMPLATE", template),
|
|
252
291
|
("ENCODING", encoding),
|
|
253
|
-
("LC_COLLATE", lc_collate),
|
|
254
|
-
("LC_CTYPE", lc_ctype),
|
|
292
|
+
("LC_COLLATE", "'{0}'".format(lc_collate) if lc_collate else lc_collate),
|
|
293
|
+
("LC_CTYPE", "'{0}'".format(lc_ctype) if lc_ctype else lc_ctype),
|
|
255
294
|
("TABLESPACE", tablespace),
|
|
256
295
|
("CONNECTION LIMIT", connection_limit),
|
|
257
296
|
):
|
|
@@ -267,7 +306,51 @@ def database(
|
|
|
267
306
|
database=psql_database,
|
|
268
307
|
)
|
|
269
308
|
else:
|
|
270
|
-
|
|
309
|
+
current_db = current_databases[database]
|
|
310
|
+
|
|
311
|
+
for key, value, current_value in (
|
|
312
|
+
("TEMPLATE", template, current_db.get("istemplate")),
|
|
313
|
+
("ENCODING", encoding, current_db.get("encoding")),
|
|
314
|
+
("LC_COLLATE", lc_collate, None),
|
|
315
|
+
("LC_CTYPE", lc_ctype, None),
|
|
316
|
+
):
|
|
317
|
+
if value and (current_value is None or current_value != value):
|
|
318
|
+
host.noop(
|
|
319
|
+
"postgresql database {0} already exists, skipping {1}".format(database, key)
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
sql_bits = []
|
|
323
|
+
|
|
324
|
+
if owner and "owner" in current_db and current_db["owner"] != owner:
|
|
325
|
+
sql_bits.append('ALTER DATABASE "{0}" OWNER TO "{1}";'.format(database, owner))
|
|
326
|
+
|
|
327
|
+
if tablespace and "tablespace" in current_db and current_db["tablespace"] != tablespace:
|
|
328
|
+
sql_bits.append(
|
|
329
|
+
'ALTER DATABASE "{0}" SET TABLESPACE "{1}";'.format(database, tablespace)
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
if (
|
|
333
|
+
connection_limit
|
|
334
|
+
and "connlimit" in current_db
|
|
335
|
+
and current_db["connlimit"] != connection_limit
|
|
336
|
+
):
|
|
337
|
+
sql_bits.append(
|
|
338
|
+
'ALTER DATABASE "{0}" CONNECTION LIMIT {1};'.format(database, connection_limit)
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
if len(sql_bits) > 0:
|
|
342
|
+
yield make_execute_psql_command(
|
|
343
|
+
StringCommand(*sql_bits),
|
|
344
|
+
user=psql_user,
|
|
345
|
+
password=psql_password,
|
|
346
|
+
host=psql_host,
|
|
347
|
+
port=psql_port,
|
|
348
|
+
database=psql_database,
|
|
349
|
+
)
|
|
350
|
+
else:
|
|
351
|
+
host.noop(
|
|
352
|
+
"postgresql database {0} already exists with the same parameters".format(database)
|
|
353
|
+
)
|
|
271
354
|
|
|
272
355
|
|
|
273
356
|
@operation(is_idempotent=False)
|
pyinfra/operations/server.py
CHANGED
|
@@ -437,7 +437,7 @@ def sysctl(
|
|
|
437
437
|
existing_sysctls = host.get_fact(Sysctl, keys=[key])
|
|
438
438
|
existing_value = existing_sysctls.get(key)
|
|
439
439
|
|
|
440
|
-
if
|
|
440
|
+
if existing_value != value:
|
|
441
441
|
yield "sysctl {0}='{1}'".format(key, string_value)
|
|
442
442
|
else:
|
|
443
443
|
host.noop("sysctl {0} is set to {1}".format(key, string_value))
|
|
@@ -764,6 +764,7 @@ def user(
|
|
|
764
764
|
shell: str | None = None,
|
|
765
765
|
group: str | None = None,
|
|
766
766
|
groups: list[str] | None = None,
|
|
767
|
+
append=False,
|
|
767
768
|
public_keys: str | list[str] | None = None,
|
|
768
769
|
delete_keys=False,
|
|
769
770
|
ensure_home=True,
|
|
@@ -771,7 +772,6 @@ def user(
|
|
|
771
772
|
system=False,
|
|
772
773
|
uid: int | None = None,
|
|
773
774
|
comment: str | None = None,
|
|
774
|
-
add_deploy_dir=True,
|
|
775
775
|
unique=True,
|
|
776
776
|
password: str | None = None,
|
|
777
777
|
):
|
|
@@ -784,14 +784,14 @@ def user(
|
|
|
784
784
|
+ shell: the users shell
|
|
785
785
|
+ group: the users primary group
|
|
786
786
|
+ groups: the users secondary groups
|
|
787
|
+
+ append: whether to add `user` to `groups`, w/o losing membership of other groups
|
|
787
788
|
+ public_keys: list of public keys to attach to this user, ``home`` must be specified
|
|
788
789
|
+ delete_keys: whether to remove any keys not specified in ``public_keys``
|
|
789
790
|
+ ensure_home: whether to ensure the ``home`` directory exists
|
|
790
|
-
+ create_home: whether
|
|
791
|
+
+ create_home: whether user create new user home directories from the system skeleton
|
|
791
792
|
+ system: whether to create a system account
|
|
792
793
|
+ uid: use a specific userid number
|
|
793
794
|
+ comment: the user GECOS comment
|
|
794
|
-
+ add_deploy_dir: any public_key filenames are relative to the deploy directory
|
|
795
795
|
+ unique: prevent creating users with duplicate UID
|
|
796
796
|
+ password: set the encrypted password for the user
|
|
797
797
|
|
|
@@ -931,6 +931,8 @@ def user(
|
|
|
931
931
|
|
|
932
932
|
# Check secondary groups, if defined
|
|
933
933
|
if groups and set(existing_user["groups"]) != set(groups):
|
|
934
|
+
if append:
|
|
935
|
+
args.append("-a")
|
|
934
936
|
args.append("-G {0}".format(",".join(groups)))
|
|
935
937
|
|
|
936
938
|
if comment and existing_user["comment"] != comment:
|
|
@@ -1,38 +1,60 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
from typing import Any, Dict, List
|
|
3
|
+
|
|
1
4
|
from pyinfra.api import OperationError
|
|
2
5
|
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
7
|
+
@dataclasses.dataclass
|
|
8
|
+
class ContainerSpec:
|
|
9
|
+
image: str = ""
|
|
10
|
+
ports: List[str] = dataclasses.field(default_factory=list)
|
|
11
|
+
networks: List[str] = dataclasses.field(default_factory=list)
|
|
12
|
+
volumes: List[str] = dataclasses.field(default_factory=list)
|
|
13
|
+
env_vars: List[str] = dataclasses.field(default_factory=list)
|
|
14
|
+
pull_always: bool = False
|
|
15
|
+
|
|
16
|
+
def container_create_args(self):
|
|
17
|
+
args = []
|
|
18
|
+
for network in self.networks:
|
|
19
|
+
args.append("--network {0}".format(network))
|
|
6
20
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
volumes = kwargs["volumes"] if kwargs["volumes"] else []
|
|
10
|
-
env_vars = kwargs["env_vars"] if kwargs["env_vars"] else []
|
|
21
|
+
for port in self.ports:
|
|
22
|
+
args.append("-p {0}".format(port))
|
|
11
23
|
|
|
12
|
-
|
|
13
|
-
|
|
24
|
+
for volume in self.volumes:
|
|
25
|
+
args.append("-v {0}".format(volume))
|
|
14
26
|
|
|
15
|
-
|
|
27
|
+
for env_var in self.env_vars:
|
|
28
|
+
args.append("-e {0}".format(env_var))
|
|
16
29
|
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
if self.pull_always:
|
|
31
|
+
args.append("--pull always")
|
|
19
32
|
|
|
20
|
-
|
|
21
|
-
command.append("-p {0}".format(port))
|
|
33
|
+
args.append(self.image)
|
|
22
34
|
|
|
23
|
-
|
|
24
|
-
command.append("-v {0}".format(volume))
|
|
35
|
+
return args
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
def diff_from_inspect(self, inspect_dict: Dict[str, Any]) -> List[str]:
|
|
38
|
+
# TODO(@minor-fixes): Diff output of "docker inspect" against this spec
|
|
39
|
+
# to determine if the container needs to be recreated. Currently, this
|
|
40
|
+
# function will never recreate when attributes change, which is
|
|
41
|
+
# consistent with prior behavior.
|
|
42
|
+
del inspect_dict
|
|
43
|
+
return []
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _create_container(**kwargs):
|
|
47
|
+
if "spec" not in kwargs:
|
|
48
|
+
raise OperationError("missing 1 required argument: 'spec'")
|
|
28
49
|
|
|
29
|
-
|
|
30
|
-
command.append("--pull always")
|
|
50
|
+
spec = kwargs["spec"]
|
|
31
51
|
|
|
32
|
-
|
|
52
|
+
if not spec.image:
|
|
53
|
+
raise OperationError("Docker image not specified")
|
|
33
54
|
|
|
34
|
-
|
|
35
|
-
|
|
55
|
+
command = [
|
|
56
|
+
"docker container create --name {0}".format(kwargs["container"])
|
|
57
|
+
] + spec.container_create_args()
|
|
36
58
|
|
|
37
59
|
return " ".join(command)
|
|
38
60
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright (C)
|
|
1
|
+
Copyright (C) 2025 Nick Barrett <nick@fizzadar.com>
|
|
2
2
|
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
4
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pyinfra
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3
|
|
4
4
|
Summary: pyinfra automates/provisions/manages/deploys infrastructure.
|
|
5
5
|
Home-page: https://pyinfra.com
|
|
6
6
|
Author: Nick / Fizzadar
|
|
@@ -16,7 +16,6 @@ Classifier: Intended Audience :: Information Technology
|
|
|
16
16
|
Classifier: License :: OSI Approved :: MIT License
|
|
17
17
|
Classifier: Operating System :: OS Independent
|
|
18
18
|
Classifier: Programming Language :: Python :: 3
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.9
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -24,7 +23,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
24
23
|
Classifier: Topic :: System :: Systems Administration
|
|
25
24
|
Classifier: Topic :: System :: Installation/Setup
|
|
26
25
|
Classifier: Topic :: Utilities
|
|
27
|
-
Requires-Python: >=3.
|
|
26
|
+
Requires-Python: >=3.9
|
|
28
27
|
Description-Content-Type: text/markdown
|
|
29
28
|
License-File: LICENSE.md
|
|
30
29
|
Requires-Dist: gevent >=1.5
|
|
@@ -41,43 +40,45 @@ Requires-Dist: importlib-metadata >=3.6 ; python_version < "3.10"
|
|
|
41
40
|
Requires-Dist: typing-extensions ; python_version < "3.11"
|
|
42
41
|
Requires-Dist: graphlib-backport ; python_version < "3.9"
|
|
43
42
|
Provides-Extra: dev
|
|
44
|
-
Requires-Dist: pytest ==8.3.
|
|
45
|
-
Requires-Dist: coverage ==7.
|
|
46
|
-
Requires-Dist: pytest-cov ==
|
|
47
|
-
Requires-Dist: black ==
|
|
48
|
-
Requires-Dist: isort ==
|
|
49
|
-
Requires-Dist: flake8 ==7.1.
|
|
43
|
+
Requires-Dist: pytest ==8.3.5 ; extra == 'dev'
|
|
44
|
+
Requires-Dist: coverage ==7.7.1 ; extra == 'dev'
|
|
45
|
+
Requires-Dist: pytest-cov ==6.0.0 ; extra == 'dev'
|
|
46
|
+
Requires-Dist: black ==25.1.0 ; extra == 'dev'
|
|
47
|
+
Requires-Dist: isort ==6.0.1 ; extra == 'dev'
|
|
48
|
+
Requires-Dist: flake8 ==7.1.2 ; extra == 'dev'
|
|
50
49
|
Requires-Dist: flake8-black ==0.3.6 ; extra == 'dev'
|
|
51
|
-
Requires-Dist: flake8-isort ==6.1.
|
|
50
|
+
Requires-Dist: flake8-isort ==6.1.2 ; extra == 'dev'
|
|
51
|
+
Requires-Dist: pyyaml ==6.0.2 ; extra == 'dev'
|
|
52
52
|
Requires-Dist: mypy ; extra == 'dev'
|
|
53
53
|
Requires-Dist: types-cryptography ; extra == 'dev'
|
|
54
54
|
Requires-Dist: types-paramiko ; extra == 'dev'
|
|
55
55
|
Requires-Dist: types-python-dateutil ; extra == 'dev'
|
|
56
56
|
Requires-Dist: types-PyYAML ; extra == 'dev'
|
|
57
57
|
Requires-Dist: types-setuptools ; extra == 'dev'
|
|
58
|
-
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.
|
|
59
|
-
Requires-Dist: myst-parser ==
|
|
60
|
-
Requires-Dist: sphinx ==
|
|
58
|
+
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.17 ; extra == 'dev'
|
|
59
|
+
Requires-Dist: myst-parser ==4.0.1 ; extra == 'dev'
|
|
60
|
+
Requires-Dist: sphinx ==8.2.3 ; extra == 'dev'
|
|
61
61
|
Requires-Dist: wheel ; extra == 'dev'
|
|
62
62
|
Requires-Dist: twine ; extra == 'dev'
|
|
63
63
|
Requires-Dist: ipython ; extra == 'dev'
|
|
64
64
|
Requires-Dist: ipdb ; extra == 'dev'
|
|
65
65
|
Requires-Dist: ipdbplugin ; extra == 'dev'
|
|
66
|
-
Requires-Dist: flake8-spellcheck ==0.
|
|
66
|
+
Requires-Dist: flake8-spellcheck ==0.28.0 ; extra == 'dev'
|
|
67
67
|
Requires-Dist: redbaron ; extra == 'dev'
|
|
68
68
|
Provides-Extra: docs
|
|
69
|
-
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.
|
|
70
|
-
Requires-Dist: myst-parser ==
|
|
71
|
-
Requires-Dist: sphinx ==
|
|
69
|
+
Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.17 ; extra == 'docs'
|
|
70
|
+
Requires-Dist: myst-parser ==4.0.1 ; extra == 'docs'
|
|
71
|
+
Requires-Dist: sphinx ==8.2.3 ; extra == 'docs'
|
|
72
72
|
Provides-Extra: test
|
|
73
|
-
Requires-Dist: pytest ==8.3.
|
|
74
|
-
Requires-Dist: coverage ==7.
|
|
75
|
-
Requires-Dist: pytest-cov ==
|
|
76
|
-
Requires-Dist: black ==
|
|
77
|
-
Requires-Dist: isort ==
|
|
78
|
-
Requires-Dist: flake8 ==7.1.
|
|
73
|
+
Requires-Dist: pytest ==8.3.5 ; extra == 'test'
|
|
74
|
+
Requires-Dist: coverage ==7.7.1 ; extra == 'test'
|
|
75
|
+
Requires-Dist: pytest-cov ==6.0.0 ; extra == 'test'
|
|
76
|
+
Requires-Dist: black ==25.1.0 ; extra == 'test'
|
|
77
|
+
Requires-Dist: isort ==6.0.1 ; extra == 'test'
|
|
78
|
+
Requires-Dist: flake8 ==7.1.2 ; extra == 'test'
|
|
79
79
|
Requires-Dist: flake8-black ==0.3.6 ; extra == 'test'
|
|
80
|
-
Requires-Dist: flake8-isort ==6.1.
|
|
80
|
+
Requires-Dist: flake8-isort ==6.1.2 ; extra == 'test'
|
|
81
|
+
Requires-Dist: pyyaml ==6.0.2 ; extra == 'test'
|
|
81
82
|
Requires-Dist: mypy ; extra == 'test'
|
|
82
83
|
Requires-Dist: types-cryptography ; extra == 'test'
|
|
83
84
|
Requires-Dist: types-paramiko ; extra == 'test'
|