Skip to content

Introduce ruff for codestyle and linting #356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .flake8

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

services:
db:
image: 'postgres:15'
image: 'postgres:17'
env:
POSTGRES_USER: serveradmin
POSTGRES_PASSWORD: serveradmin
Expand Down
14 changes: 0 additions & 14 deletions CHANGELOG.md

This file was deleted.

1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ setuptools = "*"
# Generate fake data for tests
faker = "<14.0.0"
tblib = "*"
ruff ="*"

[requires]
python_version = "3.9"
Expand Down
27 changes: 26 additions & 1 deletion Pipfile.lock

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

2 changes: 1 addition & 1 deletion adminapi/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
Copyright (c) 2019 InnoGames GmbH
"""

from adminapi.request import send_request
from adminapi.exceptions import ApiError
from adminapi.request import send_request

API_CALL_ENDPOINT = '/call'

Expand Down
6 changes: 2 additions & 4 deletions adminapi/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Copyright (c) 2019 InnoGames GmbH
"""

import sys
from argparse import ArgumentParser, ArgumentTypeError

Expand Down Expand Up @@ -63,10 +64,7 @@ def main():
query = Query(filters, attribute_ids_to_fetch, args.order)

if args.one and len(query) > 1:
raise Exception(
'Expecting exactly one server, found {} servers'
.format(len(query))
)
raise Exception('Expecting exactly one server, found {} servers'.format(len(query)))

for server in query:
if args.reset:
Expand Down
3 changes: 1 addition & 2 deletions adminapi/cmduser.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
"""

import os
from os.path import isfile
from os.path import expanduser
from os.path import expanduser, isfile


def get_auth_token():
Expand Down
60 changes: 19 additions & 41 deletions adminapi/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
from types import GeneratorType

from adminapi import api
from adminapi.datatype import validate_value, json_to_datatype
from adminapi.datatype import json_to_datatype, validate_value
from adminapi.exceptions import AdminapiException, DatasetError
from adminapi.filters import Any, BaseFilter, ContainedOnlyBy
from adminapi.request import send_request, json_encode_extra
from adminapi.exceptions import DatasetError, AdminapiException
from adminapi.request import json_encode_extra, send_request

NEW_OBJECT_ENDPOINT = '/dataset/new_object'
COMMIT_ENDPOINT = '/dataset/commit'
Expand All @@ -27,10 +27,7 @@ def __init__(self, filters=None, restrict=['hostname'], order_by=None):
self._results = []
return

self._filters = {
a: f if isinstance(f, BaseFilter) else BaseFilter(f)
for a, f in filters.items()
}
self._filters = {a: f if isinstance(f, BaseFilter) else BaseFilter(f) for a, f in filters.items()}

self._restrict = restrict
self._order_by = order_by
Expand Down Expand Up @@ -81,11 +78,7 @@ def _ensure_object_id(restrict):
restrict = restrict.copy()
restrict.append('object_id')

return [
i if not isinstance(i, dict) else
{k: _ensure_object_id(v) for k, v in i.items()}
for i in restrict
]
return [i if not isinstance(i, dict) else {k: _ensure_object_id(v) for k, v in i.items()} for i in restrict]

self.__restrict = _ensure_object_id(new_restrict)

Expand All @@ -105,14 +98,9 @@ def new_object(self, servertype):
if self._filters:
for attribute, filt in self._filters:
if attribute not in obj:
raise DatasetError(
'"{}" is not on the new object'.format(attribute)
)
raise DatasetError('"{}" is not on the new object'.format(attribute))
if not filt.matches(obj[attribute]):
raise DatasetError(
'"{}" is not consistent with the query'
.format(attribute)
)
raise DatasetError('"{}" is not consistent with the query'.format(attribute))

self._get_results().append(obj)

Expand Down Expand Up @@ -145,10 +133,7 @@ def order_by(self, *attribute_ids):
def get(self):
results = self._get_results()
if len(results) != 1:
raise DatasetError(
'get() requires exactly 1 matched object, {} found'.format(
len(results)
))
raise DatasetError('get() requires exactly 1 matched object, {} found'.format(len(results)))
return results[0]

# XXX: Deprecated
Expand Down Expand Up @@ -216,9 +201,12 @@ def get_free_ip_addrs(self):
# Index host and network addresses separately
used_hosts = set()
used_networks = list()
for obj in type(self)({
'intern_ip': Any(*(ContainedOnlyBy(n) for n in networks)),
}, ['intern_ip']):
for obj in type(self)(
{
'intern_ip': Any(*(ContainedOnlyBy(n) for n in networks)),
},
['intern_ip'],
):
addr = obj['intern_ip']
if isinstance(addr, (IPv4Address, IPv6Address)):
used_hosts.add(addr)
Expand Down Expand Up @@ -265,9 +253,7 @@ def get_free_ip_addr(self, lock=True):

class Query(BaseQuery):
def _fetch_new_object(self, servertype):
response = send_request(
NEW_OBJECT_ENDPOINT, [('servertype', servertype)]
)
response = send_request(NEW_OBJECT_ENDPOINT, [('servertype', servertype)])
return _format_obj(response['result'])

def commit(self):
Expand Down Expand Up @@ -336,10 +322,7 @@ def commit_state(self):
if self._deleted:
return 'deleted'
for attribute_id, old_value in self.old_values.items():
if (
json_encode_extra(self[attribute_id]) !=
json_encode_extra(old_value)
):
if json_encode_extra(self[attribute_id]) != json_encode_extra(old_value):
return 'changed'
return 'consistent'

Expand All @@ -366,10 +349,7 @@ def _serialize_changes(self):
for key, old_value in self.old_values.items():
new_value = self[key]

if (
json_encode_extra(old_value) ==
json_encode_extra(new_value)
):
if json_encode_extra(old_value) == json_encode_extra(new_value):
continue

if isinstance(old_value, MultiAttr):
Expand Down Expand Up @@ -430,9 +410,7 @@ def __setitem__(self, key, value):
if self._deleted:
raise DatasetError('Cannot set attributes to deleted object')
if key not in self:
raise DatasetError(
'Cannot set nonexistent attribute "{}"'.format(key)
)
raise DatasetError('Cannot set nonexistent attribute "{}"'.format(key))

self._save_old_value(key)
self.validate(key, value)
Expand Down Expand Up @@ -611,4 +589,4 @@ def strtobool(val) -> bool:
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
return False
else:
raise ValueError(f"invalid truth value {val}")
raise ValueError(f'invalid truth value {val}')
18 changes: 8 additions & 10 deletions adminapi/datatype.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@

Copyright (c) 2019 InnoGames GmbH
"""

