wizlib 3.1.2__py3-none-any.whl → 3.1.4__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.
Potentially problematic release.
This version of wizlib might be problematic. Click here for more details.
- wizlib/app.py +4 -1
- wizlib/io.py +21 -0
- wizlib/stream_handler.py +8 -4
- wizlib/test_case.py +36 -0
- wizlib/ui/shell/line_editor.py +2 -4
- wizlib/ui/shell_ui.py +7 -13
- {wizlib-3.1.2.dist-info → wizlib-3.1.4.dist-info}/METADATA +1 -1
- {wizlib-3.1.2.dist-info → wizlib-3.1.4.dist-info}/RECORD +9 -8
- wizlib/util.py +0 -8
- {wizlib-3.1.2.dist-info → wizlib-3.1.4.dist-info}/WHEEL +0 -0
wizlib/app.py
CHANGED
|
@@ -70,15 +70,18 @@ class WizApp:
|
|
|
70
70
|
"""Set up the parser for the app class"""
|
|
71
71
|
cls.parser = WizParser(prog=cls.name)
|
|
72
72
|
subparsers = cls.parser.add_subparsers(dest='command')
|
|
73
|
+
cls.dparser = WizParser(prog=f"{cls.name} {cls.base.default}")
|
|
73
74
|
for command in cls.base.family_members('name'):
|
|
74
75
|
key = command.get_member_attr('key')
|
|
75
76
|
aliases = [key] if key else []
|
|
76
77
|
subparser = subparsers.add_parser(command.name, aliases=aliases)
|
|
77
78
|
if command.name == cls.base.default:
|
|
78
|
-
cls.dparser
|
|
79
|
+
command.add_args(cls.dparser)
|
|
79
80
|
command.add_args(subparser)
|
|
80
81
|
for handler in cls.handlers:
|
|
81
82
|
handler.add_args(cls.parser)
|
|
83
|
+
# Throws ArgumentError if the default command includes an optional
|
|
84
|
+
# argument that overlaps with one of the handlers
|
|
82
85
|
handler.add_args(cls.dparser)
|
|
83
86
|
|
|
84
87
|
def __init__(self, **vals):
|
wizlib/io.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Primitive i/o functions referenced elsewhere, useful for test patching (a
|
|
2
|
+
# sort of dependency injection
|
|
3
|
+
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
import readchar
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
ISATTY = sys.stdin.isatty()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def isatty():
|
|
13
|
+
return ISATTY
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def stream():
|
|
17
|
+
return '' if ISATTY else sys.stdin.read()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def ttyin():
|
|
21
|
+
return readchar.readkey()
|
wizlib/stream_handler.py
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
# In a non-interactive, non-testing mode, route input from stdin to the output.
|
|
2
|
+
# When testing, read from the object provided (probably a StreamIO)
|
|
3
|
+
|
|
1
4
|
from pathlib import Path
|
|
2
5
|
import sys
|
|
3
6
|
|
|
4
7
|
from wizlib.handler import Handler
|
|
5
8
|
from wizlib.parser import WizParser
|
|
6
|
-
|
|
7
|
-
INTERACTIVE = sys.stdin.isatty()
|
|
9
|
+
import wizlib.io
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
class StreamHandler(Handler):
|
|
13
|
+
"""Handle non-interactive input, such as via a pipe in a shell. Only runs
|
|
14
|
+
when not in a tty."""
|
|
11
15
|
|
|
12
16
|
name = 'stream'
|
|
13
17
|
text: str = ''
|
|
@@ -15,8 +19,8 @@ class StreamHandler(Handler):
|
|
|
15
19
|
def __init__(self, file=None, stdin=True):
|
|
16
20
|
if file:
|
|
17
21
|
self.text = Path(file).read_text()
|
|
18
|
-
elif
|
|
19
|
-
self.text =
|
|
22
|
+
elif not wizlib.io.isatty():
|
|
23
|
+
self.text = wizlib.io.stream()
|
|
20
24
|
|
|
21
25
|
def __str__(self):
|
|
22
26
|
return self.text
|
wizlib/test_case.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Patch inputs and outputs for easy testing
|
|
2
|
+
|
|
3
|
+
from io import StringIO
|
|
4
|
+
from unittest import TestCase
|
|
5
|
+
from unittest.mock import Mock, patch
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class WizLibTestCase(TestCase):
|
|
9
|
+
"""Wrap your test cases in this class to use the patches correctly"""
|
|
10
|
+
|
|
11
|
+
def setUp(self):
|
|
12
|
+
self.notty = patch('wizlib.io.isatty', Mock(return_value=False))
|
|
13
|
+
self.notty.start()
|
|
14
|
+
|
|
15
|
+
def tearDown(self):
|
|
16
|
+
self.notty.stop()
|
|
17
|
+
|
|
18
|
+
@staticmethod
|
|
19
|
+
def patch_stream(val: str):
|
|
20
|
+
"""Patch stream input such as pipes for stream handler"""
|
|
21
|
+
mock = Mock(return_value=val)
|
|
22
|
+
return patch('wizlib.io.stream', mock)
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def patch_ttyin(val: str):
|
|
26
|
+
"""Patch input typed by a user in shell ui"""
|
|
27
|
+
mock = Mock(side_effect=val)
|
|
28
|
+
return patch('wizlib.io.ttyin', mock)
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def patcherr(): # pragma: nocover
|
|
32
|
+
return patch('sys.stderr', StringIO())
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def patchout(): # pragma: nocover
|
|
36
|
+
return patch('sys.stdout', StringIO())
|
wizlib/ui/shell/line_editor.py
CHANGED
|
@@ -2,10 +2,8 @@ from enum import Enum
|
|
|
2
2
|
import sys
|
|
3
3
|
import re
|
|
4
4
|
|
|
5
|
-
from readchar import readkey
|
|
6
|
-
|
|
7
5
|
from wizlib.ui.shell import S
|
|
8
|
-
|
|
6
|
+
import wizlib.io
|
|
9
7
|
|
|
10
8
|
if (sys.platform == "win32"):
|
|
11
9
|
import ctypes
|
|
@@ -89,7 +87,7 @@ class ShellLineEditor: # pragma: nocover
|
|
|
89
87
|
write(S.RESET)
|
|
90
88
|
while True:
|
|
91
89
|
self.write_fill()
|
|
92
|
-
key =
|
|
90
|
+
key = wizlib.io.ttyin()
|
|
93
91
|
self.clear_fill()
|
|
94
92
|
if key == S.RETURN:
|
|
95
93
|
break
|
wizlib/ui/shell_ui.py
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
from enum import StrEnum
|
|
2
2
|
import sys
|
|
3
3
|
|
|
4
|
-
from readchar import readkey
|
|
5
|
-
|
|
6
4
|
from wizlib.ui import UI, Chooser, Emphasis
|
|
7
5
|
from wizlib.ui.shell.line_editor import ShellLineEditor
|
|
8
6
|
from wizlib.ui.shell import S
|
|
9
|
-
|
|
10
|
-
INTERACTIVE = sys.stdin.isatty()
|
|
7
|
+
import wizlib.io
|
|
11
8
|
|
|
12
9
|
COLOR = {
|
|
13
10
|
Emphasis.INFO: S.BLUE,
|
|
@@ -38,13 +35,11 @@ class ShellUI(UI):
|
|
|
38
35
|
sys.stderr.flush()
|
|
39
36
|
|
|
40
37
|
def get_option(self, chooser: Chooser):
|
|
41
|
-
"""Get a choice from the user with a single keystroke
|
|
38
|
+
"""Get a choice from the user with a single keystroke. Only works when
|
|
39
|
+
in a tty."""
|
|
42
40
|
while True:
|
|
43
41
|
self.ask(chooser.prompt_string)
|
|
44
|
-
|
|
45
|
-
key = readkey()
|
|
46
|
-
else:
|
|
47
|
-
key = sys.stdin.read(1)
|
|
42
|
+
key = wizlib.io.ttyin()
|
|
48
43
|
out = chooser.default if key == '\n' else \
|
|
49
44
|
key if key.isprintable() else ''
|
|
50
45
|
choice = chooser.choice_by_key(key)
|
|
@@ -59,8 +54,7 @@ class ShellUI(UI):
|
|
|
59
54
|
"""Allow the user to input an arbitrary line of text, with possible tab
|
|
60
55
|
completion"""
|
|
61
56
|
self.ask(prompt)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
value = input()
|
|
57
|
+
value = ShellLineEditor(choices, default).edit()
|
|
58
|
+
# else:
|
|
59
|
+
# value = input()
|
|
66
60
|
return value
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
wizlib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
wizlib/app.py,sha256=
|
|
2
|
+
wizlib/app.py,sha256=ke0NbaYC6ArmdtLTySl6VIGIGicxTsIuzW9wag6b7rU,4180
|
|
3
3
|
wizlib/class_family.py,sha256=tORSVAaPeWTQMcz2DX-MQClj1GQR3vCmkALPXxHa_pk,4506
|
|
4
4
|
wizlib/command.py,sha256=NO1558EYuXxfkpSmX6ljjzae8n8g4w6yytZKTJtigvo,1708
|
|
5
5
|
wizlib/config_handler.py,sha256=hoDavSMiGM_7PAHI8XIwC8nxPWOZDk302ryyjluoLGg,2588
|
|
6
6
|
wizlib/error.py,sha256=ypwdMOYhtgKWd48ccfOX8idmCXmm-Skwx3gkPwqJB3c,46
|
|
7
7
|
wizlib/handler.py,sha256=Oz80aPhDyeY9tdppZ1dvtN-19JU5ydEDVW6jtppVoD4,446
|
|
8
|
+
wizlib/io.py,sha256=KAMYTyHyKO2zY2kbymO5c8QpIWfHoTipWsDWzBJzDSw,307
|
|
8
9
|
wizlib/parser.py,sha256=yLHV0fENeApFomCRWa3I6sB1x4lk1ag4vKejWVsic64,1550
|
|
9
|
-
wizlib/stream_handler.py,sha256=
|
|
10
|
+
wizlib/stream_handler.py,sha256=UUPDpvXmfYOwG0Mmz2YMA8SKxeqau14_bK1z9vZHHp0,896
|
|
10
11
|
wizlib/super_wrapper.py,sha256=msitlfFfEwnrskzTtQBEY975sh9TQPicdLVo67imuqU,315
|
|
12
|
+
wizlib/test_case.py,sha256=T5cX7yWy94hf8JuherDeBCH9Gve5tx2x_PZOte4udC0,1017
|
|
11
13
|
wizlib/ui/__init__.py,sha256=ve_p_g4aBujh4jIJMgKkJ6cE5PT0aeY5AgRlneDswGg,4241
|
|
12
14
|
wizlib/ui/shell/__init__.py,sha256=sPrYe4bG_Xf7Nwssx_dqXVk9jeyYBFUjh4oLdlSOeRY,943
|
|
13
|
-
wizlib/ui/shell/line_editor.py,sha256=
|
|
14
|
-
wizlib/ui/shell_ui.py,sha256=
|
|
15
|
+
wizlib/ui/shell/line_editor.py,sha256=vXXsCS_i4ZCjP0su2X9W_yD1CS6MiazPAtxpiaXQ6Jc,7413
|
|
16
|
+
wizlib/ui/shell_ui.py,sha256=jre7E_5vP_SceNH7GYenfXZpFf4h9Sbh9cWZZycTYk8,1911
|
|
15
17
|
wizlib/ui_handler.py,sha256=JoZadtw9DKAtGvHKP3_BJF2NaYqmcQYNdsY4PeRnOjg,634
|
|
16
|
-
wizlib/
|
|
17
|
-
wizlib-3.1.
|
|
18
|
-
wizlib-3.1.
|
|
19
|
-
wizlib-3.1.2.dist-info/RECORD,,
|
|
18
|
+
wizlib-3.1.4.dist-info/METADATA,sha256=uCYiS39PTHiOjCjA-POguOE1SpJUby4k_hAMx_MYzrA,1780
|
|
19
|
+
wizlib-3.1.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
20
|
+
wizlib-3.1.4.dist-info/RECORD,,
|
wizlib/util.py
DELETED
|
File without changes
|