FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
cecli/cecli/interruptible_input.py at main · cecli-dev/cecli · GitHub
cecli-dev
cecli
Repository navigation
Code
Issues
11
(11)
Pull requests
8
(8)
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
cecli
/
cecli
/
interruptible_input.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
100 lines (85 loc) · 2.99 KB
Breadcrumbs
cecli
/
cecli
/
interruptible_input.py
Copy path
File metadata and controls
100 lines (85 loc) · 2.99 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import
os
import
selectors
import
sys
import
threading
class
InterruptibleInput
:
"""
Unix-only, interruptible replacement for input(), designed for:
await asyncio.get_event_loop().run_in_executor(None, obj.input, prompt)
interrupt() is safe from any thread.
"""
def
__init__
(
self
):
if
os
.
name
==
"nt"
:
raise
RuntimeError
(
"InterruptibleInput is Unix-only (requires selectable stdin)."
)
self
.
_cancel
=
threading
.
Event
()
# The default selector (Kqueue on macOS, Epoll on Linux) cannot
# handle pipe-based stdin (e.g. when running inside Emacs comint-mode).
# Fall back to SelectSelector which works with any fd that supports select().
if
not
sys
.
stdin
.
isatty
():
self
.
_sel
=
selectors
.
SelectSelector
()
else
:
self
.
_sel
=
selectors
.
DefaultSelector
()
# self-pipe to wake up select() from interrupt()
self
.
_r
,
self
.
_w
=
os
.
pipe
()
os
.
set_blocking
(
self
.
_r
,
False
)
os
.
set_blocking
(
self
.
_w
,
False
)
self
.
_sel
.
register
(
self
.
_r
,
selectors
.
EVENT_READ
,
data
=
"__wakeup__"
)
def
close
(
self
)
->
None
:
try
:
self
.
_sel
.
unregister
(
self
.
_r
)
except
Exception
:
pass
try
:
os
.
close
(
self
.
_r
)
except
Exception
:
pass
try
:
os
.
close
(
self
.
_w
)
except
Exception
:
pass
try
:
self
.
_sel
.
close
()
except
Exception
:
pass
def
interrupt
(
self
)
->
None
:
self
.
_cancel
.
set
()
try
:
os
.
write
(
self
.
_w
,
b"
\x01
"
)
# wake selector immediately
except
BlockingIOError
:
pass
except
OSError
:
pass
def
input
(
self
,
prompt
:
str
=
""
)
->
str
:
if
prompt
:
sys
.
stdout
.
write
(
prompt
)
sys
.
stdout
.
flush
()
if
self
.
_cancel
.
is_set
():
self
.
_cancel
.
clear
()
raise
InterruptedError
(
"Input interrupted"
)
stdin
=
sys
.
stdin
fd
=
stdin
.
fileno
()
self
.
_sel
.
register
(
fd
,
selectors
.
EVENT_READ
,
data
=
"__stdin__"
)
try
:
while
True
:
for
key
,
_
in
self
.
_sel
.
select
():
if
key
.
data
==
"__wakeup__"
:
# drain wake bytes
try
:
while
os
.
read
(
self
.
_r
,
1024
):
pass
except
BlockingIOError
:
pass
if
self
.
_cancel
.
is_set
():
self
.
_cancel
.
clear
()
raise
InterruptedError
(
"Input interrupted"
)
continue
if
key
.
data
==
"__stdin__"
:
line
=
stdin
.
readline
()
if
line
==
""
:
raise
EOFError
return
line
.
rstrip
(
"
\n
"
)
finally
:
try
:
self
.
_sel
.
unregister
(
fd
)
except
Exception
:
pass
Back
|
FazBrowse Home
|
New Git URL