Skip to content

Commit

Permalink
Subclass list
Browse files Browse the repository at this point in the history
  • Loading branch information
goanpeca committed Apr 27, 2020
1 parent f5cf9a2 commit 39f3f8d
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 21 deletions.
2 changes: 1 addition & 1 deletion colosseum/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from .validators import (ValidationError, is_border_spacing, is_color,
is_cursor, is_integer, is_length, is_number,
is_percentage, is_quote, is_rect, is_uri)
is_percentage, is_quote, is_rect)


class Choices:
Expand Down
1 change: 0 additions & 1 deletion colosseum/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,6 @@ def uri(value):
raise ValueError('Invalid url %s' % value)



##############################################################################
# Cursor
##############################################################################
Expand Down
2 changes: 2 additions & 0 deletions colosseum/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ def is_quote(value):
value = parser.quotes(value)
except ValueError:
raise ValidationError('Value {value} is not a valid quote'.format(value=value))


URI_RE = re.compile(r"""(
(?:url\(\s?'[A-Za-z0-9\./\:\?]*'\s?\)) # Single quotes and optional spaces
|
Expand Down
53 changes: 36 additions & 17 deletions colosseum/wrappers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from collections import OrderedDict
from collections.abc import Sequence


class BorderSpacing:
Expand Down Expand Up @@ -154,7 +153,6 @@ class Border(Shorthand):
VALID_KEYS = ['border_width', 'border_style', 'border_color']



class Uri:
"""Wrapper for a url."""

Expand All @@ -172,46 +170,67 @@ def url(self):
return self._url


class ImmutableList(Sequence):
class ImmutableList(list):
"""Immutable list to store list properties."""

def __init__(self, iterable=()):
self._data = tuple(iterable)
super().__init__(iterable)

def _get_error_message(self, err):
return str(err).replace('tuple', self.__class__.__name__, 1)
return str(err).replace('list', self.__class__.__name__, 1)

def __eq__(self, other):
return other.__class__ == self.__class__ and self._data == other._data
# def __eq__(self, other):
# return other.__class__ == self.__class__ and self == other

def __getitem__(self, index):
try:
return self._data[index]
return super().__getitem__(index)
except Exception as err:
error_msg = self._get_error_message(err)
raise err.__class__(error_msg)

def __len__(self):
return len(self._data)
def __setitem__(self, index, value):
raise TypeError("{} values cannot be changed!".format(self.__class__.__name__))

def __hash__(self):
return hash((self.__class__.__name__, self._data))
return hash((self.__class__.__name__, tuple(self)))

def __repr__(self):
class_name = self.__class__.__name__
if len(self._data) > 1:
text = '{class_name}([{data}])'.format(data=str(self._data)[1:-1], class_name=class_name)
elif len(self._data) == 1:
text = '{class_name}([{data}])'.format(data=str(self._data)[1:-2], class_name=class_name)
if len(self) != 0:
text = '{class_name}([{data}])'.format(data=repr(list(self))[1:-1], class_name=class_name)
else:
text = '{class_name}()'.format(class_name=class_name)

return text

def __str__(self):
return ', '.join(str(v) for v in self._data)
return ', '.join(str(v) for v in self)

def copy(self):
return self.__class__(self._data)
return self.__class__(self)

# Disable mutating methods
def append(self, object):
raise TypeError("{} values cannot be changed!".format(self.__class__.__name__))

def extend(self, iterable):
raise TypeError("{} values cannot be changed!".format(self.__class__.__name__))

def insert(self, index, object):
raise TypeError("{} values cannot be changed!".format(self.__class__.__name__))

def pop(self, index=None):
raise TypeError("{} values cannot be changed!".format(self.__class__.__name__))

def remove(self, value):
raise TypeError("{} values cannot be changed!".format(self.__class__.__name__))

def reverse(self):
raise TypeError("{} values cannot be changed!".format(self.__class__.__name__))

def sort(self, cmp=None, key=None, reverse=False):
raise TypeError("{} values cannot be changed!".format(self.__class__.__name__))


class Cursor(ImmutableList):
Expand Down
3 changes: 1 addition & 2 deletions tests/test_declaration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
from colosseum.constants import (AUTO, BLOCK, INHERIT, INITIAL, INLINE, LEFT,
REVERT, RIGHT, RTL, TABLE, UNSET, Choices,
OtherProperty)
from colosseum.declaration import (CSS, validated_list_property,
validated_property)
from colosseum.declaration import CSS, validated_property
from colosseum.units import percent, px
from colosseum.validators import (is_color, is_integer, is_length, is_number,
is_percentage, is_uri)
Expand Down
2 changes: 2 additions & 0 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,8 @@ def test_parse_border_shorthand_invalid_too_many_items(self):

with self.assertRaises(ValueError):
func('black solid thick black thick')


class ParseUriTests(TestCase):

def test_url_valid_single_quotes_url(self):
Expand Down

0 comments on commit 39f3f8d

Please sign in to comment.