[build-system]
requires = [
    "hatchling",
    "hatch-vcs",
    "param >=2.1.0",
    "bokeh >=3.5.0,<3.7.0",
    "pyviz_comms >=0.7.4",
    "requests",
    "packaging",
]
build-backend = "hatchling.build"

[project]
name = "panel"
dynamic = ["version"]
description = 'The powerful data exploration & web app framework for Python.'
readme = "README.md"
license = { text = "BSD" }
requires-python = ">=3.10"
authors = [{ name = "HoloViz developers", email = "developers@holoviz.org" }]
maintainers = [
    { name = "HoloViz developers", email = "developers@holoviz.org" },
]
classifiers = [
    "License :: OSI Approved :: BSD License",
    "Development Status :: 5 - Production/Stable",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Operating System :: OS Independent",
    "Intended Audience :: Developers",
    "Intended Audience :: Science/Research",
    "Intended Audience :: Financial and Insurance Industry",
    "Intended Audience :: Healthcare Industry",
    "Intended Audience :: Information Technology",
    "Intended Audience :: Legal Industry",
    "Intended Audience :: Other Audience",
    "Intended Audience :: Science/Research",
    "Natural Language :: English",
    "Topic :: Scientific/Engineering",
    "Topic :: Scientific/Engineering :: Visualization",
    "Topic :: Scientific/Engineering :: Information Analysis",
    "Topic :: Office/Business",
    "Topic :: Office/Business :: Financial",
    "Topic :: Software Development :: Libraries",
]

dependencies = [
    'bokeh >=3.5.0,<3.7.0',
    'param >=2.1.0,<3.0',
    'pyviz_comms >=2.0.0',
    'markdown',
    'markdown-it-py',
    'linkify-it-py',
    'mdit-py-plugins',
    'requests',
    'bleach',
    'typing_extensions',
    'pandas >=1.2',
    'packaging',
    'tqdm',  # TODO: Should this be optional?
]

[project.urls]
Homepage = "https://panel.holoviz.org"
Source = "https://github.com/holoviz/panel"
HoloViz = "https://holoviz.org/"

[project.optional-dependencies]
recommended = [
    'jupyterlab',
    'holoviews >=1.18.0',
    'matplotlib',
    'pillow',
    'plotly',
]
fastapi = [
    'bokeh-fastapi >= 0.1.1',
    'fastapi[standard]',
]
dev = [
    'watchfiles',
]
tests = [
    'psutil' ,
    'pytest',
    'pytest-asyncio',
    'pytest-rerunfailures',
    'pytest-xdist',
]
mypy = [
    "mypy",
    "pandas-stubs",
    "types-bleach",
    "types-croniter",
    "types-Markdown",
    "types-psutil",
    "types-requests",
    "types-tqdm",
    "typing-extensions",
]

[project.scripts]
panel = "panel.command:main"

[tool.hatch.version]
source = "vcs"
raw-options = { version_scheme = "no-guess-dev" }

[tool.hatch.build.targets.wheel]
include = ["panel"]
exclude = ["panel/node_modules"]

[tool.hatch.build.targets.wheel.force-include]
"panel/dist" = "panel/dist"

[tool.hatch.build.targets.wheel.shared-data]
"scripts/jupyter-config/notebook.json" = "etc/jupyter/jupyter_notebook_config.d/panel-client-jupyter.json"
"scripts/jupyter-config/server.json" = "etc/jupyter/jupyter_server_config.d/panel-client-jupyter.json"

[tool.hatch.build.targets.sdist]
include = ["panel", "scripts", "examples"]
exclude = ["scripts/jupyterlite", "panel/node_modules"]

[tool.hatch.build.targets.sdist.force-include]
"panel/dist" = "panel/dist"

[tool.hatch.build.hooks.vcs]
version-file = "panel/_version.py"

[tool.hatch.build.hooks.custom]
path = 'hatch_build.py'

[tool.ruff]
exclude = [
    ".git",
    "__pycache__",
    ".tox",
    ".eggs",
    "*.egg",
    "doc",
    "dist",
    "build",
    "_build",
    "examples",
    ".ipynb_checkpoints",
    "node_modules",
    "apps",
]
line-length = 165
fix = true

