[project]
name = "pyfixest"
description = "Fast high dimensional fixed effect estimation following syntax of the fixest R package."
requires-python = ">= 3.9"
version = "0.26.0"
authors = [
  { name = "Alexander Fischer", email = "alexander-fischer1801@t-online.de" },
  { name = "Styfen Schär" },
]
readme = "README.md"
license = { text = "MIT" }

dependencies = [
  "lets-plot>=4.0.0",
  "scipy>=1.6",
  "formulaic>=1.0.0",
  "pandas>=1.1.0",
  "numba>=0.58.0",
  "seaborn>=0.13.2",
  "tabulate>=0.9.0",
  "polars>=0.20.1",
  "tqdm==4.66.4",
  "great-tables>=0.10.0",
  "numpy>=1.19.0",
  "jinja2>=3.1.4,<4",
]

[tool.pixi.feature.dev.dependencies]
rpy2 = ">=3.5.11,<4"

[project.optional-dependencies]
dev = [
  "pytest>=7.2.0",
  "pytest-cov>=4.1.0",
  "pytest-xdist>=3.5.0",
  "pyhdfe>=0.2.0",
  "pyarrow>=14.0.0",
  "pre-commit==3.6.0",
  "doubleml==0.7.1",
  "wildboottest>=0.3.2", "ipykernel>=6.29.5,<7",
]

docs = [
  "quartodoc>=0.7.2",
  "jupyterlab>=4.0.12",
  "jupytext==1.16.1",
  "watermark==2.4.3",
  "wildboottest>=0.3.2",
  "causaldata>=0.1.4,<0.2",
  "pylatex>=1.4.2,<2",
  "marginaleffects>=0.0.10",
]

[tool.pixi.feature.build.dependencies]
python-build = ">=1.2.2,<2"

[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]

[tool.pixi.project]
channels = ["conda-forge"]
platforms = ["linux-64", "win-64", "osx-arm64", "osx-64"]

[tool.pixi.pypi-dependencies]
pyfixest = { path = ".", editable = true }

[tool.pixi.environments]
default = { solve-group = "default" }
dev = { features = ["dev"], solve-group = "default" }
docs = { features = ["docs"], solve-group = "default" }
build = { features = ["build"], solve-group = "default" }

[tool.pixi.feature.dev.tasks]
tests = "pytest -n 4 --cov-report=term tests"
tests-regular = "pytest tests -n 4 -m \"not (extended or slow or plots)\" --cov=pyfixest --cov-report=xml"
tests-extended = "pytest tests -n 4 -m \"tests-extended\" --cov=pyfixest --cov-report=xml"
tests-slow = "pytest tests -n 4 -m slow --cov=./ --cov-report=xml"
tests-rerun = "pytest --lf -n 4"
debug = "python pyfixest/debug.py"
lint = "pre-commit run ruff --all-files"
update-test-data = "Rscript tests/r_test_comparisons.R"
install-r = "Rscript r_test_requirements.R"
render-notebooks = "python scripts/run_notebooks.py"

[tool.pixi.feature.build.tasks]
build-pip = 'python -m build .'

[tool.pixi.feature.docs.tasks]
docs-build = "quartodoc build --verbose --config docs/_quarto.yml"
docs-render = "quarto render docs"
docs-preview = "quarto preview docs"

[tool.pixi.feature.docs.dependencies]
rpy2 = ">=3.5.11,<4"
r-fixest = ">=0.12.1,<0.13"
r-broom = ">=1.0.5,<2"

[tool.pytest.ini_options]
addopts = [
  "-v",
  "--strict-markers",
  "--strict-config",
  "--cov=pyfixest",
  "--cov-report=term-missing",
  "--color=yes",
]

markers = [
  "slow: mark test to be part of the slow test suite",
  "extended: mark test to be part of the extended test suite",
  "plots: marks all tests for plotting functionality, tests only triggered when using tag in github issue",
]
filterwarnings = [
  "ignore::FutureWarning:rpy2",
  "ignore::DeprecationWarning:rpy2",
]

[tool.ruff]
line-length = 88
fix = true

# Assume Python 3.9
target-version = "py39"

[tool.ruff.lint]
# docs: https://docs.astral.sh/ruff/rules/
select = [
  "F",   # Pyflakes
  "E",   # pycodestyle errors
  "W",   # pycodestyle warnings
  "I",   # isort
  "D",   # flake8-docstrings
  "UP",  # pyupgrade
  "SIM", # flake8-simplify
  "TRY", # tryceratops
]

ignore = [
  # do not enable if formatting
  # docs: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
  "W191",   # tab indentation
  "E111",   # indentation
  "E114",   # indentation
  "E117",   # over indented
  "D206",   # indent with spaces
  "D300",   # triple single quotes
  "E501",   # line length regulated by formatter
  "D105",   # missing docstring in magic method
  "D100",   # missing docstring in public module
  "D104",   # missing docstring in public package
  "SIM110", # Use all instead of `for` loop
  "TRY003", # Avoid specifying long messages outside the exception class
  "D205",   # 1 blank line required between summary line and description
  "W505",   # Doc line too long
]

[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["D100", "D103"]
"pyfixest/multcomp.py" = ["D103"]
"pyfixest/summarize.py" = ["D103"]
"pyfixest/visualize.py" = ["D103"]
"scripts/*.py" = ["D103"]

[tool.ruff.lint.pycodestyle]
max-doc-length = 88

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

[tool.ruff.format]
docstring-code-format = true
docstring-code-line-length = 88

[tool.mypy]
plugins = "numpy.typing.mypy_plugin"

[[tool.mypy.overrides]]
module = [
  "pandas.*",
  "numpy.*",
  "scipy.*",
  "numba.*",
  "lets_plot.*",
  "formulaic.*",
  "wildboottest.*",
  "tabulate.*",
]
ignore_missing_imports = true
