[tool.poetry]
name = "abilian-sbe-next"
version = "1.0.4"
description = ""
authors = ["Abilian SAS <contact@abilian.com>"]

packages = [
  { include = "extranet", from = "src" },
  { include = "abilian", from = "src" },
]


[tool.poetry.dependencies]
# Doesn't work currently w/ Python 3.12
python = "^3.9,<3.12"

# Flask (and dependencies), pinned because it's hard to upgrade
Flask = "~2.1"
jinja2 = "~3.0"
# Pinned because wtforms is pinned too.
werkzeug = "~2.0"
# requirement of jinja2; > 0.21 has an important fix for string format. See
# https://github.com/mitsuhiko/markupsafe/issues/28
MarkupSafe = ">=2.1.1"

# Flask plugins (somme are pinned)
flask-babel = "~1.0.0"
flask-assets = ">=0.12"
flask-mail = ">=0.9.1"
flask-migrate = ">=3.1.0"
flask-login = ">=0.6.2"
flask-talisman = ">=1.0.0"

# TODO: replace by flask-vite which is maintained
flask-tailwind = "^0.2.2"

# Transitive dependencies, but called explicitly in our code
Babel = "*"
blinker = "*"
click = "*"
itsdangerous = "*"
numpy = "^1.26.0"
pytest = "*"
pytz = "*"
requests = "*"

# Databases / persistence
# We're not ready for SQLAlchemy 1.4 yet (due to sqlalchemy_utils).
sqlalchemy = "~1.3.24"
# flask-sqlachemy 2.2 breaks our apps.
flask-sqlalchemy = "~2.1"
# flask-sqlalchemy = {git = "https://github.com/pallets/flask-sqlalchemy.git", rev = "f4662ad464a73befa47cf74754fdbfe156570e59"}
psycopg2 = "^2.9.9"

# Currently broken w/ 0.13
Flask-WTF = ">=0.12,<0.13"
wtforms = "<2.2"
WTForms-Alchemy = ">=0.17.0"
wtforms-sqlalchemy = "*"

# Currently broken w/ 2.0
webassets = "< 2"

# can parse isoformat / used in a jinja filter
python-dateutil = "^2.8.2"

# Indexing
Whoosh = "^2.7.4"

# Task queue
celery = "~5.2.7"
redis = "~3.5.3"

# Security
bleach = { version = "^5.0.1", extras = [ "css" ] }
bcrypt = "*"

# low-level tools
deprecated = "*"
hyperlink = "*"

# Used by DeferredJS (TODO: remove)
lxml = "*"

# Used by the logging config loader (TODO: remove)
PyYAML = "*"

# Configuration
toml = "*"

# Used by the connection audit
pygeoip = "*"

# Progres bar, used by some scripts
tqdm = "*"

# Used by the Sentry extension
sentry-sdk = { version="*", extras=["flask"] }

# for debug toolbar

# antivirus interface
clamd = "*"

# Content detection / transformation
python-magic = "*"
pillow = "*"

# Reporting
pandas = ">=1.5.0"

#
# Assets management (might not be necessary if distributing compiled assets)
#
jsmin = "*"
cssmin = "*"
closure = "==20161201"

# Email validation (when sending digests)
validate_email = "*"

# Language and charset detection
langid = ">=1.1.6"
chardet = "*"

# Markdown support for Wiki
markdown = "^3"

# needed by folder: export to xls
xlwt = "*"
openpyxl = "*"

# Better FP library than itertools IMHO.
toolz = "*"

html2text = "^2020.1.16"


# Production
gunicorn = "*"
# raven = "*"

# Debug tools
icecream = "*"
devtools = "*"

# Additional stuff
python-dotenv = "^1.0.0"
#flask-env = "*"
importlib-resources = "^5.10.0"
defusedxml = "^0.7.1"


[tool.poetry.group.dev.dependencies]
# Generic dev deps
abilian-devtools = "*"
# Pinned because bug in 0.991
mypy = "^1.5.1"

# Testing
pytest-flask = "*"
# pytest-testmon = "^1.2.0"
Flask-LinkTester = "*"
Flask-DebugToolbar = "*"
# used by the DTB
sqlparse = "^0.4.4"

# Deploy
plumbum = "*"
watchgod = "*"
honcho = "*"

# Added later...
html5lib = "*"

# Typing
types-bleach = "*"
types-deprecated = "*"
types-python-dateutil = "*"
types-pytz = "*"
types-pyyaml = "*"
types-redis = "*"
types-requests = "*"
types-setuptools = "*"
types-chardet = "*"
types-Markdown = "*"

# Keep for now
pyanalyze = "*"

# Tools
sqla2uml = "*"
pyupgrade = "*"
pytest = "^7.2.2"
tox = "^4.5.1"
git-cliff = "^1.3.1"
deptry = "^0.12.0"
fawltydeps = "^0.13.2"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

# -----------------------------------------------------------------------------

[tool.pytest.ini_options]
minversion = "6.0"
filterwarnings = [
    'ignore::DeprecationWarning',
    'ignore::sqlalchemy.exc.SAWarning'
]
# addopts = "-ra -q"
testpaths = [
    "src",
    "tests",
]
python_files = [
    "test_*.py",
    "tests.py",
    "test.py",
    "*_tests.py",
]
# norecursedirs = .* env* _build *.egg *.egg-info tools deploy etc docs demo bin

