[project]
name = "codeflash"
dynamic = ["version"]
description = "Client for codeflash.ai - automatic code performance optimization, powered by AI"
authors = [{ name = "CodeFlash Inc.", email = "contact@codeflash.ai" }]
requires-python = ">=3.9"
readme = "README.md"
license-files = ["LICENSE"]
keywords = [
    "codeflash",
    "performance",
    "optimization",
    "ai",
    "code",
    "machine learning",
    "LLM",
]
dependencies = [
    "unidiff>=0.7.5",
    "pytest>=8.4.2",
    "gitpython>=3.1.47",
    "libcst>=1.8.6",
    "jedi>=0.19.2",
    # Tree-sitter for multi-language support
    "tree-sitter>=0.23.2",
    "tree-sitter-javascript>=0.23.1",
    "tree-sitter-typescript>=0.23.2",
    "tree-sitter-java>=0.23.5",
    "tree-sitter-groovy>=0.1.2",
    "tree-sitter-kotlin>=1.1.0",
    "pytest-timeout>=2.4.0",
    "tomlkit>=0.14.0",
    "attrs>=26.1.0",
    "requests>=2.32.5",
    "junitparser>=4.0.2",
    "pydantic>=2.13.3",
    "humanize>=4.13.0",
    "posthog>=6.9.3",
    "click>=8.1.8",
    "inquirer>=3.4.0",
    "sentry-sdk>=2.58.0,<3.0.0",
    "parameterized>=0.9.0",
    "isort>=6.1.0",
    "dill>=0.4.1",
    "rich>=15.0.0",
    "lxml>=6.1.0",
    "crosshair-tool>=0.0.103; python_version < '3.15'",
    "coverage>=7.10.7",
    "line_profiler>=5.0.2",
    "platformdirs>=4.4.0",
    "pygls>=2.1.1,<3.0.0",
    "codeflash-benchmark",
    "filelock>=3.19.1; python_version >= '3.10'",
    "filelock<3.20.3; python_version < '3.10'",
    "pytest-asyncio>=1.2.0",
    "memray>=1.19.3; sys_platform != 'win32'",
    "pytest-memray>=1.8.0; sys_platform != 'win32'",
]

[project.urls]
Homepage = "https://codeflash.ai"

[project.scripts]
codeflash = "codeflash.main:main"

[project.optional-dependencies]

[dependency-groups]
dev = [
    "ipython>=8.12.0",
    "mypy>=1.19.1",
    "ruff>=0.15.11",
    "lxml-stubs>=0.5.1",
    "pandas-stubs>=2.2.2.240807, <2.2.3.241009",
    "types-Pygments>=2.19.0.20251121",
    "types-colorama>=0.4.15.20250801",
    "types-decorator>=5.2.0.20251101",
    "types-jsonschema>=4.26.0.20260202",
    "types-requests>=2.32.4.20260107",
    "types-six>=1.17.0.20251009",
    "types-cffi>=1.17.0.20250915",
    "types-openpyxl>=3.1.5.20250919",
    "types-regex>=2026.1.15.20260116",
    "types-python-dateutil>=2.9.0.20260124",
    "types-gevent>=25.9.0.20251228",
    "types-greenlet>=3.3.0.20251206",
    "types-pexpect>=4.9.0.20260127",
    "types-unidiff>=0.7.0.20240505",
    "prek>=0.3.10",
    "ty>=0.0.32",
    "uv>=0.11.7",
    "pytest-cov>=7.1.0",
]
tests = [
    "black>=25.11.0",
    "jax>=0.4.30",
    "numpy>=2.0.2",
    "pandas>=2.3.3",
    "pyarrow>=21.0.0",
    "pyrsistent>=0.20.0",
    "scipy>=1.13.1",
    "torch>=2.8.0",
    "xarray>=2024.7.0",
    "eval_type_backport>=0.3.1",
    "numba>=0.60.0",
    "tensorflow>=2.20.0; python_version >= '3.10'",
]

[tool.hatch.build.targets.sdist]
include = ["codeflash"]
exclude = [
    "docs/*",
    "experiments/*",
    "tests/*",
    "*.pyc",
    "__pycache__",
    "*.pyo",
    "*.pyd",
    "*.so",
    "*.dylib",
    "*.dll",
    "*.exe",
    "*.log",
    "*.tmp",
    ".env",
    ".env.*",
    "**/.env",
    "**/.env.*",
    ".env.example",
    "*.pem",
    "*.key",
    "secrets.*",
    "config.yaml",
    "config.json",
    ".git",
    ".gitignore",
    ".gitattributes",
    ".github",
    "Dockerfile",
    "docker-compose.yml",
    "*.md",
    "*.txt",
    "*.csv",
    "*.db",
    "*.sqlite3",
    "*.pdf",
    "*.docx",
    "*.xlsx",
    "*.pptx",
    "*.iml",
    ".idea",
    ".vscode",
    ".DS_Store",
    "Thumbs.db",
    "venv",
    "env",
]

