Improve NumberRange parsing
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from collections import Iterable
|
||||||
|
from decimal import Decimal
|
||||||
try:
|
try:
|
||||||
from functools import total_ordering
|
from functools import total_ordering
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -13,20 +15,21 @@ class NumberRangeException(Exception):
|
|||||||
|
|
||||||
class RangeBoundsException(NumberRangeException):
|
class RangeBoundsException(NumberRangeException):
|
||||||
def __init__(self, min_value, max_value):
|
def __init__(self, min_value, max_value):
|
||||||
self.message = 'Min value %d is bigger than max value %d.' % (
|
self.message = 'Min value %s is bigger than max value %s.' % (
|
||||||
min_value,
|
min_value,
|
||||||
max_value
|
max_value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def is_number(number):
|
||||||
|
return isinstance(number, (float, int, Decimal))
|
||||||
|
|
||||||
|
|
||||||
def parse_number(number):
|
def parse_number(number):
|
||||||
if (
|
if number is None or number == '':
|
||||||
number == float('inf') or
|
|
||||||
number == -float('inf') or
|
|
||||||
number is None or
|
|
||||||
number == ''
|
|
||||||
):
|
|
||||||
return None
|
return None
|
||||||
|
elif is_number(number):
|
||||||
|
return number
|
||||||
else:
|
else:
|
||||||
return int(number)
|
return int(number)
|
||||||
|
|
||||||
@@ -46,17 +49,39 @@ class NumberRange(object):
|
|||||||
self.parse_integer(arg)
|
self.parse_integer(arg)
|
||||||
elif isinstance(arg, six.string_types):
|
elif isinstance(arg, six.string_types):
|
||||||
self.parse_string(arg)
|
self.parse_string(arg)
|
||||||
|
elif isinstance(arg, Iterable):
|
||||||
|
self.parse_sequence(arg)
|
||||||
elif hasattr(arg, 'lower') and hasattr(arg, 'upper'):
|
elif hasattr(arg, 'lower') and hasattr(arg, 'upper'):
|
||||||
self.parse_object(arg)
|
self.parse_object(arg)
|
||||||
|
|
||||||
|
if self.lower > self.upper:
|
||||||
|
raise RangeBoundsException(self.lower, self.upper)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def lower(self):
|
||||||
|
return self._lower
|
||||||
|
|
||||||
|
@lower.setter
|
||||||
|
def lower(self, value):
|
||||||
|
if value is None:
|
||||||
|
self._lower = -float('inf')
|
||||||
|
self._lower = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def upper(self):
|
||||||
|
return self._upper
|
||||||
|
|
||||||
|
@upper.setter
|
||||||
|
def upper(self, value):
|
||||||
|
if value is None:
|
||||||
|
self._upper = float('inf')
|
||||||
|
self._upper = value
|
||||||
|
|
||||||
def parse_object(self, obj):
|
def parse_object(self, obj):
|
||||||
self.lower = obj.lower
|
self.lower = obj.lower
|
||||||
self.upper = obj.upper
|
self.upper = obj.upper
|
||||||
if not obj.lower_inc:
|
self.lower_inc = obj.lower_inc
|
||||||
self.lower += 1
|
self.upper_inc = obj.upper_inc
|
||||||
|
|
||||||
if not obj.upper_inc:
|
|
||||||
self.upper -= 1
|
|
||||||
|
|
||||||
def parse_string(self, value):
|
def parse_string(self, value):
|
||||||
if ',' not in value:
|
if ',' not in value:
|
||||||
@@ -66,8 +91,6 @@ class NumberRange(object):
|
|||||||
|
|
||||||
def parse_sequence(self, seq):
|
def parse_sequence(self, seq):
|
||||||
lower, upper = seq
|
lower, upper = seq
|
||||||
if lower > upper:
|
|
||||||
raise RangeBoundsException(lower, upper)
|
|
||||||
self.lower = parse_number(lower)
|
self.lower = parse_number(lower)
|
||||||
self.upper = parse_number(upper)
|
self.upper = parse_number(upper)
|
||||||
self.lower_inc = self.upper_inc = True
|
self.lower_inc = self.upper_inc = True
|
||||||
|
Reference in New Issue
Block a user