Make Users model inherit from sequence

This gives the same behaviour as you’d expect inheriting from `list`.
However because `list` is written with a lot of optimisations it’s
unpredictable to inherit from.

Python provides a series of abstract base classes that you can inherit
from instead.

Further reading:
1. https://docs.python.org/3.4/library/collections.abc.html#collections.abc.Sequence
2. https://treyhunner.com/2019/04/why-you-shouldnt-inherit-from-list-and-dict-in-python/
This commit is contained in:
Chris Hill-Scott
2019-06-05 10:34:32 +01:00
parent 8492496c34
commit f8fb2d3c8f

View File

@@ -1,3 +1,5 @@
from collections.abc import Sequence
from flask import abort, current_app, request, session
from flask_login import AnonymousUserMixin, UserMixin, login_user
from notifications_python_client.errors import HTTPError
@@ -517,15 +519,18 @@ class AnonymousUser(AnonymousUserMixin):
return Organisation(None)
class Users():
class Users(Sequence):
client = user_api_client.get_users_for_service
def __init__(self, service_id):
self.users = self.client(service_id)
def __iter__(self):
return (User(user) for user in self.users)
def __getitem__(self, index):
return User(self.users[index])
def __len__(self):
return len(self.users)
def __add__(self, other):
return list(self) + list(other)
@@ -540,11 +545,14 @@ class InvitedUsers(Users):
client = invite_api_client.get_invites_for_service
model = InvitedUser
def __iter__(self):
return (
self.model(**invite) for invite in self.users
if invite['status'] != 'accepted'
)
def __init__(self, service_id):
self.users = [
user for user in self.client(service_id)
if user['status'] != 'accepted'
]
def __getitem__(self, index):
return self.model(**self.users[index])
class OrganisationInvitedUsers(InvitedUsers):