[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.5.3,<5.0.0", "packaging", "pillow>=9.1.0", "precis-i18n>=1.0.0", "cryptography>=3.4.8", "pycairo>=1.16.0", "PyGObject>=3.42.0", "qrcode>=7.3.1", "omemo-dr>=1.0.0,<2.0.0", "winsdk ; platform_system == 'Windows'", ] dynamic = ["version"] [project.urls] homepage = "https://gajim.org" repository = "https://dev.gajim.org/gajim/gajim" [project.optional-dependencies] dev = [ "ruff>=0.0.286", "codespell[toml]>=2.2.5", "isort>=5.12.0", "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.remote:run" [project.gui-scripts] gajim = "gajim.main:run" [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_root,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", "test/common/test_uri_util.py", "test/dialogs/change_password.py", "test/dialogs/dataform.py", "test/dialogs/groupchat_info.py", "test/gui/test_menus.py", "test/gui/test_nick_completion.py", ] include = [ "launch.py", ".ci/*", "mac/*", "scripts/*", "win/*", "pep517build/*", "gajim/common/application.py", "gajim/common/call_manager.py", "gajim/common/cert_store.py", "gajim/common/client_modules.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/main.py", "gajim/remote.py", "gajim/gtk/*", "gajim/plugins/*", "test/*", ] [tool.ruff] line-length = 80 select = [ "A", # flake8-builtins # "AIR", # Airflow # "ANN", # flake8-annotations # "ARG", # flake8-unused-arguments # "ASYNC", # flake8-async "B", # flake8-bugbear "BLE", # flake8-blind-except "C4", # flake8-comprehensions "C90", # mccabe "COM", # flake8-commas "CPY", # flake8-copyright # "D", # pydocstyle # "DJ", # flake8-django # "DTZ", # flake8-datetimez "E", # Error # "EM", # flake8-errmsg # "ERA", # eradicate "EXE", # flake8-executable "F", # Pyflakes "FA", # flake8-future-annotations # "FBT", # flake8-boolean-trap # "FIX", # flake8-fixme # "FLY", # flynt "G", # flake8-logging-format # "I", # isort "ICN", # flake8-import-conventions # "INP", # flake8-no-pep420 "INT", # flake8-gettext # "ISC", # flake8-implicit-str-concat "N", # pep8-naming # "NPY", # NumPy-specific rules # "PD", # pandas-vet # "PERF", # Perflint "PGH", # pygrep-hooks "PIE", # flake8-pie "PL", # Pylint # "PT", # flake8-pytest-style # "PTH", # flake8-use-pathlib # "PYI", # flake8-pyi "Q", # flake8-quotes # "RET", # flake8-return "RSE", # flake8-raise "RUF", # Ruff-specific rules "S", # flake8-bandit "SIM", # flake8-simplify # "SLF", # flake8-self "SLOT", # flake8-slots "T10", # flake8-debugger # "T20", # flake8-print # "TCH", # flake8-type-checking # "TD", # flake8-todos # "TID", # flake8-tidy-imports # "TRY", # tryceratops "UP", # pyupgrade "W", # Warning "YTT", # flake8-2020 ] ignore = [ "A003", # Class attribute is shadowing python builtin "B904", # Within an except clause .. "BLE001", # Blind except Exception: statement "C901", # too complex "COM812", # Trailing comma missing "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 "PGH003", # Use specific rule codes when ignoring type issues "PLC1901",# Expression can be simplified to x as an empty string is falsey "PLR0911",# Too many return statements "PLR0912",# Too many branches "PLR0913",# Too many arguments to function call "PLR0915",# Too many statements "PLR2004",# Magic value used in comparison, consider replacing x with a constant variable "PLR5501",# Consider using `elif` instead of `else` then `if` to remove one indentation level "PLW0603",# Using the global statement to update `x` is discouraged "PLW2901",# `for` loop variable `x` overwritten by assignment target "RUF001", # AmbiguousUnicodeCharacterString "RUF002", # AmbiguousUnicodeCharacterDocstring "RUF003", # AmbiguousUnicodeCharacterComment "RUF005", # Consider x instead of concatenation "RUF012", # Mutable class attributes should be annotated with `typing.ClassVar` "RUF100", # Unused `noqa` directive "S101", # Use of `assert` detected "S110", # `try`-`except`-`pass` detected, consider logging the exception "S301", # `pickle` and modules that wrap it can be unsafe when used to deserialize untrusted data, possible security issue "S303", # Use of insecure MD2, MD4, MD5, or SHA1 hash function "S310", # Audit URL open for permitted schemes "S311", # Standard pseudo-random generators are not suitable for cryptographic purposes "S314", # Using `xml` to parse untrusted data is known to be vulnerable to XML attacks; use `defusedxml` equivalents "S324", # Probable use of insecure hash functions "S608", # Possible SQL injection vector through string-based query construction "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 "SIM114", # Combine `if` branches using logical `or` 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 "UP037", # Remove quotes from type annotation ] 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] "gajim/common/iana.py" = ["E501"] "gajim/common/storage/omemo.py" = ["N803"] "test/*" = ["E402"] "test/common/test_styling.py" = ["RUF001", "E501"] "test/common/test_regex.py" = ["RUF001"] "pep517build/*" = ["S603", "S607"] "mac/*" = ["S603", "S607"] "win/*" = ["S603", "S607"] "scripts/*" = ["S603", "S607"] "launch.py" = ["S603", "S607"] [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