Skip to content

Commit

Permalink
more ruff rules; bandit; pre-commit
Browse files Browse the repository at this point in the history
  • Loading branch information
gjcarneiro committed Mar 23, 2024
1 parent e978f9f commit 4f7936a
Show file tree
Hide file tree
Showing 12 changed files with 112 additions and 61 deletions.
17 changes: 17 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
repos:
- repo: https://github.com/PyCQA/bandit
rev: 1.7.8
hooks:
- id: bandit
args: ["-c", "pyproject.toml", "--severity-level=medium"]
additional_dependencies: ["bandit[toml]"]

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.3.0
hooks:
# Run the linter.
- id: ruff
args: [--fix]
# Run the formatter.
- id: ruff-format
24 changes: 24 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,29 @@ target_version = ['py310']
target-version = "py310"
line-length = 79

[tool.ruff.lint]
select = [
# Bugbear warnings
"B",
"B9",
# mccabe complexity warnings
"C",
# Pycodestyle errors https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes
"E",
# Pyflakes violations https://flake8.pycqa.org/en/latest/user/error-codes.html
"F",
# Pycodestyle warnings
"W",
# pyupgrade
# "UP",
"I", # <= import sorting
]

[tool.ruff.lint.mccabe]
max-complexity = 20

[tool.pytest.ini_options]
asyncio_mode = "auto"

[tool.bandit]
exclude_dirs = ["tests"]
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

"""The setup script."""

from setuptools import setup, find_packages
from setuptools import find_packages, setup

with open("README.rst") as readme_file:
readme = readme_file.read()
Expand Down
1 change: 1 addition & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os

import pytest

from yacron import config
Expand Down
13 changes: 6 additions & 7 deletions tests/test_cron.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import time
import asyncio
import datetime
import time
from pathlib import Path

import pytest
import pytz

import yacron.cron
from yacron.job import RunningJob
from yacron.config import JobConfig
import asyncio
import pytest
from yacron.job import RunningJob


@pytest.fixture(autouse=True)
Expand Down Expand Up @@ -37,7 +38,6 @@ def tracing_running_job(monkeypatch):


class TracingRunningJob(RunningJob):

_TRACE = asyncio.Queue()

def __init__(self, config: JobConfig, retry_state) -> None:
Expand Down Expand Up @@ -380,7 +380,7 @@ def test_simple_config_file(tracing_running_job):


