[build-system]
# Minimum requirements for the build system to execute.
# See https://github.com/scipy/scipy/pull/12940 for the AIX issue.
requires = [
    "setuptools>=61.0.0",
    "wheel",
    "Cython>=0.29.32,<3",  # Note: sync with setup.py, environment.yml and asv.conf.json
    "oldest-supported-numpy>=2022.8.16",
    "versioneer[toml]"
]
# build-backend = "setuptools.build_meta"

[project]
name = 'pandas'
dynamic = [
  'version'
]
description = 'Powerful data structures for data analysis, time series, and statistics'
readme = 'README.md'
authors = [
  { name = 'The Pandas Development Team', email='pandas-dev@python.org' },
]
license = {file = 'LICENSE'}
requires-python = '>=3.8'
dependencies = [
  "numpy>=1.20.3; python_version<'3.10'",
  "numpy>=1.21.0; python_version>='3.10'",
  "numpy>=1.23.2; python_version>='3.11'",
  "python-dateutil>=2.8.2",
  "pytz>=2020.1"
]
classifiers = [
    'Development Status :: 5 - Production/Stable',
    'Environment :: Console',
    'Intended Audience :: Science/Research',
    'License :: OSI Approved :: BSD License',
    'Operating System :: OS Independent',
    'Programming Language :: Cython',
    'Programming Language :: Python',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3 :: Only',
    'Programming Language :: Python :: 3.11',
    'Topic :: Scientific/Engineering'
]

[project.urls]
homepage = 'https://pandas.pydata.org'
documentation = 'https://pandas.pydata.org/docs/'
repository = 'https://github.com/pandas-dev/pandas'

[project.entry-points."pandas_plotting_backends"]
matplotlib = "pandas:plotting._matplotlib"

[project.optional-dependencies]
test = ['hypothesis>=6.34.2', 'pytest>=7.3.2', 'pytest-xdist>=3.4.0']
performance = ['bottleneck>=1.3.2', 'numba>=0.53.1', 'numexpr>=2.7.1']
timezone = ['tzdata>=2023.3']
computation = ['scipy>=1.7.1', 'xarray>=0.21.0']
fss = ['fsspec>=2021.07.0']
aws = ['s3fs>=2021.08.0']
gcp = ['gcsfs>=2021.07.0']
excel = ['odfpy>=1.4.1', 'openpyxl>=3.0.7', 'python-calamine>=0.1.7', 'pyxlsb>=1.0.8', 'xlrd>=2.0.1', 'xlsxwriter>=1.4.3']
parquet = ['pyarrow>=7.0.0']
feather = ['pyarrow>=7.0.0']
hdf5 = ['tables>=3.6.1']
spss = ['pyreadstat>=1.1.2']
postgresql = ['SQLAlchemy>=1.4.16', 'psycopg2>=2.9.9']
mysql = ['SQLAlchemy>=1.4.16', 'pymysql>=1.1.0']
sql-other = ['SQLAlchemy>=1.4.16']
html = ['beautifulsoup4>=4.9.3', 'html5lib>=1.1', 'lxml>=4.6.3']
xml = ['lxml>=4.6.3']
plot = ['matplotlib>=3.6.1']
output_formatting = ['jinja2>=3.0.0', 'tabulate>=0.8.9']
clipboard = ['PyQt5>=5.15.1', 'qtpy>=2.3.0']
compression = ['zstandard>=0.15.2']
all = ['beautifulsoup4>=5.9.3',
       'bottleneck>=1.3.2',
       'fastparquet>=0.6.3',
       'fsspec>=2021.07.0',
       'gcsfs>=2021.07.0',
       'html5lib>=1.1',
       'hypothesis>=6.34.2',
       'jinja2>=3.0.0',
       'lxml>=4.6.3',
       'matplotlib>=3.6.1',
       'numba>=0.53.1',
       'numexpr>=2.7.3',
       'odfpy>=1.4.1',
       'openpyxl>=3.0.7',
       'psycopg2>=2.9.9',
       'pyarrow>=7.0.0',
       'pymysql>=1.1.0',
       'PyQt5>=5.15.1',
       'pyreadstat>=1.1.2',
       'pytest>=7.3.2',
       'pytest-xdist>=3.4.0',
       'python-calamine>=0.1.7',
       'pyxlsb>=1.0.8',
       'qtpy>=2.3.0',
       'scipy>=1.7.1',
       's3fs>=2021.08.0',
       'SQLAlchemy>=1.4.16',
       'tables>=3.6.1',
       'tabulate>=0.8.9',
       'tzdata>=2023.3',
       'xarray>=0.21.0',
       'xlrd>=2.0.1',
       'xlsxwriter>=1.4.3',
       'zstandard>=0.15.2']

# TODO: Remove after setuptools support is dropped.
[tool.setuptools]
include-package-data = true

