[build-system] build-backend = "backend" requires = [ "setuptools>=67.8", ] backend-path = [ "_custom_build", ] [project] name = "pillow" description = "Python Imaging Library (Fork)" readme = "README.md" keywords = [ "Imaging", ] license = { text = "HPND" } authors = [ { name = "Jeffrey A. Clark", email = "aclark@aclark.net" }, ] requires-python = ">=3.9" classifiers = [ "Development Status :: 6 - Mature", "License :: OSI Approved :: Historical Permission Notice and Disclaimer (HPND)", "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", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Multimedia :: Graphics", "Topic :: Multimedia :: Graphics :: Capture :: Digital Camera", "Topic :: Multimedia :: Graphics :: Capture :: Screen Capture", "Topic :: Multimedia :: Graphics :: Graphics Conversion", "Topic :: Multimedia :: Graphics :: Viewers", "Typing :: Typed", ] dynamic = [ "version", ] optional-dependencies.docs = [ "furo", "olefile", "sphinx>=7.3", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph", ] optional-dependencies.fpx = [ "olefile", ] optional-dependencies.mic = [ "olefile", ] optional-dependencies.tests = [ "check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", ] optional-dependencies.typing = [ "typing-extensions; python_version<'3.10'", ] optional-dependencies.xmp = [ "defusedxml", ] urls.Changelog = "https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst" urls.Documentation = "https://pillow.readthedocs.io" urls.Funding = "https://tidelift.com/subscription/pkg/pypi-pillow?utm_source=pypi-pillow&utm_medium=pypi" urls.Homepage = "https://python-pillow.org" urls.Mastodon = "https://fosstodon.org/@pillow" urls."Release notes" = "https://pillow.readthedocs.io/en/stable/releasenotes/index.html" urls.Source = "https://github.com/python-pillow/Pillow" [tool.setuptools] packages = [ "PIL", ] include-package-data = true package-dir = { "" = "src" } [tool.setuptools.dynamic] version = { attr = "PIL.__version__" } [tool.cibuildwheel] before-all = ".github/workflows/wheels-dependencies.sh" build-verbosity = 1 config-settings = "raqm=enable raqm=vendor fribidi=vendor imagequant=disable" test-command = "cd {project} && .github/workflows/wheels-test.sh" test-extras = "tests" [tool.ruff] fix = true lint.select = [ "C4", # flake8-comprehensions "E", # pycodestyle errors "EM", # flake8-errmsg "F", # pyflakes errors "I", # isort "ISC", # flake8-implicit-str-concat "LOG", # flake8-logging "PGH", # pygrep-hooks "PT", # flake8-pytest-style "PYI", # flake8-pyi "RUF100", # unused noqa (yesqa) "UP", # pyupgrade "W", # pycodestyle warnings "YTT", # flake8-2020 ] lint.ignore = [ "E203", # Whitespace before ':' "E221", # Multiple spaces before operator "E226", # Missing whitespace around arithmetic operator "E241", # Multiple spaces after ',' "PT001", # pytest-fixture-incorrect-parentheses-style "PT007", # pytest-parametrize-values-wrong-type "PT011", # pytest-raises-too-broad "PT012", # pytest-raises-with-multiple-statements "PT017", # pytest-assert-in-except "PYI026", # flake8-pyi: typing.TypeAlias added in Python 3.10 "PYI034", # flake8-pyi: typing.Self added in Python 3.11 ] lint.per-file-ignores."Tests/oss-fuzz/fuzz_font.py" = [ "I002", ] lint.per-file-ignores."Tests/oss-fuzz/fuzz_pillow.py" = [ "I002", ] lint.flake8-pytest-style.parametrize-names-type = "csv" lint.isort.known-first-party = [ "PIL", ] lint.isort.required-imports = [ "from __future__ import annotations", ] [tool.pyproject-fmt] max_supported_python = "3.13" [tool.pytest.ini_options] addopts = "-ra --color=yes" testpaths = [ "Tests", ] [tool.mypy] python_version = "3.9" pretty = true disallow_any_generics = true enable_error_code = "ignore-without-code" extra_checks = true follow_imports = "silent" warn_redundant_casts = true warn_unreachable = true warn_unused_ignores = true