New code to guess types
This commit is contained in:
parent
f410b112af
commit
73aa0dd2a1
@ -23,98 +23,47 @@
|
||||
import datetime
|
||||
import keyword
|
||||
import re
|
||||
from typing import Union
|
||||
from typing import Union, Set, Any, Callable
|
||||
|
||||
|
||||
RELATION_NAME_REGEXP = re.compile(r'^[_a-z][_a-z0-9]*$', re.IGNORECASE)
|
||||
|
||||
|
||||
class Rstring(str):
|
||||
|
||||
'''String subclass with some custom methods'''
|
||||
|
||||
int_regexp = re.compile(r'^[\+\-]{0,1}[0-9]+$')
|
||||
float_regexp = re.compile(r'^[\+\-]{0,1}[0-9]+(\.([0-9])+)?$')
|
||||
date_regexp = re.compile(
|
||||
_date_regexp = re.compile(
|
||||
r'^([0-9]{1,4})(\\|-|/)([0-9]{1,2})(\\|-|/)([0-9]{1,2})$'
|
||||
)
|
||||
CastValue = Union[str, int, float, 'Rdate']
|
||||
|
||||
|
||||
def guess_type(value: str) -> Set[Callable[[Any], Any]]:
|
||||
r: Set[Callable[[Any], Any]] = {str}
|
||||
if _date_regexp.match(value) is not None:
|
||||
r.add(Rdate)
|
||||
|
||||
def autocast(self) -> Union[int, float, 'Rdate', 'Rstring']:
|
||||
'''
|
||||
Returns the automatic cast for this
|
||||
value.
|
||||
'''
|
||||
try:
|
||||
return self._autocast
|
||||
except:
|
||||
int(value)
|
||||
r.add(int)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
self._autocast = self # type: Union[int, float, 'Rdate', 'Rstring']
|
||||
if len(self) > 0:
|
||||
if self.isInt():
|
||||
self._autocast = int(self)
|
||||
elif self.isFloat():
|
||||
self._autocast = float(self)
|
||||
elif self.isDate():
|
||||
self._autocast = Rdate(self)
|
||||
return self._autocast
|
||||
|
||||
def isInt(self) -> bool:
|
||||
'''Returns true if the string represents an int number
|
||||
it only considers as int numbers the strings matching
|
||||
the following regexp:
|
||||
r'^[\+\-]{0,1}[0-9]+$'
|
||||
'''
|
||||
return Rstring.int_regexp.match(self) is not None
|
||||
|
||||
def isFloat(self) -> bool:
|
||||
'''Returns true if the string represents a float number
|
||||
it only considers as float numbers, the strings matching
|
||||
the following regexp:
|
||||
r'^[\+\-]{0,1}[0-9]+(\.([0-9])+)?$'
|
||||
'''
|
||||
return Rstring.float_regexp.match(self) is not None
|
||||
|
||||
def isDate(self) -> bool:
|
||||
'''Returns true if the string represents a date,
|
||||
in the format YYYY-MM-DD. as separators '-' , '\', '/' are allowed.
|
||||
As side-effect, the date object will be stored for future usage, so
|
||||
no more parsings are needed
|
||||
'''
|
||||
try:
|
||||
return self._isdate # type: ignore
|
||||
except:
|
||||
float(value)
|
||||
r.add(float)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
r = Rstring.date_regexp.match(self)
|
||||
if r is None:
|
||||
self._isdate = False
|
||||
self._date = None
|
||||
return False
|
||||
|
||||
try: # Any of the following operations can generate an exception, if it happens, we aren't dealing with a date
|
||||
year = int(r.group(1))
|
||||
month = int(r.group(3))
|
||||
day = int(r.group(5))
|
||||
d = datetime.date(year, month, day)
|
||||
self._isdate = True
|
||||
self._date = d
|
||||
return True
|
||||
except:
|
||||
self._isdate = False
|
||||
self._date = None
|
||||
return False
|
||||
|
||||
def getDate(self):
|
||||
'''Returns the datetime.date object or None'''
|
||||
try:
|
||||
return self._date
|
||||
except:
|
||||
self.isDate()
|
||||
return self._date
|
||||
return r
|
||||
|
||||
|
||||
class Rdate (object):
|
||||
def cast(value: str, guesses: Set) -> CastValue:
|
||||
if int in guesses:
|
||||
return int(value)
|
||||
if Rdate in guesses:
|
||||
print(repr(value), guesses)
|
||||
return Rdate(value)
|
||||
if float in guesses:
|
||||
return float(value)
|
||||
return value
|
||||
|
||||
|
||||
class Rdate(datetime.date):
|
||||
'''Represents a date'''
|
||||
|
||||
def __init__(self, date):
|
||||
|
Loading…
Reference in New Issue
Block a user