content: [build-system]
  requires = ["setuptools>=61.0"]
  build-backend = "setuptools.build_meta"
  
  [project]
  name = "attachments"
  version = "0.25.1"
  authors = [{ name = "Maxime Rivest", email = "mrive052@gmail.com" }]
  description = "The Python funnel for LLM context - turn any file into model-ready text + images, in one line."
  readme = "README.md"
  requires-python = ">=3.10"
  license = "MIT"
  classifiers = [
      "Development Status :: 4 - Beta",
      "Intended Audience :: Developers",
      "Intended Audience :: Science/Research",
      "Operating System :: OS Independent",
      "Programming Language :: Python :: 3",
      "Programming Language :: Python :: 3.10",
      "Programming Language :: Python :: 3.11",
      "Programming Language :: Python :: 3.12",
      "Topic :: Scientific/Engineering :: Artificial Intelligence",
      "Topic :: Software Development :: Libraries :: Python Modules",
      "Topic :: Text Processing",
      "Topic :: Multimedia",
  ]
  keywords = [
      "llm",
      "ai",
      "pdf",
      "document",
      "multimodal",
      "openai",
      "claude",
      "context",
      "attachments",
  ]
  
  # Core dependencies for the modular architecture
  dependencies = [
      # Core file processing
      "requests>=2.25.0", # HTTP library for URL processing and web content
      "beautifulsoup4>=4.9.0", # HTML parsing for web content and HTML files
      "pillow>=11.2.1",
      "pydantic>=2.11.5",
      "pdfplumber>=0.11.6",
      "pillow-heif>=0.22.0", # For IPYNB notebook processing
      "nbformat>=5.10.4",
      "copykitten>=1.2.2",
      "typer>=0.12",
      "pyperclip>=1.8",
      "pytesseract>=0.3.13",
      "pypdfium2>=4.30.0",
  ]
  
  [project.urls]
  "Homepage" = "https://maximerivest.github.io/attachments/"
  "Documentation" = "https://maximerivest.github.io/attachments/"
  "Repository" = "https://github.com/maximerivest/attachments"
  "Bug Tracker" = "https://github.com/maximerivest/attachments/issues"
  "Changelog" = "https://maximerivest.github.io/attachments/changelog.html"
  
  [project.scripts]
  attachments = "attachments.cli:app"
  att = "attachments.cli:app"
  
  
  [project.optional-dependencies]
  # Development dependencies
  dev = [
      "pytest>=8.0.0",
      "pytest-randomly>=3.15.0",
      "pytest-cov>=4.0.0",
      "black>=24.0.0",
      "ruff>=0.5.6",
      "mypy>=1.8.0",
      "pre-commit>=3.6.0",
      "mystmd>=1.2.0",
      "jupyter>=1.0.0",
      "jupytext>=1.16.0",
      "sphinx>=7.0.0",
      "sphinx-autodoc2>=0.5.0",
      "ipykernel>=6.29.5",       # For Jupyter notebook execution
      "dspy-ai>=2.6.24",         # For testing dspy integration
      "python-pptx>=1.0.2",      # For testing PowerPoint processing
  ]
  
  
  # Common file formats (most users will want these)
  common = [
      "pandas>=2.0.0",      # Data analysis and CSV processing
      "Pillow>=10.0.0",     # Image processing and conversion
      "pdfplumber>=0.10.0", # PDF text and table extraction
      "python-pptx>=1.0.2", # PowerPoint (.pptx) processing
      "python-docx>=1.1.0", # Word (.docx) processing
      "openpyxl>=3.1.0",    # Excel (.xlsx) processing
      "pypdfium2>=4.0.0",   # PDF rendering for images (DOCX, PDF visual conversion)
  ]
  
  # Microsoft Office formats
  office = [
      "python-pptx>=0.6.0", # PowerPoint (.pptx) processing
      "python-docx>=1.1.0", # Word (.docx) processing
      "openpyxl>=3.1.0",    # Excel (.xlsx) processing
  ]
  
  # 3D model rendering and processing
  3d = [
      "bpy>=4.4.0; python_version >= '3.11' and python_version < '3.12'", # Blender Python API (requires Python 3.11)
      "trimesh>=4.3.0",                                                   # Lightweight 3D mesh processing (fallback for Python 3.12)
      "pyrender>=0.1.45",                                                 # OpenGL-based rendering (fallback for Python 3.12)
      "numpy>=1.24.0",                                                    # Required for 3D math operations
  ]
  
  # PDF processing (MIT-compatible)
  pdf = [
      "pdfplumber>=0.7.0", # Primary PDF library
      "pypdf>=5.0.0",      # Pure Python PDF library (BSD license)
      "pypdfium2>=4.26.0", # Google's PDFium Python binding (BSD/Apache)
  ]
  
  # Extended file format support
  extended = [
      "pillow-heif>=0.22.0", # HEIF image support
      "pytesseract>=0.3.10", # OCR support
      "copykitten>=1.0.0",   # Cross-platform clipboard support
  ]
  
  # Browser automation for web content
  browser = ["playwright>=1.43.0"]
  
  # All dependencies (comprehensive installation)
  most = [
      # Include all common dependencies
      "dspy-ai>=2.6.24",
      "pandas>=1.3.0",
      "Pillow>=8.0.0",
      "pdfplumber>=0.7.0",
      "python-pptx>=0.6.21",
      "python-docx>=0.8.11",
      "openpyxl>=3.0.9",
      # Extended format support
      "pillow-heif>=0.22.0",
      "pytesseract>=0.3.10",
      "copykitten>=1.0.0",   # Cross-platform clipboard support
      # Additional PDF support
      "pypdf>=5.0.0",
      "pypdfium2>=4.26.0",
      # Browser automation
      "playwright>=1.43.0",
      # 3D model rendering
      "trimesh>=4.3.0",
      "pyrender>=0.1.45",
  ]
  
  # Test dependencies for CI
  test = [
      "pytest>=8.0.0",
      "pytest-randomly>=3.15.0",
      "pytest-cov>=4.0.0",
      "tox>=4.0.0",
      "coverage[toml]>=7.4.0",
  ]
  
  [tool.setuptools]
  zip-safe = false
  
  [tool.setuptools.packages.find]
  where = ["src"]
  namespaces = false
  
  [tool.setuptools.package-data]
  attachments = ["py.typed"]
  
  # Black formatting configuration
  [tool.black]
  line-length = 100
  target-version = ['py310', 'py311', 'py312']
  include = '\.pyi?$'
  extend-exclude = '''
  /(
    \.eggs
    | \.git
    | \.hg
    | \.mypy_cache
    | \.tox
    | \.venv
    | _build
    | buck-out
    | build
    | dist
  )/
  '''
  
  # MyPy type checking configuration
  [tool.mypy]
  python_version = "3.10"
  warn_return_any = true
  warn_unused_configs = true
  disallow_untyped_defs = true
  disallow_incomplete_defs = true
  check_untyped_defs = true
  disallow_untyped_decorators = true
  no_implicit_optional = true
  warn_redundant_casts = true
  warn_unused_ignores = true
  warn_no_return = true
  warn_unreachable = true
  strict_equality = true
  
  [[tool.mypy.overrides]]
  module = ["PIL.*", "pandas.*", "numpy.*", "docx.*", "pptx.*", "odf.*"]
  ignore_missing_imports = true
  
  # Pytest configuration
  [tool.pytest.ini_options]
  minversion = "6.0"
  pythonpath = ["src"]
  testpaths = ["tests"]
  norecursedirs = ["mrplay", ".venv", "dist", "build", "*.egg-info", "_build"]
  addopts = [
      "--strict-markers",
      "--strict-config",
      "--cov=src/attachments",
      "--cov-branch",
      "--cov-report=term-missing",
      "--cov-report=html:htmlcov",
      "--cov-report=xml",
      "--cov-fail-under=70",       # Lowered from 90 for now, will increase as we add tests
      "--ignore=mrplay",           # Explicitly ignore mrplay directory
      "-v",                        # Verbose output by default
      "--disable-warnings",        # Disable all warnings
  ]
  markers = [
      "slow: marks tests as slow (deselect with '-m \"not slow\"')",
      "integration: marks tests as integration tests",
      "unit: marks tests as unit tests",
      "contract: marks tests as contract tests (slower, more comprehensive)",
  ]
  filterwarnings = ["ignore::DeprecationWarning", "ignore::UserWarning"]
  
  # Coverage configuration
  [tool.coverage.run]
  source = ["src"]
  omit = ["*/tests/*", "*/test_*", "*/__main__.py", "*/setup.py", "*/conftest.py"]
  
  [tool.coverage.report]
  exclude_lines = [
      "pragma: no cover",
      "def __repr__",
      "if self.debug:",
      "if settings.DEBUG",
      "raise AssertionError",
      "raise NotImplementedError",
      "if 0:",
      "if __name__ == .__main__.:",
      "class .*\\bProtocol\\):",
      "@(abc\\.)?abstractmethod",
  ]
  
  [dependency-groups]
  dev = ["mystmd>=1.3.6", "pytest>=8.3.5"]
  
  # Ruff linter configuration
  [tool.ruff]
  line-length = 100
  target-version = "py310"
  
  [tool.ruff.lint]
  select = [
      "E",   # pycodestyle errors
      "F",   # pyflakes
      "B",   # flake8-bugbear
      "UP",  # pyupgrade
      "I",   # isort (import sorting)
  ]
  ignore = [
      "F811",  # Redefinition of unused variable (needed for multiple dispatch)
      "F821",  # Undefined name (for type hints in quotes)
      "E402",  # Module level import not at top (needed for conditional imports in tests)
      "E501",  # Line too long (handled by Black)
      "UP038", # Use X | Y in isinstance (backwards compatibility)
  ]
  exclude = [
      ".venv", "_build", "build", "dist",
      "docs/scripts/how_splitting_works.py",  # Has markdown blocks in Python - needs restructuring
  ]
  
  [tool.ruff.lint.per-file-ignores]
  # Notebook-style documentation scripts often have expressions for display
  "docs/scripts/*.py" = ["B018", "B007", "B904"]
  "docs/extending_attachments/*.py" = ["B018"]
  # Script utilities
  "scripts/*.py" = ["F841", "E722"]
  # Adapt module uses import checks  
  "src/attachments/adapt.py" = ["F401"]
  # __init__ files use imports for side effects
  "**/__init__.py" = ["F401", "F403", "F405"]
  