Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/sqlalchemy/processors.py: 24%
86 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +0000
1# sqlalchemy/processors.py
2# Copyright (C) 2010-2023 the SQLAlchemy authors and contributors
3# <see AUTHORS file>
4# Copyright (C) 2010 Gaetan de Menten gdementen@gmail.com
5#
6# This module is part of SQLAlchemy and is released under
7# the MIT License: https://www.opensource.org/licenses/mit-license.php
9"""defines generic type conversion functions, as used in bind and result
10processors.
12They all share one common characteristic: None is passed through unchanged.
14"""
16import codecs
17import datetime
18import re
20from . import util
23def str_to_datetime_processor_factory(regexp, type_):
24 rmatch = regexp.match
25 # Even on python2.6 datetime.strptime is both slower than this code
26 # and it does not support microseconds.
27 has_named_groups = bool(regexp.groupindex)
29 def process(value):
30 if value is None:
31 return None
32 else:
33 try:
34 m = rmatch(value)
35 except TypeError as err:
36 util.raise_(
37 ValueError(
38 "Couldn't parse %s string '%r' "
39 "- value is not a string." % (type_.__name__, value)
40 ),
41 from_=err,
42 )
43 if m is None:
44 raise ValueError(
45 "Couldn't parse %s string: "
46 "'%s'" % (type_.__name__, value)
47 )
48 if has_named_groups:
49 groups = m.groupdict(0)
50 return type_(
51 **dict(
52 list(
53 zip(
54 iter(groups.keys()),
55 list(map(int, iter(groups.values()))),
56 )
57 )
58 )
59 )
60 else:
61 return type_(*list(map(int, m.groups(0))))
63 return process
66def py_fallback():
67 def to_unicode_processor_factory(encoding, errors=None):
68 decoder = codecs.getdecoder(encoding)
70 def process(value):
71 if value is None:
72 return None
73 else:
74 # decoder returns a tuple: (value, len). Simply dropping the
75 # len part is safe: it is done that way in the normal
76 # 'xx'.decode(encoding) code path.
77 return decoder(value, errors)[0]
79 return process
81 def to_conditional_unicode_processor_factory(encoding, errors=None):
82 decoder = codecs.getdecoder(encoding)
84 def process(value):
85 if value is None:
86 return None
87 elif isinstance(value, util.text_type):
88 return value
89 else:
90 # decoder returns a tuple: (value, len). Simply dropping the
91 # len part is safe: it is done that way in the normal
92 # 'xx'.decode(encoding) code path.
93 return decoder(value, errors)[0]
95 return process
97 def to_decimal_processor_factory(target_class, scale):
98 fstring = "%%.%df" % scale
100 def process(value):
101 if value is None:
102 return None
103 else:
104 return target_class(fstring % value)
106 return process
108 def to_float(value): # noqa
109 if value is None:
110 return None
111 else:
112 return float(value)
114 def to_str(value): # noqa
115 if value is None:
116 return None
117 else:
118 return str(value)
120 def int_to_boolean(value): # noqa
121 if value is None:
122 return None
123 else:
124 return bool(value)
126 DATETIME_RE = re.compile(
127 r"(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)(?:\.(\d+))?"
128 )
129 TIME_RE = re.compile(r"(\d+):(\d+):(\d+)(?:\.(\d+))?")
130 DATE_RE = re.compile(r"(\d+)-(\d+)-(\d+)")
132 str_to_datetime = str_to_datetime_processor_factory( # noqa
133 DATETIME_RE, datetime.datetime
134 )
135 str_to_time = str_to_datetime_processor_factory( # noqa
136 TIME_RE, datetime.time
137 ) # noqa
138 str_to_date = str_to_datetime_processor_factory( # noqa
139 DATE_RE, datetime.date
140 ) # noqa
141 return locals()
144try:
145 from sqlalchemy.cprocessors import DecimalResultProcessor # noqa
146 from sqlalchemy.cprocessors import int_to_boolean # noqa
147 from sqlalchemy.cprocessors import str_to_date # noqa
148 from sqlalchemy.cprocessors import str_to_datetime # noqa
149 from sqlalchemy.cprocessors import str_to_time # noqa
150 from sqlalchemy.cprocessors import to_float # noqa
151 from sqlalchemy.cprocessors import to_str # noqa
152 from sqlalchemy.cprocessors import UnicodeResultProcessor # noqa
154 def to_unicode_processor_factory(encoding, errors=None):
155 if errors is not None:
156 return UnicodeResultProcessor(encoding, errors).process
157 else:
158 return UnicodeResultProcessor(encoding).process
160 def to_conditional_unicode_processor_factory(encoding, errors=None):
161 if errors is not None:
162 return UnicodeResultProcessor(encoding, errors).conditional_process
163 else:
164 return UnicodeResultProcessor(encoding).conditional_process
166 def to_decimal_processor_factory(target_class, scale):
167 # Note that the scale argument is not taken into account for integer
168 # values in the C implementation while it is in the Python one.
169 # For example, the Python implementation might return
170 # Decimal('5.00000') whereas the C implementation will
171 # return Decimal('5'). These are equivalent of course.
172 return DecimalResultProcessor(target_class, "%%.%df" % scale).process
175except ImportError:
176 globals().update(py_fallback())