invoke-toolkit 0.0.68__tar.gz → 0.0.69__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/PKG-INFO +1 -1
  2. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/runners/rich.py +37 -6
  3. invoke_toolkit-0.0.69/tests/test_pty_stdin.py +24 -0
  4. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/.gitignore +0 -0
  5. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/LICENSE.txt +0 -0
  6. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/README.md +0 -0
  7. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/pyproject.toml +0 -0
  8. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/__init__.py +0 -0
  9. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/__main__.py +0 -0
  10. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/collections.py +0 -0
  11. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/completion.py +0 -0
  12. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/config/__init__.py +0 -0
  13. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/config/config.py +0 -0
  14. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/config/registry.py +0 -0
  15. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/config/schema.py +0 -0
  16. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/config/status_helper.py +0 -0
  17. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/context/__init__.py +0 -0
  18. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/context/async_tools.py +0 -0
  19. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/context/context.py +0 -0
  20. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/context/types.py +0 -0
  21. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/executor.py +0 -0
  22. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/extensions/__init__.py +0 -0
  23. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/extensions/tasks/__init__.py +0 -0
  24. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/extensions/tasks/config.py +0 -0
  25. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/extensions/tasks/create.py +0 -0
  26. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/extensions/tasks/dist.py +0 -0
  27. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/extensions/tasks/shell.py +0 -0
  28. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/field_resolvers.py +0 -0
  29. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/loader/entrypoint.py +0 -0
  30. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/log/__init__.py +0 -0
  31. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/log/logger.py +0 -0
  32. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/output/__init__.py +0 -0
  33. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/output/console.py +0 -0
  34. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/output/utils.py +0 -0
  35. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/parser.py +0 -0
  36. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/program/__init__.py +0 -0
  37. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/program/main.py +0 -0
  38. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/program/program.py +0 -0
  39. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/py.typed +0 -0
  40. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/runners/__init__.py +0 -0
  41. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/scripts/__init__.py +0 -0
  42. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/scripts/loader.py +0 -0
  43. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/tasks/__init__.py +0 -0
  44. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/tasks/autocomplete.py +0 -0
  45. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/tasks/cache.py +0 -0
  46. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/tasks/fields.py +0 -0
  47. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/tasks/fields.pyi +0 -0
  48. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/tasks/tasks.py +0 -0
  49. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/tasks/types.py +0 -0
  50. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/testing.py +0 -0
  51. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/utils/__init__.py +0 -0
  52. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/utils/fzf.py +0 -0
  53. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/utils/inspection.py +0 -0
  54. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/utils/singleton.py +0 -0
  55. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/src/invoke_toolkit/utils/text.py +0 -0
  56. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/package-template/.gitignore.jinja +0 -0
  57. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/package-template/README.md.jinja +0 -0
  58. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/package-template/copier.yml +0 -0
  59. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/package-template/pyproject.toml.jinja +0 -0
  60. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/package-template/src/{{package_slug}}/__init__.py.jinja +0 -0
  61. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/package-template/src/{{package_slug}}/tasks.py.jinja +0 -0
  62. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/provider-template/.gitignore.jinja +0 -0
  63. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/provider-template/README.md.jinja +0 -0
  64. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/provider-template/copier.yml +0 -0
  65. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/provider-template/pyproject.toml.jinja +0 -0
  66. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/provider-template/src/{{package_slug}}/__init__.py.jinja +0 -0
  67. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/templates/provider-template/tests/test_resolver.py.jinja +0 -0
  68. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/__init__.py +0 -0
  69. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/conftest.py +0 -0
  70. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/cached_completion/tasks.py +0 -0
  71. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/completion_with_config/.gitignore +0 -0
  72. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/completion_with_config/tasks.py +0 -0
  73. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/config_schema/tasks.py +0 -0
  74. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/enum_select_size/tasks.py +0 -0
  75. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/fzf_selector/tasks.py +0 -0
  76. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/literal_set_level/tasks.py +0 -0
  77. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/local_field_resolver/tasks.py +0 -0
  78. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/local_tasks/local_tasks.py +0 -0
  79. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/examples/local_tasks/tasks.py +0 -0
  80. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/extensions/conftest.py +0 -0
  81. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/extensions/test_config_tasks.py +0 -0
  82. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/extensions/test_create.py +0 -0
  83. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/extensions/test_package_template_entrypoint.py +0 -0
  84. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/extensions/test_shell_tasks.py +0 -0
  85. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/fixtures/future_fields.py +0 -0
  86. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/__init__.py +0 -0
  87. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/all-four/invoke.json +0 -0
  88. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/all-four/invoke.py +0 -0
  89. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/all-four/invoke.yml +0 -0
  90. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/collection.py +0 -0
  91. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/echo.yaml +0 -0
  92. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/json/invoke.json +0 -0
  93. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/json-and-python/invoke.json +0 -0
  94. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/json-and-python/invoke.py +0 -0
  95. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/no-dedupe.yaml +0 -0
  96. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/no-echo.yaml +0 -0
  97. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/package/invoke.yml +0 -0
  98. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/package/tasks/__init__.py +0 -0
  99. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/python/invoke.py +0 -0
  100. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/runtime.py +0 -0
  101. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/three-of-em/invoke.json +0 -0
  102. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/three-of-em/invoke.py +0 -0
  103. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/three-of-em/invoke.yml +0 -0
  104. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/underscores/tasks.py +0 -0
  105. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/yaml/explicit.py +0 -0
  106. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/yaml/tasks.py +0 -0
  107. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/yml/explicit.py +0 -0
  108. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/yml/invoke.yml +0 -0
  109. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/configs/yml/tasks.py +0 -0
  110. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/_support/has_modules.py +0 -0
  111. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/conftest.py +0 -0
  112. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/original_invoke/test_config.py +0 -0
  113. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/program/main.py +0 -0
  114. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/program/tasks/__init__.py +0 -0
  115. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/program/tasks/coll1.py +0 -0
  116. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/script/test_script.py +0 -0
  117. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/tasks/test_cache.py +0 -0
  118. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/tasks/test_extensions_config.py +0 -0
  119. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_alias_self_reference.py +0 -0
  120. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_annotated_help.py +0 -0
  121. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_async_edge_cases.py +0 -0
  122. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_async_support.py +0 -0
  123. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_cofig_class.py +0 -0
  124. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_collection.py +0 -0
  125. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_collection_configure.py +0 -0
  126. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_completion_with_choices.py +0 -0
  127. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_config_helper.py +0 -0
  128. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_config_registry.py +0 -0
  129. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_config_schema.py +0 -0
  130. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_console.py +0 -0
  131. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_context_class.py +0 -0
  132. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_disable_status_cli.py +0 -0
  133. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_enum_arguments.py +0 -0
  134. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_executor.py +0 -0
  135. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_field_typing.py +0 -0
  136. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_fields.py +0 -0
  137. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_file_completion.py +0 -0
  138. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_global_context.py +0 -0
  139. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_help_flags.py +0 -0
  140. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_invoke_3_compat.py +0 -0
  141. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_invoke_compatibility.py +0 -0
  142. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_list_filter_flags.py +0 -0
  143. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_loader.py +0 -0
  144. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_parsing.py +0 -0
  145. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_proctitle.py +0 -0
  146. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_program_with_collection.py +0 -0
  147. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_release_guard.py +0 -0
  148. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/test_toplevel.py +0 -0
  149. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/typecheck/fields.py +0 -0
  150. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/typecheck/fields_negative.py.fixture +0 -0
  151. {invoke_toolkit-0.0.68 → invoke_toolkit-0.0.69}/tests/utils/test_fzf.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: invoke-toolkit
