content: [build-system]
  requires = ["hatchling"]
  build-backend = "hatchling.build"
  
  [project]
  name = "fickling"
  dynamic = ["version"]
  description = "A static analyzer and interpreter for Python pickle data"
  readme = "README.md"
  license = { file = "LICENSE" }
  authors = [{ name = "Trail of Bits", email = "opensource@trailofbits.com" }]
  maintainers = [{ name = "Trail of Bits", email = "opensource@trailofbits.com" }]
  classifiers = [
    "Development Status :: 4 - Beta",
    "Environment :: Console",
    "Intended Audience :: Science/Research",
    "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Topic :: Security",
    "Topic :: Software Development :: Testing",
    "Topic :: Utilities",
  ]
  dependencies = ["stdlib_list ~= 0.11.1"]
  requires-python = ">=3.9"
  
  [project.optional-dependencies]
  torch = ["torch >= 2.1.0", "torchvision >= 0.16.1", "numpy >= 1.24.0"]
  lint = [
    "ruff >= 0.8.0",
    "mypy >= 1.10.0",
    # for the Buffer ABC before Python 3.12
    "typing-extensions; python_version < '3.12'",
  ]
  test = [
    "pytest >= 8.0.0",
    "pytest-cov >= 5.0.0",
    "coverage[toml] >= 7.0.0",
    "numpy",
    "torch >= 2.1.0",
    "torchvision >= 0.16.1",
  ]
  dev = [
    "fickling[lint,test,torch]",
    "pre-commit >= 3.5.0",
  ]
  examples = ["numpy", "pytorchfi"]
  
  [project.scripts]
  "fickling" = "fickling.__main__:main"
  
  [project.urls]
  Homepage = "https://pypi.org/project/fickling"
  Issues = "https://github.com/trailofbits/fickling/issues"
  Source = "https://github.com/trailofbits/fickling"
  
  # Black configuration removed - using ruff format instead
  
  [tool.coverage.run]
  # don't attempt code coverage for the CLI entrypoints
  omit = ["fickling/__main__.py", "fickling/cli.py"]
  
  [tool.mypy]
  allow_redefinition = true
  check_untyped_defs = true
  disallow_incomplete_defs = true
  disallow_untyped_defs = true
  ignore_missing_imports = true
  no_implicit_optional = true
  show_error_codes = true
  sqlite_cache = true
  strict_equality = true
  warn_no_return = true
  warn_redundant_casts = true
  warn_return_any = true
  warn_unreachable = true
  warn_unused_configs = true
  warn_unused_ignores = true
  
  [tool.hatch.version]
  path = "fickling/__init__.py"
  
  [tool.hatch.build.targets.sdist]
  exclude = [
    "/.github",
    "/test",
    "/example",
    "/pickle_scanning_benchmark",
    "/.gitignore",
    "/Makefile",
    "/.pre-commit-config.yaml",
  ]
  
  [tool.hatch.build.targets.wheel]
  packages = ["fickling"]
  
  [tool.ruff]
  line-length = 100
  target-version = "py39"
  
  [tool.ruff.lint]
  select = [
    "E",     # pycodestyle errors
    "F",     # pyflakes
    "W",     # pycodestyle warnings
    "I",     # isort
    "N",     # pep8-naming
    "UP",    # pyupgrade
    "YTT",   # flake8-2020
    "BLE",   # flake8-blind-except
    "B",     # flake8-bugbear
    "C4",    # flake8-comprehensions
    "T20",   # flake8-print
    "RET",   # flake8-return
    "SIM",   # flake8-simplify
    "PTH",   # flake8-use-pathlib
    "PERF",  # perflint
    "RUF",   # ruff-specific rules
  ]
  ignore = [
    "E501",  # line too long (handled by formatter)
    "T201",  # print statements (needed for CLI)
    "T203",  # pprint statements
    # Pre-existing issues to fix in future PRs
    "PTH123",  # open() should be replaced by Path.open()
    "PTH107",  # os.remove should be replaced by Path.unlink
    "PTH118",  # os.path.join should be replaced by Path
    "PTH119",  # os.path.basename should be replaced by Path.name
    "RUF012",  # Mutable class attributes should use ClassVar
    "RUF013",  # PEP 484 prohibits implicit Optional
    "B028",   # No explicit stacklevel in warnings
    "B904",   # Use raise ... from within except blocks
    "SIM102",  # Use single if instead of nested if
    "SIM108",  # Use ternary operator instead of if-else
    "SIM114",  # Combine if branches with same body
    "SIM115",  # Use context handler for opening files
    "SIM117",  # Use single with statement for multiple contexts
    "SIM118",  # Use `key in dict` instead of `key in dict.keys()`
    "SIM201",  # Use `!=` instead of `not ==`
    "PERF203", # try-except in loop could be moved outside
    "RET503",  # Missing explicit return
    "RET504",  # Unnecessary assignment before return
    "RUF015",  # Prefer next() over list indexing
  ]
  
  [tool.ruff.lint.per-file-ignores]
  # Ignore various checks for benchmark and example code
  "pickle_scanning_benchmark/*.py" = ["BLE", "T20", "N806"]
  "example/*.py" = ["T20"]
  "test/*.py" = ["T20"]
  
  [tool.ruff.lint.isort]
  known-first-party = ["fickling"]
  
  [tool.ruff.format]
  quote-style = "double"
  indent-style = "space"
  skip-magic-trailing-comma = false
  