[project]
name = "prolif"
description = "Interaction Fingerprints for protein-ligand complexes and more"
authors = [{ name = "Cédric Bouysset", email = "cedric@bouysset.net" }]
readme = "README.rst"
license = "Apache-2.0"
license-files = ["LICENSE"]
requires-python = ">=3.10"
version = "2.2.1"
classifiers = [
    "Development Status :: 5 - Production/Stable",
    "Operating System :: OS Independent",
    "Intended Audience :: Science/Research",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Topic :: Scientific/Engineering :: Bio-Informatics",
    "Topic :: Scientific/Engineering :: Chemistry",
]
keywords = [
    "science",
    "chemistry",
    "drug-design",
    "cheminformatics",
    "chemoinformatics",
    "molecular-dynamics",
    "interaction-fingerprint",
]
dependencies = [
    "pandas>=1.1.0",
    "numpy>=1.13.3",
    "scipy>=1.3.0",
    "mdanalysis>=2.2.0,<3; python_version<'3.13'",
    "mdanalysis>=2.7.0,<3; python_version>='3.13'",
    "networkx>=2.5.0",
    "tqdm",
    "multiprocess",
    "dill",
    "psutil",
    "gemmi>=0.7.5",
]

[project.optional-dependencies]
plots = ["py3Dmol", "matplotlib>=3.5"]
tutorials = [
    "rdkit>=2022.09.1",
    "matplotlib>=3.7",
    "seaborn<1.0",
    "pyvis",
    "prolif[plots]",
]

[dependency-groups]
tests = [
    "pytest>=6.1.2",
    "pytest-cov",
    "ipython",
    "rdkit>=2022.09.1",
    "prolif[plots]",
]
docs = [
    "sphinx==5.3.0",
    "sphinx-copybutton",
    "myst-nb<1.0",
    "ipywidgets",
    "recommonmark",
    "sphinx-book-theme",
    "prolif[tutorials]",
    "sphinx-autobuild>=2024.10.3",
]
type-check = [
    "mypy>=1.0.0",
    "rdkit>=2024.03.2",
    "pandas-stubs",
    "types-tqdm",
    "types-setuptools",
    "scipy-stubs",
    "types-networkx",
    "types-psutil",
]
dev = [
    "ruff==0.11.2",                   # keep synced with formatting_linting.yml
    "black[jupyter]",
    "poethepoet>=0.33.0",
    { include-group = "tests" },
    { include-group = "docs" },
    { include-group = "type-check" },
]

[project.urls]
Homepage = "https://github.com/chemosim-lab/ProLIF"
Documentation = "https://prolif.readthedocs.io/en/stable/"
Discussions = "https://github.com/chemosim-lab/ProLIF/discussions"
Issues = "https://github.com/chemosim-lab/ProLIF/issues"
Changelog = "https://github.com/chemosim-lab/ProLIF/blob/master/CHANGELOG.md"

[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[tool.setuptools.packages.find]
include = ["prolif*"]

[tool.setuptools.package-data]
"prolif" = ["py.typed"]
"prolif.data" = ["*"]
"prolif.data.vina" = ["*"]
"prolif.data.molecule_standardizer" = ["*"]
"prolif.data.molecule_standardizer.templates" = ["*"]
"prolif.data.implicitHbond" = ["*"]
"prolif.plotting.network" = ["*"]

[tool.uv]
default-groups = ["dev"]

[tool.poe.tasks.format-check]
help = "Checks that the code and notebooks don't require formatting"
sequence = [
    { cmd = "ruff format --diff" },
    { cmd = "black --diff docs/notebooks/" },
]

[tool.poe.tasks.lint-check]
help = "Checks if the code requires linting"
cmd = "ruff check --preview --diff"

[tool.poe.tasks.style-check]
help = "Runs the formatting and linting checks"
sequence = [{ ref = "format-check" }, { ref = "lint-check" }]

[tool.poe.tasks.format]
help = "Formats the code and notebooks"
sequence = [{ cmd = "ruff format" }, { cmd = "black docs/notebooks/" }]

[tool.poe.tasks.lint]
help = "Lints the code"
cmd = "ruff check --preview --fix"

[tool.poe.tasks.style-fix]
help = "Fixes formatting and linting issues"
sequence = [{ ref = "format" }, { ref = "lint" }]

[tool.poe.tasks.type-check]
help = "Run mypy to check type hints across the codebase"
cmd = "mypy ${FILE_PATHS}"
args = [
    { name = "FILE_PATHS", positional = true, multiple = true, default = "." },
]

[tool.poe.tasks.test]
help = "Runs the test suite"
cmd = "pytest"

[tool.poe.tasks.docs]
help = "Builds the documentation"
cmd = "sphinx-build -M html docs/ docs/_build/"

[tool.poe.tasks.live-docs]
help = "Builds and serves the documentation with live reload"
cmd = "sphinx-autobuild --watch . docs docs/_build/html"

[tool.poe.tasks.check]
help = "Runs all of the checks"
sequence = [
    { ref = "style-check" },
    { ref = "type-check" },
    { ref = "test" },
    { ref = "docs" },
]

[tool.mypy]
python_version = "3.10"
disallow_untyped_defs = true
allow_redefinition = true
disallow_any_unimported = true
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_return_any = true
warn_unreachable = true
show_error_context = true
exclude = "docs/conf.py|build/"

[[tool.mypy.overrides]]
module = ["MDAnalysis.*", "py3Dmol.*", "dill.*", "multiprocess.*"]
ignore_missing_imports = true

[[tool.mypy.overrides]]
module = ["tests.*"]
disallow_any_unimported = false

[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.ruff]
extend-exclude = [
    "*.ipynb",
    ".ipynb_checkpoints",
    ".pytest_cache",
    ".vscode",
    "build",
    "site-packages",
]

[tool.ruff.lint]
select = [
    # pycodestyle
    "E",
    # Pyflakes
    "F",
    # Warning
    "W",
    # pyupgrade
    "UP",
    # flake8
    "B",   # bugbear
    "SIM", # simplify
    "A",   # builtins
    "COM", # commas
    "C4",  # comprehensions
    "ISC", # implicit-str-concat
    "ICN", # import-conventions
    "PIE", # pie
    "T20", # print
    "PT",  # pytest-style
    "Q",   # quotes
    "RET", # return
    "ARG", # unused-arguments
    "PTH", # use-pathlib
    # pandas-vet
    "PD",
    # pylint
    "PLR", # refactor
    "PLW", # warning
    # numpy
    "NPY",
    # refurb
    "FURB",
    # ruff
    "RUF",
    # isort
    "I",
]
ignore = [
    "PLW3201",
    "PLW1514",
    "PTH123",
    "PLR0904",
    "PLR0911",
    "PLR0913",
    "PLR0914",
    "PLR0915",
    "PLR0916",
    "PLR0917",
    "PLR1702",
    "PLR2004",
    "PLR6301",
    "PD901",
    "PT001",
    "PT018",
    "FURB103",
    "COM812",
    "UP037",
]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
"tests/*" = ["ARG001"]

[tool.isort]
profile = "black"

[tool.black]
target-version = ["py310", "py311", "py312", "py313"]
include = '(docs/notebooks/.+\.ipynb)$'

[tool.coverage.report]
include_namespace_packages = true
exclude_also = [
    "def __repr__",
    "if __name__ == .__main__.:",
    "if .*TYPE_CHECKING:",
    "@.*abstractmethod",
]
omit = ["prolif/typeshed.py"]