from datetime import date, datetime
from re import compile as re_compile
from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network
from re import compile as re_compile

from netaddr import EUI

try:
from netaddr import mac_unix_expanded
except ImportError:
from netaddr import mac_unix as mac_unix_expanded

from adminapi.exceptions import DatatypeError, FilterValueError


# We use a set of regular expressions to cast to datatypes. This module
# is not aware of the attributes types of the server, neither it tries
# to match with them one to one. Its purpose is to provide convenience
Expand Down Expand Up @@ -88,22 +89,19 @@ def validate_value(value, datatype=None):
if isinstance(value, special_datatypes):
raise DatatypeError('Value cannot be from {}'.format(type(value)))

assert datatype != object
if type(value) == object:
assert datatype is not object
if type(value) is object:
raise DatatypeError('Value cannot be a generic object')

newtype = type(value)
if datatype is None or issubclass(datatype, newtype):
return newtype

for supertype in datatype.mro():
if issubclass(newtype, supertype) and supertype != object:
if issubclass(newtype, supertype) and supertype is not object:
return supertype

raise DatatypeError(
'Value from {} is not compatible with existing value from {}'
.format(type(value), datatype)
)
raise DatatypeError('Value from {} is not compatible with existing value from {}'.format(type(value), datatype))


def str_to_datatype(value):
Expand All @@ -123,7 +121,7 @@ def json_to_datatype(value):
if regexp.match(str(value)):
# date constructors need a decode format
if datatype is date:
return datetime.strptime(value, "%Y-%m-%d").date()
return datetime.strptime(value, '%Y-%m-%d').date()
if datatype is datetime:
return datetime.strptime(value, '%Y-%m-%d %H:%M:%S%z')

Expand Down
6 changes: 6 additions & 0 deletions adminapi/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

class AdminapiException(Exception):
"""Adminapi exception parent class."""

pass


Expand All @@ -15,6 +16,7 @@ class ConfigurationError(AdminapiException):

class ApiError(AdminapiException):
"""An API request wasn't successful"""

def __init__(self, *args, **kwargs):
if 'status_code' in kwargs:
self.status_code = kwargs.pop('status_code')
Expand All @@ -25,20 +27,24 @@ def __init__(self, *args, **kwargs):

class AuthenticationError(AdminapiException):
"""No suitable authentication credentials available"""

pass


class DatasetError(AdminapiException):
"""Something went wrong within a dataset instance"""

pass


class DatatypeError(AdminapiException):
"""A query or dataset attribute had the wrong value datatype"""

pass


# XXX: Sub-class ValueError for backwards compatibility
class FilterValueError(DatatypeError, ValueError):
"""A filter value made no sense"""

pass
Loading
Loading