[build-system]
requires = [
    "setuptools>=66.1",
    "setuptools_scm>=8.1",
]
build-backend = "setuptools.build_meta"

[project]
name = "mqt.bench"
description = "MQT Bench - A MQT tool for Benchmarking Quantum Software Tools"
readme = "README.md"
authors = [
    { name = "Nils Quetschlich", email = "nils.quetschlich@tum.de" },
    { name = "Lukas Burgholzer", email = "lukas.burgholzer@tum.de"},
]
keywords = ["MQT",  "quantum computing", "benchmarking", "performance", "testing"]
license = { file = "LICENSE" }
requires-python = ">=3.10"
dynamic = ["version"]

dependencies = [
    "pytket-qiskit>=0.53.0",  #  manages the dependencies for qiskit and tket in a combined fashion
    "pytket>=1.29.0",  # lowest version that supports the used pytket AutoRebase pass instead of auto_rebase
    "qiskit!=1.2.0",  # there is a bug in 1.2.0 that causes an error some benchmarks, see https://github.com/Qiskit/qiskit/issues/12969
    "qiskit_optimization>=0.6",
    "qiskit_nature[pyscf]>=0.7",
    "qiskit_finance>=0.4.1",
    "pandas>=2.1.2",
    "flask>=2.3.0",
    "networkx>=2.8.8",
    "packaging>=21.0",
    "tqdm>=4.29.0",
    "joblib>=1.3.0",
    "numpy>=1.26; python_version >= '3.12'",
    "numpy>=1.24; python_version >= '3.11'",
    "numpy>=1.22",
]


classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Operating System :: Microsoft :: Windows",
    "Operating System :: MacOS",
    "Operating System :: POSIX :: Linux",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Intended Audience :: Science/Research",
    "Natural Language :: English",
    "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
]

[project.optional-dependencies]
test = ["pytest>=7.2", "pytest-console-scripts>=1.4"]
coverage = ["mqt.bench[test]", "pytest-cov>=4"]
docs = [
    "furo>=2023.9.10",
    "qiskit[visualization]",
    "setuptools-scm>=8.1",
    "sphinx_design>=0.6",
    "sphinx-autoapi>=3",
    "sphinx-copybutton>=0.5",
    "sphinxcontrib-bibtex>=2.4.2",
    "sphinxcontrib-svg2pdfconverter>=1.2",
    "sphinxext-opengraph>=0.9",
    "ipython",
    "ipykernel",
    "nbsphinx",
    "sphinx-autodoc-typehints",
]
dev = ["mqt.bench[coverage, docs]"]

[project.scripts]
"mqt.bench" = "mqt.bench.viewer.main:start_server"
"create_mqt_bench_zip" = "mqt.bench.utils:create_zip_file"
"generate_mqt_bench" = "mqt.bench.benchmark_generator:generate"
"mqt.bench.cli" = "mqt.bench.cli:main"

[project.urls]
Homepage = "https://github.com/cda-tum/mqtbench"
"Bug Tracker" = "https://github.com/cda-tum/mqtbench/issues"
Discussions = "https://github.com/cda-tum/mqtbench/discussions"
Research = "https://www.cda.cit.tum.de/research/quantum/"

[tool.setuptools_scm]

[tool.pytest.ini_options]
minversion = "7.2"
testpaths = ["tests"]
addopts = ["-ra", "--strict-markers", "--strict-config", "--showlocals"]
log_cli_level = "INFO"
xfail_strict = true
filterwarnings = [
    "error",
    'ignore:.*pkg_resources.*:DeprecationWarning:',
    'ignore:.*sre_.*:DeprecationWarning:',
    'ignore:.*Rigetti.*:UserWarning:',
    'ignore:.*Values in x.*:RuntimeWarning:',
    'ignore:.*divide by zero encountered in det.*:RuntimeWarning:',
    'ignore:.*invalid value encountered in det.*:RuntimeWarning:',
    'ignore::DeprecationWarning:.*(docplex).*',
    'ignore::SyntaxWarning:.*(docplex).*',
    'ignore:.*The abstract Provider and ProviderV1 classes are deprecated.*:DeprecationWarning:qiskit.*',
    'ignore:.*qiskit.providers.models is deprecated since Qiskit 1.2*:DeprecationWarning:',
    'ignore:.*Treating CircuitInstruction as an iterable is deprecated legacy behavior since Qiskit 1.2*:DeprecationWarning:pytket.*',
    'ignore:.*qiskit.providers.models.* is deprecated since qiskit 1.2*:DeprecationWarning:qiskit.*',
    'ignore:.*qiskit.primitives.* is deprecated as of qiskit 1.2*:DeprecationWarning:qiskit.*',
    'ignore:.*The class ``qiskit.qobj.pulse_qobj.Pulse.*`` is deprecated as of qiskit 1.2.*:DeprecationWarning:qiskit.*',
    'ignore:.*The class ``qiskit.primitives.sampler.Sampler`` is deprecated as of qiskit 1.2*:DeprecationWarning:mqt.*',
    'ignore:.*The class ``qiskit.primitives.estimator.Estimator`` is deprecated as of qiskit 1.2*:DeprecationWarning:mqt.*',
]