[tool.setuptools.packages.find]
include = ["pandas", "pandas.*"]
namespaces = false

[tool.setuptools.exclude-package-data]
"*" = ["*.c", "*.h"]

# See the docstring in versioneer.py for instructions. Note that you must
# re-run 'versioneer.py setup' after changing this section, and commit the
# resulting files.
[tool.versioneer]
VCS = "git"
style = "pep440"
versionfile_source = "pandas/_version.py"
versionfile_build = "pandas/_version.py"
tag_prefix = "v"
parentdir_prefix = "pandas-"

[tool.cibuildwheel]
skip = "cp36-* cp37-* pp37-* *-manylinux_i686 *_ppc64le *_s390x *-musllinux*"
build-verbosity = "3"
test-requires = "hypothesis>=6.34.2 pytest>=7.3.2 pytest-xdist>=3.4.0"
test-command = "python {project}/ci/test_wheels.py"

[tool.cibuildwheel.macos]
archs = "x86_64 arm64"
test-skip = "*_arm64"

[tool.cibuildwheel.windows]
repair-wheel-command = "python ci/fix_wheels.py {wheel} {dest_dir}"

[[tool.cibuildwheel.overrides]]
select = "*-win*"
# We test separately for Windows, since we use
# the base windows docker image to check if any dlls are
# missing from the wheel
test-command = ""

[[tool.cibuildwheel.overrides]]
select = "*-win32"
environment = { IS_32_BIT="true" }

[tool.ruff]
line-length = 88
update-check = false
target-version = "py38"

select = [
  # pyflakes
  "F",
  # pycodestyle
  "E",
  "W",
  # flake8-2020
  "YTT",
  # flake8-bugbear
  "B",
  # flake8-quotes
  "Q",
  # pylint
  "PLE", "PLR", "PLW",
]

ignore = [
  # space before : (needed for how black formats slicing)
  # "E203",  # not yet implemented
  # module level import not at top of file
  "E402",
  # do not assign a lambda expression, use a def
  "E731",
  # line break before binary operator
  # "W503",  # not yet implemented
  # line break after binary operator
  # "W504",  # not yet implemented
  # controversial
  "B006",
  # controversial
  "B007",
  # controversial
  "B008",
  # setattr is used to side-step mypy
  "B009",
  # getattr is used to side-step mypy
  "B010",
  # tests use assert False
  "B011",
  # tests use comparisons but not their returned value
  "B015",
  # false positives
  "B019",
  # Loop control variable overrides iterable it iterates
  "B020",
  # Function definition does not bind loop variable
  "B023",
  # Functions defined inside a loop must not use variables redefined in the loop
  # "B301",  # not yet implemented

  # Additional checks that don't pass yet
  # Within an except clause, raise exceptions with ...
  "B904",
]

exclude = [
  "doc/sphinxext/*.py",
  "doc/build/*.py",
  "doc/temp/*.py",
  ".eggs/*.py",
  "versioneer.py",
  # exclude asv benchmark environments from linting
  "env",
]

[tool.pytest.ini_options]
# sync minversion with pyproject.toml & install.rst
minversion = "7.0"
addopts = "--strict-data-files --strict-markers --strict-config --capture=no --durations=30 --junitxml=test-data.xml"
empty_parameter_set_mark = "fail_at_collect"
xfail_strict = true
testpaths = "pandas"
doctest_optionflags = [
  "NORMALIZE_WHITESPACE",
  "IGNORE_EXCEPTION_DETAIL",
  "ELLIPSIS",
]
filterwarnings = [
  # Will be fixed in numba 0.56: https://github.com/numba/numba/issues/7758
  "ignore:`np.MachAr` is deprecated:DeprecationWarning:numba",
  "ignore:.*urllib3:DeprecationWarning:botocore",
  "ignore:Setuptools is replacing distutils.:UserWarning:_distutils_hack",
  # https://github.com/PyTables/PyTables/issues/822
  "ignore:a closed node found in the registry:UserWarning:tables",
  "ignore:`np.object` is a deprecated:DeprecationWarning:tables",
  "ignore:tostring:DeprecationWarning:tables",
  "ignore:distutils Version classes are deprecated:DeprecationWarning:numexpr",
  "ignore:distutils Version classes are deprecated:DeprecationWarning:fastparquet",
  "ignore:distutils Version classes are deprecated:DeprecationWarning:fsspec",
]
junit_family = "xunit2"
markers = [
  "single_cpu: tests that should run on a single cpu only",
  "slow: mark a test as slow",
  "network: mark a test as network",
  "db: tests requiring a database (mysql or postgres)",
  "clipboard: mark a pd.read_clipboard test",
  "arm_slow: mark a test as slow for arm64 architecture",
  "skip_ubsan: tests known to invoke undefined behavior",
]