[tool.hatch.build.targets.wheel]
exclude = [
    "docs/*",
    "experiments/*",
    "tests/*",
    "*.pyc",
    "__pycache__",
    "*.pyo",
    "*.pyd",
    "*.so",
    "*.dylib",
    "*.dll",
    "*.exe",
    "*.log",
    "*.tmp",
    ".env",
    ".env.*",
    "**/.env",
    "**/.env.*",
    ".env.example",
    "*.pem",
    "*.key",
    "secrets.*",
    "config.yaml",
    "config.json",
    ".git",
    ".gitignore",
    ".gitattributes",
    ".github",
    "Dockerfile",
    "docker-compose.yml",
    "*.md",
    "*.txt",
    "*.csv",
    "*.db",
    "*.sqlite3",
    "*.pdf",
    "*.docx",
    "*.xlsx",
    "*.pptx",
    "*.iml",
    ".idea",
    ".vscode",
    ".DS_Store",
    "Thumbs.db",
    "venv",
    "env",
    "codeflash/languages/java/resources/codeflash-runtime-*.jar",
]

[tool.mypy]
show_error_code_links = true
pretty = true
show_absolute_path = true
show_error_context = true
show_error_end = true
strict = true
warn_unreachable = true
install_types = true
plugins = ["pydantic.mypy"]

exclude = ["tests/", "code_to_optimize/", "pie_test_set/", "experiments/"]

[[tool.mypy.overrides]]
module = ["jedi", "jedi.api.classes", "inquirer", "inquirer.themes", "numba"]
ignore_missing_imports = true

[tool.pydantic-mypy]
init_forbid_extra = true
init_typed = true
warn_required_dynamic_aliases = true

[tool.ruff]
target-version = "py39"
line-length = 120
fix = true
show-fixes = true
extend-exclude = ["code_to_optimize/", "pie_test_set/", "tests/", "experiments/"]

[tool.ruff.lint]
select = ["ALL"]
ignore = [
    "N802",
    "C901",
    "D100",
    "D101",
    "D102",
    "D103",
    "D105",
    "D107",
    "D203",  # incorrect-blank-line-before-class (incompatible with D211)
    "D213",  # multi-line-summary-second-line (incompatible with D212)
    "S101",
    "S603",
    "S607",
    "COM812",
    "FIX002",
    "PLR0912",
    "PLR0913",
    "PLR0915",
    "TD002",
    "TD003",
    "TD004",
    "PLR2004",
    "UP007", # remove once we drop 3.9 support.
    "E501",
    "BLE001",
    "ERA001",
    "TRY003",
    "EM101",
    "T201",
    "PGH004",
    "S301",
    "D104",
    "PERF203",
    "LOG015",
    "PLC0415",
    "UP045",
    "TD007",
    "D417",
    "D401",
    "S110",    # try-except-pass - we do this a lot
    "ARG002",  # Unused method argument
    # Added for multi-language branch
    "FBT001",  # Boolean positional argument
    "FBT002",  # Boolean default positional argument
    "ANN401",  # typing.Any disallowed
    "ARG001",  # Unused function argument (common in abstract/interface methods)
    "TRY300",  # Consider moving to else block
    "FURB110", # if-exp-instead-of-or-operator - we prefer explicit if-else over "or"
    "TRY401",  # Redundant exception in logging.exception
    "PLR0911", # Too many return statements
    "PLW0603", # Global statement
    "PLW2901", # Loop variable overwritten
    "SIM102",  # Nested if statements
    "SIM103",  # Return negated condition
    "ANN001",  # Missing type annotation
    "PLC0206", # Dictionary items
    "S314",    # XML parsing (acceptable for dev tool)
    "S608",    # SQL injection (internal use only)
    "S112",    # try-except-continue
    "PERF401", # List comprehension suggestion
    "SIM108",  # Ternary operator suggestion
    "F841",    # Unused variable (often intentional)
    "ANN202",  # Missing return type for private functions
    "B009",    # getattr-with-constant - needed to avoid mypy [misc] on dunder access
    "PTH119",  # os.path.basename — faster than Path().name for string paths
]

[tool.ruff.lint.flake8-type-checking]
strict = true
runtime-evaluated-base-classes = ["pydantic.BaseModel"]
runtime-evaluated-decorators = ["pydantic.validate_call", "pydantic.dataclasses.dataclass"]

[tool.ruff.lint.pep8-naming]
classmethod-decorators = [
    # Allow Pydantic's `@validator` decorator to trigger class method treatment.
    "pydantic.validator",
]

[tool.ruff.lint.isort]
split-on-trailing-comma = false

[tool.ruff.format]
docstring-code-format = true
skip-magic-trailing-comma = true

[tool.ty.src]
exclude = ["tests", "code_to_optimize", "pie_test_set", "experiments"]

[tool.hatch.version]
source = "uv-dynamic-versioning"

[tool.uv]
workspace = { members = ["codeflash-benchmark"] }

[tool.uv.sources]
codeflash-benchmark = { workspace = true }

[tool.uv-dynamic-versioning]
enable = true
style = "pep440"
vcs = "git"

[tool.hatch.build.hooks.version]
path = "codeflash/version.py"
template = """# These version placeholders will be replaced by uv-dynamic-versioning during build.
__version__ = "{version}"
"""


#[tool.hatch.build.hooks.custom]
#path = "codeflash/update_license_version.py"


[tool.codeflash]
# All paths are relative to this pyproject.toml's directory.
module-root = "codeflash"
tests-root = "tests"
benchmarks-root = ".codeflash/benchmarks"
ignore-paths = []
formatter-cmds = [
    "uvx ruff check --exit-zero --fix $file",
    "uvx ruff format $file",
]

[tool.pytest.ini_options]
filterwarnings = [
    "ignore::pytest.PytestCollectionWarning",
]
markers = [
    "ci_skip: mark test to skip in CI environment",
]


[build-system]
requires = ["hatchling", "uv-dynamic-versioning"]
build-backend = "hatchling.build"

