返回 Skill 列表
extension
分类: 开发与工程无需 API Key

dependency-deprecation

用于在保持向后兼容性的同时弃用外部依赖项的模式。触发条件:移除Java/FIJI/MATLAB,弃用可选依赖项

person作者: jakexiaohubgithub

Dependency Deprecation Pattern

Experiment Overview

| Item | Details | |------|---------| | Date | 2025-12-11 | | Goal | Remove Java/Maven/FIJI/CLIJ2 dependencies from KINTSUGI while maintaining backward compatibility | | Environment | Python 3.10+, cross-platform (Windows/Linux/macOS) | | Status | Success |

Context

KINTSUGI originally depended on Java/Maven for PyImageJ and CLIJ2 GPU processing. This created installation friction and cross-platform issues. The goal was to replace these with pure Python implementations (CuPy/NumPy) while allowing legacy users to continue using Java if needed.

Verified Workflow

Step 1: Identify all dependency touchpoints

Search for all references to the dependency:

# Search code
grep -r "java\|Java\|FIJI\|fiji\|clij\|CLIJ\|maven\|Maven\|ImageJ\|imagej" src/ notebooks/

# Check configuration files
grep -r "java\|openjdk\|maven" envs/ pyproject.toml

Files typically affected:

  • pyproject.toml - optional dependencies
  • envs/*.yml - conda environment files
  • src/*/deps.py - dependency checker
  • docs/*.md - documentation
  • Core modules using the dependency

Step 2: Update the core module with deprecation

# Example: edf.py - deprecating CLIJ2 backend

import warnings
from typing import Literal

BackendType = Literal["auto", "cupy", "numpy", "clij2"]

def _detect_backend(self, requested: BackendType) -> str:
    """Detect best available backend."""
    if requested == "clij2":
        warnings.warn(
            "CLIJ2 backend is deprecated and will be removed in v2.0. "
            "Use 'cupy' or 'numpy' instead.",
            DeprecationWarning,
            stacklevel=2
        )
        # Still allow it to work for now
        if self._check_clij2_available():
            return "clij2"
        else:
            warnings.warn("CLIJ2 not available, falling back to cupy")
            requested = "auto"

    if requested == "auto":
        # NEW priority order: CuPy > NumPy (CLIJ2 excluded from auto)
        if self._check_cupy_available():
            return "cupy"
        return "numpy"

    return requested

Step 3: Update dependency checker

# deps.py - mark as deprecated but keep functional

def _check_java(self, verbose: bool):
    """Check Java installation.

    .. deprecated::
        Java/Maven dependencies are no longer required for core functionality.
        Kept for backward compatibility with legacy CLIJ2 workflows.
    """
    if verbose:
        print("\n[Java/Maven] (DEPRECATED - no longer required)")

    # Still check and report, but don't fail
    try:
        # ... existing check code ...
        if verbose:
            print(f"  [OK]       java v{version} (optional)")
    except Exception as e:
        if verbose:
            print(f"  [SKIP]     java (optional, not required)")

Step 4: Update pyproject.toml

[project.optional-dependencies]
# Keep the optional group but exclude from [full]
java = [
    "JPype1>=1.5.0",
    "scyjava>=1.0.0",
    "pyimagej>=1.4.0",
]

# Remove java from full install
full = [
    "kintsugi[gpu,viz,dl,analysis,bio]",  # Note: java excluded
]

Step 5: Update environment files

# envs/env-*.yml - comment out with deprecation note

# Java/ImageJ Integration (DEPRECATED - no longer required)
# Uncomment if you need legacy CLIJ2 support:
# - openjdk=11
# - maven
# - jpype1

Step 6: Update documentation

Add deprecation notices to all relevant docs:

> **Note:** Java, Maven, and FIJI are no longer required. KINTSUGI now uses
> pure Python implementations (CuPy/NumPy) for all processing including EDF.

For historical documents, add a header:

> **DEPRECATION NOTICE (2025):** This document is historical. Java/Maven/FIJI
> dependencies have been removed. See `src/kintsugi/edf.py` for current implementation.

Failed Attempts (Critical)

| Attempt | Why it Failed | Lesson Learned | |---------|---------------|----------------| | Removing code completely | Broke existing user workflows | Keep deprecated code functional | | Silent removal | Users confused when code stopped working | Always emit deprecation warnings | | Keeping in [full] install | Users still got Java install failures | Exclude from aggregate installs | | No migration path | Users didn't know what to use instead | Document the replacement clearly |

Key Insights

  • Gradual deprecation: Mark as deprecated first, remove in next major version
  • Keep it working: Deprecated doesn't mean broken - users need time to migrate
  • Clear warnings: Use Python's warnings.warn() with DeprecationWarning
  • Document the alternative: Every deprecation notice should say what to use instead
  • Update ALL touchpoints: Code, configs, docs, environment files, README
  • Test both paths: Verify deprecated code still works AND new code works

Checklist for Dependency Deprecation

  • [ ] Search entire codebase for dependency references
  • [ ] Add deprecation warnings to code using the dependency
  • [ ] Update auto-detection to prefer new implementation
  • [ ] Keep optional dependency group but exclude from [full]
  • [ ] Comment out in environment files with explanation
  • [ ] Update installation documentation
  • [ ] Add deprecation notices to historical docs
  • [ ] Update CLAUDE.md / project documentation
  • [ ] Test deprecated path still works
  • [ ] Test new path works
  • [ ] Update changelog/release notes

References

  • Python deprecation warnings: https://docs.python.org/3/library/warnings.html
  • Semantic versioning for breaking changes: https://semver.org/
  • PEP 387 - Backwards Compatibility Policy: https://peps.python.org/pep-0387/