@pytest.mark.asyncio
async def test_concurrency_and_backoff(monkeypatch, tracing_running_job):
async def test_concurrency_and_backoff(monkeypatch, tracing_running_job): # noqa: C901
START_TIME = datetime.datetime(
year=1999,
month=12,
Expand Down Expand Up @@ -587,7 +587,6 @@ def test_naturaltime(value_in, out):
"",
True,
),
# enabled: false
(
"* * * * *",
Expand Down
43 changes: 20 additions & 23 deletions tests/test_job.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import yacron.job
import yacron.config
import asyncio
import pytest
import aiosmtplib
from unittest.mock import Mock, patch
import tempfile
import os
import tempfile
from unittest.mock import Mock, patch

import aiosmtplib
import pytest

import yacron.config
import yacron.job


@pytest.mark.parametrize(
Expand Down Expand Up @@ -215,12 +217,12 @@ def init(self, *args, **kwargs):
smtp_init_args = args, kwargs
real_init(self, *args, **kwargs)

with patch("aiosmtplib.SMTP.__init__", init), patch(
"aiosmtplib.SMTP.connect", connect
), patch("aiosmtplib.SMTP.send_message", send_message), patch(
"aiosmtplib.SMTP.login", login
), patch(
"aiosmtplib.SMTP.starttls", starttls
with (
patch("aiosmtplib.SMTP.__init__", init),
patch("aiosmtplib.SMTP.connect", connect),
patch("aiosmtplib.SMTP.send_message", send_message),
patch("aiosmtplib.SMTP.login", login),
patch("aiosmtplib.SMTP.starttls", starttls),
):
await mail.report(success, job, job_config.onSuccess["report"])

Expand Down Expand Up @@ -302,7 +304,7 @@ def init(self, *args, **kwargs):
],
)
@pytest.mark.asyncio
async def test_report_sentry(
async def test_report_sentry( # noqa: C901
success,
dsn_from,
body,
Expand Down Expand Up @@ -345,9 +347,9 @@ async def test_report_sentry(
else:
raise AssertionError

job_config.onSuccess["report"]["sentry"][
"body"
] = yacron.config.DEFAULT_CONFIG["onFailure"]["report"]["sentry"]["body"]
job_config.onSuccess["report"]["sentry"]["body"] = (
yacron.config.DEFAULT_CONFIG["onFailure"]["report"]["sentry"]["body"]
)

job_config.onSuccess["report"]["sentry"]["fingerprint"] = ["{{ name }}"]

Expand Down Expand Up @@ -490,7 +492,6 @@ async def test_report_shell(command, expected_output):
async def test_job_run(
monkeypatch, shell, command, expected_type, expected_args
):

shell_commands = []
exec_commands = []

Expand Down Expand Up @@ -543,9 +544,7 @@ async def create_subprocess_exec(*args, **kwargs):
environment:
- key: FOO
value: bar
""".format(
command=command_snippet, shell=shell
),
""".format(command=command_snippet, shell=shell),
"",
)
job_config = conf.jobs[0]
Expand Down Expand Up @@ -688,9 +687,7 @@ def connection_lost(*_):
host: 127.0.0.1
port: {port}
prefix: the.prefix
""".format(
port=port, command=command
),
""".format(port=port, command=command),
"",
)
job_config = conf.jobs[0]
Expand Down
8 changes: 5 additions & 3 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import yacron.__main__
from yacron.config import parse_config
import sys
import asyncio
import sys
from pathlib import Path

import pytest

import yacron.__main__
from yacron.config import parse_config


class FakeCron:
def __init__(self, config_arg):
Expand Down
4 changes: 2 additions & 2 deletions yacron/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import asyncio
import asyncio.subprocess
import logging
import os
import signal
import sys
import os

from yacron.cron import Cron, ConfigError
import yacron.version
from yacron.cron import ConfigError, Cron

CONFIG_DEFAULT = "/etc/yacron.d"

Expand Down
50 changes: 31 additions & 19 deletions yacron/config.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
from dataclasses import dataclass
from pwd import getpwnam
from grp import getgrnam
import datetime
import logging
import os.path
from typing import Union # noqa
from typing import List, Optional, Any, Dict, NewType
import datetime
import pytz
from dataclasses import dataclass
from grp import getgrnam
from pwd import getpwnam
from typing import (
Any,
Dict,
List,
NewType,
Optional,
Union, # noqa
)

import pytz
import strictyaml
from strictyaml import Optional as Opt, EmptyDict
from crontab import CronTab
from strictyaml import Any as YamlAny
from strictyaml import (
Bool,
EmptyDict,
EmptyNone,
Enum,
Float,
Int,
Map,
MapPattern,
Seq,
Str,
MapPattern,
)
from strictyaml import Optional as Opt
from strictyaml.ruamel.error import YAMLError

from crontab import CronTab

logger = logging.getLogger("yacron.config")
WebConfig = NewType("WebConfig", Dict[str, Any])
JobDefaults = NewType("JobDefaults", Dict[str, Any])
Expand Down Expand Up @@ -281,7 +287,7 @@ def mergedicts(dict1, dict2):


class JobConfig:
def __init__(self, config: dict) -> None:
def __init__(self, config: dict) -> None: # noqa: C901
self.name = config["name"] # type: str
self.command = config["command"] # type: Union[str, List[str]]
self.schedule_unparsed = config.pop("schedule")
Expand Down Expand Up @@ -315,7 +321,7 @@ def __init__(self, config: dict) -> None:
try:
self.timezone = pytz.timezone(config["timezone"])
except pytz.UnknownTimeZoneError as err:
raise ConfigError("unknown timezone: " + str(err))
raise ConfigError("unknown timezone: " + str(err)) from err
elif self.utc:
self.timezone = datetime.timezone.utc

Expand All @@ -330,7 +336,9 @@ def __init__(self, config: dict) -> None:
try:
file_environs = parse_environment_file(self.env_file)
except OSError as e:
raise ConfigError("Could not load env_file: {}".format(e))
raise ConfigError(
"Could not load env_file: {}".format(e)
) from e
else:
# unpack variables in dictionaries
config_environs = {
Expand Down Expand Up @@ -360,8 +368,10 @@ def __init__(self, config: dict) -> None:
pw = getpwnam(user)
self.uid = pw.pw_uid
self.gid = pw.pw_gid
except KeyError:
raise ConfigError("User not found: {!r}".format(user))
except KeyError as e:
raise ConfigError(
"User not found: {!r}".format(user)
) from e

group = config.pop("group", None)
if group is not None:
Expand All @@ -370,8 +380,10 @@ def __init__(self, config: dict) -> None:
else:
try:
self.gid = getgrnam(group).gr_gid
except KeyError:
raise ConfigError("Group not found: {!r}".format(group))
except KeyError as e:
raise ConfigError(
"Group not found: {!r}".format(group)
) from e

if self.uid is not None or self.gid is not None:
if os.geteuid() != 0:
Expand Down Expand Up @@ -427,7 +439,7 @@ def parse_config_string(data: str, path: str) -> YacronConfig:
try:
doc = strictyaml.load(data, CONFIG_SCHEMA, label=path).data
except YAMLError as ex:
raise ConfigError(str(ex))
raise ConfigError(str(ex)) from ex

inc_defaults_merged: dict = {}
jobs = []
Expand Down
4 changes: 2 additions & 2 deletions yacron/cron.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ async def _web_start_job(self, request: web.Request) -> web.Response:
name = request.match_info["name"]
try:
job = self.cron_jobs[name]
except KeyError:
raise web.HTTPNotFound()
except KeyError as ex:
raise web.HTTPNotFound() from ex
await self.maybe_launch_job(job)
return web.Response()

Expand Down
4 changes: 2 additions & 2 deletions yacron/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,13 +446,13 @@ def _demote(self):
try:
os.setgid(self.config.gid)
except OSError as ex:
raise RuntimeError("setgid: {}".format(ex))
raise RuntimeError("setgid: {}".format(ex)) from ex
if self.config.uid is not None:
logger.debug("Changing to uid %r ...", self.config.uid)
try:
os.setuid(self.config.uid)
except OSError as ex:
raise RuntimeError("setuid: {}".format(ex))
raise RuntimeError("setuid: {}".format(ex)) from ex

async def wait(self) -> None:
if self.proc is None:
Expand Down
3 changes: 1 addition & 2 deletions yacron/statsd.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import asyncio
import logging
import time
import asyncio


logger = logging.getLogger("statsd")

Expand Down

0 comments on commit 4f7936a

Please sign in to comment.