Skip to content

Commit

Permalink
Add Ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
sbrunner committed Dec 3, 2024
1 parent 2f733d3 commit a36ad5c
Show file tree
Hide file tree
Showing 46 changed files with 236 additions and 145 deletions.
3 changes: 0 additions & 3 deletions .bandit.yaml

This file was deleted.

31 changes: 8 additions & 23 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
25 changes: 4 additions & 21 deletions .prospector.yaml
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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'
38 changes: 33 additions & 5 deletions acceptance_tests/app/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions acceptance_tests/app/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ 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.8.0"
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]
Expand Down
1 change: 1 addition & 0 deletions c2cwsgiutils/acceptance/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]:
Expand Down
5 changes: 3 additions & 2 deletions c2cwsgiutils/acceptance/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 += "/"
Expand Down Expand Up @@ -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

Expand Down
8 changes: 5 additions & 3 deletions c2cwsgiutils/acceptance/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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 = {}
Expand Down
1 change: 1 addition & 0 deletions c2cwsgiutils/acceptance/print.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion c2cwsgiutils/acceptance/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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)


Expand Down
17 changes: 9 additions & 8 deletions c2cwsgiutils/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -209,6 +209,7 @@ def check_access(
request: is the request object.
repo: is the repository to check access to (<organization>/<repository>).
access_type: is the type of access to check (admin|push|pull).
"""
if not is_auth(request):
return False
Expand Down
2 changes: 1 addition & 1 deletion c2cwsgiutils/broadcast/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down
4 changes: 4 additions & 0 deletions c2cwsgiutils/broadcast/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit a36ad5c

Please sign in to comment.