pyinfra 3.3__py2.py3-none-any.whl → 3.4__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.
Files changed (47) hide show
  1. pyinfra/api/arguments.py +8 -16
  2. pyinfra/api/deploy.py +1 -1
  3. pyinfra/api/facts.py +10 -26
  4. pyinfra/api/host.py +10 -4
  5. pyinfra/api/inventory.py +5 -2
  6. pyinfra/api/operation.py +1 -1
  7. pyinfra/api/util.py +20 -6
  8. pyinfra/connectors/docker.py +117 -38
  9. pyinfra/connectors/dockerssh.py +1 -0
  10. pyinfra/connectors/local.py +1 -0
  11. pyinfra/connectors/ssh.py +1 -0
  12. pyinfra/connectors/sshuserclient/client.py +5 -5
  13. pyinfra/connectors/terraform.py +3 -0
  14. pyinfra/connectors/vagrant.py +3 -0
  15. pyinfra/context.py +14 -5
  16. pyinfra/facts/brew.py +1 -0
  17. pyinfra/facts/docker.py +6 -2
  18. pyinfra/facts/git.py +10 -0
  19. pyinfra/facts/hardware.py +1 -1
  20. pyinfra/facts/opkg.py +1 -0
  21. pyinfra/facts/server.py +81 -23
  22. pyinfra/facts/systemd.py +1 -1
  23. pyinfra/operations/crontab.py +7 -5
  24. pyinfra/operations/docker.py +2 -0
  25. pyinfra/operations/files.py +64 -21
  26. pyinfra/operations/flatpak.py +17 -2
  27. pyinfra/operations/git.py +6 -2
  28. pyinfra/operations/server.py +34 -24
  29. pyinfra/operations/util/docker.py +4 -0
  30. pyinfra/operations/util/files.py +44 -3
  31. {pyinfra-3.3.dist-info → pyinfra-3.4.dist-info}/METADATA +5 -4
  32. {pyinfra-3.3.dist-info → pyinfra-3.4.dist-info}/RECORD +47 -47
  33. {pyinfra-3.3.dist-info → pyinfra-3.4.dist-info}/entry_points.txt +1 -0
  34. pyinfra_cli/inventory.py +1 -1
  35. pyinfra_cli/main.py +4 -2
  36. tests/test_api/test_api_arguments.py +25 -20
  37. tests/test_api/test_api_facts.py +28 -15
  38. tests/test_api/test_api_operations.py +43 -44
  39. tests/test_cli/test_cli.py +17 -17
  40. tests/test_cli/test_cli_inventory.py +4 -4
  41. tests/test_cli/test_context_objects.py +26 -26
  42. tests/test_connectors/test_docker.py +83 -43
  43. tests/test_connectors/test_ssh.py +153 -132
  44. tests/test_connectors/test_sshuserclient.py +10 -5
  45. {pyinfra-3.3.dist-info → pyinfra-3.4.dist-info}/LICENSE.md +0 -0
  46. {pyinfra-3.3.dist-info → pyinfra-3.4.dist-info}/WHEEL +0 -0
  47. {pyinfra-3.3.dist-info → pyinfra-3.4.dist-info}/top_level.txt +0 -0
