Source code for pyphyschemtools

# tools4pyPhysChem/__init__.py
"""
The pyphyschemtools library provides a comprehensive suite of utilities for Physical Chemistry, ranging from spectroscopic unit management to kinetic modeling and cheminformatics.
"""

__version__ = "0.9.7"
__last_update__ = "2026-04-22"

import importlib
import importlib.util
from pathlib import Path
from importlib import resources

# 1. FAST IMPORTS
from .visualID_Eng import fg, hl, bg, color, init, apply_css_style, chrono_start, chrono_stop, chrono_show, end
from .core import centerTitle, centertxt, crop_images, save_fig, save_data, get_qc_examples

# Explicitly define what is already imported so that __getattr__ does not interfere.
_EXPLICIT_EXPORTS = {
    "fg", "hl", "bg", "color", "init", "apply_css_style", 
    "chrono_start", "chrono_stop", "end", "centerTitle", 
    "centertxt", "crop_images", "save_fig", "save_data", "get_qc_examples"
}

# 2. AUTOMATIC LAZY LOADING
def __getattr__(name):
    # Si l'attribut est dans les imports explicites, on ne devrait pas être ici,
    # mais au cas où, on le gère.
    if name in _EXPLICIT_EXPORTS:
        # On le récupère dans le namespace local
        return globals()[name]

    modules_to_search = [
        ".ML", ".PeriodicTable", ".Chem3D",  
        ".aithermo", ".cheminformatics", ".kinetics", 
        ".misc", ".nano", ".orgachem",
        ".spectro", ".survey", 
        ".sympyUtilities", ".tools4AS", ".units"
    ]

    import_errors = []
    
    for mod_name in modules_to_search:
        try:
            # On tente l'import relatif
            module = importlib.import_module(mod_name, __package__)
            if hasattr(module, name):
                return getattr(module, name)
        except (ImportError, AttributeError) as e:
            # Track errors to help the user diagnose missing dependencies
            import_errors.append(f"  - In {mod_name}: {e}")
            continue

    # Final error message if the attribute is not found
    error_msg = f"module {__name__} has no attribute '{name}'."
    if import_errors:
        error_msg += "\nPossible causes (errors encountered during scan):"
        for err in import_errors:
            error_msg += f"\n{err}"

    raise AttributeError(error_msg)

[docs] def get_ppct_data(file: str, main_folder: str="data_examples") -> Path: """ Retrieves the absolute path to a pyphyschemtools resource. Compatible with Python 3.11+ using importlib.resources. Works across all platforms (Windows, Linux, MacOS) and Google Colab. Args: file (str): The path and name of the file (e.g., "Molecules/betaCD-closed.xyz"). main_folder (str): The resource subfolder inside the package (defaults to "data_examples"). Returns: Path: A pathlib.Path object pointing to the absolute location of the file. """ # Access the data_examples directory inside the installed pyphyschemtools package # .files() returns a Traversable object (behaving much like a Path object) data_dir = resources.files("pyphyschemtools") / main_folder # Construct the full internal path file_path = data_dir.joinpath(file) # Verify if the file actually exists if not file_path.exists(): raise FileNotFoundError( f"❌ Resource not found: {file}\n" f"Expected internal location: pyphyschemtools/{main_folder}/{file}" ) # Convert to a standard pathlib.Path object for the user return Path(str(file_path))