[build-system]
requires = [
  "setuptools >= 65.0.0",
]
build-backend = "backend"
backend-path = ["pep517build"]

[project]
name = "gajim"
description = "A GTK XMPP Client"
readme = "README.md"
requires-python = ">=3.10"
license = {text = "GPL-3.0-or-later"}
authors = [
    {name = "Philipp Hörist", email = "philipp@hoerist.com"},
    {name = "Yann Leboulanger", email = "yann@leboulanger.org"},
]
keywords = ["chat", "messaging", "im", "xmpp", "voip"]
classifiers = [
  "Development Status :: 5 - Production/Stable",
  "Environment :: X11 Applications :: GTK",
  "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
  "Operating System :: OS Independent",
  "Programming Language :: Python :: 3.10",
  "Topic :: Communications :: Chat",
]
dependencies = [
  "css-parser",
  "keyring",
  "nbxmpp>=4.2.0,<5.0.0",
  "packaging",
  "pillow",
  "precis-i18n>=1.0.0",
  "cryptography>=3.4.8",
  "pycairo>=1.16.0",
  "PyGObject>=3.42.0",
]
dynamic = ["version"]

[project.urls]
homepage = "https://gajim.org"
repository = "https://dev.gajim.org/gajim/gajim"

[project.optional-dependencies]
dev = [
  "ruff",
  "codespell[toml]",
  "nbxmpp @ git+https://dev.gajim.org/gajim/python-nbxmpp.git",
  "PyGObject-stubs @ git+https://github.com/pygobject/pygobject-stubs.git",
  "python-gitlab",
  "sentry-sdk",
]

[project.scripts]
gajim-remote = "gajim.gajim_remote:main"

[project.gui-scripts]
gajim = "gajim.gajim:main"

[tool.setuptools.packages.find]
include = ["gajim*"]

[tool.setuptools.package-data]
gajim = ["py.typed"]
"gajim.data" = ["**/*"]

[tool.setuptools.dynamic]
version = {attr = "gajim.__version__"}

[tool.codespell]
skip = "*__pycache__*,build,dist,test,*.egg-info,.git,*.po,*.nsi,*.spec"
ignore-words-list = "claus,pres,ser,trough"

[tool.pyright]
pythonVersion = "3.10"
pythonPlatform = "All"
typeCheckingMode = "strict"

reportUnnecessaryTypeIgnoreComment = "error"
reportPropertyTypeMismatch = "error"
reportMissingModuleSource = "none"

exclude = [
  "**/__pycache__",
  ".git",
  "gajim/gtk/account_wizard.py",
  "gajim/gtk/add_contact.py",
  "gajim/gtk/adhoc.py",
  "gajim/gtk/advanced_config.py",
  "gajim/gtk/component_search.py",
  "gajim/gtk/dataform.py",
  "gajim/gtk/discovery.py",
  "gajim/gtk/filetransfer.py",
  "gajim/gtk/vcard_grid.py",
  "gajim/gtk/types.py",
  "gajim/gtk/start_chat.py",
  "gajim/gtk/settings.py",
  "gajim/gtk/server_info.py",
  "gajim/gtk/groupchat_info.py",
  "gajim/plugins/pluginmanager.py",
  "scripts/update_flatpak_manifest.py",
]
include = [
    "launch.py",
    "setup.py",
    ".ci/*",
    "mac/*",
    "scripts/*",
    "win/*",
    "pep517build/*",
    "gajim/common/application.py",
    "gajim/common/call_manager.py",
    "gajim/common/cert_store.py",
    "gajim/common/commands.py",
    "gajim/common/configpaths.py",
    "gajim/common/const.py",
    "gajim/common/dbus/*",
    "gajim/common/events.py",
    "gajim/common/exceptions.py",
    "gajim/common/filetransfer.py",
    "gajim/common/ged.py",
    "gajim/common/i18n.py",
    "gajim/common/idle.py",
    "gajim/common/logging_helpers.py",
    "gajim/common/modules/chat_markers.py",
    "gajim/common/modules/pep.py",
    "gajim/common/modules/register.py",
    "gajim/common/modules/vcard4.py",
    "gajim/common/modules/vcard_temp.py",
    "gajim/common/passwords.py",
    "gajim/common/preview_helpers.py",
    "gajim/common/regex.py",
    "gajim/common/setting_values.py",
    "gajim/common/sound.py",
    "gajim/common/storage/*",
    "gajim/common/styling.py",
    "gajim/common/task_manager.py",
    "gajim/common/util/*",
    "gajim/gajim.py",
    "gajim/gajim_remote.py",
    "gajim/gtk/*",
    "gajim/plugins/*",
]