# -----------------------------------------------------------------------------

[tool.ruff]
extend-select = [
    "F",
    "E",
    "I",
    "UP",
    "YTT",
    "B",
    "C4",
    "ICN",
    "Q",
    "S",
    "RUF",
    # "PLC", "PLE", "PLR", "PLW",
    # Ignore for now
    # "A",
    # "BLE",
    # "C90",
    # "RET",
    # "TID",
    # "N",
    # "SIM",
]
extend-ignore = [
    # False positive
    "E711",  # comparison to None should be 'if cond is not None:'
    "E712",  # ...
    "E713",  # Test for membership should be `not in`
    "S320",  # OK, we're using defusedxml
    # Fix these
    "A003",  # Class attribute ... is shadowing a python builtin
    "B024",  # `...` is an abstract base class, but it has no abstract methods
    "B027",  # `...` is an empty method in an abstract base class, but has no abstract decorator
    "B028",  # No explicit `stacklevel` keyword argument found
    "B905",  # `zip()` without an explicit `strict=` parameter
    "E402",  # Module level import not at top of file
    "E501",  # line too long
    "E741",  # Ambiguous variable name
    "F401",  # 'module' imported but unused
    "F841",  # Local variable `...` is assigned to but never used
    "I001",  # Import block is un-sorted or un-formatted
    "PLR2004",  # Magic value used
    "S101",  # use of assert
    "S104",  # Possible binding to all interfaces
    "S301",
    "S603",
    "S605",
    "S606",
    "S607",
    "S701", # By default, jinja2 sets `autoescape` to `False`
    "UP038",  # Use `X | Y` in `isinstance` call instead of `(X, Y)`
#    "S110", # `try`-`except`-`pass` detected, consider logging the exception
    "RUF005",
    "RUF012",
]

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

# -----------------------------------------------------------------------------

[tool.deptry.per_rule_ignores]
# X defined as a dependency but not used in the codebase
DEP002 = [
    # Used (implicitly) by Flask-Migrate
    'alembic',
    # Used by webassets
    'jsmin',
    'cssmin',
    'closure',
    # Used implicitly by SQLA
    'psycopg2',
    # Web
    'gunicorn',
    # Debug
    'icecream',
    # Misc
    'importlib-resources',
]

# X imported but missing from the dependency definitions
DEP001 = [
    'pkg_resources',
]

# X imported but declared as a dev dependency
DEP004 = [
    'flask_debugtoolbar',
    'html5lib',
]

# -----------------------------------------------------------------------------

[tool.pyright]
exclude = [
    '.nox',
    'tests',
    'noxfile.py',
]
include = ["src"]
# strict = ["src"]

# False positives
reportPrivateImportUsage = false

# -----------------------------------------------------------------------------

[tool.mypy]
python_version = "3.10"

ignore_missing_imports = true
#warn_redundant_casts = true
#warn_no_return = true
#warn_return_any = true
#strict_optional = true
#warn_unused_ignores = true

# exclude = [
#     '^file1\.py$',  # TOML literal string (single-quotes, no escaping necessary)
#     "^file2\\.py$",  # TOML basic string (double-quotes, backslash and other characters need escaping)
# ]

# -----------------------------------------------------------------------------

[tool.pyanalyze]
paths = ["src/"]
import_paths = ["."]

# Enable or disable some checks
add_import = true
already_declared = true
bad_async_yield = true
bad_evaluator = true
bad_except_handler = true
bad_exception = true
bad_format_string = true
bad_global = true
bad_match = true
bad_nonlocal = true

attribute_is_never_set = false

bad_star_import = true
bad_super_call = true
bad_unpack = false
bad_yield_from = false
bare_ignore = false
cant_import = false
class_variable_redefinition = false
condition_always_true = false
duplicate_dict_key = false
duplicate_enum_member = false
duplicate_yield = false
implicit_any = false
implicit_non_ascii_string = false
implicit_reexport = false
import_failed = false
impossible_pattern = false
impure_async_call = false
incompatible_argument = false
incompatible_assignment = false
incompatible_call = false
incompatible_default = false
incompatible_override = false
incompatible_return_value = false
incompatible_yield = false
inference_failure = false
internal_error = false
invalid_annotated_assignment = false
invalid_annotation = false
invalid_context_manager = false
invalid_method_return_type = false
invalid_typeddict_key = false
method_first_arg = false
missing_asynq = false
missing_await = false
missing_f = false
missing_parameter_annotation = false
missing_return = false
missing_return_annotation = false
mixing_bytes_and_text = false
no_return_may_return = false
non_boolean_in_boolean_context = false
not_callable = false
possibly_undefined_name = false
suggested_parameter_type = false
suggested_return_type = false
task_needs_yield = false
type_always_true = false
type_does_not_support_bool = false
undefined_attribute = false
undefined_name = false
unexpected_node = false
unhashable_key = false
unnecessary_yield = false
unsupported_operation = false
unused_assignment = false
unused_ignore = false
unused_variable = false
use_floor_div = false
use_fstrings = false
value_always_true = false
yield_in_comprehension = false
yield_without_value = false

# -----------------------------------------------------------------------------

[tool.bandit]
# nothing
