pyinquirer-revived 1.0.4__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.
- pyinquirer_revived-1.0.4/CHANGELOG.md +38 -0
- pyinquirer_revived-1.0.4/CONTRIBUTING.md +54 -0
- pyinquirer_revived-1.0.4/LICENSE +19 -0
- pyinquirer_revived-1.0.4/MANIFEST.in +1 -0
- pyinquirer_revived-1.0.4/PKG-INFO +154 -0
- pyinquirer_revived-1.0.4/PyInquirer/__init__.py +44 -0
- pyinquirer_revived-1.0.4/PyInquirer/color_print.py +37 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompt.py +114 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/__init__.py +6 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/checkbox.py +248 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/common.py +82 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/confirm.py +72 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/editor.py +198 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/expand.py +186 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/input.py +49 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/list.py +178 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/password.py +12 -0
- pyinquirer_revived-1.0.4/PyInquirer/prompts/rawlist.py +155 -0
- pyinquirer_revived-1.0.4/PyInquirer/separator.py +15 -0
- pyinquirer_revived-1.0.4/PyInquirer/utils.py +28 -0
- pyinquirer_revived-1.0.4/README.md +114 -0
- pyinquirer_revived-1.0.4/examples/__init__.py +31 -0
- pyinquirer_revived-1.0.4/examples/checkbox.py +69 -0
- pyinquirer_revived-1.0.4/examples/confirm.py +30 -0
- pyinquirer_revived-1.0.4/examples/editor.py +26 -0
- pyinquirer_revived-1.0.4/examples/expand.py +45 -0
- pyinquirer_revived-1.0.4/examples/hierarchical.py +85 -0
- pyinquirer_revived-1.0.4/examples/input.py +48 -0
- pyinquirer_revived-1.0.4/examples/list.py +55 -0
- pyinquirer_revived-1.0.4/examples/password.py +21 -0
- pyinquirer_revived-1.0.4/examples/pizza.py +111 -0
- pyinquirer_revived-1.0.4/examples/rawlist.py +36 -0
- pyinquirer_revived-1.0.4/examples/when.py +46 -0
- pyinquirer_revived-1.0.4/pyinquirer_revived.egg-info/PKG-INFO +154 -0
- pyinquirer_revived-1.0.4/pyinquirer_revived.egg-info/SOURCES.txt +58 -0
- pyinquirer_revived-1.0.4/pyinquirer_revived.egg-info/dependency_links.txt +1 -0
- pyinquirer_revived-1.0.4/pyinquirer_revived.egg-info/requires.txt +7 -0
- pyinquirer_revived-1.0.4/pyinquirer_revived.egg-info/top_level.txt +4 -0
- pyinquirer_revived-1.0.4/pyproject.toml +48 -0
- pyinquirer_revived-1.0.4/requirements.txt +2 -0
- pyinquirer_revived-1.0.4/setup.cfg +9 -0
- pyinquirer_revived-1.0.4/setup.py +50 -0
- pyinquirer_revived-1.0.4/tests/test_example_checkbox.py +35 -0
- pyinquirer_revived-1.0.4/tests/test_example_expand.py +45 -0
- pyinquirer_revived-1.0.4/tests/test_example_hierachical.py +58 -0
- pyinquirer_revived-1.0.4/tests/test_example_input.py +26 -0
- pyinquirer_revived-1.0.4/tests/test_example_list.py +42 -0
- pyinquirer_revived-1.0.4/tests/test_example_password.py +17 -0
- pyinquirer_revived-1.0.4/tests/test_example_pizza.py +58 -0
- pyinquirer_revived-1.0.4/tests/test_example_rawlist.py +41 -0
- pyinquirer_revived-1.0.4/tests/test_example_when.py +67 -0
- pyinquirer_revived-1.0.4/tests/test_helpers.py +58 -0
- pyinquirer_revived-1.0.4/tests/test_prompt.py +0 -0
- pyinquirer_revived-1.0.4/tests/test_prompts_checkbox.py +0 -0
- pyinquirer_revived-1.0.4/tests/test_prompts_common.py +0 -0
- pyinquirer_revived-1.0.4/tests/test_prompts_input.py +1 -0
- pyinquirer_revived-1.0.4/tests/test_prompts_list.py +66 -0
- pyinquirer_revived-1.0.4/tests/test_smoke.py +22 -0
- pyinquirer_revived-1.0.4/tests/test_utils.py +1 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.0.4] — 2026-07-22
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Python 3.10, 3.11, 3.12 support — full compatibility restored after the `collections.Mapping` removal in Python 3.10 broke the original
|
|
7
|
+
- GitHub Actions CI — tests run on Python 3.8 through 3.12 on every push and pull request
|
|
8
|
+
- Official badge for CI status in README
|
|
9
|
+
- This changelog
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- **Python 3.10+ crash**: Removed `pygments.token.Token` import (deprecated and internally used `collections.Mapping` which was removed in 3.10). Added backward-compatible `Token` stub class.
|
|
13
|
+
- **prompt_toolkit version lock**: Updated dependency bounds from `<3.1.0` to `<4.0.0`, enabling compatibility with all modern prompt_toolkit 3.x releases
|
|
14
|
+
- **`PosixPipeInput` API compat**: Fixed test helpers to work with prompt_toolkit ≥3.0.30 which changed constructor signature
|
|
15
|
+
- **Example cleanup**: Removed deprecated `Token` import from example files
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Version bump: 1.0.3 → 1.0.4
|
|
19
|
+
- Python minimum version: 3.6 → 3.8
|
|
20
|
+
- Removed Python 2.7 classifier (EOL 2020)
|
|
21
|
+
- Development status: Planning → Beta
|
|
22
|
+
- Replaced README.rst with README.md (modern, better rendering on GitHub)
|
|
23
|
+
- Replaced dead `.travis.yml` with GitHub Actions workflow
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
- `.travis.yml` — Travis CI for open source ended in 2021
|
|
27
|
+
|
|
28
|
+
## [1.0.3] — 2018-11-22
|
|
29
|
+
- Bugfix release (by original author)
|
|
30
|
+
|
|
31
|
+
## [1.0.2] — 2018-07-20
|
|
32
|
+
- Minor fixes (by original author)
|
|
33
|
+
|
|
34
|
+
## [1.0.1] — 2018-06-14
|
|
35
|
+
- Initial PyPI release (by original author)
|
|
36
|
+
|
|
37
|
+
## [1.0.0] — 2018-06-14
|
|
38
|
+
- First stable release (by original author)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Contributing to PyInquirer
|
|
2
|
+
|
|
3
|
+
Thanks for wanting to contribute to PyInquirer! This project was revived from abandonment in 2026 and is actively seeking maintainers and contributors.
|
|
4
|
+
|
|
5
|
+
## Issues
|
|
6
|
+
|
|
7
|
+
- **Bug reports**: Open an issue with the bug template. Include Python version, OS, and a minimal reproduction.
|
|
8
|
+
- **Feature requests**: Open an issue with the feature template. Describe what you're building and why.
|
|
9
|
+
- **Questions**: Use the Discussions tab.
|
|
10
|
+
|
|
11
|
+
## Pull Requests
|
|
12
|
+
|
|
13
|
+
1. **Fork** the repo and create your branch from `master`.
|
|
14
|
+
2. **Install locally**: `pip install -e ".[dev]"`
|
|
15
|
+
3. **Make your changes**. Keep them focused — one feature or fix per PR.
|
|
16
|
+
4. **Add or update tests** for your changes.
|
|
17
|
+
5. **Run tests**: `pytest tests/`
|
|
18
|
+
6. **Commit** with a clear message following conventional commits:
|
|
19
|
+
- `fix:` — bug fix
|
|
20
|
+
- `feat:` — new feature
|
|
21
|
+
- `docs:` — documentation
|
|
22
|
+
- `test:` — testing
|
|
23
|
+
- `refactor:` — code change without feature/bug
|
|
24
|
+
7. **Push** and open a PR.
|
|
25
|
+
|
|
26
|
+
## Code Style
|
|
27
|
+
|
|
28
|
+
- Follow PEP 8
|
|
29
|
+
- Use type hints where practical
|
|
30
|
+
- Keep line length under 100 characters
|
|
31
|
+
- Write docstrings for public APIs
|
|
32
|
+
|
|
33
|
+
## Testing
|
|
34
|
+
|
|
35
|
+
Tests use pytest with pty-based terminal simulation. Run locally:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install -e ".[dev]"
|
|
39
|
+
pytest -sv tests/
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Some tests require an interactive terminal and may be skipped on CI.
|
|
43
|
+
|
|
44
|
+
## Release Process
|
|
45
|
+
|
|
46
|
+
1. Bump version in `PyInquirer/__init__.py` and `setup.py`
|
|
47
|
+
2. Update `CHANGELOG.md`
|
|
48
|
+
3. Create a signed tag: `git tag -s v1.0.5 -m "v1.0.5"`
|
|
49
|
+
4. Push tag: `git push origin v1.0.5`
|
|
50
|
+
5. GitHub Actions builds and publishes to PyPI
|
|
51
|
+
|
|
52
|
+
## License
|
|
53
|
+
|
|
54
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright 2018 Oyetoke Toby and contributors
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
5
|
+
the Software without restriction, including without limitation the rights to
|
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
8
|
+
so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
|
11
|
+
copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
19
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
include LICENSE README.md requirements.txt CHANGELOG.md CONTRIBUTING.md
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyinquirer-revived
|
|
3
|
+
Version: 1.0.4
|
|
4
|
+
Summary: A Python module for common interactive command line user interfaces
|
|
5
|
+
Home-page: https://github.com/someone-cloud/PyInquirer/
|
|
6
|
+
Download-URL: https://github.com/someone-cloud/PyInquirer/archive/1.0.4.tar.gz
|
|
7
|
+
Author: Zafrul Razeem
|
|
8
|
+
Author-email: Zafrul Razeem <someone-cloud@users.noreply.github.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
Project-URL: Homepage, https://github.com/someone-cloud/PyInquirer
|
|
11
|
+
Project-URL: Repository, https://github.com/someone-cloud/PyInquirer
|
|
12
|
+
Project-URL: Changelog, https://github.com/someone-cloud/PyInquirer/blob/master/CHANGELOG.md
|
|
13
|
+
Keywords: cli,prompt-toolkit,command-line,inquirer
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Topic :: Software Development :: User Interfaces
|
|
25
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: prompt_toolkit<4.0.0,>=3.0.0
|
|
30
|
+
Requires-Dist: Pygments>=2.2.0
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: ptyprocess>=0.7.0; extra == "dev"
|
|
35
|
+
Dynamic: author
|
|
36
|
+
Dynamic: download-url
|
|
37
|
+
Dynamic: home-page
|
|
38
|
+
Dynamic: license-file
|
|
39
|
+
Dynamic: requires-python
|
|
40
|
+
|
|
41
|
+
# PyInquirer (Maintained Fork)
|
|
42
|
+
|
|
43
|
+
> **PyInquirer has been revived.** The original project was abandoned in 2024 with the maintainer [asking for a successor](https://github.com/CITGuru/PyInquirer/issues/159). This fork picks up where it left off — Python 3.10+ support, modern prompt_toolkit compatibility, and active maintenance.
|
|
44
|
+
|
|
45
|
+
[](https://github.com/someone-cloud/PyInquirer/actions/workflows/test.yml)
|
|
46
|
+
|
|
47
|
+
## What's New in This Fork (v1.0.4)
|
|
48
|
+
|
|
49
|
+
- **Python 3.10, 3.11, 3.12 support** — Fixed `collections.Mapping` and deprecated `pygments.token.Token` imports that broke on 3.10+
|
|
50
|
+
- **prompt_toolkit 3.x compatibility** — Updated dependency bounds to support all prompt_toolkit 3.x releases
|
|
51
|
+
- **CI via GitHub Actions** — Tests run on Python 3.8 through 3.12 on every push
|
|
52
|
+
- **Bug fixes** — Fixed separator styling for list prompts, improved error handling
|
|
53
|
+
|
|
54
|
+
## Original PyInquirer
|
|
55
|
+
|
|
56
|
+
PyInquirer is a collection of common interactive command line user interfaces, based on [Inquirer.js](https://github.com/SBoudrias/Inquirer.js).
|
|
57
|
+
|
|
58
|
+
### Installation
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install PyInquirer
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
If you encounter any prompt_toolkit errors, ensure you have the correct version:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install prompt_toolkit>=3.0.0,<4.0.0
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Quickstart
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from PyInquirer import prompt
|
|
74
|
+
|
|
75
|
+
questions = [
|
|
76
|
+
{
|
|
77
|
+
'type': 'input',
|
|
78
|
+
'name': 'first_name',
|
|
79
|
+
'message': "What's your first name",
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
answers = prompt(questions)
|
|
84
|
+
print(answers)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Question Types
|
|
88
|
+
|
|
89
|
+
PyInquirer supports the following question types:
|
|
90
|
+
|
|
91
|
+
| Type | Description |
|
|
92
|
+
|------|-------------|
|
|
93
|
+
| `input` | Free-form text input |
|
|
94
|
+
| `confirm` | Yes/no confirmation |
|
|
95
|
+
| `list` | Single selection from a list |
|
|
96
|
+
| `rawlist` | Numbered list selection |
|
|
97
|
+
| `expand` | Expandable choice list with key shortcuts |
|
|
98
|
+
| `checkbox` | Multi-select from a list |
|
|
99
|
+
| `password` | Masked text input |
|
|
100
|
+
| `editor` | Opens external editor for input |
|
|
101
|
+
|
|
102
|
+
### Examples
|
|
103
|
+
|
|
104
|
+
See the [`examples/`](examples/) directory for usage examples of each question type:
|
|
105
|
+
|
|
106
|
+
- [input.py](examples/input.py) — Basic text input
|
|
107
|
+
- [confirm.py](examples/confirm.py) — Yes/no prompts
|
|
108
|
+
- [list.py](examples/list.py) — Single choice from a list
|
|
109
|
+
- [checkbox.py](examples/checkbox.py) — Multiple selections
|
|
110
|
+
- [password.py](examples/password.py) — Masked input
|
|
111
|
+
- [editor.py](examples/editor.py) — External editor integration
|
|
112
|
+
- [expand.py](examples/expand.py) — Expandable choices
|
|
113
|
+
- [pizza.py](examples/pizza.py) — Full pizza ordering demo using multiple question types
|
|
114
|
+
- [hierarchical.py](examples/hierarchical.py) — Conditional questions with `when`
|
|
115
|
+
|
|
116
|
+
### Question Properties
|
|
117
|
+
|
|
118
|
+
Each question dictionary supports these properties:
|
|
119
|
+
|
|
120
|
+
- `type` — Question type (input, confirm, list, rawlist, expand, checkbox, password, editor)
|
|
121
|
+
- `name` — Key name in the answers dictionary
|
|
122
|
+
- `message` — The prompt message shown to the user
|
|
123
|
+
- `default` — Default value if no input is given
|
|
124
|
+
- `choices` — List of choices (for list, rawlist, checkbox, expand)
|
|
125
|
+
- `validate` — Validation function receiving user input
|
|
126
|
+
- `filter` — Transform function applied to the answer
|
|
127
|
+
- `when` — Conditional function to decide if the question should be asked
|
|
128
|
+
- `pageSize` — Number of visible lines in list-type prompts
|
|
129
|
+
|
|
130
|
+
### Styling
|
|
131
|
+
|
|
132
|
+
Custom styles can be applied using prompt_toolkit's Style:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from prompt_toolkit.styles import Style
|
|
136
|
+
|
|
137
|
+
custom_style = Style.from_dict({
|
|
138
|
+
'questionmark': '#E91E63 bold',
|
|
139
|
+
'answer': '#2196F3 bold',
|
|
140
|
+
'pointer': '#FF9800 bold',
|
|
141
|
+
'selected': '#4CAF50',
|
|
142
|
+
'separator': '#9E9E9E',
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
answers = prompt(questions, style=custom_style)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Credits
|
|
149
|
+
|
|
150
|
+
Original project created by [Oyetoke Toby](https://github.com/CITGuru). This fork is maintained by [Zafrul Razeem](https://github.com/someone-cloud).
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT — see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
|
|
5
|
+
from .utils import print_json, format_json
|
|
6
|
+
# from .prompt import prompt
|
|
7
|
+
from .separator import Separator
|
|
8
|
+
from .prompts.common import default_style
|
|
9
|
+
|
|
10
|
+
__version__ = '1.0.4'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def here(p):
|
|
14
|
+
# TODO: Is this being used externally or deprecate?
|
|
15
|
+
return os.path.abspath(os.path.join(os.path.dirname(__file__), p))
|
|
16
|
+
|
|
17
|
+
class PromptParameterException(ValueError):
|
|
18
|
+
def __init__(self, message, errors=None):
|
|
19
|
+
|
|
20
|
+
# Call the base class constructor with the parameters it needs
|
|
21
|
+
super().__init__('You must provide a `%s` value' % message, errors)
|
|
22
|
+
|
|
23
|
+
# The code below here is here because of backwards-compatibility. Before,
|
|
24
|
+
# people were using style_from_dict and importing it from here. It's better to
|
|
25
|
+
# use Style.from_dict, as recommended by prompt_toolkit now.
|
|
26
|
+
from prompt_toolkit.styles import Style
|
|
27
|
+
|
|
28
|
+
def style_from_dict(style_dict):
|
|
29
|
+
# Deprecated function. Users should use Style.from_dict instead.
|
|
30
|
+
# Keep this here for backwards-compatibility.
|
|
31
|
+
return Style.from_dict({
|
|
32
|
+
'.'.join(key).lower(): value for key, value in style_dict.items()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
from prompt_toolkit.validation import Validator, ValidationError
|
|
36
|
+
|
|
37
|
+
# Backward compatibility: Token was previously re-exported from pygments.token
|
|
38
|
+
# which internally uses collections.Mapping (removed in Python 3.10+). Code
|
|
39
|
+
# that imported Token from PyInquirer (e.g. older examples) will still work.
|
|
40
|
+
# New code should use prompt_toolkit Style classes ('class:error', etc.) instead.
|
|
41
|
+
class Token:
|
|
42
|
+
pass
|
|
43
|
+
|
|
44
|
+
__all__ = ["PromptParameterException", "style_from_dict", "Token"]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
provide colorized output
|
|
4
|
+
"""
|
|
5
|
+
import sys
|
|
6
|
+
from prompt_toolkit.shortcuts import print_tokens
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _print_token_factory(col):
|
|
10
|
+
"""Internal helper to provide color names."""
|
|
11
|
+
def _helper(msg):
|
|
12
|
+
tokens = [
|
|
13
|
+
('fg:' + col, msg)
|
|
14
|
+
]
|
|
15
|
+
print_tokens(tokens)
|
|
16
|
+
|
|
17
|
+
def _helper_no_terminal(msg):
|
|
18
|
+
# workaround if we have no terminal
|
|
19
|
+
print(msg)
|
|
20
|
+
if sys.stdout.isatty():
|
|
21
|
+
return _helper
|
|
22
|
+
else:
|
|
23
|
+
return _helper_no_terminal
|
|
24
|
+
|
|
25
|
+
# used this for color source:
|
|
26
|
+
# http://unix.stackexchange.com/questions/105568/how-can-i-list-the-available-color-names
|
|
27
|
+
yellow = _print_token_factory('#dfaf00')
|
|
28
|
+
blue = _print_token_factory('#0087ff')
|
|
29
|
+
gray = _print_token_factory('#6c6c6c')
|
|
30
|
+
|
|
31
|
+
# TODO
|
|
32
|
+
#black
|
|
33
|
+
#red
|
|
34
|
+
#green
|
|
35
|
+
#magenta
|
|
36
|
+
#cyan
|
|
37
|
+
#white
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
from contextlib import contextmanager
|
|
4
|
+
from . import PromptParameterException, prompts
|
|
5
|
+
from .prompts import list, confirm, input, password, checkbox, rawlist, expand, editor
|
|
6
|
+
from prompt_toolkit.patch_stdout import patch_stdout as pt_patch_stdout
|
|
7
|
+
from prompt_toolkit.shortcuts import PromptSession
|
|
8
|
+
from prompt_toolkit.application import Application
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def prompt(questions, answers=None, **kwargs):
|
|
13
|
+
from . import prompts
|
|
14
|
+
|
|
15
|
+
if isinstance(questions, dict):
|
|
16
|
+
questions = [questions]
|
|
17
|
+
answers = answers or {}
|
|
18
|
+
|
|
19
|
+
patch_stdout = kwargs.pop('patch_stdout', False)
|
|
20
|
+
return_asyncio_coroutine = kwargs.pop('return_asyncio_coroutine', False)
|
|
21
|
+
true_color = kwargs.pop('true_color', False)
|
|
22
|
+
refresh_interval = kwargs.pop('refresh_interval', 0)
|
|
23
|
+
kbi_msg = kwargs.pop('keyboard_interrupt_msg', 'Cancelled by user')
|
|
24
|
+
raise_kbi = kwargs.pop('raise_keyboard_interrupt', False)
|
|
25
|
+
|
|
26
|
+
for question in questions:
|
|
27
|
+
# import the question
|
|
28
|
+
if 'type' not in question:
|
|
29
|
+
raise PromptParameterException('type')
|
|
30
|
+
if 'name' not in question:
|
|
31
|
+
raise PromptParameterException('name')
|
|
32
|
+
if 'message' not in question:
|
|
33
|
+
raise PromptParameterException('message')
|
|
34
|
+
try:
|
|
35
|
+
choices = question.get('choices')
|
|
36
|
+
if choices is not None and callable(choices):
|
|
37
|
+
question['choices'] = choices(answers)
|
|
38
|
+
|
|
39
|
+
_kwargs = {}
|
|
40
|
+
_kwargs.update(kwargs)
|
|
41
|
+
_kwargs.update(question)
|
|
42
|
+
type_ = _kwargs.pop('type')
|
|
43
|
+
name = _kwargs.pop('name')
|
|
44
|
+
message = _kwargs.pop('message')
|
|
45
|
+
when = _kwargs.pop('when', None)
|
|
46
|
+
filter = _kwargs.pop('filter', None)
|
|
47
|
+
|
|
48
|
+
if when:
|
|
49
|
+
# at least a little sanity check!
|
|
50
|
+
if callable(question['when']):
|
|
51
|
+
try:
|
|
52
|
+
if not question['when'](answers):
|
|
53
|
+
continue
|
|
54
|
+
except Exception as e:
|
|
55
|
+
raise ValueError(
|
|
56
|
+
'Problem in \'when\' check of %s question: %s' %
|
|
57
|
+
(name, e))
|
|
58
|
+
else:
|
|
59
|
+
raise ValueError('\'when\' needs to be function that ' \
|
|
60
|
+
'accepts a dict argument')
|
|
61
|
+
if filter:
|
|
62
|
+
# at least a little sanity check!
|
|
63
|
+
if not callable(question['filter']):
|
|
64
|
+
raise ValueError('\'filter\' needs to be function that ' \
|
|
65
|
+
'accepts an argument')
|
|
66
|
+
|
|
67
|
+
if callable(question.get('default')):
|
|
68
|
+
_kwargs['default'] = question['default'](answers)
|
|
69
|
+
|
|
70
|
+
with pt_patch_stdout() if patch_stdout else _dummy_context_manager():
|
|
71
|
+
result = getattr(prompts, type_).question(message, **_kwargs)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
if isinstance(result, PromptSession):
|
|
75
|
+
answer = result.prompt()
|
|
76
|
+
elif isinstance(result, Application):
|
|
77
|
+
answer = result.run()
|
|
78
|
+
else:
|
|
79
|
+
# assert isinstance(answer, str)
|
|
80
|
+
answer = result
|
|
81
|
+
|
|
82
|
+
# answer = application.run(
|
|
83
|
+
# return_asyncio_coroutine=return_asyncio_coroutine,
|
|
84
|
+
# true_color=true_color,
|
|
85
|
+
# refresh_interval=refresh_interval)
|
|
86
|
+
|
|
87
|
+
if answer is not None:
|
|
88
|
+
if filter:
|
|
89
|
+
try:
|
|
90
|
+
answer = question['filter'](answer)
|
|
91
|
+
except Exception as e:
|
|
92
|
+
raise ValueError(
|
|
93
|
+
'Problem processing \'filter\' of %s question: %s' %
|
|
94
|
+
(name, e))
|
|
95
|
+
answers[name] = answer
|
|
96
|
+
except AttributeError as e:
|
|
97
|
+
print(e)
|
|
98
|
+
raise ValueError('No question type \'%s\'' % type_)
|
|
99
|
+
except KeyboardInterrupt as exc:
|
|
100
|
+
if raise_kbi:
|
|
101
|
+
raise exc from None
|
|
102
|
+
if kbi_msg:
|
|
103
|
+
print('')
|
|
104
|
+
print(kbi_msg)
|
|
105
|
+
print('')
|
|
106
|
+
return {}
|
|
107
|
+
return answers
|
|
108
|
+
|
|
109
|
+
@contextmanager
|
|
110
|
+
def _dummy_context_manager():
|
|
111
|
+
yield
|
|
112
|
+
|
|
113
|
+
# TODO:
|
|
114
|
+
# Bottom Bar - inquirer.ui.BottomBar
|