CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pip-upgrader

An interactive pip requirements upgrader that also updates the version in your requirements.txt file

Pending
Overview
Eval results
Files

interactive-selection.mddocs/

Interactive Selection

User interface for selecting packages to upgrade, presenting upgrade information in formatted tables with interactive prompts and pre-selection options.

Capabilities

Interactive Package Selection

Presents available package upgrades in a formatted table and handles user selection through an interactive command-line interface.

class PackageInteractiveSelector:
    def __init__(self, packages_map, options):
        """
        Initialize interactive package selector.
        
        Args:
            packages_map (dict): Package status map from PackagesStatusDetector
            options (dict): Command-line options including -p for pre-selection
            
        Raises:
            KeyboardInterrupt: If no packages need upgrading
        """
    
    def get_packages(self):
        """
        Return the list of packages selected for upgrade.
        
        Returns:
            list: List of package status dictionaries for selected packages
        """
    
    def ask_for_packages(self):
        """
        Display interactive upgrade table and prompt for user selection.
        
        Displays:
        - Formatted table with package names, versions, and upload dates
        - Color-coded output for better readability
        - Interactive prompt for package selection
        
        Raises:
            KeyboardInterrupt: On invalid selection or user cancellation
        """

Package Selection Processing

Processes user selection input and validates package choices.

def _select_packages(self, indexes):
    """
    Select packages by index numbers from the upgrade table.
    
    Args:
        indexes (list): List of integer indexes corresponding to table rows
        
    Returns:
        list: List of booleans indicating successful selections
        
    Side effects:
        Populates self.selected_packages with selected package dictionaries
    """

Cross-Platform Input Handling

Provides compatible input handling across Python 2 and 3.

def user_input(prompt=None):
    """
    Cross-Python compatible input function.
    
    Args:
        prompt (str, optional): Prompt string to display
        
    Returns:
        str: User input string
        
    Compatibility:
        Uses raw_input for Python 2, input for Python 3
    """

Selection Modes

Interactive Mode (Default)

When no -p option is provided, displays an interactive table for package selection.

Table Format:

Available upgrades:
┌─────┬─────────────────┬─────────────────┬────────────────┬─────────────────┐
│ No. │ Package         │ Current version │ Latest version │ Release date    │
├─────┼─────────────────┼─────────────────┼────────────────┼─────────────────┤
│  1  │ django          │ 3.2.0           │ 4.1.0          │ 2022-08-03      │
│  2  │ requests        │ 2.25.1          │ 2.28.1         │ 2022-06-29      │
│  3  │ flask           │ 2.0.0           │ 2.2.2          │ 2022-08-08      │
└─────┴─────────────────┴─────────────────┴────────────────┴─────────────────┘

Please choose which packages should be upgraded. Choices: "all", "q" (quit), "x" (exit) or "1 2 3"
Choice:

Selection Options:

  • all - Select all available upgrades
  • q or x - Quit/exit without upgrading
  • 1 2 3 - Space-separated list of package numbers
  • Empty input - Cancel operation

Pre-Selection Mode

When -p option is provided, skips interactive prompts.

All Packages:

pip-upgrade requirements.txt -p all

Specific Packages:

pip-upgrade requirements.txt -p django -p flask

Matches package names case-insensitively.

Usage Examples

Interactive Selection

from pip_upgrader.packages_interactive_selector import PackageInteractiveSelector

# Package status map from status detector
packages_map = {
    'django': {
        'name': 'django',
        'current_version': Version('3.2.0'),
        'latest_version': Version('4.1.0'), 
        'upgrade_available': True,
        'upload_time': '2022-08-03 08:15:30'
    },
    'requests': {
        'name': 'requests',
        'current_version': Version('2.25.1'),
        'latest_version': Version('2.28.1'),
        'upgrade_available': True, 
        'upload_time': '2022-06-29 14:22:18'
    }
}

# Interactive selection (no -p option)
options = {'-p': []}
selector = PackageInteractiveSelector(packages_map, options)
selected = selector.get_packages()

# User sees table and chooses "1 2"
print(len(selected))  # 2 packages selected

Pre-Selection All

# Select all packages automatically
options = {'-p': ['all']}
selector = PackageInteractiveSelector(packages_map, options)
selected = selector.get_packages()

print(len(selected))  # All upgradeable packages selected

Pre-Selection Specific

# Pre-select specific packages
options = {'-p': ['django', 'flask']}
selector = PackageInteractiveSelector(packages_map, options)
selected = selector.get_packages()

# Only django and flask will be selected (if available for upgrade)

Color-Coded Output

The interface uses colorclass for enhanced terminal output:

Table Headers

  • Blue: Column headers (No., Package, Current version, etc.)

Package Information

  • Green: Package names and row numbers
  • Default: Version numbers and dates

User Prompts

  • Green: "Available upgrades:" header
  • Red: Error messages ("No choice selected", "Invalid choice")

Status Messages

  • Green: "All packages are up-to-date" when no upgrades available

Input Validation

Valid Inputs

"all"           # Select all packages
"1"             # Select package #1
"1 2 3"         # Select packages #1, #2, #3  
"q"             # Quit
"x"             # Exit

Invalid Inputs

""              # Empty input -> "No choice selected"
"   "           # Whitespace only -> "No choice selected"  
"5 6 7"         # Non-existent indexes -> "No valid choice selected"
"abc"           # Non-numeric -> "Invalid choice"

All invalid inputs raise KeyboardInterrupt with appropriate error messages.

Edge Cases

No Upgrades Available

When all packages are up-to-date:

# Prints colored message and raises KeyboardInterrupt
print(Color('{autogreen}All packages are up-to-date.{/autogreen}'))
raise KeyboardInterrupt()

Package Filtering

Only packages with upgrade_available: True are included in the interactive table. Up-to-date packages are filtered out automatically.

Case-Insensitive Matching

Pre-selected package names are matched case-insensitively:

# These are equivalent:
-p Django
-p django  
-p DJANGO

Index Mapping

Interactive selection uses 1-based indexing for user-friendliness, but internally maps to 0-based dictionary keys.

Error Handling

Selection Errors

  • Empty selection: Displays "No choice selected" and cancels
  • Invalid numbers: Displays "Invalid choice" and cancels
  • Out-of-range numbers: Displays "No valid choice selected" and cancels
  • No matching pre-selected packages: Results in empty selection (not an error)

User Cancellation

  • Keyboard interrupts: Ctrl+C during input gracefully exits
  • Quit commands: 'q' and 'x' commands raise KeyboardInterrupt for clean exit
  • Empty selections: Treated as cancellation

Package Mapping Errors

  • Missing packages: Pre-selected packages not found in packages_map are silently skipped
  • Invalid package data: Malformed package dictionaries may cause processing errors in later stages

Integration Points

Input from PackagesStatusDetector

Requires package status map with specific structure:

{
    'package_name': {
        'name': str,
        'current_version': Version,
        'latest_version': Version, 
        'upgrade_available': bool,
        'upload_time': str
    }
}

Output to PackagesUpgrader

Produces list of package dictionaries for upgrade processing:

[
    {
        'name': 'django',
        'current_version': Version('3.2.0'),
        'latest_version': Version('4.1.0'),
        'upgrade_available': True,
        'upload_time': '2022-08-03 08:15:30'
    }
]

Install with Tessl CLI

npx tessl i tessl/pypi-pip-upgrader

docs

cli-interface.md

environment-validation.md

index.md

interactive-selection.md

package-parsing.md

package-upgrading.md

requirements-detection.md

status-detection.md

tile.json