3
- Version: 0.0.68
3
+ Version: 0.0.69
4
4
  Summary: Extended APIs for PyInvoke: composable task plugins, typed CLI args, Rich output, shell completion, and PEP 723 script support
5
5
  Project-URL: Documentation, https://github.com/D3f0/invoke-toolkit#readme
6
6
  Project-URL: Issues, https://github.com/D3f0/invoke-toolkit/issues
@@ -3,15 +3,24 @@ Config object used for invoke attribute resolution
3
3
  in tasks.
4
4
  """
5
5
 
6
+ import array
7
+ import errno
6
8
  import sys
7
- from typing import TYPE_CHECKING
9
+ from typing import IO, TYPE_CHECKING
8
10
 
9
- from invoke.runners import Local
10
- from invoke.util import debug
11
+ from invoke.runners import Local, ready_for_reading
12
+ from invoke.util import debug, has_fileno, isatty
11
13
  from rich.syntax import Syntax
12
14
 
13
15
  from invoke_toolkit.output import get_console
14
16
 
17
+ if sys.platform != "win32":
18
+ import fcntl
19
+ import termios
20
+ else:
21
+ fcntl = None # pylint: disable=invalid-name
22
+ termios = None # pylint: disable=invalid-name
23
+
15
24
  if TYPE_CHECKING:
16
25
  from invoke_toolkit.config.status_helper import StatusHelper
17
26
 
@@ -96,9 +105,31 @@ class OutputCapturingStream:
96
105
 
97
106
 
98
107
  class NoStdoutRunner(Local):
99
- """Invoke runner that prints to stderr when invoke is used with -e/--echo
100
- and redacts secrets from subprocess output when redaction is enabled.
101
- """
108
+ """Invoke runner with output handling and safe POSIX stdin probing."""
109
+
110
+ def read_our_stdin(self, input_: IO) -> str | None:
111
+ """Read stdin without Invoke's undersized POSIX ioctl buffer."""
112
+ if not ready_for_reading(input_):
113
+ return None
114
+
115
+ bytes_to_read = 1
116
+ if sys.platform != "win32" and isatty(input_) and has_fileno(input_):
117
+ buffer = array.array("i", [0])
118
+ try:
119
+ fcntl.ioctl(input_, termios.FIONREAD, buffer, True)
120
+ bytes_to_read = max(buffer[0], 1)
121
+ except OSError:
122
+ pass
123
+
124
+ try:
125
+ bytes_ = input_.read(bytes_to_read)
126
+ except OSError as e:
127
+ if e.errno != errno.EBADF:
128
+ raise
129
+ bytes_ = None
130
+ if bytes_ and isinstance(bytes_, bytes):
131
+ bytes_ = self.decode(bytes_)
132
+ return bytes_
102
133
 
103
134
  def echo(self, command):
104
135
  if hasattr(self.context, "print"):
@@ -0,0 +1,24 @@
1
+ import os
2
+ import tty
3
+ from contextlib import closing
4
+
5
+ import pytest
6
+
7
+ from invoke_toolkit import Context
8
+ from invoke_toolkit.runners.rich import NoStdoutRunner
9
+
10
+
11
+ @pytest.mark.skipif(os.name == "nt", reason="PTYs are POSIX-only")
12
+ def test_read_our_stdin_handles_escape_sequence_from_pty():
13
+ master_fd, slave_fd = os.openpty()
14
+ try:
15
+ tty.setcbreak(slave_fd)
16
+ os.write(master_fd, b"\x1b[A")
17
+ stream = os.fdopen(slave_fd, "rb", closefd=False)
18
+ with closing(stream):
19
+ runner = NoStdoutRunner(Context())
20
+ runner.encoding = "utf-8"
21
+ assert runner.read_our_stdin(stream) == "\x1b[A"
22
+ finally:
23
+ os.close(master_fd)
24
+ os.close(slave_fd)