CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-scooby

A Python environment detective tool that reports package versions and hardware resources.

Pending
Overview
Eval results
Files

utilities.mddocs/

Utilities

Utility functions for package version detection, version comparison, and environment detection. These functions provide the building blocks used by the reporting system.

Capabilities

Constants

MODULE_NOT_FOUND = 'Module not found'
MODULE_TROUBLE = 'Trouble importing'
VERSION_NOT_FOUND = 'Version unknown'

Version Detection

Get version information for any installed package using multiple detection strategies.

def get_version(module: str | ModuleType) -> tuple[str, str | None]:
    """
    Get the version of a module by passing the package or its name.

    This function tries multiple strategies to detect version information:
    1. importlib.metadata (preferred)
    2. Common version attributes (__version__, version)
    3. Known package-specific version locations
    4. Package-specific version methods

    Parameters:
    - module (str | ModuleType): Name of module to import or the module itself

    Returns:
    - tuple[str, str | None]: (package_name, version_string)
        - version_string can be None if version cannot be determined
        - Returns MODULE_NOT_FOUND if module cannot be imported
        - Returns MODULE_TROUBLE if module import fails with error
        - Returns VERSION_NOT_FOUND if module loads but version cannot be found
    """

Version Comparison

Compare version strings to check if a package meets minimum version requirements.

def meets_version(version: str, meets: str) -> bool:
    """
    Check if a version string meets a minimum version requirement.

    This is a simplified version comparison tool. For robust version
    comparison, consider using the 'packaging' library.

    Parameters:
    - version (str): Version string to check (e.g., '1.2.3')
    - meets (str): Required minimum version (e.g., '1.2.0')

    Returns:
    - bool: True if version >= meets, False otherwise

    Raises:
    - ValueError: If version strings have more than 3 parts
    - AssertionError: If versions are not comparable

    Examples:
    >>> meets_version('1.2.3', '1.2.0')
    True
    >>> meets_version('1.1.9', '1.2.0')
    False
    """

def version_tuple(v: str) -> tuple[int, ...]:
    """
    Convert a version string to a tuple of integers.

    Non-numeric version components are converted to 0.
    Version strings shorter than 3 parts are padded with 0.

    Parameters:
    - v (str): Version string (e.g., '1.2.3dev0')

    Returns:
    - tuple[int, ...]: Tuple of integers (e.g., (1, 2, 3))

    Raises:
    - ValueError: If version string has more than 3 parts

    Examples:
    >>> version_tuple('1.2.3')
    (1, 2, 3)
    >>> version_tuple('1.2.3dev0')
    (1, 2, 0)
    >>> version_tuple('1.2')
    (1, 2, 0)
    """

Environment Detection

Detect the Python execution environment to enable environment-specific formatting.

def in_ipython() -> bool:
    """
    Check if running in an IPython environment.

    Returns:
    - bool: True if in IPython, False otherwise
    """

def in_ipykernel() -> bool:
    """
    Check if running in an ipykernel (most likely Jupyter) environment.

    Note: This detects if using an ipykernel but cannot distinguish between
    Jupyter Notebook, JupyterLab, QtConsole, or other frontends.

    Returns:
    - bool: True if using an ipykernel, False otherwise
    """

Standard Library Detection

Get information about Python's standard library modules for filtering purposes.

def get_standard_lib_modules() -> set[str]:
    """
    Return a set of names of all modules in the standard library.

    This is used internally to filter out standard library modules from
    package reports and import tracking.

    Returns:
    - set[str]: Set of standard library module names
    """

Distribution Dependencies

Get dependency information for installed packages using distribution metadata.

def get_distribution_dependencies(dist_name: str) -> list[str]:
    """
    Get the dependencies of a specified package distribution.
    
    Uses importlib.metadata to read distribution metadata and extract
    required dependencies. This is used internally by AutoReport to
    automatically include package dependencies in reports.

    Parameters:
    - dist_name (str): Name of the package distribution

    Returns:
    - list[str]: List of dependency package names

    Raises:
    - PackageNotFoundError: If the distribution is not found
    """

Usage Examples

Version Detection

import scooby
import numpy

# Get version by module name
name, version = scooby.get_version('numpy')
print(f"{name}: {version}")  # numpy: 1.21.0

# Get version by module object
name, version = scooby.get_version(numpy)
print(f"{name}: {version}")  # numpy: 1.21.0

# Handle missing packages
name, version = scooby.get_version('nonexistent_package')
print(f"{name}: {version}")  # nonexistent_package: Module not found

# Handle packages without version info
name, version = scooby.get_version('some_local_module')
print(f"{name}: {version}")  # some_local_module: Version unknown

# Check against constants
import scooby
from scooby.report import MODULE_NOT_FOUND

name, version = scooby.get_version('missing_pkg')
if version == MODULE_NOT_FOUND:
    print(f"Package {name} is not installed")

Version Comparison

import scooby

