pyinfra 3.3.1__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 (45) 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/terraform.py +3 -0
  13. pyinfra/connectors/vagrant.py +3 -0
  14. pyinfra/context.py +14 -5
  15. pyinfra/facts/brew.py +1 -0
  16. pyinfra/facts/docker.py +6 -2
  17. pyinfra/facts/git.py +10 -0
  18. pyinfra/facts/hardware.py +1 -1
  19. pyinfra/facts/opkg.py +1 -0
  20. pyinfra/facts/server.py +81 -23
  21. pyinfra/facts/systemd.py +1 -1
  22. pyinfra/operations/crontab.py +7 -5
  23. pyinfra/operations/docker.py +2 -0
  24. pyinfra/operations/files.py +64 -21
  25. pyinfra/operations/flatpak.py +17 -2
  26. pyinfra/operations/git.py +6 -2
  27. pyinfra/operations/server.py +34 -24
  28. pyinfra/operations/util/docker.py +4 -0
  29. pyinfra/operations/util/files.py +44 -3
  30. {pyinfra-3.3.1.dist-info → pyinfra-3.4.dist-info}/METADATA +5 -4
  31. {pyinfra-3.3.1.dist-info → pyinfra-3.4.dist-info}/RECORD +45 -45
  32. {pyinfra-3.3.1.dist-info → pyinfra-3.4.dist-info}/entry_points.txt +1 -0
  33. pyinfra_cli/inventory.py +1 -1
  34. pyinfra_cli/main.py +4 -2
  35. tests/test_api/test_api_arguments.py +25 -20
  36. tests/test_api/test_api_facts.py +28 -15
  37. tests/test_api/test_api_operations.py +43 -44
  38. tests/test_cli/test_cli.py +17 -17
  39. tests/test_cli/test_cli_inventory.py +4 -4
  40. tests/test_cli/test_context_objects.py +26 -26
  41. tests/test_connectors/test_docker.py +83 -43
  42. tests/test_connectors/test_ssh.py +153 -132
  43. {pyinfra-3.3.1.dist-info → pyinfra-3.4.dist-info}/LICENSE.md +0 -0
  44. {pyinfra-3.3.1.dist-info → pyinfra-3.4.dist-info}/WHEEL +0 -0
  45. {pyinfra-3.3.1.dist-info → pyinfra-3.4.dist-info}/top_level.txt +0 -0
@@ -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.1
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
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
177
+ tests/test_connectors/test_ssh.py,sha256=XsfzS1OGzPtkzswThkUw6JR8osFCRvMI9_6OgLziYSM,44856
178
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.1.dist-info/LICENSE.md,sha256=BzCnRYLJv0yb-FJuEd_XOrrQSOEQKzIVo0yHT8taNnM,1076
183
- pyinfra-3.3.1.dist-info/METADATA,sha256=inqtKGeD5djmhaeEnIH_OhWzMGsxCCiUOE95qGLhORc,8056
184
- pyinfra-3.3.1.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
185
- pyinfra-3.3.1.dist-info/entry_points.txt,sha256=BraEFyquy05M8ch33HZXOHoH_m2BTqejL3xX3NrpzOM,471
186
- pyinfra-3.3.1.dist-info/top_level.txt,sha256=2K6D1mK35JTSEBgOfEPV-N-uA2SDErxGiE0J-HUMMVI,26
187
- pyinfra-3.3.1.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
@@ -1,11 +1,13 @@
1
+ from typing import cast
1
2
  from unittest.mock import MagicMock, patch
2
3
 
3
4
  from pyinfra.api import Config, State
4
- from pyinfra.api.arguments import CONNECTOR_ARGUMENT_KEYS, pop_global_arguments
5
+ from pyinfra.api.arguments import CONNECTOR_ARGUMENT_KEYS, AllArguments, pop_global_arguments
5
6
  from pyinfra.api.connect import connect_all
6
7
  from pyinfra.api.exceptions import PyinfraError
7
8
  from pyinfra.api.facts import get_facts
8
9
  from pyinfra.connectors.util import CommandOutput, OutputLine
10
+ from pyinfra.context import ctx_host, ctx_state
9
11
  from pyinfra.facts.server import Arch, Command
10
12
 
11
13
  from ..paramiko_util import PatchSSHTestCase
@@ -13,7 +15,9 @@ from ..util import make_inventory
13
15
 
14
16
 
15
17
  def _get_executor_defaults(state, host):
16
- global_argument_defaults, _ = pop_global_arguments({}, state=state, host=host)
18
+ with ctx_state.use(state):
19
+ with ctx_host.use(host):
20
+ global_argument_defaults, _ = pop_global_arguments(state, host, {})
17
21
  return {
18
22
  key: value
19
23
  for key, value in global_argument_defaults.items()
@@ -52,13 +56,16 @@ class TestFactsApi(PatchSSHTestCase):
52
56
  anotherhost = inventory.get_host("anotherhost")
53
57
 
54
58
  connect_all(state)
55
- anotherhost.current_op_global_arguments = {
56
- "_sudo": True,
57
- "_sudo_user": "someuser",
58
- "_su_user": "someuser",
59
- "_timeout": 10,
60
- "_env": {"HELLO": "WORLD"},
61
- }
59
+ anotherhost.current_op_global_arguments = cast(
60
+ AllArguments,
61
+ {
62
+ "_sudo": True,
63
+ "_sudo_user": "someuser",
64
+ "_su_user": "someuser",
65
+ "_timeout": 10,
66
+ "_env": {"HELLO": "WORLD"},
67
+ },
68
+ )
62
69
 
63
70
  with patch("pyinfra.connectors.ssh.SSHConnector.run_shell_command") as fake_run_command:
64
71
  fake_run_command.return_value = True, CommandOutput(
@@ -109,9 +116,12 @@ class TestFactsApi(PatchSSHTestCase):
109
116
 
110
117
  connect_all(state)
111
118
  anotherhost.in_op = True
112
- anotherhost.current_op_global_arguments = {
113
- "_ignore_errors": True,
114
- }
119
+ anotherhost.current_op_global_arguments = cast(
120
+ AllArguments,
121
+ {
122
+ "_ignore_errors": True,
123
+ },
124
+ )
115
125
 
116
126
  with patch("pyinfra.connectors.ssh.SSHConnector.run_shell_command") as fake_run_command:
117
127
  fake_run_command.return_value = False, MagicMock()
@@ -188,9 +198,12 @@ class TestFactsApi(PatchSSHTestCase):
188
198
  anotherhost.data._sudo_user = "this-should-be-overridden"
189
199
  anotherhost.data._su_user = "this-should-be-overridden"
190
200
 
191
- anotherhost.current_op_global_arguments = {
192
- "_su_user": "override-su-user",
193
- }
201
+ anotherhost.current_op_global_arguments = cast(
202
+ AllArguments,
203
+ {
204
+ "_su_user": "override-su-user",
205
+ },
206
+ )
194
207
 
195
208
  connect_all(state)
196
209