[tool.ruff.lint]
ignore = [
    "E402", # Module level import not at top of file
    "E712", # Avoid equality comparisons to True; use if {cond}: for truth checks
    "E731", # Do not assign a lambda expression, use a def
    "E741", # Ambiguous variable name
    "W605", # Invalid escape sequence
    "E701", # Multiple statements on one line
    "B006", # Do not use mutable data structures for argument defaults
    "B905", # `zip()` without an explicit `strict=` parameter
]
select = [
    "B",
    "E",
    "F",
    "W",
    "PIE",
    "T20",
    "RUF006",
    "UP004",
    "UP006",
    "UP020",
    "UP028",
    "UP030",
    "UP031",
    "UP032",
    "UP034",
    "UP036",
]
unfixable = [
    "F401", # Unused imports
    "F841", # Unused variables
]

[tool.ruff.lint.per-file-ignores]
"panel/tests/ui/jupyter_server_test_config.py" = ["F821"]
"panel/compiler.py" = ["T201"]
"panel/io/convert.py" = ["T201"]
"panel/pane/vtk/synchronizable_*.py" = ["T201"]
"scripts/*.py" = ["T201"]
"hatch_build.py" = ["T201"]

[tool.isort]
force_grid_wrap = 4
multi_line_output = 5
combine_as_imports = true
lines_between_types = 1
include_trailing_comma = true

[tool.codespell]
ignore-words-list = "nd,doubleclick,ser"
skip = "doc/generate_modules.py,examples/reference/templates/FastGridTemplate.ipynb,panel/.eslintrc.js,panel/package-lock.json,panel/package.json"
write-changes = true

[tool.pytest.ini_options]
# addopts = "-v --pyargs --doctest-ignore-import-errors --color=yes"
addopts = "--pyargs --doctest-ignore-import-errors --color=yes"
norecursedirs = "doc .git dist build _build .ipynb_checkpoints panel/examples"
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
xfail_strict = true
minversion = "7"
log_cli_level = "INFO"
filterwarnings = [
    "error",
    # 2023-11: `pkg_resources` is deprecated
    "ignore:Deprecated call to `pkg_resources.+?'zope:DeprecationWarning",  # https://github.com/zopefoundation/meta/issues/194
    "ignore: pkg_resources is deprecated as an API:DeprecationWarning:streamz.plugins", # https://github.com/python-streamz/streamz/issues/460
    # 2024-06: Adding error to the filterwarnings
    "ignore:Jupyter is migrating its paths to use standard platformdirs:DeprecationWarning", # OK
    "ignore:distutils Version classes are deprecated:DeprecationWarning:ipywidgets_bokeh.kernel", # OK
    "ignore:unclosed file <_io.TextIOWrapper name='(/dev/null|nul)' mode='w':ResourceWarning", # OK
    "ignore:Deprecated in traitlets 4.1, use the instance .metadata dictionary directly", # OK (ipywidgets internal)
    # 2024-11
    "ignore:websockets.legacy is deprecated:DeprecationWarning", # https://github.com/encode/uvicorn/issues/1908
    "ignore:websockets.server.WebSocketServerProtocol is deprecated:DeprecationWarning", # https://github.com/encode/uvicorn/issues/1908
]

[tool.mypy]
namespace_packages = true
explicit_package_bases = true
disable_error_code = "attr-defined"
mypy_path = ""
exclude = []

[[tool.mypy.overrides]]
module = [
    "anywidget.*",
    "bokeh_django.*",
    "bokeh_fastapi.*",
    "bokeh.*",
    "cachecontrol.*",
    "cryptography.*",
    "diskcache.*",
    "flask.*",
    "fsspec.*",
    "holoviews.*",
    "hvplot.*",
    "ipympl.*",
    "ipywidgets_bokeh.*",
    "ipywidgets.*",
    "js.*",
    "jupyter_bokeh.*",
    "langchain.*",
    "lumen.*",
    "magic.*",
    "matplotlib.*",
    "mdit_py_emoji.*",
    "memray.*",
    "myst_parser.*",
    "param.*",
    "playwright.*",
    "plotly.*",
    "pydeck.*",
    "pyecharts.*",
    "pyodide_http.*",
    "pyodide.*",
    "pyscript.*",
    "pyvista.*",
    "pyviz_comms.*",
    "rpy2.*",
    "scipy.*",
    "setuptools_scm.*",
    "snakeviz.*",
    "streamz.*",
    "traitlets.*",
    "tranquilizer.*",
    "uvicorn.*",
    "vtk.*",
    "watchfiles.*"
]
ignore_missing_imports = true
