pyhabitat 1.0.14__py3-none-any.whl → 1.0.16__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 pyhabitat might be problematic. Click here for more details.
- pyhabitat/__init__.py +5 -5
- pyhabitat/environment.py +41 -29
- {pyhabitat-1.0.14.dist-info → pyhabitat-1.0.16.dist-info}/METADATA +6 -4
- pyhabitat-1.0.16.dist-info/RECORD +7 -0
- pyhabitat-1.0.14.dist-info/RECORD +0 -7
- {pyhabitat-1.0.14.dist-info → pyhabitat-1.0.16.dist-info}/WHEEL +0 -0
- {pyhabitat-1.0.14.dist-info → pyhabitat-1.0.16.dist-info}/licenses/LICENSE +0 -0
- {pyhabitat-1.0.14.dist-info → pyhabitat-1.0.16.dist-info}/top_level.txt +0 -0
pyhabitat/__init__.py
CHANGED
|
@@ -11,7 +11,7 @@ from .environment import (
|
|
|
11
11
|
is_windows,
|
|
12
12
|
is_apple,
|
|
13
13
|
is_ish_alpine,
|
|
14
|
-
|
|
14
|
+
is_pyinstaller,
|
|
15
15
|
is_frozen,
|
|
16
16
|
is_elf,
|
|
17
17
|
is_pyz,
|
|
@@ -20,7 +20,7 @@ from .environment import (
|
|
|
20
20
|
is_pipx,
|
|
21
21
|
interactive_terminal_is_available,
|
|
22
22
|
web_browser_is_available,
|
|
23
|
-
|
|
23
|
+
edit_textfile,
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
# Optional: Set __all__ for explicit documentation and cleaner imports
|
|
@@ -35,7 +35,7 @@ __all__ = [
|
|
|
35
35
|
'is_windows',
|
|
36
36
|
'is_apple',
|
|
37
37
|
'is_ish_alpine',
|
|
38
|
-
'
|
|
38
|
+
'is_pyinstaller',
|
|
39
39
|
'is_frozen',
|
|
40
40
|
'is_elf',
|
|
41
41
|
'is_pyz',
|
|
@@ -44,5 +44,5 @@ __all__ = [
|
|
|
44
44
|
'is_pipx',
|
|
45
45
|
'interactive_terminal_is_available',
|
|
46
46
|
'web_browser_is_available',
|
|
47
|
-
'
|
|
48
|
-
]
|
|
47
|
+
'edit_textfile',
|
|
48
|
+
]
|
pyhabitat/environment.py
CHANGED
|
@@ -12,8 +12,7 @@ import shutil
|
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
import subprocess
|
|
14
14
|
import io
|
|
15
|
-
|
|
16
|
-
from pipeline.helpers import check_if_zip
|
|
15
|
+
import zipfile
|
|
17
16
|
|
|
18
17
|
# Global cache for tkinter and matplotlib (mpl) availability
|
|
19
18
|
_TKINTER_AVAILABILITY: bool | None = None
|
|
@@ -212,7 +211,7 @@ def is_ish_alpine() -> bool:
|
|
|
212
211
|
|
|
213
212
|
# --- BUILD AND EXECUTABLE CHECKS ---
|
|
214
213
|
|
|
215
|
-
def
|
|
214
|
+
def is_pyinstaller():
|
|
216
215
|
"""Detects if the Python script is running as a 'frozen' in the course of generating a PyInstaller binary executable."""
|
|
217
216
|
# If the app is frozen AND has the PyInstaller-specific temporary folder path
|
|
218
217
|
return is_frozen() and hasattr(sys, '_MEIPASS')
|
|
@@ -277,7 +276,7 @@ def is_pyz(exec_path: Path=None, debug=False) -> bool:
|
|
|
277
276
|
if not str(exec_path).endswith(".pyz"):
|
|
278
277
|
return False
|
|
279
278
|
|
|
280
|
-
if not
|
|
279
|
+
if not _check_if_zip():
|
|
281
280
|
return False
|
|
282
281
|
|
|
283
282
|
def is_windows_portable_executable(exec_path: Path = None, debug=False) -> bool:
|
|
@@ -449,36 +448,39 @@ def web_browser_is_available() -> bool:
|
|
|
449
448
|
return False
|
|
450
449
|
|
|
451
450
|
# --- LAUNCH MECHANISMS BASED ON ENVIRONMENT ---
|
|
452
|
-
def
|
|
451
|
+
def edit_textfile(filepath) -> None:
|
|
452
|
+
#def open_text_file_for_editing(filepath):
|
|
453
453
|
"""
|
|
454
454
|
Opens a file with the environment's default application (Windows, Linux, macOS)
|
|
455
455
|
or a guaranteed console editor (nano) in constrained environments (Termux, iSH)
|
|
456
456
|
after ensuring line-ending compatibility.
|
|
457
457
|
"""
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
458
|
+
try:
|
|
459
|
+
if is_windows():
|
|
460
|
+
os.startfile(filepath)
|
|
461
|
+
elif is_termux():
|
|
462
|
+
# Install dependencies if missing (Termux pkg returns non-zero if already installed, so no check=True)
|
|
463
|
+
subprocess.run(['pkg','install', 'dos2unix', 'nano'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
464
|
+
_run_dos2unix(filepath)
|
|
465
|
+
subprocess.run(['nano', filepath])
|
|
466
|
+
elif is_ish_alpine():
|
|
467
|
+
# Install dependencies if missing (apk returns 0 if already installed, so check=True is safe)
|
|
468
|
+
subprocess.run(['apk','add', 'dos2unix'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
|
|
469
|
+
subprocess.run(['apk','add', 'nano'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True)
|
|
470
|
+
_run_dos2unix(filepath)
|
|
471
|
+
subprocess.run(['nano', filepath])
|
|
472
|
+
# --- Standard Unix-like Systems (Conversion + Default App) ---
|
|
473
|
+
elif is_linux():
|
|
474
|
+
_run_dos2unix(filepath) # Safety conversion for user-defined console apps
|
|
475
|
+
subprocess.run(['xdg-open', filepath])
|
|
476
|
+
elif is_apple():
|
|
477
|
+
_run_dos2unix(filepath) # Safety conversion for user-defined console apps
|
|
478
|
+
subprocess.run(['open', filepath])
|
|
479
|
+
else:
|
|
480
|
+
print("Unsupported operating system.")
|
|
481
|
+
except Exception as e:
|
|
482
|
+
print("The file could not be opened for editing in the current environment. Known failure points: Pydroid3")
|
|
483
|
+
|
|
482
484
|
"""Why Not Use check=True on Termux:
|
|
483
485
|
The pkg utility in Termux is a wrapper around Debian's apt. When you run pkg install <package>, if the package is already installed, the utility often returns an exit code of 100 (or another non-zero value) to indicate that no changes were made because the package was already present.
|
|
484
486
|
"""
|
|
@@ -522,3 +524,13 @@ def _get_pipx_paths():
|
|
|
522
524
|
pipx_venv_base = Path.home() / '.local' / 'share' / 'pipx' / 'venvs'
|
|
523
525
|
|
|
524
526
|
return pipx_bin_path, pipx_venv_base.resolve()
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
def _check_if_zip(file_path: str | Path) -> bool:
|
|
530
|
+
"""Checks if the file at the given path is a valid ZIP archive."""
|
|
531
|
+
try:
|
|
532
|
+
return zipfile.is_zipfile(file_path)
|
|
533
|
+
except Exception:
|
|
534
|
+
# Handle cases where the path might be invalid, or other unexpected errors
|
|
535
|
+
return False
|
|
536
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyhabitat
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.16
|
|
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
|
|
@@ -89,10 +89,12 @@ Key question: "What is the character of my executable?"
|
|
|
89
89
|
| Function | Description |
|
|
90
90
|
| :--- | :--- |
|
|
91
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). |
|
|
92
93
|
| `is_pipx()` | Returns `True` if running from a pipx managed virtual environment. |
|
|
93
94
|
| `is_elf()` | Checks if the executable is an ELF binary (Linux standalone executable), excluding pipx. |
|
|
94
95
|
| `is_windows_portable_executable()` | Checks if the executable is a Windows PE binary (MZ header), excluding pipx. |
|
|
95
|
-
| `is_macos_executable()` | Checks if the executable is a macOS/Darwin Mach-O binary, 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
|
+
|
|
96
98
|
|
|
97
99
|
### Capability Checking
|
|
98
100
|
|
|
@@ -110,7 +112,7 @@ Key Question: "What could I do next?"
|
|
|
110
112
|
|
|
111
113
|
| Function | Description |
|
|
112
114
|
| :--- | :--- |
|
|
113
|
-
| `
|
|
115
|
+
| `edit_textfile()` | Smoothly opens a text file for editing (for configuration editing prompted by a CLI flag). |
|
|
114
116
|
|
|
115
117
|
</details>
|
|
116
118
|
|
|
@@ -177,7 +179,7 @@ Use this function to smoothly open a text file for editing.
|
|
|
177
179
|
Ideal use case: Edit a configuration file, if prompted by a CLI command like 'config --textedit'.
|
|
178
180
|
|
|
179
181
|
```python
|
|
180
|
-
|
|
182
|
+
edit_textfile(filepath=Path('./config.json'))
|
|
181
183
|
```
|
|
182
184
|
</details>
|
|
183
185
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
pyhabitat/__init__.py,sha256=MiYIzYPqB3o6ZFXQ1C9BV2M2KI17BSq9CA6p8Uc7_h0,1096
|
|
2
|
+
pyhabitat/environment.py,sha256=v9e47TdbtMSiljkjr9-lfdUILQu95HLH0SB6k7QIba0,20757
|
|
3
|
+
pyhabitat-1.0.16.dist-info/licenses/LICENSE,sha256=D4fg30ctUGnCJlWu3ONv5-V8JE1v3ctakoJTcVjsJlg,1072
|
|
4
|
+
pyhabitat-1.0.16.dist-info/METADATA,sha256=APK_RIRIKYUzZ3nuNgcRUvbDhaHZnWXAwvatvPwU_Qg,9001
|
|
5
|
+
pyhabitat-1.0.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
+
pyhabitat-1.0.16.dist-info/top_level.txt,sha256=zXYK44Qu8EqxUETREvd2diMUaB5JiGRErkwFaoLQnnI,10
|
|
7
|
+
pyhabitat-1.0.16.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
pyhabitat/__init__.py,sha256=XVMOgp7YPR0xYD1F_4-VEhG4rTwx3ga3CttdRKpkyxA,1115
|
|
2
|
-
pyhabitat/environment.py,sha256=c_eUqlqiAYGBX2LLCMo3PctOYhwTywOrCBrvjg_rXUs,20248
|
|
3
|
-
pyhabitat-1.0.14.dist-info/licenses/LICENSE,sha256=D4fg30ctUGnCJlWu3ONv5-V8JE1v3ctakoJTcVjsJlg,1072
|
|
4
|
-
pyhabitat-1.0.14.dist-info/METADATA,sha256=2_t5JIthRCcKCg5s4cX-CnAGLzfd36LNNmksec8zrM0,8813
|
|
5
|
-
pyhabitat-1.0.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
6
|
-
pyhabitat-1.0.14.dist-info/top_level.txt,sha256=zXYK44Qu8EqxUETREvd2diMUaB5JiGRErkwFaoLQnnI,10
|
|
7
|
-
pyhabitat-1.0.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|