@@ -20,6 +20,7 @@ from pyinfra.facts.server import (
20
20
  Groups,
21
21
  Home,
22
22
  Hostname,
23
+ Kernel,
23
24
  KernelModules,
24
25
  Locales,
25
26
  Mounts,
@@ -335,7 +336,15 @@ def mount(
335
336
  mounted_options = mounts[path]["options"]
336
337
  needed_options = set(options) - set(mounted_options)
337
338
  if needed_options:
338
- yield "mount -o remount,{0} {1}".format(options_string, path)
339
+ if host.get_fact(Kernel).strip() == "FreeBSD":
340
+ fs_type = mounts[path]["type"]
341
+ device = mounts[path]["device"]
342
+
343
+ yield "mount -o update,{options} -t {fs_type} {device} {path}".format(
344
+ options=options_string, fs_type=fs_type, device=device, path=path
345
+ )
346
+ else:
347
+ yield "mount -o remount,{0} {1}".format(options_string, path)
339
348
 
340
349
  else:
341
350
  host.noop(
@@ -890,22 +899,29 @@ def user(
890
899
 
891
900
  if create_home:
892
901
  args.append("-m")
893
- else:
902
+ elif os_type != "FreeBSD":
894
903
  args.append("-M")
895
904
 
896
- if password:
905
+ if password and os_type != "FreeBSD":
897
906
  args.append("-p '{0}'".format(password))
898
907
 
899
908
  # Users are often added by other operations (package installs), so check
900
909
  # for the user at runtime before adding.
901
910
  add_user_command = "useradd"
911
+
902
912
  if os_type == "FreeBSD":
903
913
  add_user_command = "pw useradd"
904
- yield "{0} -n {2} {1}".format(
905
- add_user_command,
906
- " ".join(args),
907
- user,
908
- )
914
+
915
+ if password:
916
+ yield "echo '{3}' | {0} -n {2} -H 0 {1}".format(
917
+ add_user_command, " ".join(args), user, password
918
+ )
919
+ else:
920
+ yield "{0} -n {2} {1}".format(
921
+ add_user_command,
922
+ " ".join(args),
923
+ user,
924
+ )
909
925
  else:
910
926
  yield "{0} {1} {2}".format(
911
927
  add_user_command,
@@ -930,16 +946,22 @@ def user(
930
946
  args.append("-g {0}".format(group))
931
947
 
932
948
  # Check secondary groups, if defined
933
- if groups and set(existing_user["groups"]) != set(groups):
949
+ if groups:
934
950
  if append:
935
- args.append("-a")
936
- args.append("-G {0}".format(",".join(groups)))
951
+ if not set(groups).issubset(existing_user["groups"]):
952
+ args.append("-a")
953
+ args.append("-G {0}".format(",".join(groups)))
954
+ elif set(existing_user["groups"]) != set(groups):
955
+ args.append("-G {0}".format(",".join(groups)))
937
956
 
938
957
  if comment and existing_user["comment"] != comment:
939
958
  args.append("-c '{0}'".format(comment))
940
959
 
941
960
  if password and existing_user["password"] != password:
942
- args.append("-p '{0}'".format(password))
961
+ if os_type == "FreeBSD":
962
+ yield "echo '{0}' | pw usermod -n {1} -H 0".format(password, user)
963
+ else:
964
+ args.append("-p '{0}'".format(password))
943
965
 
944
966
  # Need to mod the user?
945
967
  if args:
@@ -947,18 +969,6 @@ def user(
947
969
  yield "pw usermod -n {1} {0}".format(" ".join(args), user)
948
970
  else:
949
971
  yield "usermod {0} {1}".format(" ".join(args), user)
950
- if comment:
951
- existing_user["comment"] = comment
952
- if home:
953
- existing_user["home"] = home
954
- if shell:
955
- existing_user["shell"] = shell
956
- if group:
957
- existing_user["group"] = group
958
- if groups:
959
- existing_user["groups"] = groups
960
- if password:
961
- existing_user["password"] = password
962
972
 
963
973
  # Ensure home directory ownership
964
974
  if ensure_home and home:
@@ -117,6 +117,7 @@ def _remove_volume(**kwargs):
117
117
 
118
118
  def _create_network(**kwargs):
119
119
  command = []
120
+ aux_addresses = kwargs["aux_addresses"] if kwargs["aux_addresses"] else {}
120
121
  opts = kwargs["opts"] if kwargs["opts"] else []
121
122
  ipam_opts = kwargs["ipam_opts"] if kwargs["ipam_opts"] else []
122
123
  labels = kwargs["labels"] if kwargs["labels"] else []
@@ -146,6 +147,9 @@ def _create_network(**kwargs):
146
147
  if kwargs["attachable"]:
147
148
  command.append("--attachable")
148
149
 
150
+ for host, address in aux_addresses.items():
151
+ command.append("--aux-address '{0}={1}'".format(host, address))
152
+
149
153
  for opt in opts:
150
154
  command.append("--opt {0}".format(opt))
151
155
 
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import re
4
4
  from datetime import datetime
5
+ from typing import Callable
5
6
 
6
7
  from pyinfra.api import QuoteString, StringCommand
7
8
 
@@ -32,6 +33,34 @@ def get_timestamp() -> str:
32
33
  return datetime.now().strftime("%y%m%d%H%M")
33
34
 
34
35
 
36
+ _sed_ignore_case = re.compile("[iI]")
37
+
38
+
39
+ def _sed_delete_builder(line: str, replace: str, flags: str, interpolate_variables: bool) -> str:
40
+ return (
41
+ '"/{0}/{1}d"' if interpolate_variables else # fmt: skip
42
+ "'/{0}/{1}d'"
43
+ ).format(line, "I" if _sed_ignore_case.search(flags) else "")
44
+
45
+
46
+ def sed_delete(
47
+ filename: str,
48
+ line: str,
49
+ replace: str,
50
+ flags: list[str] | None = None,
51
+ backup=False,
52
+ interpolate_variables=False,
53
+ ) -> StringCommand:
54
+ return _sed_command(**locals(), sed_script_builder=_sed_delete_builder)
55
+
56
+
57
+ def _sed_replace_builder(line: str, replace: str, flags: str, interpolate_variables: bool) -> str:
58
+ return (
59
+ '"s/{0}/{1}/{2}"' if interpolate_variables else # fmt: skip
60
+ "'s/{0}/{1}/{2}'"
61
+ ).format(line, replace, flags)
62
+
63
+
35
64
  def sed_replace(
36
65
  filename: str,
37
66
  line: str,
@@ -39,6 +68,20 @@ def sed_replace(
39
68
  flags: list[str] | None = None,
40
69
  backup=False,
41
70
  interpolate_variables=False,
71
+ ) -> StringCommand:
72
+ return _sed_command(**locals(), sed_script_builder=_sed_replace_builder)
73
+
74
+
75
+ def _sed_command(
76
+ filename: str,
77
+ line: str,
78
+ replace: str,
79
+ flags: list[str] | None = None,
80
+ backup=False,
81
+ interpolate_variables=False,
82
+ # Python requires a default value here, so use _sed_replace_builder for
83
+ # backwards compatibility.
84
+ sed_script_builder: Callable[[str, str, str, bool], str] = _sed_replace_builder,
42
85
  ) -> StringCommand:
43
86
  flags_str = "".join(flags) if flags else ""
44
87
 
@@ -51,15 +94,13 @@ def sed_replace(
51
94
  if interpolate_variables:
52
95
  line = line.replace('"', '\\"')
53
96
  replace = replace.replace('"', '\\"')
54
- sed_script_formatter = '"s/{0}/{1}/{2}"'
55
97
  else:
56
98
  # Single quotes cannot contain other single quotes, even when escaped , so turn
57
99
  # each ' into '"'"' (end string, double quote the single quote, (re)start string)
58
100
  line = line.replace("'", "'\"'\"'")
59
101
  replace = replace.replace("'", "'\"'\"'")
60
- sed_script_formatter = "'s/{0}/{1}/{2}'"
61
102
 
62
- sed_script = sed_script_formatter.format(line, replace, flags_str)
103
+ sed_script = sed_script_builder(line, replace, flags_str, interpolate_variables)
63
104
 
64
105
  sed_command = StringCommand(
65
106
  "sed",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyinfra
3
- Version: 3.3
3
+ Version: 3.4
4
4
  Summary: pyinfra automates/provisions/manages/deploys infrastructure.
5
5
  Home-page: https://pyinfra.com
6
6
  Author: Nick / Fizzadar
@@ -31,7 +31,6 @@ Requires-Dist: paramiko <4,>=2.7
31
31
  Requires-Dist: click >2
32
32
  Requires-Dist: jinja2 <4,>2
33
33
  Requires-Dist: python-dateutil <3,>2
34
- Requires-Dist: setuptools
35
34
  Requires-Dist: pywinrm
36
35
  Requires-Dist: typeguard
37
36
  Requires-Dist: distro <2,>=1.6
@@ -40,9 +39,11 @@ Requires-Dist: importlib-metadata >=3.6 ; python_version < "3.10"
40
39
  Requires-Dist: typing-extensions ; python_version < "3.11"
41
40
  Requires-Dist: graphlib-backport ; python_version < "3.9"
42
41
  Provides-Extra: dev
42
+ Requires-Dist: click >=8.2 ; extra == 'dev'
43
43
  Requires-Dist: pytest ==8.3.5 ; extra == 'dev'
44
44
  Requires-Dist: coverage ==7.7.1 ; extra == 'dev'
45
45
  Requires-Dist: pytest-cov ==6.0.0 ; extra == 'dev'
46
+ Requires-Dist: pytest-testinfra ==10.2.2 ; extra == 'dev'
46
47
  Requires-Dist: black ==25.1.0 ; extra == 'dev'
47
48
  Requires-Dist: isort ==6.0.1 ; extra == 'dev'
48
49
  Requires-Dist: flake8 ==7.1.2 ; extra == 'dev'
@@ -54,7 +55,6 @@ Requires-Dist: types-cryptography ; extra == 'dev'
54
55
  Requires-Dist: types-paramiko ; extra == 'dev'
55
56
  Requires-Dist: types-python-dateutil ; extra == 'dev'
56
57
  Requires-Dist: types-PyYAML ; extra == 'dev'
57
- Requires-Dist: types-setuptools ; extra == 'dev'
58
58
  Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.17 ; extra == 'dev'
59
59
  Requires-Dist: myst-parser ==4.0.1 ; extra == 'dev'
60
60
  Requires-Dist: sphinx ==8.2.3 ; extra == 'dev'
@@ -70,9 +70,11 @@ Requires-Dist: pyinfra-guzzle-sphinx-theme ==0.17 ; extra == 'docs'
70
70
  Requires-Dist: myst-parser ==4.0.1 ; extra == 'docs'
71
71
  Requires-Dist: sphinx ==8.2.3 ; extra == 'docs'
72
72
  Provides-Extra: test
73
+ Requires-Dist: click >=8.2 ; extra == 'test'
73
74
  Requires-Dist: pytest ==8.3.5 ; extra == 'test'
74
75
  Requires-Dist: coverage ==7.7.1 ; extra == 'test'
75
76
  Requires-Dist: pytest-cov ==6.0.0 ; extra == 'test'
77
+ Requires-Dist: pytest-testinfra ==10.2.2 ; extra == 'test'
76
78
  Requires-Dist: black ==25.1.0 ; extra == 'test'
77
79
  Requires-Dist: isort ==6.0.1 ; extra == 'test'
78
80
  Requires-Dist: flake8 ==7.1.2 ; extra == 'test'
@@ -84,7 +86,6 @@ Requires-Dist: types-cryptography ; extra == 'test'
84
86
  Requires-Dist: types-paramiko ; extra == 'test'
85
87
  Requires-Dist: types-python-dateutil ; extra == 'test'
86
88
  Requires-Dist: types-PyYAML ; extra == 'test'
87
- Requires-Dist: types-setuptools ; extra == 'test'
88
89
 
89
90
  <p align="center">
90
91
  <a href="https://pyinfra.com">
@@ -1,66 +1,66 @@
1
1
  pyinfra/__init__.py,sha256=7ZcKHGWk7_nYxsYrbFBB_vJr-J-Ddbc56ZS4sk5ArVw,535
2
2
  pyinfra/__main__.py,sha256=aVd00glLz5CMJGXgt1XxbOvC2HluqaowoTOjxgIpBaA,47
3
- pyinfra/context.py,sha256=CLUKJxvZm3VGtxMp6OlZnhYvZBGevSnJYemSDhQRd6E,3534
3
+ pyinfra/context.py,sha256=HyJCarfQmbrdJ9Re_CNuzMwnfwINB3UFNz3chGatAdQ,3828
4
4
  pyinfra/local.py,sha256=wT84xkJc9UBN5isvIVbNpm2fzZaadwE-dkbAwaFQdZk,2808
5
5
  pyinfra/progress.py,sha256=X3hXZ4Flh_L9FE4ZEWxWoG0R4dA5UPd1FCO-Exd5Xtc,4193
6
6
  pyinfra/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  pyinfra/version.py,sha256=LZf50PHDzEZv65w0G-iMICoQ9US0U5LWHAOEmNtkF3I,216
8
8
  pyinfra/api/__init__.py,sha256=suGbKKM-qCduuXFYBEcyswlTqozewtYpdLRhK63PVn0,942
9
- pyinfra/api/arguments.py,sha256=GdkwOpBOUKCDer6gxXtChKmRD8iDr_1pQMXXv7jzfDw,10266
9
+ pyinfra/api/arguments.py,sha256=-R1qdnwLZ79gJL8ggHTxQjz2vJgJDZN_ds42RjdcYBA,10014
10
10
  pyinfra/api/arguments_typed.py,sha256=IZuhpmDfW9CP6ASS5Ie-3Wcnxl6bDNR3egU4Mfhbsb4,2303
11
11
  pyinfra/api/command.py,sha256=NwF2syxV3zxCbBdHzvJ6ve5G-xwdNTjPHFPwguKVcYs,7741
12
12
  pyinfra/api/config.py,sha256=LhmMKOoAaawSsrSnl55BBj63oT-U-Wn8nwgbe43kzd0,9113
13
13
  pyinfra/api/connect.py,sha256=Z9wusMLR_jBkKKk5D4AUOj8LHl3H5MsNO5FxAeR4jac,1416
14
14
  pyinfra/api/connectors.py,sha256=nie7JuLxMSC6gqPjmjuCisQ11R-eAQDtMMWF6YbSQ48,659
15
- pyinfra/api/deploy.py,sha256=CllKp1QYLseeMStj35waZazB0hUuy3iGvDt7b_lH31M,3138
15
+ pyinfra/api/deploy.py,sha256=Upd92oThQN0zhKbKW8vyPvBuoYiEGStuiEy7kNhZ00Y,3167
16
16
  pyinfra/api/exceptions.py,sha256=cCbUp1qN1QO0d9aAvOAbRgYpLi0vUI5j7ZqSjcD1_P8,1861
17
- pyinfra/api/facts.py,sha256=CoUtBfn5_O9oFHqwVEghQftH-Hc2XUBJI8LCEpn0nPc,9516
18
- pyinfra/api/host.py,sha256=KZr2ZvcCM3asrFkpKL25tQIGCr8lZFKTh1aoC2wIpyE,14002
19
- pyinfra/api/inventory.py,sha256=nPITdNEJ7q71adIqS_OKHsMjD7amUuHEuTl6xzgh1Gk,7734
20
- pyinfra/api/operation.py,sha256=tyslPCFmHDGydxf0Sv-QfDq1DzGGul9oOgKCXYEfusM,15194
17
+ pyinfra/api/facts.py,sha256=Hh9YCrqOppHdeUegOzmg6qbik5X6EyHPzhg8O_oF_Sg,9146
18
+ pyinfra/api/host.py,sha256=4a1bFR8vX8mUuXRZttXlzp2_ARzrg-xsH7n8uOxaaqQ,14098
19
+ pyinfra/api/inventory.py,sha256=i_LBI-Gn5FF-9SVDBH6xefTtvFzjuz12QQiFPGK2TrQ,7864
20
+ pyinfra/api/operation.py,sha256=_7R2piJDpkcUnC6rxbZjgkeGcWuwTHS5Aruboc8S-wI,15207
21
21
  pyinfra/api/operations.py,sha256=jvz9ISfwmQnAQVUKLnbrRdD9QHIAAfypo9l5b3fYG1w,10894
22
22
  pyinfra/api/state.py,sha256=IqdWT1Uwf_Rd5piqYLrf7y8HsXPs1hY6wCmxoRGqPTE,12630
23
- pyinfra/api/util.py,sha256=K4aFjGW7KAz2ZQqfRriRqyHMCQFFrX06WPola3epjaE,12410
23
+ pyinfra/api/util.py,sha256=62l3eLUhbcHm5N-Y58i7g8-NtAxuXakeOymDBptTjQ4,12838
24
24
  pyinfra/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
25
  pyinfra/connectors/base.py,sha256=0-BKInwTpjbnTakJhMTn_8LUOl81vUmC-q-HzVrwhkw,4703
26
26
  pyinfra/connectors/chroot.py,sha256=sQIM1nOLzyIvv7FsqgAZsZ71jJtWLAQB_uaeB4m4GqE,6007
27
- pyinfra/connectors/docker.py,sha256=bPbw9g9y5-WreD9drTRbDJ1x-CKuO-hgIDUZxuGc86s,9284
28
- pyinfra/connectors/dockerssh.py,sha256=sJxnmZ-xG19C9BSw6jx54zJhM3PH5ucmdTCZR2ywbrk,9007
29
- pyinfra/connectors/local.py,sha256=E57xCdBibo2M0IJQ7o6V5nTeBCCn_Bg6vmhydDhHagI,6976
30
- pyinfra/connectors/ssh.py,sha256=RF_0R8Vy8MFO8A6Eq-F3VjvZXVVWiN7dXVKaWt_5cww,21328
27
+ pyinfra/connectors/docker.py,sha256=At68g9Fx62Wm9dum0GLmQRkk0sr5NCYHWM6Zlfxx1Gc,11960
28
+ pyinfra/connectors/dockerssh.py,sha256=NGG6hSZ3z66RRKt6T0hnG2jiXFLR4P5uudi1COcGnY0,9021
29
+ pyinfra/connectors/local.py,sha256=DJMmZiPgeYvZyW0ANvWjCxF3elmDlmolkY0ktTW3rcg,6990
30
+ pyinfra/connectors/ssh.py,sha256=HmYHvPXVZKFsqWTtHzVrplyouk1ziv99hJN04ZUGeaY,21342
31
31
  pyinfra/connectors/ssh_util.py,sha256=CN_5AdTA3RpiWCnXTrRBjez1NsN59hITDzQmXIkZvoE,3683
32
- pyinfra/connectors/terraform.py,sha256=92KwojQKQhqRYuX3UE9ANRvj0Diwg3EEi6blTgu_LPk,4235
32
+ pyinfra/connectors/terraform.py,sha256=j-a2yStBLdw1QLZRVnl_9TanDtdyujyCxBO2Oa00rPM,4289
33
33
  pyinfra/connectors/util.py,sha256=Up7kToERfcyjoayY9K6-Xdwjg4-SO2THAy7jzzcznJ8,11651
34
- pyinfra/connectors/vagrant.py,sha256=oEeRglzRmemRXW3vilsp_Xg9qnZMRprRJO9fd_C-f5M,4759
34
+ pyinfra/connectors/vagrant.py,sha256=0TT73ks64I4Yl-JSZjMBbpWA3VYBkqqLB-fUS8pS8GY,4813
35
35
  pyinfra/connectors/sshuserclient/__init__.py,sha256=Qc4RO2wknSWIiNTwOeQ0y2TeiuKHmyWDW2Dz4MOo9CE,44
36
- pyinfra/connectors/sshuserclient/client.py,sha256=z4FpWJ9zX3TNdb1SM4g53m5XByADVSyu2A_oPcalj3I,10489
36
+ pyinfra/connectors/sshuserclient/client.py,sha256=Ei2_mzCMNJopbpvpeLsdSiNb98rxEEy7uCOmpJbfd2o,10506
37
37
  pyinfra/connectors/sshuserclient/config.py,sha256=FZkPrUYXkURZcFUHBGWw9lLC9uiH3DJ0rBYXJePchxw,2774
38
38
  pyinfra/facts/__init__.py,sha256=myTXSOZmAqmU88Fyifn035h9Lr6Gj2mlka_jDcXyKGw,347
39
39
  pyinfra/facts/apk.py,sha256=UEMHzhx2Wx3qq-OcjetWgE2iZ7_EjI-bszLxSN6PJa0,799
40
40
  pyinfra/facts/apt.py,sha256=RYPqGgdH0QpDIoMNhBY9nKtMu-baQNX4DIYNrsllcLQ,4026
41
- pyinfra/facts/brew.py,sha256=vkl3tr9U6gyx3UDZzanz3WXmvpZ3HqBpUGUxkxdnjU4,2778
41
+ pyinfra/facts/brew.py,sha256=nE6YVc2S9zasyJPZmPR5FMeGKPViZYEcpnnBQlDf1EU,2792
42
42
  pyinfra/facts/bsdinit.py,sha256=SVY4hagjyy1yz8FKWhIbX9fHm5AugvTFl4xQh2FFO74,631
43
43
  pyinfra/facts/cargo.py,sha256=qgOClhwZm4COcncDzOZccCzs67nPBi_x6VGiF2UA0sA,687
44
44
  pyinfra/facts/choco.py,sha256=mpLleSqNqiaGRgyrhgceno2iPB1_1yjn8UJ90pvOZCs,886
45
45
  pyinfra/facts/crontab.py,sha256=yCpBzBqgXt2BjAGCIttuQ2xKKtuhzg0VQ9WCDV46eV8,5754
46
46
  pyinfra/facts/deb.py,sha256=1dR1puwY5wyyhhYYwaEBLjKU9sIyaNBNBlamVZ2KQg0,2074
47
47
  pyinfra/facts/dnf.py,sha256=IFOJWeXMLYxSZEgleOCMZaBIZOzJzklwCmemZIUwDmk,1059
48
- pyinfra/facts/docker.py,sha256=KCHz0onAHXOtMlF8ljG7AOrDS57ajhE5RJ34qnTT1VA,2626
48
+ pyinfra/facts/docker.py,sha256=78jYZNUT6_9YFpECiULiBgSyt2stpqrnsrtL20zElx8,2772
49
49
  pyinfra/facts/efibootmgr.py,sha256=JPJSokE_RV9JstEPJRECnqSU-B0JCxmrocY8zBOva7M,3555
50
50
  pyinfra/facts/files.py,sha256=bnu3JSoWRdOR1Uxv9nBn1DbanBeF3kWet_rc-3Aj63s,15363
51
51
  pyinfra/facts/flatpak.py,sha256=ovi3duwTqqwvt5GoDRN7R-PpkvR6sQ1SmgEADcSnkUE,1646
52
52
  pyinfra/facts/freebsd.py,sha256=z7ZJRK8NV5HL-BfAdQs6pQKLEdrfdv7dVUmmOtVKUbA,2248
53
53
  pyinfra/facts/gem.py,sha256=aX2-vcEqkxUIP0UJ_SVp9bf4B944oyDjsuujjs5q_9w,654
54
- pyinfra/facts/git.py,sha256=os8zA2F8UbdX444VUedfL3zYFN_sKsumMjEo-H3isc4,1485
54
+ pyinfra/facts/git.py,sha256=Zfzpdccsz2InviirJO17EkEFTVNqYQclSlXJIRFkD_s,1699
55
55
  pyinfra/facts/gpg.py,sha256=8fvC9AglzmO08SAT_Py6H6G0i73soO1D2cSCbw-O9JA,3923
56
- pyinfra/facts/hardware.py,sha256=JKyz3gZxSXPcVaMuH7iKHOww5a4kbZTiLIQbNmvkF2Q,12217
56
+ pyinfra/facts/hardware.py,sha256=mta8hXPTlJ5j_5IdrXUfsDZAo4_89QjInuiT7DIxRYQ,12219
57
57
  pyinfra/facts/iptables.py,sha256=ORRExNnPR5ysymDbkUjeQWt9mzjSI7su4uQfsu3FlJQ,3506
58
58
  pyinfra/facts/launchd.py,sha256=Nl4EFbGwlXTj8GNWlS9UMZODHr63bve73xmMeqyf2gc,849
59
59
  pyinfra/facts/lxd.py,sha256=A2LQN5armY_nI6gV-m1j4l2J2_mMZnvVa1X2RntDnDk,548
60
60
  pyinfra/facts/mysql.py,sha256=ZVN6eN0Xetidvq_RAntSCzHgy4jmf8Enrm2mPXxO488,6247
61
61
  pyinfra/facts/npm.py,sha256=WzZHCfgWwY9WsPPzL0njlazwiBHI0gpvyZV93Nfu428,838
62
62
  pyinfra/facts/openrc.py,sha256=wB4fjzgWCgX6wexBm4jlWv4YH6b4z5_tAqQAO1qO9Kg,1614
63
- pyinfra/facts/opkg.py,sha256=o11yGcox2q5O8K_pvCxPqNywiV2lET9WJrgkeCU0Ahs,7390
63
+ pyinfra/facts/opkg.py,sha256=yTPuzoUyDDn-o7H97lPtyPe-FOkYg5zqkVmfKt9HwY4,7404
64
64
  pyinfra/facts/pacman.py,sha256=SPI3jpzZbq_VnJ0z5q7A2Rw___EHVntOz6M19ErGpmQ,1324
65
65
  pyinfra/facts/pip.py,sha256=MA2yed2_kVzLNjCulnCJEz4GeQ5dbGVtaAv4Bqm9fLw,820
66
66
  pyinfra/facts/pipx.py,sha256=3-oP0yHWvi__RGRlgkQzRKQBMwZN3Ke9A-z8oYB5upM,1854
@@ -72,9 +72,9 @@ pyinfra/facts/postgresql.py,sha256=4nusMVvGhtku86KX4O4vjSxh_MamxZy_kmTQvvy0GhE,2
72
72
  pyinfra/facts/rpm.py,sha256=ikuKYiUmjgvPA84qfE-gbq4Iv4AB5cvor1uKU6uHbXQ,2391
73
73
  pyinfra/facts/runit.py,sha256=qok1FTSshiNrN603vjYTKOeM-NIlxwLbwOp-vPbPySo,2131
74
74
  pyinfra/facts/selinux.py,sha256=8OylQ3H-huktRS34g5FYwivlp1wb4mKP0EFVf1LtMEE,4679
75
- pyinfra/facts/server.py,sha256=peaK4q2MGhFoKkQGTJ20rU1P9_YPrLQKNPmmw2VqYbA,19678
75
+ pyinfra/facts/server.py,sha256=_Th60Ya-P6Q89i7JDklzCn_jJ2Rb28i45riUbwTEjUM,21958
76
76
  pyinfra/facts/snap.py,sha256=2-c3z1qpOG7prmKJssLpOXmKo_wwdfROryro6gif2vo,2137
77
- pyinfra/facts/systemd.py,sha256=ua5ACLINcCwXv39gnU6HJuIYhQB896yi6-M6hSuUtsU,4309
77
+ pyinfra/facts/systemd.py,sha256=meHXURtnoxeJbmPzWFTwvhjQBZ2NlQCY8Tj-oHTG_dI,4320
78
78
  pyinfra/facts/sysvinit.py,sha256=q1OpHATFJxjLwatcnYRfpTR7_K2c29b4ppmZu-wgC-4,1589
79
79
  pyinfra/facts/upstart.py,sha256=GcreN0mIM6_qRgqzFaA7PnX45RtbBpvVC00J6bKujyA,717
80
80
  pyinfra/facts/vzctl.py,sha256=lUacmyakn2sJ2tD2FDAh1eeX3sxEVq7aRRwWM4QTguQ,760
@@ -94,13 +94,13 @@ pyinfra/operations/brew.py,sha256=aghLE4qyuhhRbt6fgSPV6_5fyWgTohA77Dc0gol19UU,51
94
94
  pyinfra/operations/bsdinit.py,sha256=okQUQDr2H8Z-cAdfdbPJiuGujsHLuV5gpuMZ1UlICEM,1648
95
95
  pyinfra/operations/cargo.py,sha256=mXWd6pb0IR6kzJMmPHwXZN-VJ-B_y8AdOFlrRzDQOZI,1104
96
96
  pyinfra/operations/choco.py,sha256=8nG0wc1tZEA0L0HTIjgR00IDiONARokyzHyKj-R3xmo,1515
97
- pyinfra/operations/crontab.py,sha256=qhYzj9xh-A6p95sJ0i_DDKOIm7WoNgiPjcR43ZB9iv8,6454
97
+ pyinfra/operations/crontab.py,sha256=tdgOSKTO71Nxto6rcBbuDZQRfzBYrR-ucp73M0hadS8,6551
98
98
  pyinfra/operations/dnf.py,sha256=3154Rer6dejVB1AK-CqyJhpMVn_djaSDJrVMs62GNcE,5599
99
- pyinfra/operations/docker.py,sha256=lU0AQqfIQYPHniruu770ClQODUSMuPVhFdIKy9gGmbw,8455
100
- pyinfra/operations/files.py,sha256=Hs_HKU2STE0Byt-fZHdsfcrhM6m82mzAELMA22b_X_c,56215
101
- pyinfra/operations/flatpak.py,sha256=c2OAyuAvt3alVm9D8W6gCfmk5JFydcZD36gO_OhB8Bc,1891
99
+ pyinfra/operations/docker.py,sha256=39MFhUs1edbzbG8ejR-r3-xczeV8op7kFerk6qQieoU,8520
100
+ pyinfra/operations/files.py,sha256=ZnHsZ-qcvVO_boHnpAT-yvzL_F8j4NTiFY5KkeFCzIE,57814
101
+ pyinfra/operations/flatpak.py,sha256=QEJpzSXLyMQFk1XPAPHAfJVWcYWHnKA-tQr2hX6sB9o,2319
102
102
  pyinfra/operations/gem.py,sha256=2C85sOwIRMHGvmPg4uAlUVf6MokhiA7LLPqzdJRHsBg,1132
103
- pyinfra/operations/git.py,sha256=ajyusK8rFeU_u3piR3glzJGLhomKF0IuzlbR667eyts,13035
103
+ pyinfra/operations/git.py,sha256=ETENOkGfs9Io27mguK8tlRn0Zbw0eTvtFvRaE2H6Bsk,13236
104
104
  pyinfra/operations/iptables.py,sha256=brYa4kMhZKFTu24BNds_1b6sOaG94EfqWEoWrScx-Ck,9341
105
105
  pyinfra/operations/launchd.py,sha256=6HWvqoQ74idV_NStOEmFXwu0dmTv7YDvFtsK8An2Lu4,1177
106
106
  pyinfra/operations/lxd.py,sha256=bKm9gsgZaruKYSL7OYFMiou-wGP4BzwIMWzjW4AZYrk,1742
@@ -119,7 +119,7 @@ pyinfra/operations/puppet.py,sha256=eDe8D9jQbHYQ4_r4-dmEZfMASKQvj36BR8z_h8aDfw8,
119
119
  pyinfra/operations/python.py,sha256=u569cdPrPesrmzU09nwIPA3bk6TZ-Qv2QP0lJLcO_bw,2021
120
120
  pyinfra/operations/runit.py,sha256=-K0GhORE56J4Gjh7PCriSx9zZI7XJV-cIb-LnnSuKdY,5162
121
121
  pyinfra/operations/selinux.py,sha256=imZ4dbY4tl0GpBSkUgV983jbDDihWNs_OQkOBulT7FQ,5948
122
- pyinfra/operations/server.py,sha256=6OkfbEH5jWltXjiQkXoq_82UidHPB551dL6TyxCfzr8,30733
122
+ pyinfra/operations/server.py,sha256=EFZ1QYnySpe0ufVzJC6x-Jj3Xt_XPIic0IkCzdcIUws,31248
123
123
  pyinfra/operations/snap.py,sha256=a-QtNE4Dlsavqq425TUIwpEJu4oGw8UlLRkdTFyT1F8,3049
124
124
  pyinfra/operations/ssh.py,sha256=wocoaYDlOhhItItAVQCEfnVowTtkg3AP0hQ3mnpUnl0,5634
125
125
  pyinfra/operations/systemd.py,sha256=hPHTjASj6N_fRAzLr3DNHnxxIbiiTIIT9UStSxKDkTk,3984
@@ -136,52 +136,52 @@ pyinfra/operations/freebsd/pkg.py,sha256=3AyfI0-_9F4ho47KqZsOMQocwNtTF2q9g0i6Tff
136
136
  pyinfra/operations/freebsd/service.py,sha256=1f7nTHELnhs3HBSrMFsmopVgYFMIwB8Se88yneRQ8Rw,3198
137
137
  pyinfra/operations/freebsd/sysrc.py,sha256=eg7u_JsCge_uKq3Ysc_mohUc6qgJrOZStp_B_l2Hav4,2330
138
138
  pyinfra/operations/util/__init__.py,sha256=ZAHjeCXtLo0TIOSfZ9h0Sh5IXXRCspfHs3RR1l8tQCE,366
139
- pyinfra/operations/util/docker.py,sha256=WUyn2BZGClBwQDNTNNM3UNOX64YkpD4JMGk3lBufMTg,5285
140
- pyinfra/operations/util/files.py,sha256=Zcet3ydNVbdT9jss0BDm6RJFyR_s6XTr0isDR60Zubw,3622
139
+ pyinfra/operations/util/docker.py,sha256=LetDzYhB4jgNPT5ccYf6Wk1--XQuwN_pcNBe8tcJJIU,5485
140
+ pyinfra/operations/util/files.py,sha256=BH2My7PeB9OWoW6UYhRSEwCm9_y6G6qa6BTdSxbf0YA,4817
141
141
  pyinfra/operations/util/packaging.py,sha256=xFtOlEX46ms7g3gDvOOInRVR1RVfgsmhLzFzsJAL_eU,9381
142
142
  pyinfra/operations/util/service.py,sha256=kJd1zj4-sAaGIp5Ts7yAJznogWaGr8oQTztwenLAr7Y,1309
143
143
  pyinfra_cli/__init__.py,sha256=G0X7tNdqT45uWuK3aHIKxMdDeCgJ7zHo6vbxoG6zy_8,284
144
144
  pyinfra_cli/__main__.py,sha256=WlW7eP0rrL06eguuD_q2RAqgUjg3SW-QnmrayAh2mBQ,887
145
145
  pyinfra_cli/commands.py,sha256=J-mCJYvDebJ8M7o3HreB2zToa871-xO6_KjVhPLeHho,1832
146
146
  pyinfra_cli/exceptions.py,sha256=RRaOprL7SmVv--FLy4x7fxeTitx9wYI0Y3_h01LfhJA,4901
147
- pyinfra_cli/inventory.py,sha256=05Z0LpMW8Qt3c2X2sx-roYCQGxNlEDD0RgZILpXCcJs,11768
147
+ pyinfra_cli/inventory.py,sha256=JYSixJZKY8GNWlOxh-nGDsAknCdaAktlWAmdg13kvNk,11771
148
148
  pyinfra_cli/log.py,sha256=mD96MH2owQQ5AsYRw7osCKENdp-E3Wum5IDr6qhSIa4,2268
149
- pyinfra_cli/main.py,sha256=PyofivS-dRF8Sfq-PIy7_GrJKKAdmucZ0IbtkNlcHy4,20085
149
+ pyinfra_cli/main.py,sha256=_cW7PNVxMjwEl8IA8GSU15XrMCvFapFurnqDVCHgt2E,20111
150
150
  pyinfra_cli/prints.py,sha256=eaLRQAdiVGmPR2GsHF_fCY706aSt5JyXxz42z6qLAFM,10299
151
151
  pyinfra_cli/util.py,sha256=9ehdJQ8pDNBLHXoFst9p696VDT-b_qo8UFMJrqdE1rE,6424
152
152
  pyinfra_cli/virtualenv.py,sha256=wRNxOPcUkbD_Pzuj-Lnrz1KxGmsLlb2ObmCTFrdD-S8,2474
153
153
  tests/test_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
154
154
  tests/test_api/test_api.py,sha256=Ig2ebkNACYbHcC4_zRkxS9vj5ZEogoPqGx30ErIKChg,2413
155
- tests/test_api/test_api_arguments.py,sha256=5k7w0_x5cnABEFOk0LQBCt5gU9iTN9lo2XS6MlJTnhQ,1961
155
+ tests/test_api/test_api_arguments.py,sha256=w9hEL0M_2Ob0VV11DvbjGuq_NvwNMuQcMOB2_ZlZ_ao,2181
156
156
  tests/test_api/test_api_command.py,sha256=OW0ESMyS5vo38u17DHeCrSIaIkW9gMU5PSkXL7mRrq0,3204
157
157
  tests/test_api/test_api_config.py,sha256=bf0mDrUie3On6zGC_hJBpv-wvSf3LHBIBzUDvkopEt0,708
158
158
  tests/test_api/test_api_deploys.py,sha256=h_zbI6CK4K8SdzEr3LEAMPxOf9hnQBdi_suqiNPqHHQ,4200
159
- tests/test_api/test_api_facts.py,sha256=WnKwgLq7sk2LNO5IgIZbO5HRkDr-2GdUWO_EFfTjhO8,10695
159
+ tests/test_api/test_api_facts.py,sha256=_Z3g5mN3PJdqVGHYxwNUBqPoe6FZBiJEjBEJ0zS9EtY,11047
160
160
  tests/test_api/test_api_host.py,sha256=U_VW2vTl35vR8EdyIGMKr4y0ydsDLbvHSjZDa99CyNE,1119
161
161
  tests/test_api/test_api_inventory.py,sha256=rqXd3e_Wwc-SxCzxgR5eLd7ZOdrF8CcHbcTZndLy5gE,2744
162
- tests/test_api/test_api_operations.py,sha256=GUfnuHK2NoTAGdOT4AbytT9R8i3ZZIvGP7KBfoYcYUQ,20134
162
+ tests/test_api/test_api_operations.py,sha256=5x4UJspW12_z3HNe5NcivnPXeGfLdmgC13V5iUTUxyw,20385
163
163
  tests/test_api/test_api_util.py,sha256=uHv4oLpoy1_tzOoqFA1zpdvC74SvjitZbxQwp0dmjTs,1716
164
164
  tests/test_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
165
- tests/test_cli/test_cli.py,sha256=IeWuhkhLzIkRbOEx5-yaW6xV5l4Y8fxaGaDGlMcOyYE,6016
165
+ tests/test_cli/test_cli.py,sha256=I9QMrp0xI_5p2N3ZyeNBBcPTUNkPVDdQvlWM860YIwM,6016
166
166
  tests/test_cli/test_cli_deploy.py,sha256=vZC7twj8sPCy05loO50P-D_Xf73r6XN4m7yVj7TIFmo,5243
167
167
  tests/test_cli/test_cli_exceptions.py,sha256=QaUv40q6Tp0HdcVEvPggFF4dsP2qdy57y9VAcGcR1So,3060
168
- tests/test_cli/test_cli_inventory.py,sha256=feYSyxGBUsDGriOaqs0CBMbAIW7yUfoT1mktLwqMI0w,4036
168
+ tests/test_cli/test_cli_inventory.py,sha256=FD4Hc4MzOfnrZTugVeNPOBf7bvE1degpDWQf5s6LZAg,4036
169
169
  tests/test_cli/test_cli_util.py,sha256=Fqn_9fnG6xNfw8OMHSZs9hQoW260aSt409S1bUAJs-Q,2500
170
- tests/test_cli/test_context_objects.py,sha256=JiUTwQP7yvcqA47Kq9jtdsB_Z8nxGMZN46d9pR--FYA,2130
170
+ tests/test_cli/test_context_objects.py,sha256=dTr7WPewTk-Z8ZbPRPX5o5DKBne1-jUwOncFWjTWhII,2259
171
171
  tests/test_cli/util.py,sha256=kp_-XsGnTyDgG6IHWorYzl5VD_WLe77dKOH007TDOUE,338
172
172
  tests/test_connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
173
  tests/test_connectors/test_chroot.py,sha256=QK7YgFPXzHh8y363-tmHvzZ0Ok5PVJWFTDAvwt91eac,5907
174
- tests/test_connectors/test_docker.py,sha256=0EjkfhCHpLCfL4X-AIdMNw5ASaseY0tbRAn7T_TAkMQ,6566
174
+ tests/test_connectors/test_docker.py,sha256=vYt-rZl05uXi5fH6IgkcP7EGtR1FRDQQdwyquk1ygoc,8313
175
175
  tests/test_connectors/test_dockerssh.py,sha256=MaC9IK1OZDiqoIsuLOZBJnPDglsMoPDoL19LQtXsyCE,9303
176
176
  tests/test_connectors/test_local.py,sha256=N_FkejDZKu7XLnKeApqfBARYMyxf-hRXCQJrXLHvwRg,7442
177
- tests/test_connectors/test_ssh.py,sha256=YeCZtYDogm6M8xSFXjNXXmfgMGOH-0fzTeRaNXyOAtU,42995
178
- tests/test_connectors/test_sshuserclient.py,sha256=Rm1zxSODDXQXuQ3qdkCA12FCUj7Zkgwwe-s2UrsZAoE,8599
177
+ tests/test_connectors/test_ssh.py,sha256=XsfzS1OGzPtkzswThkUw6JR8osFCRvMI9_6OgLziYSM,44856
178
+ tests/test_connectors/test_sshuserclient.py,sha256=_anSd1cVQGIQkn08RdRbWjnSEkSS5InVkp6_HVvoVYk,8714
179
179
  tests/test_connectors/test_terraform.py,sha256=RZInSjes394eR5CrGGEjzZEFY-UpQj47n4MZH0_ExyY,3779
180
180
  tests/test_connectors/test_util.py,sha256=hQir0WyjH0LEF6xvIyHNyqdI5pkJX6qUR9287MgO2bY,4647
181
181
  tests/test_connectors/test_vagrant.py,sha256=27qRB7ftjEPaj4ejBNZ-rR4Ou1AD1VyVcf2XjwZPG3M,3640
182
- pyinfra-3.3.dist-info/LICENSE.md,sha256=BzCnRYLJv0yb-FJuEd_XOrrQSOEQKzIVo0yHT8taNnM,1076
183
- pyinfra-3.3.dist-info/METADATA,sha256=altc2EhdZvDuH_4Nbn_T4yocK5cA7feHsKONJBvEm4E,8054
184
- pyinfra-3.3.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
185
- pyinfra-3.3.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
186
- pyinfra-3.3.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
187
- pyinfra-3.3.dist-info/RECORD,,
182
+ pyinfra-3.4.dist-info/LICENSE.md,sha256=BzCnRYLJv0yb-FJuEd_XOrrQSOEQKzIVo0yHT8taNnM,1076
183
+ pyinfra-3.4.dist-info/METADATA,sha256=OgZy8dxZfcjuGsrJM8J_aZVOHOX0O8M4GxycFOhUyxo,8135
184
+ pyinfra-3.4.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
185
+ pyinfra-3.4.dist-info/entry_points.txt,sha256=MT4cxTreOa_MzKgyPXk2BkeQ-KKcF1P8PJQe4vLQDaw,522
186
+ pyinfra-3.4.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
187
+ pyinfra-3.4.dist-info/RECORD,,
@@ -6,6 +6,7 @@ chroot = pyinfra.connectors.chroot:ChrootConnector
6
6
  docker = pyinfra.connectors.docker:DockerConnector
7
7
  dockerssh = pyinfra.connectors.dockerssh:DockerSSHConnector
8
8
  local = pyinfra.connectors.local:LocalConnector
9
+ podman = pyinfra.connectors.docker:PodmanConnector
9
10
  ssh = pyinfra.connectors.ssh:SSHConnector
10
11
  terraform = pyinfra.connectors.terraform:TerraformInventoryConnector
11
12
  vagrant = pyinfra.connectors.vagrant:VagrantInventoryConnector
pyinfra_cli/inventory.py CHANGED
@@ -172,7 +172,7 @@ def make_inventory(
172
172
  # The inventory is either an inventory file or a (list of) hosts
173
173
  return make_inventory_from_files(inventory, override_data, cwd, group_data_directories)
174
174
  elif inventory_func is None:
175
- logger.warn(
175
+ logger.warning(
176
176
  f"{inventory} is neither an inventory file, a (list of) hosts or connectors "
177
177
  "nor refers to a python module"
178
178
  )
pyinfra_cli/main.py CHANGED
@@ -515,10 +515,12 @@ def _set_verbosity(state, verbosity):
515
515
  state.print_noop_info = True
516
516
 
517
517
  if verbosity > 1:
518
- state.print_input = state.print_fact_input = True
518
+ state.print_input = True
519
+ state.print_fact_input = True
519
520
 
520
521
  if verbosity > 2:
521
- state.print_output = state.print_fact_output = True
522
+ state.print_output = True
523
+ state.print_fact_output = True
522
524
 
523
525
  return state
524
526
 
@@ -1,7 +1,8 @@
1
+ from typing import cast
1
2
  from unittest import TestCase
2
3
 
3
- from pyinfra.api import Config, Inventory, State
4
- from pyinfra.api.arguments import pop_global_arguments
4
+ from pyinfra.api import Config, Host, Inventory, State
5
+ from pyinfra.api.arguments import AllArguments, pop_global_arguments
5
6
 
6
7
 
7
8
  class TestOperationKwargs(TestCase):
@@ -10,46 +11,50 @@ class TestOperationKwargs(TestCase):
10
11
  inventory = Inventory((("somehost",), {}))
11
12
 
12
13
  state = State(config=config, inventory=inventory)
14
+ host = inventory.get_host("somehost")
13
15
 
14
- kwargs, keys = pop_global_arguments({}, state=state, host=inventory.get_host("somehost"))
15
- assert kwargs["_sudo"] == "config-value"
16
+ kwargs, _ = pop_global_arguments(state, host, {})
17
+ assert kwargs.get("_sudo") == "config-value"
16
18
 
17
19
  def test_get_from_host(self):
18
20
  config = Config(SUDO="config-value")
19
21
  inventory = Inventory(([("somehost", {"_sudo": True})], {}))
20
22
 
21
23
  state = State(config=config, inventory=inventory)
24
+ host = inventory.get_host("somehost")
22
25
 
23
- kwargs, keys = pop_global_arguments({}, state=state, host=inventory.get_host("somehost"))
24
- assert kwargs["_sudo"] is True
26
+ kwargs, _ = pop_global_arguments(state, host, {})
27
+ assert kwargs.get("_sudo") is True
25
28
 
26
29
  def test_get_from_state_deploy_kwargs(self):
27
30
  config = Config(SUDO="config-value")
28
31
  inventory = Inventory(([("somehost", {"_sudo": False})], {}))
29
32
  somehost = inventory.get_host("somehost")
33
+ assert isinstance(somehost, Host)
30
34
 
31
35
  state = State(config=config, inventory=inventory)
32
- somehost.current_deploy_kwargs = {"_sudo": True}
36
+ host = inventory.get_host("somehost")
37
+ somehost.current_deploy_kwargs = cast(AllArguments, {"_sudo": True})
33
38
 
34
- kwargs, keys = pop_global_arguments({}, state=state, host=somehost)
35
- assert kwargs["_sudo"] is True
39
+ kwargs, keys = pop_global_arguments(state, host, {})
40
+ assert kwargs.get("_sudo") is True
36
41
 
37
42
  def test_get_from_kwargs(self):
38
43
  config = Config(SUDO="config-value")
39
44
  inventory = Inventory(([("somehost", {"_sudo": False})], {}))
40
45
  somehost = inventory.get_host("somehost")
46
+ assert isinstance(somehost, Host)
41
47
 
42
48
  state = State(config=config, inventory=inventory)
43
- somehost.current_deploy_kwargs = {
44
- "_sudo": False,
45
- "_sudo_user": "deploy-kwarg-user",
46
- }
47
-
48
- kwargs, keys = pop_global_arguments(
49
- {"_sudo": True},
50
- state=state,
51
- host=somehost,
49
+ somehost.current_deploy_kwargs = cast(
50
+ AllArguments,
51
+ {
52
+ "_sudo": False,
53
+ "_sudo_user": "deploy-kwarg-user",
54
+ },
52
55
  )
53
- assert kwargs["_sudo"] is True
54
- assert kwargs["_sudo_user"] == "deploy-kwarg-user"
56
+
57
+ kwargs, keys = pop_global_arguments(state, somehost, {"_sudo": True})
58
+ assert kwargs.get("_sudo") is True
59
+ assert kwargs.get("_sudo_user") == "deploy-kwarg-user"
55
60
  assert "_sudo" in keys