[tool.ruff]
line-length = 80

select = [
  "A",      # flake8-builtins
  # "ANN",  # flake8-annotations
  # "ARG",    # flake8-unused-arguments
  "B",      # flake8-bugbear
  "BLE",    # flake8-blind-except
  "C",      # flake8-comprehensions
  "C901",   # mccabe
  # "D",    # pydocstyle
  "E",      # pycodestyle
  # "EM",     # flake8-errmsg
  # "ERA",    # eradicate
  "F",      # pyflakes  
  # "FBT",    # flake8-boolean-trap
  # "I",    # flake8-tidy-imports, isort
  "ICN",    # flake8-import-conventions
  "N",      # pep8-naming
  # "PDV",    # pandas-vet
  "PGH",    # pygrep-hooks
  "PLC",    # pylint
  "PLE",    # pylint
  "PLR",    # pylint
  "PLW",    # pylint
  "Q",      # flake8-quotes
  "RUF",    # Ruff-specific rules
  # "RET",    # flake8-return
  "S",      # flake8-bandit
  "SIM",    # flake8-simplify
  # "T",      # flake8-debugger, flake8-print
  # "TID",    # flake8-tidy-imports
  "UP",     # pyupgrade
  "W",      # pycodestyle
  "YTT",    # flake8-2020
]

ignore = [
  "A003",   # Class attribute is shadowing python builtin
  "B904",   # Within an except clause ..
  "BLE001", # Blind except Exception: statement
  "C901",   # too complex
  "FBT003", # Boolean positional value in function call
  "N802",   # Function name should be lower case
  "N806",   # Variable should be lower case
  "N817",   # CamelCase imported as acronym
  "N818",   # Exception name should be named with an Error suffix
  "PLR2004",# Magic value used in comparison, consider replacing x with a constant variable
  "RUF001", # AmbiguousUnicodeCharacterString
  "RUF002", # AmbiguousUnicodeCharacterDocstring
  "RUF003", # AmbiguousUnicodeCharacterComment
  "RUF005", # Consider x instead of concatenation
  "RUF100", # Unused `noqa` directive
  "S101",   # Use of `assert` detected
  "S110",   # `try`-`except`-`pass` detected, consider logging the exception
  "S324",   # Probable use of insecure hash functions
  "SIM102", # Use a single `if` statement instead of nested `if` statements
  "SIM105", # Use `contextlib.suppress(Exception)` instead of try-except-pass
  "SIM108", # Use ternary operator
  "SIM115", # Use context handler for opening files
  "SIM201", # Use x instead of not x
  "SIM212", # Use `value if value else ''` instead of `'' if not value else value`
  "SIM300", # Yoda conditions are discouraged use x instead
  "UP007",  # Use X | Y for type annotations
  "UP030",  # Use implicit references for positional format fields
  "UP031",  # Use format specifiers instead of percent format
  "UP032",  # Use f-string instead of `format` call
  "UP034",  # Avoid extraneous parentheses
]

exclude = [
  ".eggs",
  ".git",
  ".ruff_cache",
  ".venv",
  "build",
  "dist",
  "venv",
  "*.pyi",
  # Code Folders
  "typings",
  "gajim/common/config.py",     # legacy module, will be removed
  "gajim/common/optparser.py",  # legacy module, will be removed
  "gajim/common/socks5.py",     # legacy module, will be removed
]

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
target-version = "py310"

[tool.ruff.per-file-ignores]
"test/*" = ["E402"]
"test/common/test_styling.py" = ["RUF001", "E501"]
"test/common/test_regex.py" = ["RUF001"]

[tool.ruff.mccabe]
max-complexity = 15

[tool.ruff.flake8-quotes]
inline-quotes = "single"
docstring-quotes = "single"
multiline-quotes = "single"

[tool.isort]
force_alphabetical_sort_within_sections = true
force_single_line = true
group_by_package = true
known_typing = ["typing"]
known_gtk = ["gajim.gtk"]
sections = [
  "FUTURE",
  "TYPING",
  "STDLIB",
  "THIRDPARTY",
  "FIRSTPARTY",
  "GTK",
  "LOCALFOLDER"
]
skip_gitignore = true