[tool.coverage]
run.source = ["mqt.bench"]
report.exclude_also = [
    '\.\.\.',
    'if TYPE_CHECKING:',
    'raise AssertionError',
    'raise NotImplementedError',
]

show_missing = true
skip_empty = true
precision = 1

[tool.mypy]
mypy_path = "$MYPY_CONFIG_FILE_DIR/src"
files = ["src", "tests"]
python_version = "3.10"
strict = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
warn_unreachable = true
explicit_package_bases = true
pretty = true

[[tool.mypy.overrides]]
module = ["pytket.*", "qiskit_finance.*"]
implicit_reexport = true

[[tool.mypy.overrides]]
module = ["qiskit.*", "qiskit_finance.*", "joblib.*", "networkx.*", "pandas.*", "qiskit_algorithms.*", "qiskit_ibm_runtime.*", "pytest_console_scripts.*"]
ignore_missing_imports = true

[tool.ruff]
line-length = 120
extend-include = ["*.ipynb"]
preview = true
unsafe-fixes = true

[tool.ruff.lint]
extend-select = [
    "A",           # flake8-builtins
    "ANN",         # flake8-annotations
    "ARG",         # flake8-unused-arguments
    "ASYNC",       # flake8-async
    "B",  "B904",  # flake8-bugbear
    "C4",          # flake8-comprehensions
    "D",           # pydocstyle
    "EM",          # flake8-errmsg
    "EXE",         # flake8-executable
    "FA",          # flake8-future-annotations
    "FLY",         # flynt
    "FURB",        # refurb
    "I",           # isort
    "ICN",         # flake8-import-conventions
    "ISC",         # flake8-implicit-str-concat
    "LOG",         # flake8-logging-format
    "N",           # flake8-naming
    "NPY",         # numpy
    "PERF",        # perflint
    "PGH",         # pygrep-hooks
    "PIE",         # flake8-pie
    "PL",          # pylint
    "PT",          # flake8-pytest-style
    "PTH",         # flake8-use-pathlib
    "PYI",         # flake8-pyi
    "Q",           # flake8-quotes
    "RET",         # flake8-return
    "RSE",         # flake8-raise
    "RUF",         # Ruff-specific
    "SLF",         # flake8-self
    "SLOT",        # flake8-slots
    "SIM",         # flake8-simplify
    "TCH",         # flake8-type-checking
    "TID",         # flake8-tidy-imports
    "TRY",         # tryceratops
    "UP",          # pyupgrade
    "YTT",         # flake8-2020
]
ignore = [
    "ANN101",  # Missing type annotation for self in method
    "ANN102",  # Missing type annotation for cls in classmethod
    "ISC001",  # Conflicts with formatter
    "E501",    # Line too long (Black is enough)
    "PLR",     # Design related pylint codes
    "S101",    # Use of assert detected
]
flake8-unused-arguments.ignore-variadic-names = true
isort.required-imports = ["from __future__ import annotations"]

[tool.ruff.lint.per-file-ignores]
"*.pyi" = ["D"]  # pydocstyle
"*.ipynb" = [
    "D",    # pydocstyle
    "E402", # Allow imports to appear anywhere in Jupyter notebooks
    "I002", # Allow missing `from __future__ import annotations` import
]

[tool.ruff.lint.pydocstyle]
convention = "google"


[tool.typos]
default.extend-ignore-re = [
  '"id": ".*",',
  "(?Rm)^.*(#|//)\\s*spellchecker:disable-line$",  # ignore line
  "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on" # ignore block
]
[tool.typos.default.extend-words]
wille = "wille"
anc = "anc"
aer = "aer"
fom = "fom"
bench = "bench"
benchs = "benchs"

[tool.repo-review]
ignore = ["GH200"]
