pyhabitat 1.0.16__tar.gz → 1.0.18__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.
Potentially problematic release.
This version of pyhabitat might be problematic. Click here for more details.
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/PKG-INFO +62 -34
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/README.md +60 -32
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/pyhabitat/__init__.py +26 -18
- pyhabitat-1.0.18/pyhabitat/__main__.py +4 -0
- pyhabitat-1.0.18/pyhabitat/__main__stable.py +72 -0
- pyhabitat-1.0.18/pyhabitat/cli.py +22 -0
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/pyhabitat/environment.py +323 -141
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/pyhabitat.egg-info/PKG-INFO +62 -34
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/pyhabitat.egg-info/SOURCES.txt +4 -0
- pyhabitat-1.0.18/pyhabitat.egg-info/entry_points.txt +2 -0
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/pyproject.toml +8 -4
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/LICENSE +0 -0
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/pyhabitat.egg-info/dependency_links.txt +0 -0
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/pyhabitat.egg-info/top_level.txt +0 -0
- {pyhabitat-1.0.16 → pyhabitat-1.0.18}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyhabitat
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.18
|
|
4
4
|
Summary: A lightweight library for detecting system environment, GUI, and build properties.
|
|
5
5
|
Author-email: George Clayton Bennett <george.bennett@memphistn.gov>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -8,7 +8,7 @@ Keywords: environment,os-detection,gui,build-system
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Operating System :: OS Independent
|
|
10
10
|
Classifier: Topic :: System :: Systems Administration
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.7
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Dynamic: license-file
|
|
@@ -59,11 +59,11 @@ Ultimately, [City-of-Memphis-Wastewater](https://github.com/City-of-Memphis-Wast
|
|
|
59
59
|
|
|
60
60
|
* **Definitive Environment Checks:** Rigorous checks catered to Termux and iSH (iOS Alpine). Accurate, typical modern detection for Windows, macOS (Apple), Linux, FreeBSD, Android.
|
|
61
61
|
* **GUI Availability:** Rigorous, cached checks to determine if the environment supports a graphical popup window (Tkinter/Matplotlib TkAgg) or just headless image export (Matplotlib Agg).
|
|
62
|
-
* **Build/Packaging Detection:** Reliable detection of standalone executables
|
|
63
|
-
* **Executable Type Inspection:** Uses file magic numbers (ELF
|
|
62
|
+
* **Build/Packaging Detection:** Reliable detection of standalone executables (PyInstaller), Python zipapps (.pyz), Python source scripts (.py), and correct identification/exclusion of pipx-managed virtual environments.
|
|
63
|
+
* **Executable Type Inspection:** Uses file magic numbers (ELF, MZ, Mach-O) to confirm if the running script is a monolithic, frozen binary (non-pipx) or zipapp (.pyz).
|
|
64
64
|
|
|
65
65
|
</details>
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
---
|
|
68
68
|
|
|
69
69
|
<details>
|
|
@@ -75,26 +75,31 @@ Key question: "What is this running on?"
|
|
|
75
75
|
|
|
76
76
|
| Function | Description |
|
|
77
77
|
| :--- | :--- |
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
78
|
+
| `on_windows()` | Returns `True` on Windows. |
|
|
79
|
+
| `on_apple()` | Returns `True` on macOS (Darwin). |
|
|
80
|
+
| `on_linux()` | Returns `True` on Linux in general. |
|
|
81
|
+
| `on_termux()` | Returns `True` if running in the Termux Android environment. |
|
|
82
|
+
| `on_freebsd()` | Returns `True` on FreeBSD. |
|
|
83
|
+
| `on_ish_alpine()` | Returns `True` if running in the iSH Alpine Linux iOS emulator. |
|
|
84
|
+
| `on_android()` | Returns `True` on any Android-based Linux environment. |
|
|
85
|
+
| `in_repl()` | Returns `True` is the user is currently in a Python REPL; hasattr(sys,'ps1'). |
|
|
84
86
|
|
|
85
87
|
### Packaging and Build Checking
|
|
86
88
|
|
|
87
|
-
Key question: "What is the character of my executable?"
|
|
89
|
+
Key question: "What is the character of my executable or my build state?"
|
|
90
|
+
|
|
91
|
+
These functions accept an optional path argument (Path or str), defaulting to sys.argv[0] (e.g., pyhabitat/__main__.py for python -m pyhabitat, empty in REPL). Path.resolve() is used for stability.
|
|
88
92
|
|
|
89
93
|
| Function | Description |
|
|
90
94
|
| :--- | :--- |
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
|
|
95
|
+
| `as_frozen()` | Returns `True` if the script is running as a standalone executable (any bundler). |
|
|
96
|
+
| `as_pyinstaller()` | Returns `True` if the script is frozen and generated by PyInstaller (has `_MEIPASS`). |
|
|
97
|
+
| `is_python_script(path=None)` | Returns `True` if the script or specified path is a Python source file (.py). |
|
|
98
|
+
| `is_pipx(path=None)` | Returns `True` if the script or specified path is from a pipx-managed virtual environment. |
|
|
99
|
+
| `is_elf(path=None)` | Returns `True` if the script or specified path is an ELF binary (Linux standalone executable, non-pipx). |
|
|
100
|
+
| `is_pyz(path=None)` | Returns `True` if the script or specified path is a Python zipapp (.pyz, non-pipx). |
|
|
101
|
+
| `is_windows_portable_executable(path=None)` | Returns `True` if the script or specified path is a Windows PE binary (MZ header, non-pipx). |
|
|
102
|
+
| `is_macos_executable(path=None)` | Returns `True` if the script or specified path is a macOS Mach-O binary (non-pipx). |
|
|
98
103
|
|
|
99
104
|
### Capability Checking
|
|
100
105
|
|
|
@@ -103,16 +108,18 @@ Key Question: "What could I do next?"
|
|
|
103
108
|
| Function | Description |
|
|
104
109
|
| :--- | :--- |
|
|
105
110
|
| `tkinter_is_available()` | Checks if Tkinter is imported and can successfully create a window. |
|
|
106
|
-
| `matplotlib_is_available_for_gui_plotting(termux_has_gui=False)` | Checks for Matplotlib and its TkAgg backend, required for interactive plotting. |
|
|
111
|
+
| `matplotlib_is_available_for_gui_plotting(termux_has_gui=False)` | Checks for Matplotlib and its TkAgg backend, required for interactive plotting. Set `termux_has_gui=True` for Termux with GUI support; defaults to `False`. |
|
|
107
112
|
| `matplotlib_is_available_for_headless_image_export()` | Checks for Matplotlib and its Agg backend, required for saving images without a GUI. |
|
|
108
113
|
| `interactive_terminal_is_available()` | Checks if standard input and output streams are connected to a TTY (allows safe use of interactive prompts). |
|
|
109
114
|
| `web_browser_is_available()` | Check if a web browser can be launched in the current environment (allows safe use of web-based prompts and localhost plotting). |
|
|
110
115
|
|
|
111
|
-
###
|
|
116
|
+
### Utility
|
|
112
117
|
|
|
113
118
|
| Function | Description |
|
|
114
119
|
| :--- | :--- |
|
|
115
|
-
| `edit_textfile()` |
|
|
120
|
+
| `edit_textfile(path)` | Opens a text file for editing using the default editor (Windows, Linux, macOS) or nano in Termux/iSH. In REPL mode, prints an error. Path argument (str or Path) uses Path.resolve() for stability. |
|
|
121
|
+
| `interp_path(print_path=False)` | Returns the path to the Python interpreter binary (sys.executable). Optionally prints the path. Returns empty string if unavailable. |
|
|
122
|
+
| `main()` | Prints a comprehensive environment report with sections: Interpreter Checks (sys.executable), Current Environment Check (sys.argv[0]), Current Build Checks (sys attributes), Operating System Checks (platform.system()), and Capability Checks. Run via `python -m pyhabitat` or `import pyhabitat; pyhabitat.main()` in the REPL. |
|
|
116
123
|
|
|
117
124
|
</details>
|
|
118
125
|
|
|
@@ -123,39 +130,57 @@ Key Question: "What could I do next?"
|
|
|
123
130
|
|
|
124
131
|
The module exposes all detection functions directly for easy access.
|
|
125
132
|
|
|
126
|
-
### 0\.
|
|
133
|
+
### 0\. Example of PyHabitat in Action
|
|
127
134
|
|
|
128
135
|
The `pipeline-eds` package uses the `pyhabitat` library to handle [configuration](https://github.com/City-of-Memphis-Wastewater/pipeline/blob/main/src/pipeline/security_and_config.py) and [plotting](https://github.com/City-of-Memphis-Wastewater/pipeline/blob/main/src/pipeline/cli.py), among other things.
|
|
129
136
|
|
|
130
|
-
### 1\.
|
|
137
|
+
### 1\. Running the Environment Report
|
|
138
|
+
|
|
139
|
+
Run a comprehensive environment report from the command line or REPL to inspect the interpreter (sys.executable), running script (sys.argv[0]), build state, operating system, and capabilities.
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# In the terminal
|
|
143
|
+
python -m pyhabitat
|
|
144
|
+
```
|
|
131
145
|
|
|
132
146
|
```python
|
|
133
|
-
|
|
147
|
+
# In the Python REPL
|
|
148
|
+
import pyhabitat as ph
|
|
149
|
+
ph.main()
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### 2\. Checking Environment and Build Type
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
from pyhabitat import on_termux, on_windows, is_pipx, is_python_script, as_frozen
|
|
134
156
|
|
|
135
157
|
if is_pipx():
|
|
136
158
|
print("Running inside a pipx virtual environment. This is not a standalone binary.")
|
|
137
159
|
|
|
138
|
-
|
|
160
|
+
if as_frozen():
|
|
139
161
|
print("Running as a frozen executable (PyInstaller, cx_Freeze, etc.).")
|
|
140
162
|
|
|
141
|
-
|
|
163
|
+
if is_python_script():
|
|
164
|
+
print("Running as a Python source script (.py).")
|
|
165
|
+
|
|
166
|
+
if on_termux():
|
|
142
167
|
# Expected cases:
|
|
143
168
|
#- pkg install python-numpy python-cryptography
|
|
144
|
-
#- Avoiding matplotlib unless the user explicitly
|
|
169
|
+
#- Avoiding matplotlib unless the user explicitly sets termux_has_gui=True in matplotlib_is_available_for_gui_plotting().
|
|
145
170
|
#- Auto-selection of 'termux-open-url' and 'xdg-open' in logic.
|
|
146
171
|
#- Installation on the system, like orchestrating the construction of Termux Widget entries in ~/.shortcuts.
|
|
147
172
|
print("Running in the Termux environment on Android.")
|
|
148
173
|
|
|
149
|
-
|
|
174
|
+
if on_windows():
|
|
150
175
|
print("Running on Windows.")
|
|
151
176
|
```
|
|
152
177
|
|
|
153
|
-
###
|
|
178
|
+
### 3\. Checking GUI and Plotting Availability
|
|
154
179
|
|
|
155
180
|
Use these functions to determine if you can show an interactive plot or if you must save an image file.
|
|
156
181
|
|
|
157
182
|
```python
|
|
158
|
-
from pyhabitat import matplotlib_is_available_for_gui_plotting, matplotlib_is_available_for_headless_image_export
|
|
183
|
+
from pyhabitat import matplotlib_is_available_for_gui_plotting, matplotlib_is_available_for_headless_image_export
|
|
159
184
|
|
|
160
185
|
if matplotlib_is_available_for_gui_plotting():
|
|
161
186
|
# We can safely call plt.show()
|
|
@@ -173,13 +198,16 @@ else:
|
|
|
173
198
|
print("Matplotlib is not installed or the environment is too restrictive for plotting.")
|
|
174
199
|
```
|
|
175
200
|
|
|
176
|
-
###
|
|
201
|
+
### 4\. Text Editing
|
|
177
202
|
|
|
178
|
-
Use this function to
|
|
203
|
+
Use this function to open a text file for editing.
|
|
179
204
|
Ideal use case: Edit a configuration file, if prompted by a CLI command like 'config --textedit'.
|
|
180
205
|
|
|
181
206
|
```python
|
|
182
|
-
|
|
207
|
+
from pathlib import Path
|
|
208
|
+
import pyhabitat as ph
|
|
209
|
+
|
|
210
|
+
ph.edit_textfile(path=Path('./config.json'))
|
|
183
211
|
```
|
|
184
212
|
</details>
|
|
185
213
|
|
|
@@ -44,11 +44,11 @@ Ultimately, [City-of-Memphis-Wastewater](https://github.com/City-of-Memphis-Wast
|
|
|
44
44
|
|
|
45
45
|
* **Definitive Environment Checks:** Rigorous checks catered to Termux and iSH (iOS Alpine). Accurate, typical modern detection for Windows, macOS (Apple), Linux, FreeBSD, Android.
|
|
46
46
|
* **GUI Availability:** Rigorous, cached checks to determine if the environment supports a graphical popup window (Tkinter/Matplotlib TkAgg) or just headless image export (Matplotlib Agg).
|
|
47
|
-
* **Build/Packaging Detection:** Reliable detection of standalone executables
|
|
48
|
-
* **Executable Type Inspection:** Uses file magic numbers (ELF
|
|
47
|
+
* **Build/Packaging Detection:** Reliable detection of standalone executables (PyInstaller), Python zipapps (.pyz), Python source scripts (.py), and correct identification/exclusion of pipx-managed virtual environments.
|
|
48
|
+
* **Executable Type Inspection:** Uses file magic numbers (ELF, MZ, Mach-O) to confirm if the running script is a monolithic, frozen binary (non-pipx) or zipapp (.pyz).
|
|
49
49
|
|
|
50
50
|
</details>
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
---
|
|
53
53
|
|
|
54
54
|
<details>
|
|
@@ -60,26 +60,31 @@ Key question: "What is this running on?"
|
|
|
60
60
|
|
|
61
61
|
| Function | Description |
|
|
62
62
|
| :--- | :--- |
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
63
|
+
| `on_windows()` | Returns `True` on Windows. |
|
|
64
|
+
| `on_apple()` | Returns `True` on macOS (Darwin). |
|
|
65
|
+
| `on_linux()` | Returns `True` on Linux in general. |
|
|
66
|
+
| `on_termux()` | Returns `True` if running in the Termux Android environment. |
|
|
67
|
+
| `on_freebsd()` | Returns `True` on FreeBSD. |
|
|
68
|
+
| `on_ish_alpine()` | Returns `True` if running in the iSH Alpine Linux iOS emulator. |
|
|
69
|
+
| `on_android()` | Returns `True` on any Android-based Linux environment. |
|
|
70
|
+
| `in_repl()` | Returns `True` is the user is currently in a Python REPL; hasattr(sys,'ps1'). |
|
|
69
71
|
|
|
70
72
|
### Packaging and Build Checking
|
|
71
73
|
|
|
72
|
-
Key question: "What is the character of my executable?"
|
|
74
|
+
Key question: "What is the character of my executable or my build state?"
|
|
75
|
+
|
|
76
|
+
These functions accept an optional path argument (Path or str), defaulting to sys.argv[0] (e.g., pyhabitat/__main__.py for python -m pyhabitat, empty in REPL). Path.resolve() is used for stability.
|
|
73
77
|
|
|
74
78
|
| Function | Description |
|
|
75
79
|
| :--- | :--- |
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
|
|
80
|
+
| `as_frozen()` | Returns `True` if the script is running as a standalone executable (any bundler). |
|
|
81
|
+
| `as_pyinstaller()` | Returns `True` if the script is frozen and generated by PyInstaller (has `_MEIPASS`). |
|
|
82
|
+
| `is_python_script(path=None)` | Returns `True` if the script or specified path is a Python source file (.py). |
|
|
83
|
+
| `is_pipx(path=None)` | Returns `True` if the script or specified path is from a pipx-managed virtual environment. |
|
|
84
|
+
| `is_elf(path=None)` | Returns `True` if the script or specified path is an ELF binary (Linux standalone executable, non-pipx). |
|
|
85
|
+
| `is_pyz(path=None)` | Returns `True` if the script or specified path is a Python zipapp (.pyz, non-pipx). |
|
|
86
|
+
| `is_windows_portable_executable(path=None)` | Returns `True` if the script or specified path is a Windows PE binary (MZ header, non-pipx). |
|
|
87
|
+
| `is_macos_executable(path=None)` | Returns `True` if the script or specified path is a macOS Mach-O binary (non-pipx). |
|
|
83
88
|
|
|
84
89
|
### Capability Checking
|
|
85
90
|
|
|
@@ -88,16 +93,18 @@ Key Question: "What could I do next?"
|
|
|
88
93
|
| Function | Description |
|
|
89
94
|
| :--- | :--- |
|
|
90
95
|
| `tkinter_is_available()` | Checks if Tkinter is imported and can successfully create a window. |
|
|
91
|
-
| `matplotlib_is_available_for_gui_plotting(termux_has_gui=False)` | Checks for Matplotlib and its TkAgg backend, required for interactive plotting. |
|
|
96
|
+
| `matplotlib_is_available_for_gui_plotting(termux_has_gui=False)` | Checks for Matplotlib and its TkAgg backend, required for interactive plotting. Set `termux_has_gui=True` for Termux with GUI support; defaults to `False`. |
|
|
92
97
|
| `matplotlib_is_available_for_headless_image_export()` | Checks for Matplotlib and its Agg backend, required for saving images without a GUI. |
|
|
93
98
|
| `interactive_terminal_is_available()` | Checks if standard input and output streams are connected to a TTY (allows safe use of interactive prompts). |
|
|
94
99
|
| `web_browser_is_available()` | Check if a web browser can be launched in the current environment (allows safe use of web-based prompts and localhost plotting). |
|
|
95
100
|
|
|
96
|
-
###
|
|
101
|
+
### Utility
|
|
97
102
|
|
|
98
103
|
| Function | Description |
|
|
99
104
|
| :--- | :--- |
|
|
100
|
-
| `edit_textfile()` |
|
|
105
|
+
| `edit_textfile(path)` | Opens a text file for editing using the default editor (Windows, Linux, macOS) or nano in Termux/iSH. In REPL mode, prints an error. Path argument (str or Path) uses Path.resolve() for stability. |
|
|
106
|
+
| `interp_path(print_path=False)` | Returns the path to the Python interpreter binary (sys.executable). Optionally prints the path. Returns empty string if unavailable. |
|
|
107
|
+
| `main()` | Prints a comprehensive environment report with sections: Interpreter Checks (sys.executable), Current Environment Check (sys.argv[0]), Current Build Checks (sys attributes), Operating System Checks (platform.system()), and Capability Checks. Run via `python -m pyhabitat` or `import pyhabitat; pyhabitat.main()` in the REPL. |
|
|
101
108
|
|
|
102
109
|
</details>
|
|
103
110
|
|
|
@@ -108,39 +115,57 @@ Key Question: "What could I do next?"
|
|
|
108
115
|
|
|
109
116
|
The module exposes all detection functions directly for easy access.
|
|
110
117
|
|
|
111
|
-
### 0\.
|
|
118
|
+
### 0\. Example of PyHabitat in Action
|
|
112
119
|
|
|
113
120
|
The `pipeline-eds` package uses the `pyhabitat` library to handle [configuration](https://github.com/City-of-Memphis-Wastewater/pipeline/blob/main/src/pipeline/security_and_config.py) and [plotting](https://github.com/City-of-Memphis-Wastewater/pipeline/blob/main/src/pipeline/cli.py), among other things.
|
|
114
121
|
|
|
115
|
-
### 1\.
|
|
122
|
+
### 1\. Running the Environment Report
|
|
123
|
+
|
|
124
|
+
Run a comprehensive environment report from the command line or REPL to inspect the interpreter (sys.executable), running script (sys.argv[0]), build state, operating system, and capabilities.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# In the terminal
|
|
128
|
+
python -m pyhabitat
|
|
129
|
+
```
|
|
116
130
|
|
|
117
131
|
```python
|
|
118
|
-
|
|
132
|
+
# In the Python REPL
|
|
133
|
+
import pyhabitat as ph
|
|
134
|
+
ph.main()
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 2\. Checking Environment and Build Type
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from pyhabitat import on_termux, on_windows, is_pipx, is_python_script, as_frozen
|
|
119
141
|
|
|
120
142
|
if is_pipx():
|
|
121
143
|
print("Running inside a pipx virtual environment. This is not a standalone binary.")
|
|
122
144
|
|
|
123
|
-
|
|
145
|
+
if as_frozen():
|
|
124
146
|
print("Running as a frozen executable (PyInstaller, cx_Freeze, etc.).")
|
|
125
147
|
|
|
126
|
-
|
|
148
|
+
if is_python_script():
|
|
149
|
+
print("Running as a Python source script (.py).")
|
|
150
|
+
|
|
151
|
+
if on_termux():
|
|
127
152
|
# Expected cases:
|
|
128
153
|
#- pkg install python-numpy python-cryptography
|
|
129
|
-
#- Avoiding matplotlib unless the user explicitly
|
|
154
|
+
#- Avoiding matplotlib unless the user explicitly sets termux_has_gui=True in matplotlib_is_available_for_gui_plotting().
|
|
130
155
|
#- Auto-selection of 'termux-open-url' and 'xdg-open' in logic.
|
|
131
156
|
#- Installation on the system, like orchestrating the construction of Termux Widget entries in ~/.shortcuts.
|
|
132
157
|
print("Running in the Termux environment on Android.")
|
|
133
158
|
|
|
134
|
-
|
|
159
|
+
if on_windows():
|
|
135
160
|
print("Running on Windows.")
|
|
136
161
|
```
|
|
137
162
|
|
|
138
|
-
###
|
|
163
|
+
### 3\. Checking GUI and Plotting Availability
|
|
139
164
|
|
|
140
165
|
Use these functions to determine if you can show an interactive plot or if you must save an image file.
|
|
141
166
|
|
|
142
167
|
```python
|
|
143
|
-
from pyhabitat import matplotlib_is_available_for_gui_plotting, matplotlib_is_available_for_headless_image_export
|
|
168
|
+
from pyhabitat import matplotlib_is_available_for_gui_plotting, matplotlib_is_available_for_headless_image_export
|
|
144
169
|
|
|
145
170
|
if matplotlib_is_available_for_gui_plotting():
|
|
146
171
|
# We can safely call plt.show()
|
|
@@ -158,13 +183,16 @@ else:
|
|
|
158
183
|
print("Matplotlib is not installed or the environment is too restrictive for plotting.")
|
|
159
184
|
```
|
|
160
185
|
|
|
161
|
-
###
|
|
186
|
+
### 4\. Text Editing
|
|
162
187
|
|
|
163
|
-
Use this function to
|
|
188
|
+
Use this function to open a text file for editing.
|
|
164
189
|
Ideal use case: Edit a configuration file, if prompted by a CLI command like 'config --textedit'.
|
|
165
190
|
|
|
166
191
|
```python
|
|
167
|
-
|
|
192
|
+
from pathlib import Path
|
|
193
|
+
import pyhabitat as ph
|
|
194
|
+
|
|
195
|
+
ph.edit_textfile(path=Path('./config.json'))
|
|
168
196
|
```
|
|
169
197
|
</details>
|
|
170
198
|
|
|
@@ -4,23 +4,27 @@ from .environment import (
|
|
|
4
4
|
matplotlib_is_available_for_gui_plotting,
|
|
5
5
|
matplotlib_is_available_for_headless_image_export,
|
|
6
6
|
tkinter_is_available,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
in_repl,
|
|
8
|
+
on_termux,
|
|
9
|
+
on_freebsd,
|
|
10
|
+
on_linux,
|
|
11
|
+
on_android,
|
|
12
|
+
on_windows,
|
|
13
|
+
on_apple,
|
|
14
|
+
on_ish_alpine,
|
|
15
|
+
as_pyinstaller,
|
|
16
|
+
as_frozen,
|
|
16
17
|
is_elf,
|
|
17
18
|
is_pyz,
|
|
18
19
|
is_windows_portable_executable,
|
|
19
20
|
is_macos_executable,
|
|
20
21
|
is_pipx,
|
|
22
|
+
is_python_script,
|
|
21
23
|
interactive_terminal_is_available,
|
|
22
24
|
web_browser_is_available,
|
|
23
25
|
edit_textfile,
|
|
26
|
+
interp_path,
|
|
27
|
+
main,
|
|
24
28
|
)
|
|
25
29
|
|
|
26
30
|
# Optional: Set __all__ for explicit documentation and cleaner imports
|
|
@@ -28,21 +32,25 @@ __all__ = [
|
|
|
28
32
|
'matplotlib_is_available_for_gui_plotting',
|
|
29
33
|
'matplotlib_is_available_for_headless_image_export',
|
|
30
34
|
'tkinter_is_available',
|
|
31
|
-
'
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'
|
|
39
|
-
'
|
|
35
|
+
'in_repl',
|
|
36
|
+
'on_termux',
|
|
37
|
+
'on_freebsd',
|
|
38
|
+
'on_linux',
|
|
39
|
+
'on_android',
|
|
40
|
+
'on_windows',
|
|
41
|
+
'on_apple',
|
|
42
|
+
'on_ish_alpine',
|
|
43
|
+
'as_pyinstaller',
|
|
44
|
+
'as_frozen',
|
|
40
45
|
'is_elf',
|
|
41
46
|
'is_pyz',
|
|
42
47
|
'is_windows_portable_executable',
|
|
43
48
|
'is_macos_executable',
|
|
44
49
|
'is_pipx',
|
|
50
|
+
'is_python_script',
|
|
45
51
|
'interactive_terminal_is_available',
|
|
46
52
|
'web_browser_is_available',
|
|
47
53
|
'edit_textfile',
|
|
54
|
+
'interp_path',
|
|
55
|
+
'main',
|
|
48
56
|
]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#from .cli import run_cli
|
|
2
|
+
|
|
3
|
+
from .environment import (
|
|
4
|
+
in_repl,
|
|
5
|
+
on_termux,
|
|
6
|
+
on_windows,
|
|
7
|
+
on_apple,
|
|
8
|
+
on_linux,
|
|
9
|
+
on_ish_alpine,
|
|
10
|
+
on_android,
|
|
11
|
+
on_freebsd,
|
|
12
|
+
is_elf,
|
|
13
|
+
is_windows_portable_executable,
|
|
14
|
+
is_macos_executable,
|
|
15
|
+
is_pyz,
|
|
16
|
+
is_pipx,
|
|
17
|
+
is_python_script,
|
|
18
|
+
as_frozen,
|
|
19
|
+
as_pyinstaller,
|
|
20
|
+
interp_path,
|
|
21
|
+
tkinter_is_available,
|
|
22
|
+
matplotlib_is_available_for_gui_plotting,
|
|
23
|
+
matplotlib_is_available_for_headless_image_export,
|
|
24
|
+
web_browser_is_available,
|
|
25
|
+
interactive_terminal_is_available
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def main():
|
|
29
|
+
print("PyHabitat Environment Report")
|
|
30
|
+
print("===========================")
|
|
31
|
+
print("\nInterpreter Checks // Based on sys.executable()")
|
|
32
|
+
print("-----------------------------")
|
|
33
|
+
print(f"interp_path(): {interp_path()}")
|
|
34
|
+
print(f"is_elf(interp_path()): {is_elf(interp_path())}")
|
|
35
|
+
print(f"is_windows_portable_executable(interp_path()): {is_windows_portable_executable(interp_path())}")
|
|
36
|
+
print(f"is_macos_executable(interp_path()): {is_macos_executable(interp_path())}")
|
|
37
|
+
print(f"is_pyz(interp_path()): {is_pyz(interp_path())}")
|
|
38
|
+
print(f"is_pipx(interp_path()): {is_pipx(interp_path())}")
|
|
39
|
+
print(f"is_python_script(interp_path()): {is_python_script(interp_path())}")
|
|
40
|
+
print("\nCurrent Environment Check // Based on sys.argv[0]")
|
|
41
|
+
print("-----------------------------")
|
|
42
|
+
print(f"is_elf(): {is_elf()}")
|
|
43
|
+
print(f"is_windows_portable_executable(): {is_windows_portable_executable()}")
|
|
44
|
+
print(f"is_macos_executable(): {is_macos_executable()}")
|
|
45
|
+
print(f"is_pyz(): {is_pyz()}")
|
|
46
|
+
print(f"is_pipx(): {is_pipx()}")
|
|
47
|
+
print(f"is_python_script(): {is_python_script()}")
|
|
48
|
+
print(f"\nCurrent Build Checks // Based on hasattr(sys,..) and getattr(sys,..)")
|
|
49
|
+
print("------------------------------")
|
|
50
|
+
print(f"in_repl(): {in_repl()}")
|
|
51
|
+
print(f"as_frozen(): {as_frozen()}")
|
|
52
|
+
print(f"as_pyinstaller(): {as_pyinstaller()}")
|
|
53
|
+
print("\nOperating System Checks // Based on platform.system()")
|
|
54
|
+
print("------------------------------")
|
|
55
|
+
print(f"on_termux(): {on_termux()}")
|
|
56
|
+
print(f"on_windows(): {on_windows()}")
|
|
57
|
+
print(f"on_apple(): {on_apple()}")
|
|
58
|
+
print(f"on_linux(): {on_linux()}")
|
|
59
|
+
print(f"on_ish_alpine(): {on_ish_alpine()}")
|
|
60
|
+
print(f"on_android(): {on_android()}")
|
|
61
|
+
print(f"on_freebsd(): {on_freebsd()}")
|
|
62
|
+
print("\nCapability Checks")
|
|
63
|
+
print("-------------------------")
|
|
64
|
+
print(f"tkinter_is_available(): {tkinter_is_available()}")
|
|
65
|
+
print(f"matplotlib_is_available_for_gui_plotting(): {matplotlib_is_available_for_gui_plotting()}")
|
|
66
|
+
print(f"matplotlib_is_available_for_headless_image_export(): {matplotlib_is_available_for_headless_image_export()}")
|
|
67
|
+
print(f"web_browser_is_available(): {web_browser_is_available()}")
|
|
68
|
+
print(f"interactive_terminal_is_available(): {interactive_terminal_is_available()}")
|
|
69
|
+
|
|
70
|
+
if __name__ == "__main__":
|
|
71
|
+
main()
|
|
72
|
+
#run_cli()
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from . import main
|
|
4
|
+
|
|
5
|
+
def run_cli():
|
|
6
|
+
"""Parse CLI arguments and run the pyhabitat environment report."""
|
|
7
|
+
parser = argparse.ArgumentParser(
|
|
8
|
+
description="PyHabitat: Python environment and build introspection"
|
|
9
|
+
)
|
|
10
|
+
parser.add_argument(
|
|
11
|
+
"--path",
|
|
12
|
+
type=str,
|
|
13
|
+
default=None,
|
|
14
|
+
help="Path to a script or binary to inspect (defaults to sys.argv[0])",
|
|
15
|
+
)
|
|
16
|
+
parser.add_argument(
|
|
17
|
+
"--debug",
|
|
18
|
+
action="store_true",
|
|
19
|
+
help="Enable verbose debug output",
|
|
20
|
+
)
|
|
21
|
+
args = parser.parse_args()
|
|
22
|
+
main(path=Path(args.path) if args.path else None, debug=args.debug)
|