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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyhabitat
3
- Version: 1.0.16
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.8
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 built by tools like PyInstaller, and, crucially, correct identification and exclusion of pipx-managed virtual environments, which also user binaries that could conflate the check.
63
- * **Executable Type Inspection:** Uses file magic numbers (ELF and MZ) to confirm if the running script is a monolithic, frozen binary (non-pipx).
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
- | `is_windows()` | Returns `True` on Windows. |
79
- | `is_apple()` | Returns `True` on macOS (Darwin). |
80
- | `is_linux()` | Returns `True` on Linux in general. |
81
- | `is_termux()` | Returns `True` if running in the Termux Android environment. |
82
- | `is_ish_alpine()` | Returns `True` if running in the iSH Alpine Linux iOS emulator. |
83
- | `is_android()` | Returns `True` on any Android-based Linux environment. |
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
- | `is_frozen()` | Returns `True` if the script is running as a standalone executable (any bundler). |
92
- | `is_pyinstaller()` | Returns `True` if the script is_frozen() and was generated by Pyinstaller (has MEI). |
93
- | `is_pipx()` | Returns `True` if running from a pipx managed virtual environment. |
94
- | `is_elf()` | Checks if the executable is an ELF binary (Linux standalone executable), excluding pipx. |
95
- | `is_windows_portable_executable()` | Checks if the executable is a Windows PE binary (MZ header), excluding pipx. |
96
- | `is_macos_executable()` | Checks if the executable is a macOS/Darwin Mach-O binary, excluding pipx. || `is_macos_executable()` | Checks if the executable is a macOS/Darwin Mach-O binary, excluding pipx. |
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
- ### Actions
116
+ ### Utility
112
117
 
113
118
  | Function | Description |
114
119
  | :--- | :--- |
115
- | `edit_textfile()` | Smoothly opens a text file for editing (for configuration editing prompted by a CLI flag). |
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\. Current Use
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\. Checking Environment and Build Type
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
- from pyhabitat import is_termux, is_windows, is_pipx, is_frozen
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
- elif is_frozen():
160
+ if as_frozen():
139
161
  print("Running as a frozen executable (PyInstaller, cx_Freeze, etc.).")
140
162
 
141
- elif is_termux():
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 confirms that termux_has_gui=False in matplotlib_is_available_for_gui_plotting(termux_has_gui=False).
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
- elif is_windows():
174
+ if on_windows():
150
175
  print("Running on Windows.")
151
176
  ```
152
177
 
153
- ### 2\. Checking GUI and Plotting Availability
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
- ### 3\. Text Editing
201
+ ### 4\. Text Editing
177
202
 
178
- Use this function to smoothly open a text file for editing.
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
- edit_textfile(filepath=Path('./config.json'))
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 built by tools like PyInstaller, and, crucially, correct identification and exclusion of pipx-managed virtual environments, which also user binaries that could conflate the check.
48
- * **Executable Type Inspection:** Uses file magic numbers (ELF and MZ) to confirm if the running script is a monolithic, frozen binary (non-pipx).
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
- | `is_windows()` | Returns `True` on Windows. |
64
- | `is_apple()` | Returns `True` on macOS (Darwin). |
65
- | `is_linux()` | Returns `True` on Linux in general. |
66
- | `is_termux()` | Returns `True` if running in the Termux Android environment. |
67
- | `is_ish_alpine()` | Returns `True` if running in the iSH Alpine Linux iOS emulator. |
68
- | `is_android()` | Returns `True` on any Android-based Linux environment. |
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
- | `is_frozen()` | Returns `True` if the script is running as a standalone executable (any bundler). |
77
- | `is_pyinstaller()` | Returns `True` if the script is_frozen() and was generated by Pyinstaller (has MEI). |
78
- | `is_pipx()` | Returns `True` if running from a pipx managed virtual environment. |
79
- | `is_elf()` | Checks if the executable is an ELF binary (Linux standalone executable), excluding pipx. |
80
- | `is_windows_portable_executable()` | Checks if the executable is a Windows PE binary (MZ header), excluding pipx. |
81
- | `is_macos_executable()` | Checks if the executable is a macOS/Darwin Mach-O binary, excluding pipx. || `is_macos_executable()` | Checks if the executable is a macOS/Darwin Mach-O binary, excluding pipx. |
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
- ### Actions
101
+ ### Utility
97
102
 
98
103
  | Function | Description |
99
104
  | :--- | :--- |
100
- | `edit_textfile()` | Smoothly opens a text file for editing (for configuration editing prompted by a CLI flag). |
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\. Current Use
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\. Checking Environment and Build Type
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
- from pyhabitat import is_termux, is_windows, is_pipx, is_frozen
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
- elif is_frozen():
145
+ if as_frozen():
124
146
  print("Running as a frozen executable (PyInstaller, cx_Freeze, etc.).")
125
147
 
126
- elif is_termux():
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 confirms that termux_has_gui=False in matplotlib_is_available_for_gui_plotting(termux_has_gui=False).
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
- elif is_windows():
159
+ if on_windows():
135
160
  print("Running on Windows.")
136
161
  ```
137
162
 
138
- ### 2\. Checking GUI and Plotting Availability
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
- ### 3\. Text Editing
186
+ ### 4\. Text Editing
162
187
 
163
- Use this function to smoothly open a text file for editing.
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
- edit_textfile(filepath=Path('./config.json'))
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
- is_termux,
8
- is_freebsd,
9
- is_linux,
10
- is_android,
11
- is_windows,
12
- is_apple,
13
- is_ish_alpine,
14
- is_pyinstaller,
15
- is_frozen,
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
- 'is_termux',
32
- 'is_freebsd',
33
- 'is_linux',
34
- 'is_android',
35
- 'is_windows',
36
- 'is_apple',
37
- 'is_ish_alpine',
38
- 'is_pyinstaller',
39
- 'is_frozen',
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,4 @@
1
+ from .cli import run_cli
2
+
3
+ if __name__ == "__main__":
4
+ run_cli()
@@ -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)