Skip to content

Commit

Permalink
Introduce docstring standards for Ruff
Browse files Browse the repository at this point in the history
Most rules are used, but a few are ignored for style.
  • Loading branch information
JacobCallahan committed Sep 13, 2023
1 parent 7bc1a11 commit 94aa505
Show file tree
Hide file tree
Showing 10 changed files with 379 additions and 390 deletions.
16 changes: 8 additions & 8 deletions nailgun/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def _set_content_type(kwargs):


def _truncate_data(data, max_len=500):
"""Truncate data to a max length"""
"""Truncate data to a max length."""
if isinstance(data, str | bytes):
if len(data) > max_len:
return f"{data[:max_len - 3]}..."
Expand Down Expand Up @@ -133,7 +133,7 @@ def _log_response(response):


def request(method, url, **kwargs):
"""A wrapper for ``requests.request``."""
"""Wrap ``requests.request``."""
_set_content_type(kwargs)
if _content_type_is_json(kwargs) and kwargs.get('data') is not None:
kwargs['data'] = dumps(kwargs['data'])
Expand All @@ -144,7 +144,7 @@ def request(method, url, **kwargs):


def head(url, **kwargs):
"""A wrapper for ``requests.head``."""
"""Wrap ``requests.head``."""
_set_content_type(kwargs)
if _content_type_is_json(kwargs) and kwargs.get('data') is not None:
kwargs['data'] = dumps(kwargs['data'])
Expand All @@ -155,7 +155,7 @@ def head(url, **kwargs):


def get(url, params=None, **kwargs):
"""A wrapper for ``requests.get``."""
"""Wrap ``requests.get``."""
_set_content_type(kwargs)
if _content_type_is_json(kwargs) and kwargs.get('data') is not None:
kwargs['data'] = dumps(kwargs['data'])
Expand All @@ -166,7 +166,7 @@ def get(url, params=None, **kwargs):


def post(url, data=None, json=None, **kwargs):
"""A wrapper for ``requests.post``."""
"""Wrap ``requests.post``."""
_set_content_type(kwargs)
if _content_type_is_json(kwargs) and data is not None:
data = dumps(data)
Expand All @@ -177,7 +177,7 @@ def post(url, data=None, json=None, **kwargs):


def put(url, data=None, **kwargs):
"""A wrapper for ``requests.put``. Sends a PUT request."""
"""Wrap ``requests.put``. Sends a PUT request."""
_set_content_type(kwargs)
if _content_type_is_json(kwargs) and data is not None:
data = dumps(data)
Expand All @@ -188,7 +188,7 @@ def put(url, data=None, **kwargs):


def patch(url, data=None, **kwargs):
"""A wrapper for ``requests.patch``. Sends a PATCH request."""
"""Wrap ``requests.patch``. Sends a PATCH request."""
_set_content_type(kwargs)
if _content_type_is_json(kwargs) and data is not None:
data = dumps(data)
Expand All @@ -199,7 +199,7 @@ def patch(url, data=None, **kwargs):


def delete(url, **kwargs):
"""A wrapper for ``requests.delete``. Sends a DELETE request."""
"""Wrap ``requests.delete``. Sends a DELETE request."""
_set_content_type(kwargs)
if _content_type_is_json(kwargs) and kwargs.get('data') is not None:
kwargs['data'] = dumps(kwargs['data'])
Expand Down
1 change: 1 addition & 0 deletions nailgun/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def __init__(self, url, auth=None, version=None):
self.version = parse(version)

def __repr__(self):
"""Return a string representation of the object."""
attrs = vars(self).copy()
if "version" in attrs:
attrs["version"] = str(attrs.pop("version"))
Expand Down
408 changes: 219 additions & 189 deletions nailgun/entities.py

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions nailgun/entity_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@


