pyhabitat 1.0.29__py3-none-any.whl → 1.0.32__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 +4 -0
- pyhabitat/demo.py +0 -0
- pyhabitat/environment.py +110 -18
- pyhabitat/report.py +0 -0
- {pyhabitat-1.0.29.dist-info → pyhabitat-1.0.32.dist-info}/METADATA +6 -2
- pyhabitat-1.0.32.dist-info/RECORD +17 -0
- pyhabitat-build/pyhabitat/__init__.py +4 -0
- pyhabitat-build/pyhabitat/cli.py +1 -1
- pyhabitat-build/pyhabitat/environment.py +24 -7
- pyhabitat-1.0.29.dist-info/RECORD +0 -15
- {pyhabitat-1.0.29.dist-info → pyhabitat-1.0.32.dist-info}/WHEEL +0 -0
- {pyhabitat-1.0.29.dist-info → pyhabitat-1.0.32.dist-info}/entry_points.txt +0 -0
- {pyhabitat-1.0.29.dist-info → pyhabitat-1.0.32.dist-info}/licenses/LICENSE +0 -0
- {pyhabitat-1.0.29.dist-info → pyhabitat-1.0.32.dist-info}/top_level.txt +0 -0
pyhabitat/__init__.py
CHANGED
|
@@ -30,6 +30,8 @@ from .environment import (
|
|
|
30
30
|
user_darrin_deyoung,
|
|
31
31
|
can_read_input,
|
|
32
32
|
can_spawn_shell,
|
|
33
|
+
is_ascii,
|
|
34
|
+
is_binary,
|
|
33
35
|
)
|
|
34
36
|
|
|
35
37
|
# Optional: Set __all__ for explicit documentation and cleaner imports
|
|
@@ -63,6 +65,8 @@ __all__ = [
|
|
|
63
65
|
'user_darrin_deyoung',
|
|
64
66
|
'can_read_input',
|
|
65
67
|
'can_spawn_shell',
|
|
68
|
+
'is_ascii',
|
|
69
|
+
'is_binary',
|
|
66
70
|
]
|
|
67
71
|
|
|
68
72
|
__version__ = get_version()
|
pyhabitat/demo.py
ADDED
|
File without changes
|
pyhabitat/environment.py
CHANGED
|
@@ -17,6 +17,12 @@ import logging
|
|
|
17
17
|
import getpass
|
|
18
18
|
import select
|
|
19
19
|
|
|
20
|
+
# On Windows, we need the msvcrt module for non-blocking I/O
|
|
21
|
+
try:
|
|
22
|
+
import msvcrt
|
|
23
|
+
except ImportError:
|
|
24
|
+
msvcrt = None
|
|
25
|
+
|
|
20
26
|
__all__ = [
|
|
21
27
|
'matplotlib_is_available_for_gui_plotting',
|
|
22
28
|
'matplotlib_is_available_for_headless_image_export',
|
|
@@ -512,6 +518,19 @@ def is_python_script(path: Path | str | None = None, debug: bool = False, suppre
|
|
|
512
518
|
return False
|
|
513
519
|
return exec_path.suffix.lower() == '.py'
|
|
514
520
|
|
|
521
|
+
# --- File encoding check ---
|
|
522
|
+
def is_binary(path:str|Path|None=None)->bool:
|
|
523
|
+
"""
|
|
524
|
+
Target file is encoded as binary.
|
|
525
|
+
"""
|
|
526
|
+
pass
|
|
527
|
+
|
|
528
|
+
def is_ascii(path:str|Path|None=None)->bool:
|
|
529
|
+
"""
|
|
530
|
+
Target file is encoded as ascii, plaintext.
|
|
531
|
+
"""
|
|
532
|
+
pass
|
|
533
|
+
|
|
515
534
|
# --- Interpreter Check ---
|
|
516
535
|
|
|
517
536
|
def interp_path(debug: bool = False) -> str:
|
|
@@ -543,21 +562,46 @@ def interactive_terminal_is_available():
|
|
|
543
562
|
then typer.prompt() or input() will work reliably,
|
|
544
563
|
without getting lost in a log or lost entirely.
|
|
545
564
|
|
|
565
|
+
Solution correctly identifies that true interactivity requires:
|
|
566
|
+
(1) a TTY (potential) connection
|
|
567
|
+
(2) the ability to execute
|
|
568
|
+
(3) the ability to read I/O
|
|
569
|
+
(4) ignores known limitatons in restrictive environments
|
|
570
|
+
|
|
571
|
+
Jargon:
|
|
572
|
+
A TTY, short for Teletypewriter or TeleTYpe,
|
|
573
|
+
is a conceptual or physical device that serves
|
|
574
|
+
as the interface for a user to interact with
|
|
575
|
+
a computer system.
|
|
546
576
|
"""
|
|
547
577
|
# Address walmart demo unit edge case, fast check, though this might hamstring othwrwise successful processes
|
|
548
|
-
if
|
|
578
|
+
if user_darrin_deyoung():
|
|
579
|
+
return False
|
|
580
|
+
|
|
581
|
+
# Check if a tty is attached to stdin,
|
|
582
|
+
# quick failure here if not before testing spwaning and reading
|
|
583
|
+
if not (sys.stdin.isatty() and sys.stdout.isatty()):
|
|
549
584
|
return False
|
|
550
|
-
|
|
585
|
+
|
|
586
|
+
# Check of a new shell can be launched to print stuff
|
|
551
587
|
if not can_spawn_shell():
|
|
552
588
|
return False
|
|
589
|
+
|
|
553
590
|
# A user can interact with a console, providing input
|
|
554
|
-
if not can_read_input():
|
|
555
|
-
|
|
556
|
-
|
|
591
|
+
#if not can_read_input():
|
|
592
|
+
# return False
|
|
593
|
+
|
|
557
594
|
return sys.stdin.isatty() and sys.stdout.isatty()
|
|
558
595
|
|
|
559
596
|
def user_darrin_deyoung():
|
|
560
597
|
"""Common demo unit undicator, edge case that is unable to launch terminal"""
|
|
598
|
+
# Enable teating on non-Windows, non-demo systems
|
|
599
|
+
# where this function would otherwise return False.
|
|
600
|
+
# Linux: `export USER_DARRIN_DEYOUNG=True`
|
|
601
|
+
if os.getenv('USER_DARRIN_DEYOUNG','').lower() == "true":
|
|
602
|
+
print("env var USER_DARRIN_DEYOUNG is set to True.")
|
|
603
|
+
return True
|
|
604
|
+
# Darrin Deyoung is the typical username on demo-mode Windows systems
|
|
561
605
|
if not on_windows():
|
|
562
606
|
return False
|
|
563
607
|
username = getpass.getuser()
|
|
@@ -568,23 +612,33 @@ def can_spawn_shell(override_known:bool=False)->bool:
|
|
|
568
612
|
global _CAN_SPAWN_SHELL
|
|
569
613
|
if _CAN_SPAWN_SHELL is not None and override_known is False:
|
|
570
614
|
return _CAN_SPAWN_SHELL
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
615
|
+
|
|
616
|
+
try:
|
|
617
|
+
# Use a simple, universally applicable command with shell=True
|
|
618
|
+
# 'true' on Linux/macOS, or a basic command on Windows via cmd.exe
|
|
619
|
+
# A simple 'echo' or 'exit 0' would also work
|
|
620
|
+
result = subprocess.run(
|
|
621
|
+
'exit 0', # A shell-internal command that succeeds on most shells
|
|
622
|
+
stdout=subprocess.PIPE,
|
|
623
|
+
stderr=subprocess.PIPE,
|
|
624
|
+
timeout=2,
|
|
625
|
+
shell=True # <--- ESSENTIAL for cross-platform reliability
|
|
626
|
+
)
|
|
627
|
+
|
|
628
|
+
_CAN_SPAWN_SHELL = result.returncode == 0
|
|
629
|
+
return _CAN_SPAWN_SHELL
|
|
630
|
+
|
|
577
631
|
except subprocess.TimeoutExpired:
|
|
578
|
-
|
|
579
|
-
_CAN_SPAWN_SHELL =
|
|
580
|
-
return
|
|
632
|
+
print("Shell spawn failed: TimeoutExpired")
|
|
633
|
+
_CAN_SPAWN_SHELL = result.returncode == 0
|
|
634
|
+
return _CAN_SPAWN_SHELL
|
|
581
635
|
except subprocess.SubprocessError:
|
|
582
|
-
|
|
636
|
+
print("Shell spawn failed: SubprocessError")
|
|
583
637
|
_CAN_SPAWN_SHELL = False
|
|
584
638
|
return False
|
|
585
639
|
except OSError:
|
|
586
640
|
_CAN_SPAWN_SHELL = False
|
|
587
|
-
|
|
641
|
+
print("Shell spawn failed: OSError (likely permission or missing binary)")
|
|
588
642
|
return False
|
|
589
643
|
|
|
590
644
|
def can_read_input(override_known:bool=False)-> bool:
|
|
@@ -592,9 +646,43 @@ def can_read_input(override_known:bool=False)-> bool:
|
|
|
592
646
|
global _CAN_READ_INPUT
|
|
593
647
|
if _CAN_READ_INPUT is not None and override_known is False:
|
|
594
648
|
return _CAN_READ_INPUT
|
|
649
|
+
|
|
650
|
+
# --- 1. Windows Specific Check (msvcrt) ---
|
|
651
|
+
if msvcrt is not None and sys.stdin.isatty():
|
|
652
|
+
try:
|
|
653
|
+
# msvcrt.kbhit() checks if a keyboard hit is present
|
|
654
|
+
# We don't read the input yet, just check if it's there
|
|
655
|
+
_CAN_READ_INPUT = msvcrt.kbhit()
|
|
656
|
+
# If kbhit returns True, it means a key press is waiting.
|
|
657
|
+
# We assume if the terminal *is* a TTY, it *can* read input.
|
|
658
|
+
# We can't actually call input() without blocking, so we check TTY instead.
|
|
659
|
+
if _CAN_READ_INPUT:
|
|
660
|
+
return True
|
|
661
|
+
|
|
662
|
+
# Since we are checking if a *user can* interact, if we are in a TTY,
|
|
663
|
+
# we assume the capability exists, even if nothing is currently buffered.
|
|
664
|
+
# This prevents the false negative when no key is pressed.
|
|
665
|
+
_CAN_READ_INPUT = True
|
|
666
|
+
return True
|
|
667
|
+
|
|
668
|
+
except Exception as e:
|
|
669
|
+
# Catch errors in the kbhit check itself
|
|
670
|
+
logging.debug(f"msvcrt check failed: {e}")
|
|
671
|
+
pass # Fall through to the select check
|
|
672
|
+
|
|
673
|
+
# --- 2. POSIX/General Check (select) ---
|
|
674
|
+
# This block is reliable on Linux/macOS and other POSIX systems.
|
|
595
675
|
try:
|
|
676
|
+
# _CAN_READ_INPUT is assigned the read-ready list ([] or [sys.stdin])
|
|
677
|
+
# The return value is then the boolean conversion of that list's truthiness.
|
|
678
|
+
# 1. select.select(...) returns a 3-element tuple.
|
|
679
|
+
# 2. [0] gets the read-ready list (rlist).
|
|
680
|
+
# 3. Wrapping the result in bool() converts the list's truth value:
|
|
681
|
+
# - [] becomes False
|
|
682
|
+
# - [sys.stdin] becomes True
|
|
596
683
|
_CAN_READ_INPUT = select.select([sys.stdin], [], [], 0.1)[0]
|
|
597
|
-
|
|
684
|
+
# Return the boolean value of the list: True if [sys.stdin], False if []
|
|
685
|
+
return bool(_CAN_READ_INPUT) # <--- Requied to convert list to boolean
|
|
598
686
|
except ValueError:
|
|
599
687
|
logging.debug("Input check failed: ValueError (invalid file descriptor)")
|
|
600
688
|
_CAN_READ_INPUT = False
|
|
@@ -603,6 +691,9 @@ def can_read_input(override_known:bool=False)-> bool:
|
|
|
603
691
|
logging.debug("Input check failed: OSError (likely I/O issue)")
|
|
604
692
|
_CAN_READ_INPUT = False
|
|
605
693
|
return False
|
|
694
|
+
|
|
695
|
+
# Final fallback: if nothing worked, assume False
|
|
696
|
+
return False
|
|
606
697
|
|
|
607
698
|
# --- Browser Check ---
|
|
608
699
|
def web_browser_is_available() -> bool:
|
|
@@ -620,6 +711,7 @@ def web_browser_is_available() -> bool:
|
|
|
620
711
|
if shutil.which("xdg-open"):
|
|
621
712
|
return True
|
|
622
713
|
return False
|
|
714
|
+
|
|
623
715
|
|
|
624
716
|
# --- LAUNCH MECHANISMS BASED ON ENVIRONMENT ---
|
|
625
717
|
def edit_textfile(path: Path | str | None = None) -> None:
|
|
@@ -899,7 +991,7 @@ def main(path=None, debug=False):
|
|
|
899
991
|
# Keep window open. This iteration is non rigorous.
|
|
900
992
|
# To address use pf Python launcher from Windows Store to launch downoaded .pyz, which closed quickly
|
|
901
993
|
try:
|
|
902
|
-
input("Press Return to
|
|
994
|
+
input("Press Return to Continue...")
|
|
903
995
|
except Exception as e:
|
|
904
996
|
logging.debug("input() failed")
|
|
905
997
|
|
pyhabitat/report.py
ADDED
|
File without changes
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyhabitat
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.32
|
|
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
|
|
7
7
|
Keywords: environment,os-detection,gui,build-system
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Operating System :: OS Independent
|
|
10
|
-
Classifier:
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Classifier: Topic :: Utilities
|
|
11
15
|
Requires-Python: >=3.7
|
|
12
16
|
Description-Content-Type: text/markdown
|
|
13
17
|
License-File: LICENSE
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
pyhabitat/__init__.py,sha256=7XNuHIDBXvjn_EORWZZUNsBS3qpvWRUha1NHwC3d6bw,1539
|
|
2
|
+
pyhabitat/cli.py,sha256=L7VA-OOust2g6_MxedvvOr4RdnS_-5ZGP2Aj4VtdqAg,2221
|
|
3
|
+
pyhabitat/demo.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
pyhabitat/environment.py,sha256=zUlZlB9GGbZviEeOkV3yk7GceqUtbfZYXloeRyOK6vU,40221
|
|
5
|
+
pyhabitat/report.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
pyhabitat/utils.py,sha256=2IGLKGAvDFGQgIzlId4ZGGTJRGG0MXR9UVH3nlQKmHg,988
|
|
7
|
+
pyhabitat-1.0.32.dist-info/licenses/LICENSE,sha256=D4fg30ctUGnCJlWu3ONv5-V8JE1v3ctakoJTcVjsJlg,1072
|
|
8
|
+
pyhabitat-build/__main__.py,sha256=6wcF1BhvoRQe4iwq1Px0GNughRXGFRBufWRdaZePu1s,99
|
|
9
|
+
pyhabitat-build/pyhabitat/__init__.py,sha256=7XNuHIDBXvjn_EORWZZUNsBS3qpvWRUha1NHwC3d6bw,1539
|
|
10
|
+
pyhabitat-build/pyhabitat/cli.py,sha256=L7VA-OOust2g6_MxedvvOr4RdnS_-5ZGP2Aj4VtdqAg,2221
|
|
11
|
+
pyhabitat-build/pyhabitat/environment.py,sha256=Us6AXG3T3ocSa8giPvg_zSPVneIQsxa6FjBgcBINmOg,36980
|
|
12
|
+
pyhabitat-build/pyhabitat/utils.py,sha256=2IGLKGAvDFGQgIzlId4ZGGTJRGG0MXR9UVH3nlQKmHg,988
|
|
13
|
+
pyhabitat-1.0.32.dist-info/METADATA,sha256=X9boNl2mpc7_DddSkrsA-jJ3lk9vYFF40SBfBTxcMqA,11086
|
|
14
|
+
pyhabitat-1.0.32.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
+
pyhabitat-1.0.32.dist-info/entry_points.txt,sha256=409xZ-BrarQJJLtO-aActCGkL0FMhNVi9wsq3u7tRHM,52
|
|
16
|
+
pyhabitat-1.0.32.dist-info/top_level.txt,sha256=zI4aHwfZxhq45fnyLM34qDaerg2Iyb4mcsOP-itrJPY,26
|
|
17
|
+
pyhabitat-1.0.32.dist-info/RECORD,,
|
|
@@ -30,6 +30,8 @@ from .environment import (
|
|
|
30
30
|
user_darrin_deyoung,
|
|
31
31
|
can_read_input,
|
|
32
32
|
can_spawn_shell,
|
|
33
|
+
is_ascii,
|
|
34
|
+
is_binary,
|
|
33
35
|
)
|
|
34
36
|
|
|
35
37
|
# Optional: Set __all__ for explicit documentation and cleaner imports
|
|
@@ -63,6 +65,8 @@ __all__ = [
|
|
|
63
65
|
'user_darrin_deyoung',
|
|
64
66
|
'can_read_input',
|
|
65
67
|
'can_spawn_shell',
|
|
68
|
+
'is_ascii',
|
|
69
|
+
'is_binary',
|
|
66
70
|
]
|
|
67
71
|
|
|
68
72
|
__version__ = get_version()
|
pyhabitat-build/pyhabitat/cli.py
CHANGED
|
@@ -512,6 +512,19 @@ def is_python_script(path: Path | str | None = None, debug: bool = False, suppre
|
|
|
512
512
|
return False
|
|
513
513
|
return exec_path.suffix.lower() == '.py'
|
|
514
514
|
|
|
515
|
+
# --- File encoding check ---
|
|
516
|
+
def is_binary(path:str|Path|None=None)->bool:
|
|
517
|
+
"""
|
|
518
|
+
Target file is encoded as binary.
|
|
519
|
+
"""
|
|
520
|
+
pass
|
|
521
|
+
|
|
522
|
+
def is_ascii(path:str|Path|None=None)->bool:
|
|
523
|
+
"""
|
|
524
|
+
Target file is encoded as ascii, plaintext.
|
|
525
|
+
"""
|
|
526
|
+
pass
|
|
527
|
+
|
|
515
528
|
# --- Interpreter Check ---
|
|
516
529
|
|
|
517
530
|
def interp_path(debug: bool = False) -> str:
|
|
@@ -545,14 +558,14 @@ def interactive_terminal_is_available():
|
|
|
545
558
|
|
|
546
559
|
"""
|
|
547
560
|
# Address walmart demo unit edge case, fast check, though this might hamstring othwrwise successful processes
|
|
548
|
-
if
|
|
561
|
+
if user_darrin_deyoung():
|
|
549
562
|
return False
|
|
550
|
-
#
|
|
563
|
+
# Check of a new shell can be launched to print stuff
|
|
551
564
|
if not can_spawn_shell():
|
|
552
565
|
return False
|
|
553
566
|
# A user can interact with a console, providing input
|
|
554
|
-
if not can_read_input():
|
|
555
|
-
|
|
567
|
+
#if not can_read_input():
|
|
568
|
+
# return False
|
|
556
569
|
# Check if a tty is attached to stdin
|
|
557
570
|
return sys.stdin.isatty() and sys.stdout.isatty()
|
|
558
571
|
|
|
@@ -572,12 +585,14 @@ def can_spawn_shell(override_known:bool=False)->bool:
|
|
|
572
585
|
result = subprocess.run( ['echo', 'hello'],
|
|
573
586
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
574
587
|
timeout=2 )
|
|
588
|
+
|
|
575
589
|
_CAN_SPAWN_SHELL = True
|
|
590
|
+
|
|
576
591
|
return result.returncode == 0
|
|
577
592
|
except subprocess.TimeoutExpired:
|
|
578
593
|
logging.debug("Shell spawn failed: TimeoutExpired")
|
|
579
|
-
_CAN_SPAWN_SHELL =
|
|
580
|
-
return
|
|
594
|
+
_CAN_SPAWN_SHELL = result.returncode == 0
|
|
595
|
+
return _CAN_SPAWN_SHELL
|
|
581
596
|
except subprocess.SubprocessError:
|
|
582
597
|
logging.debug("Shell spawn failed: SubprocessError")
|
|
583
598
|
_CAN_SPAWN_SHELL = False
|
|
@@ -593,6 +608,7 @@ def can_read_input(override_known:bool=False)-> bool:
|
|
|
593
608
|
if _CAN_READ_INPUT is not None and override_known is False:
|
|
594
609
|
return _CAN_READ_INPUT
|
|
595
610
|
try:
|
|
611
|
+
# ERROR THIS IS NOT A BOOLEAN, IS RETURNS []
|
|
596
612
|
_CAN_READ_INPUT = select.select([sys.stdin], [], [], 0.1)[0]
|
|
597
613
|
return _CAN_READ_INPUT
|
|
598
614
|
except ValueError:
|
|
@@ -620,6 +636,7 @@ def web_browser_is_available() -> bool:
|
|
|
620
636
|
if shutil.which("xdg-open"):
|
|
621
637
|
return True
|
|
622
638
|
return False
|
|
639
|
+
|
|
623
640
|
|
|
624
641
|
# --- LAUNCH MECHANISMS BASED ON ENVIRONMENT ---
|
|
625
642
|
def edit_textfile(path: Path | str | None = None) -> None:
|
|
@@ -899,7 +916,7 @@ def main(path=None, debug=False):
|
|
|
899
916
|
# Keep window open. This iteration is non rigorous.
|
|
900
917
|
# To address use pf Python launcher from Windows Store to launch downoaded .pyz, which closed quickly
|
|
901
918
|
try:
|
|
902
|
-
input("Press Return to
|
|
919
|
+
input("Press Return to Continue...")
|
|
903
920
|
except Exception as e:
|
|
904
921
|
logging.debug("input() failed")
|
|
905
922
|
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
pyhabitat/__init__.py,sha256=UIlLMIMnJHwV1UHAqNgvC_HURGtCUUgp-34-329FV6E,1477
|
|
2
|
-
pyhabitat/cli.py,sha256=L7VA-OOust2g6_MxedvvOr4RdnS_-5ZGP2Aj4VtdqAg,2221
|
|
3
|
-
pyhabitat/environment.py,sha256=V489_X3uX7GcszEBNo16dG2kxOP9gA86cJwG99r-D20,36616
|
|
4
|
-
pyhabitat/utils.py,sha256=2IGLKGAvDFGQgIzlId4ZGGTJRGG0MXR9UVH3nlQKmHg,988
|
|
5
|
-
pyhabitat-1.0.29.dist-info/licenses/LICENSE,sha256=D4fg30ctUGnCJlWu3ONv5-V8JE1v3ctakoJTcVjsJlg,1072
|
|
6
|
-
pyhabitat-build/__main__.py,sha256=6wcF1BhvoRQe4iwq1Px0GNughRXGFRBufWRdaZePu1s,99
|
|
7
|
-
pyhabitat-build/pyhabitat/__init__.py,sha256=UIlLMIMnJHwV1UHAqNgvC_HURGtCUUgp-34-329FV6E,1477
|
|
8
|
-
pyhabitat-build/pyhabitat/cli.py,sha256=wWGd7dwFhFjWV76WEysJ3AR4yRdrfCBM5vjPiON31bM,2220
|
|
9
|
-
pyhabitat-build/pyhabitat/environment.py,sha256=V489_X3uX7GcszEBNo16dG2kxOP9gA86cJwG99r-D20,36616
|
|
10
|
-
pyhabitat-build/pyhabitat/utils.py,sha256=2IGLKGAvDFGQgIzlId4ZGGTJRGG0MXR9UVH3nlQKmHg,988
|
|
11
|
-
pyhabitat-1.0.29.dist-info/METADATA,sha256=t9bNdd0vKy-sAOU1mnMpUgKbU1HRWBvsp7xy2uloZ7Y,10900
|
|
12
|
-
pyhabitat-1.0.29.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
13
|
-
pyhabitat-1.0.29.dist-info/entry_points.txt,sha256=409xZ-BrarQJJLtO-aActCGkL0FMhNVi9wsq3u7tRHM,52
|
|
14
|
-
pyhabitat-1.0.29.dist-info/top_level.txt,sha256=zI4aHwfZxhq45fnyLM34qDaerg2Iyb4mcsOP-itrJPY,26
|
|
15
|
-
pyhabitat-1.0.29.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|