# Check if installed version meets requirements
name, version = scooby.get_version('numpy')
if version and scooby.meets_version(version, '1.19.0'):
    print("NumPy version is sufficient")
else:
    print("NumPy version is too old or not installed")

# Version comparison examples
print(scooby.meets_version('1.2.3', '1.2.0'))  # True
print(scooby.meets_version('1.1.9', '1.2.0'))  # False
print(scooby.meets_version('2.0.0', '1.9.9'))  # True

# Convert version strings to tuples for custom comparison
v1 = scooby.version_tuple('1.2.3dev0')  # (1, 2, 0)
v2 = scooby.version_tuple('1.2.3')      # (1, 2, 3)
print(v1 < v2)  # True

Environment Detection

import scooby

# Detect execution environment
if scooby.in_ipykernel():
    print("Running in Jupyter (or similar ipykernel environment)")
    # Use HTML output
    report = scooby.Report()
    display(report)  # Will use _repr_html_()
elif scooby.in_ipython():
    print("Running in IPython")
    # Use enhanced IPython features
    report = scooby.Report()
    print(report)
else:
    print("Running in standard Python")
    # Use plain text output
    report = scooby.Report()
    print(report)

Standard Library Filtering

import scooby

# Get all standard library modules
stdlib_modules = scooby.get_standard_lib_modules()
print(f"Standard library contains {len(stdlib_modules)} modules")

# Check if a module is in standard library
def is_third_party(module_name):
    return module_name not in stdlib_modules

print(is_third_party('os'))      # False (standard library)
print(is_third_party('numpy'))   # True (third party)
print(is_third_party('json'))    # False (standard library)

Distribution Dependencies

from scooby.report import get_distribution_dependencies
from importlib.metadata import PackageNotFoundError

# Get dependencies for a package
try:
    deps = get_distribution_dependencies('matplotlib')
    print(f"matplotlib dependencies: {deps}")
    # Example output: ['numpy', 'python-dateutil', 'pyparsing', ...]
except PackageNotFoundError:
    print("Package not found")

# Use in combination with version checking
def analyze_package_ecosystem(package_name):
    """Analyze a package and its entire dependency tree."""
    try:
        # Get the main package version
        name, version = scooby.get_version(package_name)
        print(f"Main package: {name} {version}")
        
        # Get its dependencies
        deps = get_distribution_dependencies(package_name)
        print(f"Dependencies ({len(deps)}): {', '.join(deps)}")
        
        # Check versions of all dependencies
        for dep in deps:
            dep_name, dep_version = scooby.get_version(dep)
            print(f"  {dep_name}: {dep_version}")
    
    except PackageNotFoundError:
        print(f"Package {package_name} not found")

# Analyze an entire ecosystem
analyze_package_ecosystem('matplotlib')

Comprehensive Package Analysis

import scooby

def analyze_package(package_name):
    """Comprehensive analysis of a package."""
    name, version = scooby.get_version(package_name)
    
    print(f"Package: {name}")
    print(f"Version: {version}")
    
    if version and version not in ['Module not found', 'Trouble importing', 'Version unknown']:
        # Check version requirements
        if scooby.meets_version(version, '1.0.0'):
            print("✓ Meets minimum version 1.0.0")
        else:
            print("✗ Below minimum version 1.0.0")
        
        # Show version tuple
        v_tuple = scooby.version_tuple(version)
        print(f"Version tuple: {v_tuple}")
    
    # Check if it's third-party
    stdlib_modules = scooby.get_standard_lib_modules()
    if name in stdlib_modules:
        print("📦 Standard library module")
    else:
        print("🔧 Third-party package")

# Analyze various packages
for pkg in ['numpy', 'os', 'requests', 'nonexistent']:
    analyze_package(pkg)
    print()

Custom Version Checking

import scooby

def check_requirements(requirements):
    """
    Check if installed packages meet version requirements.
    
    Args:
        requirements (dict): {package_name: min_version}
    
    Returns:
        dict: {package_name: (installed_version, meets_requirement)}
    """
    import scooby
    from scooby.report import MODULE_NOT_FOUND, MODULE_TROUBLE, VERSION_NOT_FOUND
    
    results = {}
    
    for package, min_version in requirements.items():
        name, installed = scooby.get_version(package)
        
        if installed in [MODULE_NOT_FOUND, MODULE_TROUBLE, VERSION_NOT_FOUND]:
            meets_req = False
        else:
            meets_req = scooby.meets_version(installed, min_version)
        
        results[name] = (installed, meets_req)
    
    return results

# Check project requirements
requirements = {
    'numpy': '1.19.0',
    'pandas': '1.3.0',
    'matplotlib': '3.3.0'
}

results = check_requirements(requirements)
for package, (version, meets) in results.items():
    status = "✓" if meets else "✗"
    print(f"{status} {package}: {version}")

Install with Tessl CLI

npx tessl i tessl/pypi-scooby

docs

environment-reporting.md

import-tracking.md

index.md

utilities.md

tile.json