class Field:
"""Base class to implement other fields
"""Base class to implement other fields.
Record this field's attributes.
Expand All @@ -76,7 +76,7 @@ def __init__(self, required=False, choices=None, default=_SENTINEL, unique=False


class BooleanField(Field):
"""Field that represents a boolean"""
"""Field that represents a boolean."""

def gen_value(self):
"""Return a value suitable for a :class:`BooleanField`."""
Expand All @@ -85,7 +85,7 @@ def gen_value(self):


class EmailField(Field):
"""Field that represents an email"""
"""Field that represents an email."""

def gen_value(self):
"""Return a value suitable for a :class:`EmailField`."""
Expand All @@ -94,7 +94,7 @@ def gen_value(self):


class FloatField(Field):
"""Field that represents a float"""
"""Field that represents a float."""

def gen_value(self):
"""Return a value suitable for a :class:`FloatField`."""
Expand Down Expand Up @@ -159,7 +159,7 @@ def gen_value(self):


class DateField(Field):
"""Field that represents a date"""
"""Field that represents a date."""

def __init__(self, min_date=None, max_date=None, *args, **kwargs):
# If ``None`` is passed then ``FauxFactory`` will deal with it.
Expand All @@ -173,7 +173,7 @@ def gen_value(self):


class DateTimeField(Field):
"""Field that represents a datetime"""
"""Field that represents a datetime."""

def __init__(self, min_date=None, max_date=None, *args, **kwargs):
# If ``None`` is passed then ``FauxFactory`` will deal with it.
Expand All @@ -196,27 +196,27 @@ def gen_value(self):


class IPAddressField(StringField):
"""Field that represents an IP address"""
"""Field that represents an IP address."""

def gen_value(self):
"""Return a value suitable for a :class:`IPAddressField`."""
return gen_ipaddr()


class NetmaskField(StringField):
"""Field that represents an netmask"""
"""Field that represents an netmask."""

def gen_value(self):
"""Return a value suitable for a :class:`NetmaskField`."""
return gen_netmask()


class ListField(Field):
"""Field that represents a list of strings"""
"""Field that represents a list of strings."""


class MACAddressField(StringField):
"""Field that represents a MAC address"""
"""Field that represents a MAC address."""

def gen_value(self):
"""Return a value suitable for a :class:`MACAddressField`."""
Expand Down Expand Up @@ -260,7 +260,7 @@ def gen_value(self):


class URLField(StringField):
"""Field that represents an URL
"""Field that represents an URL.
:param str scheme: The URL scheme can be one of ['http', 'https', 'ftp']
"""
Expand Down
37 changes: 21 additions & 16 deletions nailgun/entity_mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@


def call_entity_method_with_timeout(entity_callable, timeout=300, **kwargs):
"""Call Entity callable with a custom timeout
"""Call Entity callable with a custom timeout.
:param entity_callable, the entity method object to call
:param timeout: the time to wait for the method call to finish
Expand Down Expand Up @@ -211,7 +211,7 @@ def _payload(fields, values):
elif isinstance(field, ListField):

def parse(obj):
"""parse obj payload if it is an Entity"""
"""Parse obj payload if it is an Entity."""
if isinstance(obj, Entity):
return _payload(obj.get_fields(), obj.get_values())
return obj
Expand Down Expand Up @@ -530,6 +530,7 @@ def get_values(self):
return attrs

def __repr__(self):
"""Return a string representation of the current object."""
kv_pairs = ", ".join(
f"{key}={value!r}"
for key, value in self.get_values().items()
Expand All @@ -538,7 +539,9 @@ def __repr__(self):
return f'{self.__module__}.{type(self).__name__}({kv_pairs})'

def to_json(self):
r"""Create a JSON encoded string with Entity properties. Ex:
r"""Create a JSON encoded string with Entity properties.
Ex:
>>> from nailgun import entities, config
>>> kwargs = {
Expand All @@ -555,6 +558,7 @@ def to_json(self):

def to_json_dict(self, filter_fcn=None):
"""Create a dict with Entity properties for json encoding.
It can be overridden by subclasses for each standard serialization
doesn't work. By default it call _to_json_dict on OneToOne fields
and build a list calling the same method on each OneToMany object's
Expand Down Expand Up @@ -591,8 +595,9 @@ def to_json_dict(self, filter_fcn=None):
return json_dct

def __eq__(self, other):
"""Compare two entities based on their properties. Even nested
objects are considered for equality
"""Compare two entities based on their properties.
Even nested objects are considered for equality.
:param other: entity to compare self to
:return: boolean indicating if entities are equal or not
Expand All @@ -602,15 +607,16 @@ def __eq__(self, other):
return self.to_json_dict() == other.to_json_dict()

def compare(self, other, filter_fcn=None):
"""Returns True if properties can be compared in terms of eq.
"""Return True if properties can be compared in terms of eq.
Entity's Fields can be filtered accordingly to 'filter_fcn'.
This callable receives field's name as first parameter and field itself
as second parameter.
It must return True if field's value should be included on
comparison and False otherwise. If not provided field's marked as
unique will not be compared by default. 'id' and 'name' are examples of
unique fields commonly ignored. Check Entities fields for fields marked
with 'unique=True'
with 'unique=True'.
:param other: entity to compare
Expand All @@ -622,15 +628,15 @@ def compare(self, other, filter_fcn=None):
if filter_fcn is None:

def filter_unique(_, field):
"""Filter function for unique fields"""
"""Filter function for unique fields."""
return not field.unique

filter_fcn = filter_unique

return self.to_json_dict(filter_fcn) == other.to_json_dict(filter_fcn)

def entity_with_parent(self, **parent):
"""Returns modified entity by adding parent entity
"""Return modified entity by adding parent entity.
:parent dict: optional, The key/value pair of base entity else fetch from the fields
"""
Expand All @@ -651,7 +657,7 @@ def entity_with_parent(self, **parent):


class EntityDeleteMixin:
"""This mixin provides the ability to delete an entity.
"""Provide the ability to delete an entity.
The methods provided by this class work together. The call tree looks like
this::
Expand Down Expand Up @@ -698,7 +704,6 @@ def delete(self, synchronous=True, timeout=None):
out.
"""

response = self.delete_raw()
response.raise_for_status()

Expand All @@ -717,7 +722,7 @@ def delete(self, synchronous=True, timeout=None):


class EntityReadMixin:
"""This mixin provides the ability to read an entity.
"""Provide the ability to read an entity.
The methods provided by this class work together. The call tree looks like
this::
Expand Down Expand Up @@ -849,7 +854,7 @@ def read(self, entity=None, attrs=None, ignore=None, params=None):


class EntityCreateMixin:
"""This mixin provides the ability to create an entity.
"""Provide the ability to create an entity.
The methods provided by this class work together. The call tree looks like
this::
Expand Down Expand Up @@ -985,7 +990,7 @@ def create(self, create_missing=None):


class EntityUpdateMixin:
"""This mixin provides the ability to update an entity.
"""Provide the ability to update an entity.
The methods provided by this class work together. The call tree looks
like this::
Expand Down Expand Up @@ -1084,7 +1089,7 @@ def update(self, fields=None):


class EntitySearchMixin:
"""This mixin provides the ability to search for entities.
"""Provide the ability to search for entities.
The methods provided by this class work together. The call tree looks like
this::
Expand Down Expand Up @@ -1444,7 +1449,7 @@ def search_filter(entities, filters):


def to_json_serializable(obj):
"""Transforms obj into a json serializable object.
"""Transform obj into a json serializable object.
:param obj: entity or any json serializable object
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ select = [
"C", # complexity
"C4", # flake8-comprehensions
"COM818", # Trailing comma on bare tuple prohibited
# "D", # docstrings
"D", # docstrings
"E", # pycodestyle
"F", # pyflakes/autoflake
"G", # flake8-logging-format
Expand Down
3 changes: 2 additions & 1 deletion tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def test_false(self):
self.assertFalse(client._content_type_is_json(kwargs))

def test_false_with_no_headers(self):
"""If no headers passed should return None"""
"""If no headers passed should return None."""
self.assertFalse(client._content_type_is_json({}))


Expand Down Expand Up @@ -63,6 +63,7 @@ class ClientTestCase(TestCase):
"""Tests for functions in :mod:`nailgun.client`."""

def setUp(self):
"""Set up some common variables."""
self.bogus_url = gen_alpha()
self.mock_response = mock.Mock(status_code=200)

Expand Down
3 changes: 2 additions & 1 deletion tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def test_init(self):

def test_init_invalid(self):
"""Test instantiating :class: `nailgun.config.BaseServerConfig`.
Assert that configs with invalid versions do not load.
"""
with self.assertRaises(InvalidVersion):
Expand Down Expand Up @@ -171,7 +172,7 @@ def test_init(self):
)

def test_raise_config_file_error(self):
"""Should raise error if path not found"""
"""Should raise error if path not found."""
with self.assertRaises(ConfigFileError):
_get_config_file_path('foo', 'bar')

Expand Down
Loading

0 comments on commit 94aa505

Please sign in to comment.