[tool.mypy]
# Import discovery
mypy_path = "typings"
files = ["pandas", "typings"]
namespace_packages = false
explicit_package_bases = false
ignore_missing_imports = true
follow_imports = "normal"
follow_imports_for_stubs = false
no_site_packages = false
no_silence_site_packages = false
# Platform configuration
python_version = "3.8"
platform = "linux-64"
# Disallow dynamic typing
disallow_any_unimported = false # TODO
disallow_any_expr = false # TODO
disallow_any_decorated = false # TODO
disallow_any_explicit = false # TODO
disallow_any_generics = false # TODO
disallow_subclassing_any = false # TODO
# Untyped definitions and calls
disallow_untyped_calls = false # TODO
disallow_untyped_defs = false # TODO
disallow_incomplete_defs = false # TODO
check_untyped_defs = true
disallow_untyped_decorators = true
# None and Optional handling
no_implicit_optional = true
strict_optional = true
# Configuring warnings
warn_redundant_casts = true
warn_unused_ignores = true
warn_no_return = true
warn_return_any = false # TODO
warn_unreachable = false # GH#27396
# Suppressing errors
ignore_errors = false
enable_error_code = "ignore-without-code"
# Miscellaneous strictness flags
allow_untyped_globals = false
allow_redefinition = false
local_partial_types = false
implicit_reexport = true
strict_equality = true
# Configuring error messages
show_error_context = false
show_column_numbers = false
show_error_codes = true

[[tool.mypy.overrides]]
module = [
  "pandas.tests.*",
  "pandas._version",
  "pandas.io.clipboard",
]
check_untyped_defs = false

[[tool.mypy.overrides]]
module = [
  "pandas.tests.apply.test_series_apply",
  "pandas.tests.arithmetic.conftest",
  "pandas.tests.arrays.sparse.test_combine_concat",
  "pandas.tests.dtypes.test_common",
  "pandas.tests.frame.methods.test_to_records",
  "pandas.tests.groupby.test_rank",
  "pandas.tests.groupby.transform.test_transform",
  "pandas.tests.indexes.interval.test_interval",
  "pandas.tests.indexing.test_categorical",
  "pandas.tests.io.excel.test_writers",
  "pandas.tests.reductions.test_reductions",
  "pandas.tests.test_expressions",
]
ignore_errors = true

# To be kept consistent with "Import Formatting" section in contributing.rst
[tool.isort]
known_pre_libs = "pandas._config"
known_pre_core = ["pandas._libs", "pandas._typing", "pandas.util._*", "pandas.compat", "pandas.errors"]
known_dtypes = "pandas.core.dtypes"
known_post_core = ["pandas.tseries", "pandas.io", "pandas.plotting"]
sections = ["FUTURE", "STDLIB", "THIRDPARTY" ,"PRE_LIBS" , "PRE_CORE", "DTYPES", "FIRSTPARTY", "POST_CORE", "LOCALFOLDER"]
profile = "black"
combine_as_imports = true
force_grid_wrap = 2
force_sort_within_sections = true
skip_glob = "env"
skip = "pandas/__init__.py"

[tool.pyright]
pythonVersion = "3.8"
typeCheckingMode = "basic"
include = ["pandas", "typings"]
exclude = ["pandas/tests", "pandas/io/clipboard", "pandas/util/version"]
# enable subset of "strict"
reportDuplicateImport = true
reportInvalidStubStatement = true
reportOverlappingOverload = true
reportPropertyTypeMismatch = true
reportUntypedClassDecorator = true
reportUntypedFunctionDecorator = true
reportUntypedNamedTuple = true
reportUnusedImport = true
# disable subset of "basic"
reportGeneralTypeIssues = false
reportMissingModuleSource = false
reportOptionalCall = false
reportOptionalIterable = false
reportOptionalMemberAccess = false
reportOptionalOperand = false
reportOptionalSubscript = false
reportPrivateImportUsage = false
reportUnboundVariable = false

[tool.coverage.run]
branch = true
omit = ["pandas/_typing.py", "pandas/_version.py"]
plugins = ["Cython.Coverage"]
source = ["pandas"]

[tool.coverage.report]
ignore_errors = false
show_missing = true
omit = ["pandas/_version.py"]
exclude_lines = [
  # Have to re-enable the standard pragma
  "pragma: no cover",
  # Don't complain about missing debug-only code:s
  "def __repr__",
  # Don't complain if tests don't hit defensive assertion code:
  "raise AssertionError",
  "raise NotImplementedError",
  "AbstractMethodError",
  # Don't complain if non-runnable code isn't run:
  "if TYPE_CHECKING:",
]

[tool.coverage.html]
directory = "coverage_html_report"

[tool.codespell]
ignore-words-list = "blocs, coo, hist, nd, sav, ser, recuse"
ignore-regex = 'https://([\w/\.])+'
