content: [build-system]
  requires = ["setuptools >= 69.0"] # v69 includes type information by default
  build-backend = "setuptools.build_meta"
  
  [project]
  name = "microsoft-python-type-stubs"
  version = "0"
  
  [dependency-groups]
  hygiene = ["ruff ==0.11.*"]
  tests = [
      # Tools used for testing
      "docopt-ng",
      "mypy ==1.16.*",
      "pyright",
  
      # External type stubs and optional dependencies
      "PyOpenGL",
      "matplotlib >=3.8",
      "pandas-stubs",
      "pytest",
      "scipy-stubs",
      "types-networkx",
      "typing_extensions",
  
      # The libraries we're stubbing.
      # Needed for stubtest and downloads their dependencies to get known import symbols
      "scikit-image",
      "scikit-learn <1.7.0", # TODO: Update stubs for sklearn
      "sympy",
      "vispy",
  ]
  dev = [{ include-group = "hygiene" }, { include-group = "tests" }]
  
  
  # Allow these stubs to be installed from GitHub
  # We need an explicit mapping instead of just
  # [tool.setuptools]
  # package-dir = {"" = "stubs"}
  # because the folder names don't all match "*-stubs" 
  # see https://github.com/microsoft/python-type-stubs/issues/315
  [tool.setuptools.package-dir]
  # See README.md as to why matplotlib is not included
  "skimage-stubs" = "stubs/skimage"
  "sklearn-stubs" = "stubs/sklearn"
  "sympy-stubs" = "stubs/sympy-stubs"
  "vispy-stubs" = "stubs/vispy"
  
  [tool.ruff]
  line-length = 130
  # Target oldest supported Python version
  target-version = "py39"
  
  [tool.ruff.lint]
  extend-select = [
      "FA", # flake8-future-annotations
      "I", # isort
      "PGH", # pygrep-hooks
      "PGH", # pygrep-hooks and blanket-noqa
      "PIE790", # unnecessary-placeholder
      "PYI", # flake8-pyi
      "RUF", # Ruff-specific and unused-noqa
      "UP", # pyupgrade
      "W", # pycodestyle Warning
  ]
  ignore = [
      ###
      # Rules we don't want or don't agree with
      ###
  
      # Used for direct, non-subclass type comparison, for example: `type(val) is str`
      # see https://github.com/astral-sh/ruff/issues/6465
      "E721", # Do not compare types, use `isinstance()`
  
      # Typeshed doesn't want complex or non-literal defaults, or long strings, for maintenance and testing reasons.
      # This doesn't affect us, let's have more complete stubs.
      "PYI011",
      "PYI014",
      "PYI053",
  
      # TODO: Investigate and fix or configure
      "PYI051", # Request for autofix: https://github.com/astral-sh/ruff/issues/14185
  ]
  
  [tool.ruff.lint.per-file-ignores]
  "*.pyi" = [
      # Ruff 0.8.0 added sorting of __all__ and __slots_.
      # There is no consensus in typeshed on whether they want to apply this to stubs, so keeping the status quo.
      # See https://github.com/python/typeshed/pull/13108
      "RUF022", # `__all__` is not sorted
      "RUF023", # `{}.__slots__` is not sorted
      ###
      # Rules that are out of the control of stub authors:
      ###
      "E743", # Ambiguous function name; stubs must follow implementation
      "F403", # `from . import *` used; unable to detect undefined names
      # Stubs can sometimes re-export entire modules.
      # Issues with using a star-imported name will be caught by type-checkers.
      "F405", # may be undefined, or defined from star imports
  ]
  
  # We keep docstrings in sklearn
  "stubs/sklearn/**" = ["PYI021"]
  
  # TODO: For public modules, manually evaluate each violation.
  # Removing unused imports change which symbols are even visible for Pylance.
  # Which may negatively affect users, especially if the symbol wasn't meant to be re-exported.
  # We do assume no public re-exports were meant from private modules
  "!_*.pyi" = ["F401"]
  "__init__.pyi" = ["F401"]
  
  [tool.ruff.lint.isort]
  combine-as-imports = true
  extra-standard-library = [
      # Group these with stdlib
      "typing_extensions",
      "_typeshed",
  ]
  
  [tool.pyright]
  exclude = ["build", ".git", ".venv*"]
  stubPath = "./stubs"
  pythonversion = "3.9" # Target oldest supported Python version
  typeCheckingMode = "standard"
  # Partial stubs are acceptable
  reportUnknownArgumentType = false
  # Stubs-only packages are fine for testing
  reportMissingModuleSource = false
  # Stubs are allowed to use private variables
  reportPrivateUsage = false
  reportPrivateImportUsage = false
  # Incompatible overrides and property type mismatches are out of our stubs' control
  # as they are inherited from the implementation.
  reportIncompatibleMethodOverride = false
  reportIncompatibleVariableOverride = false
  reportPropertyTypeMismatch = false
  # Overlapping overloads are often necessary in a stub, meaning pyright's check
  # (which is stricter than mypy's; see mypy issue #10143 and #10157)
  # would cause many false positives and catch few bugs.
  reportOverlappingOverload = false
  # The name of the self/cls parameter is out of third-party stubs' control.
  reportSelfClsParameterName = false
  # Not an error by default in standard mode
  reportUnsupportedDunderAll = "error"
  
  [tool.mypy]
  strict = true
  check_untyped_defs = true # Strict check on all defs
  show_column_numbers = true
  # Not all imports in these stubs are gonna be typed
  # Don't infer symbols from untyped packages as Any
  follow_untyped_imports = true
  warn_unused_ignores = false # Change from pandas
  # Partial stubs are acceptable
  disallow_any_generics = false
  disallow_incomplete_defs = false
  disallow_untyped_defs = false
  # Suppressing errors
  disable_error_code = [
      # mypy's overload implementation differs from pyright
      # `assert-type` issues is tests mostly comme from checking overloads
      # Since this project is specific to Pylance, just ignore them
      "assert-type",
      # Incompatible overrides are out of our stubs' control
      # as they are inherited from the implementation.
      "override",
      # TODO
      "assignment", # 744 errors in 155 files
  ]
  
  [[tool.mypy.overrides]]
  # follow_untyped_imports = true will cause stubtest to run mypy on the source
  # So disable it for partial stubs
  module = ["sympy.*"]
  follow_untyped_imports = false
  disable_error_code = ["import-untyped", "misc"]
  
  [[tool.mypy.overrides]]
  # These modules are to be removed soon, not worth solving many issues
  module = ["matplotlib.*", "networkx.*"]
  disable_error_code = [
      "assignment",
      "misc",
  ]
  [[tool.mypy.overrides]]
  module = ["skimage.*", "sklearn.*"]
  # TODO: Too many untyped decorators still left
  # https://github.com/python/mypy/issues/19148
  disable_error_code = ["misc"]
  