5
|
1 """
|
|
2 methods for casting data
|
|
3 """
|
|
4
|
|
5 import datetime
|
|
6 from collections import OrderedDict
|
|
7
|
|
8
|
|
9 try:
|
|
10 # python2
|
|
11 string = (str, unicode)
|
|
12 except NameError:
|
|
13 # python3
|
|
14 string = (str,)
|
|
15
|
|
16 def isstring(f):
|
|
17 return isinstance(f, string)
|
|
18
|
|
19 # types we expect to encounter
|
|
20 types = OrderedDict([('int', int),
|
|
21 ('float', float),
|
|
22 ('str', str)])
|
|
23
|
|
24
|
|
25 def keyvalue(_string, separator='='):
|
|
26 """
|
|
27 cast `_string` to [`key`, `value`] split on `separator`
|
|
28 """
|
|
29
|
|
30 if separator not in _string:
|
|
31 raise AssertionError("Separator '{}' not in '{}'".format(separator,
|
|
32 _string))
|
|
33 return _string.split(separator, 1)
|
|
34
|
|
35
|
|
36 def string_to_bool(string):
|
|
37 """cast a string to a `bool`"""
|
|
38 return {'true': True,
|
|
39 'false': False}.get(string.lower())
|
|
40
|
|
41
|
|
42 def unify(item, codec='utf-8'):
|
|
43 """cast item to unicode carefully if a string; otherwise, return it"""
|
|
44
|
|
45 if not isinstance(item, string):
|
|
46 return item
|
|
47 return item.encode(codec, 'ignore')
|
|
48
|
|
49
|
|
50 def datetime_handler(x):
|
|
51 """handler for JSON serialization"""
|
|
52
|
|
53 # Ref
|
|
54 # https://stackoverflow.com/questions/35869985/datetime-datetime-is-not-json-serializable
|
|
55 if isinstance(x, datetime.datetime):
|
|
56 return x.isoformat()
|
|
57
|
|
58 # go through the normal types for type casting
|
|
59 # (and hope nothing "weird" happens")
|
|
60 for _type in types.values():
|
|
61 try:
|
|
62 return str(_type(x))
|
|
63 except ValueError:
|
|
64 continue
|
|
65
|
|
66 # worst case scenario
|
|
67 raise TypeError("Unknown type: {x}".format(x=x))
|
|
68
|
|
69
|
|
70 def isiterable(obj):
|
|
71 """determines if `obj` is iterable"""
|
|
72
|
|
73 try:
|
|
74 iter(obj)
|
|
75 return True
|
|
76 except TypeError:
|
|
77 return False
|
|
78
|
|
79
|
|
80 def iterable(obj):
|
|
81 """make an iterable out of `obj`"""
|
|
82 return obj if isiterable(obj) else (obj,)
|
|
83
|
|
84
|
|
85 def infer(strings, types=types.values()):
|
|
86 """
|
|
87 inferrred the type of a bunch of strings
|
|
88 """
|
|
89 for _type in types:
|
|
90 for s in strings:
|
|
91 try:
|
|
92 _type(s)
|
|
93 except ValueError:
|
|
94 break
|
|
95 else:
|
|
96 return _type
|
|
97
|
|
98
|
|
99 def cast(strings, types=types.values()):
|
|
100 """
|
|
101 cast `strings` to `types` based on inference
|
|
102 """
|
|
103
|
|
104 _type = infer(strings, types=types)
|
|
105 return [_type(s) for s in strings]
|