diff --git a/.bandit.yaml b/.bandit.yaml deleted file mode 100644 index 6db076a13..000000000 --- a/.bandit.yaml +++ /dev/null @@ -1,3 +0,0 @@ -skips: - - B101 # Use of assert detected. - - B113 # Requests call without timeout. Done internally diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4258dba25..c4e8d478e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -61,39 +61,24 @@ repos: rev: v0.1.8 hooks: - id: ripsecrets - - repo: https://github.com/PyCQA/autoflake - rev: v2.3.1 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.8.1 hooks: - - id: autoflake - - repo: https://github.com/asottile/pyupgrade - rev: v3.19.0 - hooks: - - id: pyupgrade - args: - - --py39-plus - - repo: https://github.com/PyCQA/isort - rev: 5.13.2 - hooks: - - id: isort - # isort issue: https://github.com/PyCQA/isort/issues/1889 + - id: ruff-format args: - - --project=c2cwsgiutils - - repo: https://github.com/psf/black - rev: 24.10.0 - hooks: - - id: black - exclude: .*\.html + - --line-length=110 - repo: https://github.com/PyCQA/prospector rev: v1.13.3 hooks: - id: prospector args: - - --tool=pydocstyle + - --tool=ruff - --die-on-tool-error - --output-format=pylint additional_dependencies: - - prospector-profile-duplicated==1.8.0 # pypi - - prospector-profile-utils==1.12.2 # pypi + - prospector-profile-duplicated==1.8.1 # pypi + - prospector-profile-utils==1.14.0 # pypi + - ruff==0.8.1 # pypi - repo: https://github.com/sbrunner/jsonschema-validator rev: 0.3.2 hooks: diff --git a/.prospector.yaml b/.prospector.yaml index 730e625d3..90e033ec7 100644 --- a/.prospector.yaml +++ b/.prospector.yaml @@ -1,11 +1,11 @@ inherits: - utils:base - utils:no-design-checks + - utils:c2cwsgiutils - utils:fix + - utils:unsafe - duplicated -doc-warnings: true - ignore-paths: - docs - acceptance_tests @@ -16,24 +16,7 @@ pylint: extension-pkg-allow-list: - ujson - lxml - disable: - - no-else-return - - no-else-raise - - missing-module-docstring - - missing-timeout # A default timeout is set - -pydocstyle: - disable: - - D104 # Missing docstring in public package - - D105 # Missing docstring in magic method - - D107 # Missing docstring in __init__ - -pycodestyle: - disable: - # Buggy checks with Python 3.12 - - E221 # multiple spaces before operator - - E702 # multiple statements on one line (semicolon) -bandit: +mypy: options: - config: .bandit.yaml + python_version: '3.10' diff --git a/acceptance_tests/app/poetry.lock b/acceptance_tests/app/poetry.lock index 60bd10199..f88f73b78 100644 --- a/acceptance_tests/app/poetry.lock +++ b/acceptance_tests/app/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "astroid" @@ -415,6 +415,7 @@ pylint-django = ">=2.6.1" pylint-flask = "0.6" PyYAML = "*" requirements-detector = ">=1.3.2" +ruff = {version = "*", optional = true, markers = "extra == \"with-ruff\" or extra == \"with_everything\""} setoptconf-tmp = ">=0.3.1,<0.4.0" toml = ">=0.10.2,<0.11.0" @@ -429,26 +430,29 @@ with-vulture = ["vulture (>=1.5)"] [[package]] name = "prospector-profile-duplicated" -version = "1.6.0" +version = "1.8.1" description = "Profile that can be used to disable the duplicated or conflict rules between Prospector and other tools" optional = false python-versions = "*" files = [ - {file = "prospector_profile_duplicated-1.6.0-py2.py3-none-any.whl", hash = "sha256:bf6a6aae0c7de48043b95e4d42e23ccd090c6c7115b6ee8c8ca472ffb1a2022b"}, - {file = "prospector_profile_duplicated-1.6.0.tar.gz", hash = "sha256:9c2d541076537405e8b2484cb6222276a2df17492391b6af1b192695770aab83"}, + {file = "prospector_profile_duplicated-1.8.1-py2.py3-none-any.whl", hash = "sha256:a3c23517b9749ea0e61cc9b23d1526752c1eeb6c899cd0d9ec1fa77b1f373a49"}, + {file = "prospector_profile_duplicated-1.8.1.tar.gz", hash = "sha256:a08fa1f5aa77bdbc908b0c4f66b2bdb306aba10c44c5db51e389cd5cf79bda04"}, ] [[package]] name = "prospector-profile-utils" -version = "1.9.1" +version = "1.14.0" description = "Some utility Prospector profiles." optional = false -python-versions = "*" +python-versions = "<4.0,>=3.9" files = [ - {file = "prospector_profile_utils-1.9.1-py2.py3-none-any.whl", hash = "sha256:b458d8c4d59bdb1547e4630a2c6de4971946c4f0999443db6a9eef6d216b26b8"}, - {file = "prospector_profile_utils-1.9.1.tar.gz", hash = "sha256:008efa6797a85233fd8093dcb9d86f5fa5d89673e431c15cb1496a91c9b2c601"}, + {file = "prospector_profile_utils-1.14.0-py3-none-any.whl", hash = "sha256:15853e984314f90d688052c7dc09c9206779fdfb7f0606f6a4a617d167c6e693"}, + {file = "prospector_profile_utils-1.14.0.tar.gz", hash = "sha256:258bbe70c7411c7c11a7a7fc202c9a021db3d775a3bf45e7e8bd9f96206bcc48"}, ] +[package.dependencies] +prospector = ">=1.13.0" + [[package]] name = "pycodestyle" version = "2.12.1" @@ -689,6 +693,33 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.1 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "ruff" +version = "0.8.1" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"}, + {file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"}, + {file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"}, + {file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"}, + {file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"}, + {file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"}, + {file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"}, +] + [[package]] name = "semver" version = "3.0.2" @@ -827,4 +858,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = ">=3.10,<4.0" -content-hash = "3ed7b730fd40c8d2bf81bc7a7b721ce71aadc3374203e0bbd27aff98c578f9ec" +content-hash = "0d3414b1ec946e131b4625714e893d4b33f6aae6baf9eb6e5eb26cacc783e2d8" diff --git a/acceptance_tests/app/pyproject.toml b/acceptance_tests/app/pyproject.toml index 5a9f8d2ac..99ffc5629 100644 --- a/acceptance_tests/app/pyproject.toml +++ b/acceptance_tests/app/pyproject.toml @@ -40,9 +40,9 @@ coverage = "7.6.8" [tool.poetry.dev-dependencies] # pylint = { version = "2.15.6" } -prospector = { extras = ["with_bandit", "with_mypy"], version = "1.13.3" } -prospector-profile-duplicated = "1.6.0" -prospector-profile-utils = "1.9.1" +prospector = { version = "1.13.3", extras = ["with_bandit", "with_mypy", "with_ruff"] } +prospector-profile-duplicated = "1.8.1" +prospector-profile-utils = "1.14.0" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/c2cwsgiutils/acceptance/__init__.py b/c2cwsgiutils/acceptance/__init__.py index 2a08e32e7..d3f33963f 100644 --- a/c2cwsgiutils/acceptance/__init__.py +++ b/c2cwsgiutils/acceptance/__init__.py @@ -20,6 +20,7 @@ def retry( tries: number of times to try (not retry) before giving up delay: initial delay between retries in seconds backoff: backoff multiplier e.g. value of 2 will double the delay each retry + """ def deco_retry(f: typing.Callable[..., typing.Any]) -> typing.Callable[..., typing.Any]: diff --git a/c2cwsgiutils/acceptance/connection.py b/c2cwsgiutils/acceptance/connection.py index b6938701e..5dce89e93 100644 --- a/c2cwsgiutils/acceptance/connection.py +++ b/c2cwsgiutils/acceptance/connection.py @@ -20,6 +20,7 @@ class Connection: """The connection.""" def __init__(self, base_url: str, origin: str) -> None: + """Initialize the connection.""" self.base_url = base_url if not self.base_url.endswith("/"): self.base_url += "/" @@ -93,10 +94,10 @@ def get_xml( check_response(r, expected_status, cache_expected=cache_expected) self._check_cors(cors, r) r.raw.decode_content = True - doc = etree.parse(r.raw) # nosec + doc = etree.parse(r.raw) # noqa: S320 if schema is not None: with open(schema, encoding="utf-8") as schema_file: - xml_schema = etree.XMLSchema(etree.parse(schema_file)) # nosec + xml_schema = etree.XMLSchema(etree.parse(schema_file)) # noqa: S320 xml_schema.assertValid(doc) return doc diff --git a/c2cwsgiutils/acceptance/image.py b/c2cwsgiutils/acceptance/image.py index 6bb123b5a..529234023 100644 --- a/c2cwsgiutils/acceptance/image.py +++ b/c2cwsgiutils/acceptance/image.py @@ -10,7 +10,7 @@ import skimage.transform # pylint: disable=import-error if TYPE_CHECKING: - from typing import TypeAlias + from typing_extensions import TypeAlias NpNdarrayInt: TypeAlias = np.ndarray[np.uint8, Any] else: @@ -89,6 +89,7 @@ def check_image( level: The minimum similarity level (between 0.0 and 1.0), default to 1.0 generate_expected_image: If `True` generate the expected image instead of checking it use_mask: If `False` don't use the mask event if the file exists + """ assert image_to_check is not None, "Image required" image_file_basename = os.path.splitext(os.path.basename(expected_filename))[0] @@ -122,7 +123,7 @@ def check_image( if np.issubdtype(mask.dtype, np.floating): mask = (mask * 255).astype("uint8") - assert ((0 < mask) & (mask < 255)).sum() == 0, "Mask should be only black and white image" + assert ((mask > 0) & (mask < 255)).sum() == 0, "Mask should be only black and white image" # Convert to boolean mask = mask == 0 @@ -139,7 +140,7 @@ def check_image( return if not os.path.isfile(expected_filename): skimage.io.imsave(expected_filename, image_to_check) - assert False, "Expected image not found: " + expected_filename + raise AssertionError("Expected image not found: " + expected_filename) expected = skimage.io.imread(expected_filename) assert expected is not None, "Wrong image: " + expected_filename expected = normalize_image(expected) @@ -201,6 +202,7 @@ def check_screenshot( level: See `check_image` generate_expected_image: See `check_image` use_mask: See `check_image` + """ if headers is None: headers = {} diff --git a/c2cwsgiutils/acceptance/package-lock.json b/c2cwsgiutils/acceptance/package-lock.json index 934f25724..9ef9f188c 100644 --- a/c2cwsgiutils/acceptance/package-lock.json +++ b/c2cwsgiutils/acceptance/package-lock.json @@ -6,7 +6,7 @@ "": { "dependencies": { "commander": "12.1.0", - "puppeteer": "23.7.1" + "puppeteer": "23.9.0" } }, "node_modules/@babel/code-frame": { @@ -379,9 +379,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1354347", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1354347.tgz", - "integrity": "sha512-BlmkSqV0V84E2WnEnoPnwyix57rQxAM5SKJjf4TbYOCGLAWtz8CDH8RIaGOjPgPCXo2Mce3kxSY497OySidY3Q==", + "version": "0.0.1367902", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz", + "integrity": "sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg==", "license": "BSD-3-Clause" }, "node_modules/emoji-regex": { @@ -868,17 +868,17 @@ } }, "node_modules/puppeteer": { - "version": "23.7.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.7.1.tgz", - "integrity": "sha512-jS6XehagMvxQ12etwY/4EOYZ0Sm8GAsrtGhdQn4AqpJAyHc3RYl7tGd4QYh/MmShDw8sF9FWYQqGidhoXaqokQ==", + "version": "23.9.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.9.0.tgz", + "integrity": "sha512-WfB8jGwFV+qrD9dcJJVvWPFJBU6kxeu2wxJz9WooDGfM3vIiKLgzImEDBxUQnCBK/2cXB3d4dV6gs/LLpgfLDg==", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.4.1", "chromium-bidi": "0.8.0", "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1354347", - "puppeteer-core": "23.7.1", + "devtools-protocol": "0.0.1367902", + "puppeteer-core": "23.9.0", "typed-query-selector": "^2.12.0" }, "bin": { @@ -889,15 +889,15 @@ } }, "node_modules/puppeteer-core": { - "version": "23.7.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.7.1.tgz", - "integrity": "sha512-Om/qCZhd+HLoAr7GltrRAZpS3uOXwHu7tXAoDbNcJADHjG2zeAlDArgyIPXYGG4QB/EQUHk13Q6RklNxGM73Pg==", + "version": "23.9.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.9.0.tgz", + "integrity": "sha512-hLVrav2HYMVdK0YILtfJwtnkBAwNOztUdR4aJ5YKDvgsbtagNr6urUJk9HyjRA9e+PaLI3jzJ0wM7A4jSZ7Qxw==", "license": "Apache-2.0", "dependencies": { "@puppeteer/browsers": "2.4.1", "chromium-bidi": "0.8.0", "debug": "^4.3.7", - "devtools-protocol": "0.0.1354347", + "devtools-protocol": "0.0.1367902", "typed-query-selector": "^2.12.0", "ws": "^8.18.0" }, diff --git a/c2cwsgiutils/acceptance/package.json b/c2cwsgiutils/acceptance/package.json index 25e5e53c6..e1e5bdcff 100644 --- a/c2cwsgiutils/acceptance/package.json +++ b/c2cwsgiutils/acceptance/package.json @@ -1,7 +1,7 @@ { "dependencies": { "commander": "12.1.0", - "puppeteer": "23.7.1" + "puppeteer": "23.9.0" }, "type": "module" } diff --git a/c2cwsgiutils/acceptance/print.py b/c2cwsgiutils/acceptance/print.py index e3b59618a..9ea32898d 100644 --- a/c2cwsgiutils/acceptance/print.py +++ b/c2cwsgiutils/acceptance/print.py @@ -21,6 +21,7 @@ def __init__(self, base_url: str, origin: str) -> None: base_url: The base URL to the print server (including the /print) app: The name of the application to use origin: The origin and referrer to include in the requests + """ super().__init__(base_url=base_url, origin=origin) self.session.headers["Referrer"] = origin diff --git a/c2cwsgiutils/acceptance/utils.py b/c2cwsgiutils/acceptance/utils.py index 60f9b2eff..05af5830e 100644 --- a/c2cwsgiutils/acceptance/utils.py +++ b/c2cwsgiutils/acceptance/utils.py @@ -32,6 +32,7 @@ def retry_timeout(what: Callable[[], Any], timeout: float = _DEFAULT_TIMEOUT, in what: the function to try timeout: the timeout to get a success interval: the interval between try + """ timeout = time.perf_counter() + timeout while True: @@ -46,7 +47,7 @@ def retry_timeout(what: Callable[[], Any], timeout: float = _DEFAULT_TIMEOUT, in error = str(e) _LOG.info(" Failed: %s", e) if time.perf_counter() > timeout: - assert False, "Timeout: " + error + raise AssertionError("Timeout: " + error) time.sleep(interval) diff --git a/c2cwsgiutils/auth.py b/c2cwsgiutils/auth.py index 9e6909d8b..1bc7dafe6 100644 --- a/c2cwsgiutils/auth.py +++ b/c2cwsgiutils/auth.py @@ -12,32 +12,32 @@ from c2cwsgiutils.config_utils import config_bool, env_or_config, env_or_settings _COOKIE_AGE = 7 * 24 * 3600 -SECRET_PROP = "c2c.secret" # nosec # noqa -SECRET_ENV = "C2C_SECRET" # nosec # noqa +SECRET_PROP = "c2c.secret" # noqa: S105 +SECRET_ENV = "C2C_SECRET" # noqa: S105 _GITHUB_REPOSITORY_PROP = "c2c.auth.github.repository" _GITHUB_REPOSITORY_ENV = "C2C_AUTH_GITHUB_REPOSITORY" _GITHUB_ACCESS_TYPE_PROP = "c2c.auth.github.access_type" _GITHUB_ACCESS_TYPE_ENV = "C2C_AUTH_GITHUB_ACCESS_TYPE" GITHUB_AUTH_URL_PROP = "c2c.auth.github.auth_url" GITHUB_AUTH_URL_ENV = "C2C_AUTH_GITHUB_AUTH_URL" -GITHUB_TOKEN_URL_PROP = "c2c.auth.github.token_url" # nosec -GITHUB_TOKEN_URL_ENV = "C2C_AUTH_GITHUB_TOKEN_URL" # nosec +GITHUB_TOKEN_URL_PROP = "c2c.auth.github.token_url" # noqa: S105 +GITHUB_TOKEN_URL_ENV = "C2C_AUTH_GITHUB_TOKEN_URL" # noqa: S105 GITHUB_USER_URL_PROP = "c2c.auth.github.user_url" GITHUB_USER_URL_ENV = "C2C_AUTH_GITHUB_USER_URL" _GITHUB_REPO_URL_PROP = "c2c.auth.github.repo_url" _GITHUB_REPO_URL_ENV = "C2C_AUTH_GITHUB_REPO_URL" GITHUB_CLIENT_ID_PROP = "c2c.auth.github.client_id" GITHUB_CLIENT_ID_ENV = "C2C_AUTH_GITHUB_CLIENT_ID" -GITHUB_CLIENT_SECRET_PROP = "c2c.auth.github.client_secret" # nosec # noqa -GITHUB_CLIENT_SECRET_ENV = "C2C_AUTH_GITHUB_CLIENT_SECRET" # nosec # noqa +GITHUB_CLIENT_SECRET_PROP = "c2c.auth.github.client_secret" # noqa: S105 +GITHUB_CLIENT_SECRET_ENV = "C2C_AUTH_GITHUB_CLIENT_SECRET" # noqa: S105 GITHUB_SCOPE_PROP = "c2c.auth.github.scope" GITHUB_SCOPE_ENV = "C2C_AUTH_GITHUB_SCOPE" # To be able to use private repository GITHUB_SCOPE_DEFAULT = "repo" GITHUB_AUTH_COOKIE_PROP = "c2c.auth.github.auth.cookie" GITHUB_AUTH_COOKIE_ENV = "C2C_AUTH_GITHUB_COOKIE" -GITHUB_AUTH_SECRET_PROP = "c2c.auth.github.auth.secret" # nosec # noqa -GITHUB_AUTH_SECRET_ENV = "C2C_AUTH_GITHUB_SECRET" # nosec # noqa +GITHUB_AUTH_SECRET_PROP = "c2c.auth.github.auth.secret" # noqa: S105 +GITHUB_AUTH_SECRET_ENV = "C2C_AUTH_GITHUB_SECRET" # noqa: S105 GITHUB_AUTH_PROXY_URL_PROP = "c2c.auth.github.auth.proxy_url" GITHUB_AUTH_PROXY_URL_ENV = "C2C_AUTH_GITHUB_PROXY_URL" USE_SESSION_PROP = "c2c.use_session" @@ -209,6 +209,7 @@ def check_access( request: is the request object. repo: is the repository to check access to (/). access_type: is the type of access to check (admin|push|pull). + """ if not is_auth(request): return False diff --git a/c2cwsgiutils/broadcast/__init__.py b/c2cwsgiutils/broadcast/__init__.py index aa8350cef..a84aa1ff4 100644 --- a/c2cwsgiutils/broadcast/__init__.py +++ b/c2cwsgiutils/broadcast/__init__.py @@ -19,7 +19,7 @@ def init(config: Optional[pyramid.config.Configurator] = None) -> None: """Initialize the broadcaster with Redis, if configured, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/broadcast/local.py b/c2cwsgiutils/broadcast/local.py index 6b4dbd837..4032f7f77 100644 --- a/c2cwsgiutils/broadcast/local.py +++ b/c2cwsgiutils/broadcast/local.py @@ -9,17 +9,21 @@ class LocalBroadcaster(interface.BaseBroadcaster): """Fake implementation of broadcasting messages (will just answer locally).""" def __init__(self) -> None: + """Initialize the broadcaster.""" self._subscribers: MutableMapping[str, Callable[..., Any]] = {} def subscribe(self, channel: str, callback: Callable[..., Any]) -> None: + """Subscribe to a channel.""" self._subscribers[channel] = callback def unsubscribe(self, channel: str) -> None: + """Unsubscribe from a channel.""" del self._subscribers[channel] def broadcast( self, channel: str, params: Mapping[str, Any], expect_answers: bool, timeout: float ) -> Optional[list[Any]]: + """Broadcast a message to all the listeners.""" subscriber = self._subscribers.get(channel, None) answers = [utils.add_host_info(subscriber(**params))] if subscriber is not None else [] return answers if expect_answers else None diff --git a/c2cwsgiutils/broadcast/redis.py b/c2cwsgiutils/broadcast/redis.py index 173b4add6..fdb8e6151 100644 --- a/c2cwsgiutils/broadcast/redis.py +++ b/c2cwsgiutils/broadcast/redis.py @@ -23,6 +23,7 @@ def __init__( master: "redis.client.Redis[str]", slave: "redis.client.Redis[str]", ) -> None: + """Initialize the broadcaster.""" from c2cwsgiutils import redis_utils # pylint: disable=import-outside-toplevel self._master = master @@ -40,6 +41,8 @@ def _get_channel(self, channel: str) -> str: return self._broadcast_prefix + channel def subscribe(self, channel: str, callback: Callable[..., Any]) -> None: + """Subscribe to a channel.""" + def wrapper(message: Mapping[str, Any]) -> None: _LOG.debug("Received a broadcast on %s: %s", message["channel"], repr(message["data"])) data = json.loads(message["data"]) @@ -58,6 +61,7 @@ def wrapper(message: Mapping[str, Any]) -> None: self._pub_sub.subscribe(**{actual_channel: wrapper}) def unsubscribe(self, channel: str) -> None: + """Unsubscribe from a channel.""" _LOG.debug("Unsubscribing from %s") actual_channel = self._get_channel(channel) self._pub_sub.unsubscribe(actual_channel) @@ -65,6 +69,7 @@ def unsubscribe(self, channel: str) -> None: def broadcast( self, channel: str, params: Mapping[str, Any], expect_answers: bool, timeout: float ) -> Optional[list[Any]]: + """Broadcast a message to all the listeners.""" if expect_answers: return self._broadcast_with_answer(channel, params, timeout) else: @@ -85,7 +90,8 @@ def callback(msg: Mapping[str, Any]) -> None: cond.notify() answer_channel = self._get_channel(channel) + "".join( - random.choice(string.ascii_uppercase + string.digits) for _ in range(10) # nosec + random.choice(string.ascii_uppercase + string.digits) # noqa: S311 + for _ in range(10) ) _LOG.debug("Subscribing for broadcast answers on %s", answer_channel) self._pub_sub.subscribe(**{answer_channel: callback}) @@ -98,7 +104,7 @@ def callback(msg: Mapping[str, Any]) -> None: with cond: while len(answers) < nb_received: to_wait = timeout_time - time.perf_counter() - if to_wait <= 0.0: # pragma: no cover + if to_wait <= 0.0: _LOG.warning( "timeout waiting for %d/%d answers on %s", len(answers), diff --git a/c2cwsgiutils/client_info.py b/c2cwsgiutils/client_info.py index de8c0b014..8d4e3c723 100644 --- a/c2cwsgiutils/client_info.py +++ b/c2cwsgiutils/client_info.py @@ -16,9 +16,11 @@ class Filter: """ def __init__(self, application: Callable[[dict[str, str], Any], Any]): + """Initialize the filter.""" self._application = application def __call__(self, environ: dict[str, str], start_response: Any) -> Any: + """Update the environ with the headers.""" # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Forwarded if "HTTP_FORWARDED" in environ: _handle_forwarded(environ) diff --git a/c2cwsgiutils/coverage_setup.py b/c2cwsgiutils/coverage_setup.py index 59df37037..c9a03409a 100644 --- a/c2cwsgiutils/coverage_setup.py +++ b/c2cwsgiutils/coverage_setup.py @@ -10,7 +10,7 @@ def init() -> None: """Initialize the code coverage, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme() @@ -22,7 +22,7 @@ def includeme(config: Optional[pyramid.config.Configurator] = None) -> None: import coverage # pylint: disable=import-outside-toplevel _LOG.warning("Setting up code coverage") - report_dir = "/tmp/coverage/api" # nosec + report_dir = "/tmp/coverage/api" # noqa: S108 os.makedirs(report_dir, exist_ok=True) cov = coverage.Coverage( data_file=os.path.join(report_dir, "coverage"), diff --git a/c2cwsgiutils/db.py b/c2cwsgiutils/db.py index 7b6c3a818..310db15b6 100644 --- a/c2cwsgiutils/db.py +++ b/c2cwsgiutils/db.py @@ -66,8 +66,11 @@ def setup_session( force_slave: The method/paths that needs to use the slave Returns: The SQLAlchemy session, the R/W engine and the R/O engine + """ - warnings.warn("setup_session function is deprecated; use init and request.dbsession instead") + warnings.warn( + "setup_session function is deprecated; use init and request.dbsession instead", stacklevel=2 + ) if slave_prefix is None: slave_prefix = master_prefix settings = config.registry.settings @@ -122,8 +125,11 @@ def create_session( engine_config: The rest of the parameters are passed as is to the sqlalchemy.create_engine function Returns: The SQLAlchemy session + """ - warnings.warn("create_session function is deprecated; use init and request.dbsession instead") + warnings.warn( + "create_session function is deprecated; use init and request.dbsession instead", stacklevel=2 + ) if slave_url is None: slave_url = url @@ -215,6 +221,7 @@ def __init__( ro_engine: sqlalchemy.engine.Engine, rw_engine: sqlalchemy.engine.Engine, ): + """Initialize the session factory.""" super().__init__() self.master_paths: Iterable[Pattern[str]] = ( list(map(_RE_COMPILE, force_master)) if force_master else [] @@ -232,6 +239,7 @@ def engine_name(self, readwrite: bool) -> str: def __call__( # type: ignore self, request: Optional[pyramid.request.Request], readwrite: Optional[bool] = None, **local_kw: Any ) -> _scoped_session: + """Set the engine based on the request.""" if readwrite is not None: if readwrite and not FORCE_READONLY: _LOG.debug("Using %s database", self.rw_engine.c2c_name) # type: ignore @@ -374,6 +382,7 @@ def init( force_slave: The method/paths that needs to use the slave Returns: The SQLAlchemy session + """ settings = config.get_settings() settings["tm.manager_hook"] = "pyramid_tm.explicit_manager" diff --git a/c2cwsgiutils/db_maintenance_view.py b/c2cwsgiutils/db_maintenance_view.py index 21822025f..b9f92e743 100644 --- a/c2cwsgiutils/db_maintenance_view.py +++ b/c2cwsgiutils/db_maintenance_view.py @@ -15,7 +15,7 @@ def install_subscriber(config: pyramid.config.Configurator) -> None: """Install the view to configure the loggers, if configured to do so, for backward compatibility.""" - warnings.warn("install_subscriber function is deprecated; use includeme instead") + warnings.warn("install_subscriber function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/debug/__init__.py b/c2cwsgiutils/debug/__init__.py index 7b3b1b97e..c28a1ed34 100644 --- a/c2cwsgiutils/debug/__init__.py +++ b/c2cwsgiutils/debug/__init__.py @@ -16,7 +16,7 @@ def init(config: pyramid.config.Configurator) -> None: """Initialize the debug tools, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) @@ -37,6 +37,8 @@ def init_daemon(config: Optional[pyramid.config.Configurator] = None) -> None: those requests. """ if config_utils.env_or_config(config, ENV_KEY, CONFIG_KEY, type_=config_utils.config_bool): - from c2cwsgiutils.debug import _listeners # pylint: disable=import-outside-toplevel + from c2cwsgiutils.debug import ( # pylint: disable=import-outside-toplevel + _listeners, + ) _listeners.init() diff --git a/c2cwsgiutils/debug/_views.py b/c2cwsgiutils/debug/_views.py index 8f16f4f5d..c5f607efb 100644 --- a/c2cwsgiutils/debug/_views.py +++ b/c2cwsgiutils/debug/_views.py @@ -79,7 +79,7 @@ def _dump_memory_diff(request: pyramid.request.Request) -> list[Any]: try: if request.params.get("no_warmup", "0").lower() in ("1", "true", "on"): request.invoke_subrequest(sub_request) - except Exception: # nosec # pylint: disable=broad-except + except Exception: # pylint: disable=broad-except pass _LOG.debug("checking memory growth for %s", path) @@ -151,8 +151,7 @@ def _headers(request: pyramid.request.Request) -> Mapping[str, Any]: } if "status" in request.params: raise exception_response(int(request.params["status"]), detail=result) - else: - return result + return result def _error(request: pyramid.request.Request) -> Any: diff --git a/c2cwsgiutils/errors.py b/c2cwsgiutils/errors.py index 0dd69b212..0f147200b 100644 --- a/c2cwsgiutils/errors.py +++ b/c2cwsgiutils/errors.py @@ -9,7 +9,12 @@ import pyramid.request import sqlalchemy.exc from cornice import cors -from pyramid.httpexceptions import HTTPError, HTTPException, HTTPRedirection, HTTPSuccessful +from pyramid.httpexceptions import ( + HTTPError, + HTTPException, + HTTPRedirection, + HTTPSuccessful, +) from webob.request import DisconnectionError from c2cwsgiutils import auth, config_utils @@ -152,7 +157,7 @@ def _passthrough(exception: HTTPException, request: pyramid.request.Request) -> def init(config: pyramid.config.Configurator) -> None: """Initialize the error views, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/health_check.py b/c2cwsgiutils/health_check.py index 643e87c01..5cfb23333 100644 --- a/c2cwsgiutils/health_check.py +++ b/c2cwsgiutils/health_check.py @@ -67,6 +67,7 @@ class JsonCheckException(Exception): """Checker exception used to add some structured content to a failure.""" def __init__(self, message: str, json: Any): + """Initialize the exception.""" super().__init__() self.message = message self.json = json @@ -199,6 +200,7 @@ class HealthCheck: """ def __init__(self, config: pyramid.config.Configurator) -> None: + """Initialize the health check view.""" config.add_route( "c2c_health_check", config_utils.get_base_path(config) + r"/health_check", request_method="GET" ) @@ -235,6 +237,7 @@ def add_db_session_check( engine_type: whether to check only the RW, RO or both engines rw_engin: the RW engine to use (if None, use the session one) ro_engin: the RO engine to use (if None, use the session one) + """ if query_cb is None: query_cb = self._at_least_one(at_least_one_model) @@ -265,6 +268,7 @@ def add_alembic_check( version_table: override the table name for the version rw_engin: the RW engine to use (if None, use the session one) ro_engin: the RO engine to use (if None, use the session one) + """ version_ = _get_alembic_version(alembic_ini_path, name) @@ -287,26 +291,28 @@ def __call__(self, request: pyramid.request.Request) -> str: assert version_schema assert version_table for binding in _get_bindings(self.session, EngineType.READ_AND_WRITE): - with binding as binded_session: - with _PROMETHEUS_DB_SUMMARY.labels( + with ( + binding as binded_session, + _PROMETHEUS_DB_SUMMARY.labels( configuration=alembic_ini_path, connection=binding.name(), check="alembic" - ).time(): - result = binded_session.execute( - sqlalchemy.text( - "SELECT version_num FROM " # nosec - f"{sqlalchemy.sql.quoted_name(version_schema, True)}." - f"{sqlalchemy.sql.quoted_name(version_table, True)}" - ) - ).fetchone() - assert result is not None - (actual_version,) = result - _PROMETHEUS_ALEMBIC_VERSION.labels( - version=actual_version, name=name, configuration=alembic_ini_path - ).set(1) - if actual_version != version_: - raise Exception( # pylint: disable=broad-exception-raised - f"Invalid alembic version (db: {actual_version}, code: {version_})" - ) + ).time(), + ): + result = binded_session.execute( + sqlalchemy.text( + "SELECT version_num FROM " # noqa: S608 + f"{sqlalchemy.sql.quoted_name(version_schema, True)}." + f"{sqlalchemy.sql.quoted_name(version_table, True)}" + ) + ).fetchone() + assert result is not None + (actual_version,) = result + _PROMETHEUS_ALEMBIC_VERSION.labels( + version=actual_version, name=name, configuration=alembic_ini_path + ).set(1) + if actual_version != version_: + raise Exception( # pylint: disable=broad-exception-raised + f"Invalid alembic version (db: {actual_version}, code: {version_})" + ) return version_ self._checks.append( @@ -321,9 +327,8 @@ def add_url_check( Mapping[str, str], Callable[[pyramid.request.Request], Mapping[str, str]], None ] = None, name: Optional[str] = None, - check_cb: Callable[ - [pyramid.request.Request, requests.Response], Any - ] = lambda request, response: None, + check_cb: Callable[[pyramid.request.Request, requests.Response], Any] = lambda request, + response: None, timeout: float = 3, level: int = 1, ) -> None: @@ -339,6 +344,7 @@ def add_url_check( response as parameters) timeout: the timeout level: the level of the health check + """ def check(request: pyramid.request.Request) -> Any: @@ -365,6 +371,7 @@ def add_redis_check(self, name: Optional[str] = None, level: int = 1) -> None: Arguments: name: the name of the check (defaults to url) level: the level of the health check + """ def check(request: pyramid.request.Request) -> Any: @@ -413,6 +420,7 @@ def add_version_check(self, name: str = "version", level: int = 2) -> None: Arguments: name: the name of the check (defaults to "version") level: the level of the health check + """ def check(request: pyramid.request.Request) -> dict[str, Any]: @@ -441,6 +449,7 @@ def add_custom_check( name: the name of the check check_cb: the callback to call (takes the request as parameter) level: the level of the health check + """ assert name self._checks.append((name, check_cb, level)) @@ -453,9 +462,8 @@ def _view(self, request: pyramid.request.Request) -> Mapping[str, Any]: "successes": {}, } checks = None - if "checks" in request.params: - if request.params["checks"] != "": - checks = request.params["checks"].split(",") + if "checks" in request.params and request.params["checks"] != "": + checks = request.params["checks"].split(",") for name, check, level in self._checks: if level <= max_level and (checks is None or name in checks): self._run_one(check, is_auth, level, name, request, results) @@ -498,11 +506,13 @@ def _create_db_engine_check( ) -> tuple[str, Callable[[pyramid.request.Request], None]]: def check(request: pyramid.request.Request) -> None: del request # unused - with binding as session: - with _PROMETHEUS_DB_SUMMARY.labels( + with ( + binding as session, + _PROMETHEUS_DB_SUMMARY.labels( connection=binding.name(), check="database", configuration="" - ).time(): - return query_cb(session) + ).time(), + ): + return query_cb(session) return "db_engine_" + binding.name(), check diff --git a/c2cwsgiutils/index.py b/c2cwsgiutils/index.py index 688f46cdc..62cfdb38f 100644 --- a/c2cwsgiutils/index.py +++ b/c2cwsgiutils/index.py @@ -501,7 +501,7 @@ def _github_logout(request: pyramid.request.Request) -> dict[str, Any]: def init(config: pyramid.config.Configurator) -> None: """Initialize the index page, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/logging_view.py b/c2cwsgiutils/logging_view.py index 3fa968f39..75888624e 100644 --- a/c2cwsgiutils/logging_view.py +++ b/c2cwsgiutils/logging_view.py @@ -15,7 +15,7 @@ def install_subscriber(config: pyramid.config.Configurator) -> None: """Install the view to configure the loggers, if configured to do so, for backward compatibility.""" - warnings.warn("install_subscriber function is deprecated; use includeme instead") + warnings.warn("install_subscriber function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/models_graph.py b/c2cwsgiutils/models_graph.py index fc92e580f..de5c248d0 100644 --- a/c2cwsgiutils/models_graph.py +++ b/c2cwsgiutils/models_graph.py @@ -44,7 +44,7 @@ def _generate_model_graph(module: Any, base: Any) -> None: def _print_node(symbol: Any, interesting: set[Any]) -> None: print(f'{symbol.__name__} [label="{_get_table_desc(symbol)}", shape=box];') for parent in symbol.__bases__: - if parent != object: + if parent is not object: if parent not in interesting: _print_node(parent, interesting) interesting.add(parent) diff --git a/c2cwsgiutils/pretty_json.py b/c2cwsgiutils/pretty_json.py index 67bdede45..a407b1a4c 100644 --- a/c2cwsgiutils/pretty_json.py +++ b/c2cwsgiutils/pretty_json.py @@ -28,7 +28,7 @@ def __call__(self, v: Any, **_kargv: Any) -> str: def init(config: pyramid.config.Configurator) -> None: """Initialize json and fast_json renderer, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/profiler.py b/c2cwsgiutils/profiler.py index 9095552d3..aa00a8a26 100644 --- a/c2cwsgiutils/profiler.py +++ b/c2cwsgiutils/profiler.py @@ -9,6 +9,7 @@ class Profile(contextlib.ContextDecorator): """Used to profile a function with a decorator or with a with statement.""" def __init__(self, path: str, print_number: int = 0) -> None: + """Initialize the profiler.""" self.path = path self.print_number = print_number self.pr = cProfile.Profile() diff --git a/c2cwsgiutils/prometheus.py b/c2cwsgiutils/prometheus.py index 5b654eade..8e16d32f6 100644 --- a/c2cwsgiutils/prometheus.py +++ b/c2cwsgiutils/prometheus.py @@ -115,6 +115,7 @@ class MultiProcessCustomCollector(prometheus_client.registry.Collector): """Get the metrics from the custom collectors.""" def collect(self) -> Generator[prometheus_client.core.Metric, None, None]: + """Get the metrics from the custom collectors.""" results: list[list[SerializedMetric]] = [] for channel in MULTI_PROCESS_COLLECTOR_BROADCAST_CHANNELS: result = broadcast.broadcast(channel, expect_answers=True) @@ -159,6 +160,7 @@ def __init__(self, memory_type: str = "pss", pids: Optional[list[str]] = None): Arguments: memory_type: can be rss, pss or size pids: the list of pids or none + """ super().__init__() self.memory_type = memory_type diff --git a/c2cwsgiutils/pyramid.py b/c2cwsgiutils/pyramid.py index 7c3bdf7b2..42efa038b 100644 --- a/c2cwsgiutils/pyramid.py +++ b/c2cwsgiutils/pyramid.py @@ -31,6 +31,7 @@ def includeme(config: pyramid.config.Configurator) -> None: Arguments: config: The pyramid Configuration + """ logging.captureWarnings(True) config.include(coverage_setup.includeme) diff --git a/c2cwsgiutils/pyramid_logging.py b/c2cwsgiutils/pyramid_logging.py index fb6d3da42..045835aa8 100644 --- a/c2cwsgiutils/pyramid_logging.py +++ b/c2cwsgiutils/pyramid_logging.py @@ -87,10 +87,12 @@ class PyramidCeeSysLogHandler(cee_syslog_handler.CeeSysLogHandler): # type: ign """A CEE (JSON format) log handler with additional information about the current request.""" def __init__(self, *args: Any, **kargv: Any) -> None: + """Initialize the handler.""" super().__init__(*args, **kargv) self.addFilter(_PYRAMID_FILTER) def format(self, record: Any) -> str: + """Format the record into a CEE string.""" message = _make_message_dict( record, self._fqdn, @@ -112,11 +114,13 @@ class JsonLogHandler(Base): """Log to stdout in JSON.""" def __init__(self, stream: Optional[TextIO] = None): + """Initialize the handler.""" super().__init__(stream) self.addFilter(_PYRAMID_FILTER) self._fqdn = socket.getfqdn() def format(self, record: Any) -> str: + """Format the record into a JSON string.""" message = _make_message_dict( record, self._fqdn, debugging_fields=True, extra_fields=True, facility=None, static_fields={} ) diff --git a/c2cwsgiutils/redis_stats.py b/c2cwsgiutils/redis_stats.py index 552005b2d..a5a73c778 100644 --- a/c2cwsgiutils/redis_stats.py +++ b/c2cwsgiutils/redis_stats.py @@ -26,7 +26,7 @@ def _execute_command_patch(self: Any, command: str, *args: Any, **options: Any) def init(config: Optional[pyramid.config.Configurator] = None) -> None: """Initialize the Redis tracking, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/redis_utils.py b/c2cwsgiutils/redis_utils.py index 0675b1fe0..182aefa57 100644 --- a/c2cwsgiutils/redis_utils.py +++ b/c2cwsgiutils/redis_utils.py @@ -100,11 +100,13 @@ class PubSubWorkerThread(threading.Thread): """A clone of redis.client.PubSubWorkerThread that doesn't die when the connections are broken.""" def __init__(self, pubsub: redis.client.PubSub, name: Optional[str] = None) -> None: + """Initialize the PubSubWorkerThread.""" super().__init__(name=name, daemon=True) self.pubsub = pubsub self._running = False def run(self) -> None: + """Run the worker.""" if self._running: return self._running = True diff --git a/c2cwsgiutils/request_tracking/__init__.py b/c2cwsgiutils/request_tracking/__init__.py index 4a86c7ca7..a5369cc33 100644 --- a/c2cwsgiutils/request_tracking/__init__.py +++ b/c2cwsgiutils/request_tracking/__init__.py @@ -83,7 +83,7 @@ def send_wrapper( def init(config: Optional[pyramid.config.Configurator] = None) -> None: """Initialize the request tracking, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/scripts/genversion.py b/c2cwsgiutils/scripts/genversion.py index 84669847c..2f1614f75 100755 --- a/c2cwsgiutils/scripts/genversion.py +++ b/c2cwsgiutils/scripts/genversion.py @@ -24,7 +24,7 @@ def _get_package_version(comp: str) -> tuple[Optional[str], Optional[str]]: if matcher: return cast(tuple[str, str], matcher.groups()) else: - if len(comp) > 0 and not comp[:3] == "-e ": + if len(comp) > 0 and comp[:3] != "-e ": print("Cannot parse package version: " + comp) return None, None @@ -46,7 +46,9 @@ def _get_packages_version() -> dict[str, str]: def deprecated() -> None: """Run the command and print a deprecated notice.""" - warnings.warn("c2cwsgiutils_genversion.py is deprecated; use c2cwsgiutils-genversion instead") + warnings.warn( + "c2cwsgiutils_genversion.py is deprecated; use c2cwsgiutils-genversion instead", stacklevel=2 + ) return main() diff --git a/c2cwsgiutils/scripts/stats_db.py b/c2cwsgiutils/scripts/stats_db.py index 28d55fca1..a9d88e23d 100755 --- a/c2cwsgiutils/scripts/stats_db.py +++ b/c2cwsgiutils/scripts/stats_db.py @@ -62,6 +62,7 @@ class Reporter: """The stats reporter.""" def __init__(self, args: argparse.Namespace) -> None: + """Initialize the reporter.""" self._error: Optional[Exception] = None self.registry = CollectorRegistry() self.prometheus_push = args.prometheus_url is not None diff --git a/c2cwsgiutils/scripts/test_print.py b/c2cwsgiutils/scripts/test_print.py index bcdab60ca..9d8cfdcd5 100755 --- a/c2cwsgiutils/scripts/test_print.py +++ b/c2cwsgiutils/scripts/test_print.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 """Test a MapfishPrint server.""" + import argparse import logging import pprint @@ -23,7 +24,9 @@ def _parse_args() -> argparse.Namespace: def deprecated() -> None: """Run the command and print a deprecated notice.""" - warnings.warn("c2cwsgiutils_test_print.py is deprecated; use c2cwsgiutils-test-print instead") + warnings.warn( + "c2cwsgiutils_test_print.py is deprecated; use c2cwsgiutils-test-print instead", stacklevel=2 + ) return main() diff --git a/c2cwsgiutils/sentry.py b/c2cwsgiutils/sentry.py index e6213cdde..ca51b01a6 100644 --- a/c2cwsgiutils/sentry.py +++ b/c2cwsgiutils/sentry.py @@ -33,7 +33,7 @@ def do_filter(event: Any, hint: Any) -> Any: def init(config: Optional[pyramid.config.Configurator] = None) -> None: """Initialize the Sentry integration, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/setup_process.py b/c2cwsgiutils/setup_process.py index b0ccec6b7..e099b90f5 100644 --- a/c2cwsgiutils/setup_process.py +++ b/c2cwsgiutils/setup_process.py @@ -55,7 +55,9 @@ def init(config_file: str = "c2c:///app/production.ini") -> None: def init_logging(config_file: str = "c2c:///app/production.ini") -> None: """Initialize the non-WSGI application.""" - warnings.warn("init_logging function is deprecated; use init instead so that all features are enabled") + warnings.warn( + "init_logging function is deprecated; use init instead so that all features are enabled", stacklevel=2 + ) loader = get_config_loader(config_file) loader.setup_logging(None) diff --git a/c2cwsgiutils/sql_profiler/__init__.py b/c2cwsgiutils/sql_profiler/__init__.py index c52d77764..a12ca4f9b 100644 --- a/c2cwsgiutils/sql_profiler/__init__.py +++ b/c2cwsgiutils/sql_profiler/__init__.py @@ -18,7 +18,7 @@ def init(config: pyramid.config.Configurator) -> None: """Install a pyramid event handler that adds the request information, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/c2cwsgiutils/sql_profiler/_impl.py b/c2cwsgiutils/sql_profiler/_impl.py index a05754f8c..aa7ad18fa 100644 --- a/c2cwsgiutils/sql_profiler/_impl.py +++ b/c2cwsgiutils/sql_profiler/_impl.py @@ -56,7 +56,7 @@ def profile( ] ) _LOG.info(output) - except Exception: # nosec # pylint: disable=broad-except + except Exception: # pylint: disable=broad-except # noqa: S110 pass diff --git a/c2cwsgiutils/sqlalchemylogger/handlers.py b/c2cwsgiutils/sqlalchemylogger/handlers.py index e5318c407..68efb6c2b 100644 --- a/c2cwsgiutils/sqlalchemylogger/handlers.py +++ b/c2cwsgiutils/sqlalchemylogger/handlers.py @@ -11,7 +11,10 @@ from sqlalchemy.orm import sessionmaker from sqlalchemy_utils import create_database, database_exists -from c2cwsgiutils.sqlalchemylogger._filters import ContainsExpression, DoesNotContainExpression +from c2cwsgiutils.sqlalchemylogger._filters import ( + ContainsExpression, + DoesNotContainExpression, +) from c2cwsgiutils.sqlalchemylogger._models import Base, create_log_class _LOG = logging.getLogger(__name__) @@ -29,12 +32,13 @@ def __init__( does_not_contain_expression: str = "", contains_expression: str = "", ) -> None: + """Initialize the SQLAlchemyHandler.""" super().__init__() # Initialize DB session self.engine = create_engine(sqlalchemy_url["url"]) self.Log = create_log_class( # pylint: disable=invalid-name tablename=sqlalchemy_url.get("tablename", "logs"), - tableargs=sqlalchemy_url.get("tableargs", None), # type: ignore + tableargs=sqlalchemy_url.get("tableargs"), # type: ignore ) Base.metadata.bind = self.engine self.session = sessionmaker(bind=self.engine)() # noqa @@ -61,15 +65,16 @@ def _processor(self) -> None: if not self.log_queue.empty(): logs.append(self.log_queue.get()) self.log_queue.task_done() - if logs: - # try to reduce the number of INSERT requests to the DB - # by writing chunks of self.MAX_NB_LOGS size, - # but also do not wait forever before writing stuff (self.MAX_TIMOUT) - if (len(logs) >= self.MAX_NB_LOGS) or ( - time.perf_counter() >= (time_since_last + self.MAX_TIMEOUT) - ): - self._write_logs(logs) - break + # try to reduce the number of INSERT requests to the DB + # by writing chunks of self.MAX_NB_LOGS size, + # but also do not wait forever before writing stuff (self.MAX_TIMOUT) + if ( + logs + and (len(logs) >= self.MAX_NB_LOGS) + or (time.perf_counter() >= (time_since_last + self.MAX_TIMEOUT)) + ): + self._write_logs(logs) + break _LOG.debug("%s: stopping processor thread", __name__) def _write_logs(self, logs: list[Any]) -> None: @@ -94,7 +99,7 @@ def create_db(self) -> None: _LOG.info("%s: creating new database", __name__) if not database_exists(self.engine.url): create_database(self.engine.url) - # FIXME: we should not access directly the private __table_args__ + # FIXME: we should not access directly the private __table_args__ # pylint: disable=fixme # variable, but add an accessor method in models.Log class if not isinstance(self.Log.__table_args__, type(None)) and self.Log.__table_args__.get( "schema", None @@ -107,6 +112,7 @@ def create_db(self) -> None: Base.metadata.create_all(self.engine) def emit(self, record: Any) -> None: + """Emit the log.""" trace = None exc = record.__dict__["exc_info"] if exc: diff --git a/c2cwsgiutils/stats_pyramid/__init__.py b/c2cwsgiutils/stats_pyramid/__init__.py index 2a25a7bce..f721139e8 100644 --- a/c2cwsgiutils/stats_pyramid/__init__.py +++ b/c2cwsgiutils/stats_pyramid/__init__.py @@ -10,7 +10,7 @@ def init(config: pyramid.config.Configurator) -> None: """Initialize the whole stats module, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) @@ -20,6 +20,7 @@ def includeme(config: pyramid.config.Configurator) -> None: Arguments: config: The Pyramid config + """ _pyramid_spy.init(config) init_db_spy() diff --git a/c2cwsgiutils/stats_pyramid/_pyramid_spy.py b/c2cwsgiutils/stats_pyramid/_pyramid_spy.py index c95c66a45..c2b844ca4 100644 --- a/c2cwsgiutils/stats_pyramid/_pyramid_spy.py +++ b/c2cwsgiutils/stats_pyramid/_pyramid_spy.py @@ -99,6 +99,7 @@ def init(config: pyramid.config.Configurator) -> None: # pragma: nocover Arguments: config: The Pyramid config + """ config.add_subscriber(_request_callback, pyramid.events.NewRequest) config.add_subscriber(_before_rendered_callback, pyramid.events.BeforeRender) diff --git a/c2cwsgiutils/version.py b/c2cwsgiutils/version.py index 1536236eb..25aafbf68 100644 --- a/c2cwsgiutils/version.py +++ b/c2cwsgiutils/version.py @@ -37,7 +37,7 @@ def _sanitize_label(label: str) -> str: def init(config: pyramid.config.Configurator) -> None: """Initialize the versions view, for backward compatibility.""" - warnings.warn("init function is deprecated; use includeme instead") + warnings.warn("init function is deprecated; use includeme instead", stacklevel=2) includeme(config) diff --git a/poetry.lock b/poetry.lock index 0fc3e4042..e4c6895b0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1582,6 +1582,7 @@ pylint-flask = "0.6" pyroma = {version = ">=2.4", optional = true, markers = "extra == \"with-pyroma\" or extra == \"with_everything\""} PyYAML = "*" requirements-detector = ">=1.3.2" +ruff = {version = "*", optional = true, markers = "extra == \"with-ruff\" or extra == \"with_everything\""} setoptconf-tmp = ">=0.3.1,<0.4.0" toml = ">=0.10.2,<0.11.0" @@ -1596,26 +1597,29 @@ with-vulture = ["vulture (>=1.5)"] [[package]] name = "prospector-profile-duplicated" -version = "1.6.0" +version = "1.9.0" description = "Profile that can be used to disable the duplicated or conflict rules between Prospector and other tools" optional = false python-versions = "*" files = [ - {file = "prospector_profile_duplicated-1.6.0-py2.py3-none-any.whl", hash = "sha256:bf6a6aae0c7de48043b95e4d42e23ccd090c6c7115b6ee8c8ca472ffb1a2022b"}, - {file = "prospector_profile_duplicated-1.6.0.tar.gz", hash = "sha256:9c2d541076537405e8b2484cb6222276a2df17492391b6af1b192695770aab83"}, + {file = "prospector_profile_duplicated-1.9.0-py2.py3-none-any.whl", hash = "sha256:7b7a665e6fa8b44fac597d2bbef1a91de5b6f090b8d64890a5f38ee60e8473c2"}, + {file = "prospector_profile_duplicated-1.9.0.tar.gz", hash = "sha256:bb0b0d0946232d570ada944ee4a180fd142529db0978579b58e766d28f3c2a27"}, ] [[package]] name = "prospector-profile-utils" -version = "1.9.1" +version = "1.14.0" description = "Some utility Prospector profiles." optional = false -python-versions = "*" +python-versions = "<4.0,>=3.9" files = [ - {file = "prospector_profile_utils-1.9.1-py2.py3-none-any.whl", hash = "sha256:b458d8c4d59bdb1547e4630a2c6de4971946c4f0999443db6a9eef6d216b26b8"}, - {file = "prospector_profile_utils-1.9.1.tar.gz", hash = "sha256:008efa6797a85233fd8093dcb9d86f5fa5d89673e431c15cb1496a91c9b2c601"}, + {file = "prospector_profile_utils-1.14.0-py3-none-any.whl", hash = "sha256:15853e984314f90d688052c7dc09c9206779fdfb7f0606f6a4a617d167c6e693"}, + {file = "prospector_profile_utils-1.14.0.tar.gz", hash = "sha256:258bbe70c7411c7c11a7a7fc202c9a021db3d775a3bf45e7e8bd9f96206bcc48"}, ] +[package.dependencies] +prospector = ">=1.13.0" + [[package]] name = "psutil" version = "6.1.0" @@ -1730,13 +1734,13 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyjwt" -version = "2.9.0" +version = "2.10.1" description = "JSON Web Token implementation in Python" optional = true -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"}, - {file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"}, + {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, + {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, ] [package.extras] @@ -1892,13 +1896,13 @@ testing = ["WebTest (>=1.3.1)", "coverage", "nose"] [[package]] name = "pyramid-tm" -version = "2.5" +version = "2.6" description = "A package which allows Pyramid requests to join the active transaction" optional = true -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "pyramid_tm-2.5-py2.py3-none-any.whl", hash = "sha256:6638721946e809de8b4bf3f405bd2daaaa76d58442cbdf46be30ebc259f1a354"}, - {file = "pyramid_tm-2.5.tar.gz", hash = "sha256:5c81dcecd33770f5e3596687d2be35ffc4f8ce5eda00a31acb00ae35a51430d0"}, + {file = "pyramid_tm-2.6-py3-none-any.whl", hash = "sha256:665a4ee1d6f41f0c7ffa5e54d9b01d70cd3e8e5bd76277529acbdd6b6bd6fe9e"}, + {file = "pyramid_tm-2.6.tar.gz", hash = "sha256:8148d2191285280c9a0c23e6df1018b3514b4cef02115b872dd0350a4d78709c"}, ] [package.dependencies] @@ -2164,6 +2168,33 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.1 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "ruff" +version = "0.8.1" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"}, + {file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"}, + {file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"}, + {file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"}, + {file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"}, + {file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"}, + {file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"}, + {file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"}, + {file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"}, +] + [[package]] name = "scikit-image" version = "0.24.0" @@ -2275,13 +2306,13 @@ files = [ [[package]] name = "sentry-sdk" -version = "2.18.0" +version = "2.19.0" description = "Python client for Sentry (https://sentry.io)" optional = true python-versions = ">=3.6" files = [ - {file = "sentry_sdk-2.18.0-py2.py3-none-any.whl", hash = "sha256:ee70e27d1bbe4cd52a38e1bd28a5fadb9b17bc29d91b5f2b97ae29c0a7610442"}, - {file = "sentry_sdk-2.18.0.tar.gz", hash = "sha256:0dc21febd1ab35c648391c664df96f5f79fb0d92d7d4225cd9832e53a617cafd"}, + {file = "sentry_sdk-2.19.0-py2.py3-none-any.whl", hash = "sha256:7b0b3b709dee051337244a09a30dbf6e95afe0d34a1f8b430d45e0982a7c125b"}, + {file = "sentry_sdk-2.19.0.tar.gz", hash = "sha256:ee4a4d2ae8bfe3cac012dcf3e4607975904c137e1738116549fc3dbbb6ff0e36"}, ] [package.dependencies] @@ -2307,7 +2338,7 @@ grpcio = ["grpcio (>=1.21.1)", "protobuf (>=3.8.0)"] http2 = ["httpcore[http2] (==1.*)"] httpx = ["httpx (>=0.16.0)"] huey = ["huey (>=2)"] -huggingface-hub = ["huggingface-hub (>=0.22)"] +huggingface-hub = ["huggingface_hub (>=0.22)"] langchain = ["langchain (>=0.0.210)"] launchdarkly = ["launchdarkly-server-sdk (>=9.8.0)"] litestar = ["litestar (>=2.0.0)"] @@ -2316,7 +2347,7 @@ openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] openfeature = ["openfeature-sdk (>=0.7.1)"] opentelemetry = ["opentelemetry-distro (>=0.35b0)"] opentelemetry-experimental = ["opentelemetry-distro"] -pure-eval = ["asttokens", "executing", "pure-eval"] +pure-eval = ["asttokens", "executing", "pure_eval"] pymongo = ["pymongo (>=3.1)"] pyspark = ["pyspark (>=2.4.4)"] quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] @@ -2952,48 +2983,48 @@ test = ["zope.testrunner"] [[package]] name = "zope-interface" -version = "7.1.1" +version = "7.2" description = "Interfaces for Python" optional = true python-versions = ">=3.8" files = [ - {file = "zope.interface-7.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6650bd56ef350d37c8baccfd3ee8a0483ed6f8666e641e4b9ae1a1827b79f9e5"}, - {file = "zope.interface-7.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84e87eba6b77a3af187bae82d8de1a7c208c2a04ec9f6bd444fd091b811ad92e"}, - {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c4e1b4c06d9abd1037c088dae1566c85f344a3e6ae4350744c3f7f7259d9c67"}, - {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cd5e3d910ac87652a09f6e5db8e41bc3b49cf08ddd2d73d30afc644801492cd"}, - {file = "zope.interface-7.1.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca95594d936ee349620900be5b46c0122a1ff6ce42d7d5cb2cf09dc84071ef16"}, - {file = "zope.interface-7.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:ad339509dcfbbc99bf8e147db6686249c4032f26586699ec4c82f6e5909c9fe2"}, - {file = "zope.interface-7.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e59f175e868f856a77c0a77ba001385c377df2104fdbda6b9f99456a01e102a"}, - {file = "zope.interface-7.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0de23bcb93401994ea00bc5c677ef06d420340ac0a4e9c10d80e047b9ce5af3f"}, - {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdb7e7e5524b76d3ec037c1d81a9e2c7457b240fd4cb0a2476b65c3a5a6c81f"}, - {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3603ef82a9920bd0bfb505423cb7e937498ad971ad5a6141841e8f76d2fd5446"}, - {file = "zope.interface-7.1.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1d52d052355e0c5c89e0630dd2ff7c0b823fd5f56286a663e92444761b35e25"}, - {file = "zope.interface-7.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:179ad46ece518c9084cb272e4a69d266b659f7f8f48e51706746c2d8a426433e"}, - {file = "zope.interface-7.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e6503534b52bb1720ace9366ee30838a58a3413d3e197512f3338c8f34b5d89d"}, - {file = "zope.interface-7.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f85b290e5b8b11814efb0d004d8ce6c9a483c35c462e8d9bf84abb93e79fa770"}, - {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d029fac6a80edae80f79c37e5e3abfa92968fe921886139b3ee470a1b177321a"}, - {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5836b8fb044c6e75ba34dfaabc602493019eadfa0faf6ff25f4c4c356a71a853"}, - {file = "zope.interface-7.1.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7395f13533318f150ee72adb55b29284b16e73b6d5f02ab21f173b3e83f242b8"}, - {file = "zope.interface-7.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:1d0e23c6b746eb8ce04573cc47bcac60961ac138885d207bd6f57e27a1431ae8"}, - {file = "zope.interface-7.1.1-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:9fad9bd5502221ab179f13ea251cb30eef7cf65023156967f86673aff54b53a0"}, - {file = "zope.interface-7.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:55c373becbd36a44d0c9be1d5271422fdaa8562d158fb44b4192297b3c67096c"}, - {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed1df8cc01dd1e3970666a7370b8bfc7457371c58ba88c57bd5bca17ab198053"}, - {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99c14f0727c978639139e6cad7a60e82b7720922678d75aacb90cf4ef74a068c"}, - {file = "zope.interface-7.1.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b1eed7670d564f1025d7cda89f99f216c30210e42e95de466135be0b4a499d9"}, - {file = "zope.interface-7.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:3defc925c4b22ac1272d544a49c6ba04c3eefcce3200319ee1be03d9270306dd"}, - {file = "zope.interface-7.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8d0fe45be57b5219aa4b96e846631c04615d5ef068146de5a02ccd15c185321f"}, - {file = "zope.interface-7.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bcbeb44fc16e0078b3b68a95e43f821ae34dcbf976dde6985141838a5f23dd3d"}, - {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8e7b05dc6315a193cceaec071cc3cf1c180cea28808ccded0b1283f1c38ba73"}, - {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d553e02b68c0ea5a226855f02edbc9eefd99f6a8886fa9f9bdf999d77f46585"}, - {file = "zope.interface-7.1.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81744a7e61b598ebcf4722ac56a7a4f50502432b5b4dc7eb29075a89cf82d029"}, - {file = "zope.interface-7.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:7720322763aceb5e0a7cadcc38c67b839efe599f0887cbf6c003c55b1458c501"}, - {file = "zope.interface-7.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1a2ed0852c25950cf430067f058f8d98df6288502ac313861d9803fe7691a9b3"}, - {file = "zope.interface-7.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9595e478047ce752b35cfa221d7601a5283ccdaab40422e0dc1d4a334c70f580"}, - {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2317e1d4dba68203a5227ea3057f9078ec9376275f9700086b8f0ffc0b358e1b"}, - {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6821ef9870f32154da873fcde439274f99814ea452dd16b99fa0b66345c4b6b"}, - {file = "zope.interface-7.1.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:190eeec67e023d5aac54d183fa145db0b898664234234ac54643a441da434616"}, - {file = "zope.interface-7.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:d17e7fc814eaab93409b80819fd6d30342844345c27f3bc3c4b43c2425a8d267"}, - {file = "zope.interface-7.1.1.tar.gz", hash = "sha256:4284d664ef0ff7b709836d4de7b13d80873dc5faeffc073abdb280058bfac5e3"}, + {file = "zope.interface-7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ce290e62229964715f1011c3dbeab7a4a1e4971fd6f31324c4519464473ef9f2"}, + {file = "zope.interface-7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:05b910a5afe03256b58ab2ba6288960a2892dfeef01336dc4be6f1b9ed02ab0a"}, + {file = "zope.interface-7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:550f1c6588ecc368c9ce13c44a49b8d6b6f3ca7588873c679bd8fd88a1b557b6"}, + {file = "zope.interface-7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ef9e2f865721553c6f22a9ff97da0f0216c074bd02b25cf0d3af60ea4d6931d"}, + {file = "zope.interface-7.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27f926f0dcb058211a3bb3e0e501c69759613b17a553788b2caeb991bed3b61d"}, + {file = "zope.interface-7.2-cp310-cp310-win_amd64.whl", hash = "sha256:144964649eba4c5e4410bb0ee290d338e78f179cdbfd15813de1a664e7649b3b"}, + {file = "zope.interface-7.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1909f52a00c8c3dcab6c4fad5d13de2285a4b3c7be063b239b8dc15ddfb73bd2"}, + {file = "zope.interface-7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:80ecf2451596f19fd607bb09953f426588fc1e79e93f5968ecf3367550396b22"}, + {file = "zope.interface-7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:033b3923b63474800b04cba480b70f6e6243a62208071fc148354f3f89cc01b7"}, + {file = "zope.interface-7.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a102424e28c6b47c67923a1f337ede4a4c2bba3965b01cf707978a801fc7442c"}, + {file = "zope.interface-7.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25e6a61dcb184453bb00eafa733169ab6d903e46f5c2ace4ad275386f9ab327a"}, + {file = "zope.interface-7.2-cp311-cp311-win_amd64.whl", hash = "sha256:3f6771d1647b1fc543d37640b45c06b34832a943c80d1db214a37c31161a93f1"}, + {file = "zope.interface-7.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:086ee2f51eaef1e4a52bd7d3111a0404081dadae87f84c0ad4ce2649d4f708b7"}, + {file = "zope.interface-7.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:21328fcc9d5b80768bf051faa35ab98fb979080c18e6f84ab3f27ce703bce465"}, + {file = "zope.interface-7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6dd02ec01f4468da0f234da9d9c8545c5412fef80bc590cc51d8dd084138a89"}, + {file = "zope.interface-7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e7da17f53e25d1a3bde5da4601e026adc9e8071f9f6f936d0fe3fe84ace6d54"}, + {file = "zope.interface-7.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cab15ff4832580aa440dc9790b8a6128abd0b88b7ee4dd56abacbc52f212209d"}, + {file = "zope.interface-7.2-cp312-cp312-win_amd64.whl", hash = "sha256:29caad142a2355ce7cfea48725aa8bcf0067e2b5cc63fcf5cd9f97ad12d6afb5"}, + {file = "zope.interface-7.2-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:3e0350b51e88658d5ad126c6a57502b19d5f559f6cb0a628e3dc90442b53dd98"}, + {file = "zope.interface-7.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15398c000c094b8855d7d74f4fdc9e73aa02d4d0d5c775acdef98cdb1119768d"}, + {file = "zope.interface-7.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:802176a9f99bd8cc276dcd3b8512808716492f6f557c11196d42e26c01a69a4c"}, + {file = "zope.interface-7.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb23f58a446a7f09db85eda09521a498e109f137b85fb278edb2e34841055398"}, + {file = "zope.interface-7.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a71a5b541078d0ebe373a81a3b7e71432c61d12e660f1d67896ca62d9628045b"}, + {file = "zope.interface-7.2-cp313-cp313-win_amd64.whl", hash = "sha256:4893395d5dd2ba655c38ceb13014fd65667740f09fa5bb01caa1e6284e48c0cd"}, + {file = "zope.interface-7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d3a8ffec2a50d8ec470143ea3d15c0c52d73df882eef92de7537e8ce13475e8a"}, + {file = "zope.interface-7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:31d06db13a30303c08d61d5fb32154be51dfcbdb8438d2374ae27b4e069aac40"}, + {file = "zope.interface-7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e204937f67b28d2dca73ca936d3039a144a081fc47a07598d44854ea2a106239"}, + {file = "zope.interface-7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:224b7b0314f919e751f2bca17d15aad00ddbb1eadf1cb0190fa8175edb7ede62"}, + {file = "zope.interface-7.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baf95683cde5bc7d0e12d8e7588a3eb754d7c4fa714548adcd96bdf90169f021"}, + {file = "zope.interface-7.2-cp38-cp38-win_amd64.whl", hash = "sha256:7dc5016e0133c1a1ec212fc87a4f7e7e562054549a99c73c8896fa3a9e80cbc7"}, + {file = "zope.interface-7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7bd449c306ba006c65799ea7912adbbfed071089461a19091a228998b82b1fdb"}, + {file = "zope.interface-7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a19a6cc9c6ce4b1e7e3d319a473cf0ee989cbbe2b39201d7c19e214d2dfb80c7"}, + {file = "zope.interface-7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72cd1790b48c16db85d51fbbd12d20949d7339ad84fd971427cf00d990c1f137"}, + {file = "zope.interface-7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52e446f9955195440e787596dccd1411f543743c359eeb26e9b2c02b077b0519"}, + {file = "zope.interface-7.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ad9913fd858274db8dd867012ebe544ef18d218f6f7d1e3c3e6d98000f14b75"}, + {file = "zope.interface-7.2-cp39-cp39-win_amd64.whl", hash = "sha256:1090c60116b3da3bfdd0c03406e2f14a1ff53e5771aebe33fec1edc0a350175d"}, + {file = "zope.interface-7.2.tar.gz", hash = "sha256:8b49f1a3d1ee4cdaf5b32d2e738362c7f5e40ac8b46dd7d1a65e82a4872728fe"}, ] [package.dependencies] @@ -3041,4 +3072,4 @@ webserver = ["SQLAlchemy", "SQLAlchemy-Utils", "cornice", "gunicorn", "prometheu [metadata] lock-version = "2.0" python-versions = ">=3.10,<4.0" -content-hash = "0323323e6fdce30766da5041feb5b483b2e0655eca0bc5a226e886e47da849ed" +content-hash = "4de06f12b3dc92afce3f2b37accdd2baa1a35f8503cf19304207fafa1633b3b2" diff --git a/pyproject.toml b/pyproject.toml index 95734d40c..4c2c4b320 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -78,15 +78,15 @@ lxml = { version = "5.3.0", optional = true } objgraph = { version = "3.6.2", optional = true } psycopg2 = { version = "2.9.10", optional = true } pyramid = { version = "2.0.2", optional = true } -pyramid-tm = { version = "2.5", optional = true } -sentry-sdk = { version = "2.18.0", optional = true } +pyramid-tm = { version = "2.6", optional = true } +sentry-sdk = { version = "2.19.0", optional = true } ujson = { version = "5.10.0" } cee_syslog_handler = { version = "0.6.0" } SQLAlchemy = { version = "2.0.36", optional = true } SQLAlchemy-Utils = { version = "0.41.2", optional = true } -"zope.interface" = { version = "7.1.1", optional = true } +"zope.interface" = { version = "7.2", optional = true } "zope.sqlalchemy" = { version = "3.1", optional = true } -pyjwt = { version = "2.9.0", optional = true } +pyjwt = { version = "2.10.1", optional = true } requests-oauthlib = { version = "2.0.0", optional = true } waitress = { version = "3.0.2", optional = true } scikit-image = { version = "0.24.0", optional = true } @@ -172,9 +172,9 @@ test_images = ["scikit-image"] [tool.poetry.group.dev.dependencies] # pylint = { version = "2.15.6" } -prospector = { extras = ["with_bandit", "with_mypy", "with_pyroma"], version = "1.13.3" } -prospector-profile-duplicated = "1.6.0" -prospector-profile-utils = "1.9.1" +prospector = { version = "1.13.3", extras = ["with_bandit", "with_mypy", "with_pyroma", "with_ruff"] } +prospector-profile-duplicated = "1.9.0" +prospector-profile-utils = "1.14.0" coverage = "7.6.8" junit2html = "31.0.2" pytest = "8.3.4"