|
14 | 14 | from pynamodb.attributes import (
|
15 | 15 | BinarySetAttribute, BinaryAttribute, NumberSetAttribute, NumberAttribute,
|
16 | 16 | UnicodeAttribute, UnicodeSetAttribute, UTCDateTimeAttribute, BooleanAttribute, MapAttribute,
|
17 |
| - ListAttribute, JSONAttribute, TTLAttribute, _fast_parse_utc_datestring, |
18 |
| - VersionAttribute) |
| 17 | + ListAttribute, JSONAttribute, TTLAttribute, VersionAttribute) |
19 | 18 | from pynamodb.constants import (
|
20 |
| - DATETIME_FORMAT, DEFAULT_ENCODING, NUMBER, STRING, STRING_SET, NUMBER_SET, BINARY_SET, |
| 19 | + DEFAULT_ENCODING, NUMBER, STRING, STRING_SET, NUMBER_SET, BINARY_SET, |
21 | 20 | BINARY, BOOLEAN,
|
22 | 21 | )
|
23 | 22 | from pynamodb.models import Model
|
@@ -128,87 +127,53 @@ class TestUTCDateTimeAttribute:
|
128 | 127 | """
|
129 | 128 | Tests UTCDateTime attributes
|
130 | 129 | """
|
| 130 | + |
| 131 | + def setup(self): |
| 132 | + self.attr = UTCDateTimeAttribute() |
| 133 | + self.dt = datetime(2047, 1, 6, 8, 21, 30, 2000, tzinfo=timezone.utc) |
| 134 | + |
131 | 135 | def test_utc_datetime_attribute(self):
|
132 | 136 | """
|
133 | 137 | UTCDateTimeAttribute.default
|
134 | 138 | """
|
135 |
| - attr = UTCDateTimeAttribute() |
136 |
| - assert attr is not None |
| 139 | + attr = UTCDateTimeAttribute(default=self.dt) |
137 | 140 | assert attr.attr_type == STRING
|
138 |
| - tstamp = datetime.now() |
139 |
| - attr = UTCDateTimeAttribute(default=tstamp) |
140 |
| - assert attr.default == tstamp |
141 |
| - |
142 |
| - def test_utc_date_time_deserialize(self): |
143 |
| - """ |
144 |
| - UTCDateTimeAttribute.deserialize |
145 |
| - """ |
146 |
| - tstamp = datetime.now(timezone.utc) |
147 |
| - attr = UTCDateTimeAttribute() |
148 |
| - assert attr.deserialize(tstamp.strftime(DATETIME_FORMAT)) == tstamp |
| 141 | + assert attr.default == self.dt |
149 | 142 |
|
150 |
| - def test_dateutil_parser_fallback(self): |
| 143 | + def test_utc_date_time_serialize(self): |
151 | 144 | """
|
152 |
| - UTCDateTimeAttribute.deserialize |
| 145 | + UTCDateTimeAttribute.serialize |
153 | 146 | """
|
154 |
| - expected_value = datetime(2047, 1, 6, 8, 21, tzinfo=timezone.utc) |
155 |
| - attr = UTCDateTimeAttribute() |
156 |
| - assert attr.deserialize('January 6, 2047 at 8:21:00AM UTC') == expected_value |
| 147 | + assert self.attr.serialize(self.dt) == '2047-01-06T08:21:30.002000+0000' |
157 | 148 |
|
158 |
| - @patch('pynamodb.attributes.datetime') |
159 |
| - @patch('pynamodb.attributes.parse') |
160 |
| - def test_utc_date_time_deserialize_parse_args(self, parse_mock, datetime_mock): |
| 149 | + def test_utc_date_time_deserialize(self): |
161 | 150 | """
|
162 | 151 | UTCDateTimeAttribute.deserialize
|
163 | 152 | """
|
164 |
| - tstamp = datetime.now(timezone.utc) |
165 |
| - attr = UTCDateTimeAttribute() |
166 |
| - |
167 |
| - tstamp_str = tstamp.strftime(DATETIME_FORMAT) |
168 |
| - attr.deserialize(tstamp_str) |
169 |
| - |
170 |
| - parse_mock.assert_not_called() |
171 |
| - datetime_mock.strptime.assert_not_called() |
172 |
| - |
173 |
| - def test_utc_date_time_serialize(self): |
174 |
| - """ |
175 |
| - UTCDateTimeAttribute.serialize |
176 |
| - """ |
177 |
| - tstamp = datetime.now() |
178 |
| - attr = UTCDateTimeAttribute() |
179 |
| - assert attr.serialize(tstamp) == tstamp.replace(tzinfo=timezone.utc).strftime(DATETIME_FORMAT) |
180 |
| - |
181 |
| - def test__fast_parse_utc_datestring_roundtrips(self): |
182 |
| - tstamp = datetime.now(timezone.utc) |
183 |
| - tstamp_str = tstamp.strftime(DATETIME_FORMAT) |
184 |
| - assert _fast_parse_utc_datestring(tstamp_str) == tstamp |
185 |
| - |
186 |
| - def test__fast_parse_utc_datestring_no_microseconds(self): |
187 |
| - expected_value = datetime(2047, 1, 6, 8, 21, tzinfo=timezone.utc) |
188 |
| - assert _fast_parse_utc_datestring('2047-01-06T08:21:00.0+0000') == expected_value |
| 153 | + assert self.attr.deserialize('2047-01-06T08:21:30.002000+0000') == self.dt |
189 | 154 |
|
190 | 155 | @pytest.mark.parametrize(
|
191 | 156 | "invalid_string",
|
192 | 157 | [
|
193 |
| - '2.47-01-06T08:21:00.0+0000', |
194 |
| - '2047-01-06T08:21:00.+0000', |
195 |
| - '2047-01-06T08:21:00.0', |
196 |
| - '2047-01-06 08:21:00.0+0000', |
197 |
| - 'abcd-01-06T08:21:00.0+0000', |
198 |
| - '2047-ab-06T08:21:00.0+0000', |
199 |
| - '2047-01-abT08:21:00.0+0000', |
200 |
| - '2047-01-06Tab:21:00.0+0000', |
201 |
| - '2047-01-06T08:ab:00.0+0000', |
202 |
| - '2047-01-06T08:ab:00.0+0000', |
203 |
| - '2047-01-06T08:21:00.a+0000', |
204 |
| - '2047-01-06T08:21:00.0.1+0000', |
205 |
| - '2047-01-06T08:21:00.0+00000' |
| 158 | + '2047-01-06T08:21:30.002000', # naive datetime |
| 159 | + '2047-01-06T08:21:30+0000', # missing microseconds |
| 160 | + '2047-01-06T08:21:30.001+0000', # shortened microseconds |
| 161 | + '2047-01-06T08:21:30.002000-0000' # "negative" utc |
| 162 | + '2047-01-06T08:21:30.002000+0030' # not utc |
| 163 | + '2047-01-06 08:21:30.002000+0000', # missing separator |
| 164 | + '2.47-01-06T08:21:30.002000+0000', |
| 165 | + 'abcd-01-06T08:21:30.002000+0000', |
| 166 | + '2047-ab-06T08:21:30.002000+0000', |
| 167 | + '2047-01-abT08:21:30.002000+0000', |
| 168 | + '2047-01-06Tab:21:30.002000+0000', |
| 169 | + '2047-01-06T08:ab:30.002000+0000', |
| 170 | + '2047-01-06T08:21:ab.002000+0000', |
| 171 | + '2047-01-06T08:21:30.a00000+0000', |
206 | 172 | ]
|
207 | 173 | )
|
208 |
| - def test__fast_parse_utc_datestring_invalid_input(self, invalid_string): |
| 174 | + def test_utc_date_time_invalid(self, invalid_string): |
209 | 175 | with pytest.raises(ValueError, match="does not match format"):
|
210 |
| - _fast_parse_utc_datestring(invalid_string) |
211 |
| - |
| 176 | + self.attr.deserialize(invalid_string) |
212 | 177 |
|
213 | 178 |
|
214 | 179 | class TestBinaryAttribute:
|
|
0 commit comments