Merge lp:~ian-clatworthy/bzr/faster-log into lp:bzr
- faster-log
- Merge into bzr.dev
Proposed by
Ian Clatworthy
Status: | Merged |
---|---|
Approved by: | John A Meinel |
Approved revision: | not available |
Merged at revision: | not available |
Proposed branch: | lp:~ian-clatworthy/bzr/faster-log |
Merge into: | lp:bzr |
Diff against target: |
331 lines (+121/-49) 5 files modified
NEWS (+2/-0) bzrlib/log.py (+77/-47) bzrlib/osutils.py (+29/-0) bzrlib/revision.py (+5/-2) bzrlib/tests/test_osutils.py (+8/-0) |
To merge this branch: | bzr merge lp:~ian-clatworthy/bzr/faster-log |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
John A Meinel | Approve | ||
Review via email: mp+15416@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Ian Clatworthy (ian-clatworthy) wrote : | # |
Revision history for this message
John A Meinel (jameinel) wrote : | # |
As I understand, you don't actually change the actions, just how things are formatted, right? (You build up more stuff into fewer strings that get written out.)
I didn't go over it line-by-line, but as long as that is the general change it seems reasonable to me.
review:
Approve
Revision history for this message
Ian Clatworthy (ian-clatworthy) wrote : | # |
John A Meinel wrote:
> Review: Approve
> As I understand, you don't actually change the actions, just how things are formatted, right? (You build up more stuff into fewer strings that get written out.)
Right.
Ian C.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'NEWS' | |||
2 | --- NEWS 2009-11-30 04:49:31 +0000 | |||
3 | +++ NEWS 2009-11-30 12:45:30 +0000 | |||
4 | @@ -60,6 +60,8 @@ | |||
5 | 60 | Improvements | 60 | Improvements |
6 | 61 | ************ | 61 | ************ |
7 | 62 | 62 | ||
8 | 63 | * ``bzr log`` is now faster. (Ian Clatworthy) | ||
9 | 64 | |||
10 | 63 | * ``bzrlib.urlutils.local_path_from_url`` now accepts | 65 | * ``bzrlib.urlutils.local_path_from_url`` now accepts |
11 | 64 | 'file://localhost/' as well as 'file:///' URLs on POSIX. (Michael | 66 | 'file://localhost/' as well as 'file:///' URLs on POSIX. (Michael |
12 | 65 | Hudson) | 67 | Hudson) |
13 | 66 | 68 | ||
14 | === modified file 'bzrlib/log.py' | |||
15 | --- bzrlib/log.py 2009-10-29 03:32:42 +0000 | |||
16 | +++ bzrlib/log.py 2009-11-30 12:45:30 +0000 | |||
17 | @@ -83,6 +83,7 @@ | |||
18 | 83 | ) | 83 | ) |
19 | 84 | from bzrlib.osutils import ( | 84 | from bzrlib.osutils import ( |
20 | 85 | format_date, | 85 | format_date, |
21 | 86 | format_date_with_offset_in_original_timezone, | ||
22 | 86 | get_terminal_encoding, | 87 | get_terminal_encoding, |
23 | 87 | re_compile_checked, | 88 | re_compile_checked, |
24 | 88 | terminal_width, | 89 | terminal_width, |
25 | @@ -384,27 +385,28 @@ | |||
26 | 384 | :return: An iterator yielding LogRevision objects. | 385 | :return: An iterator yielding LogRevision objects. |
27 | 385 | """ | 386 | """ |
28 | 386 | rqst = self.rqst | 387 | rqst = self.rqst |
29 | 388 | levels = rqst.get('levels') | ||
30 | 389 | limit = rqst.get('limit') | ||
31 | 390 | diff_type = rqst.get('diff_type') | ||
32 | 387 | log_count = 0 | 391 | log_count = 0 |
33 | 388 | revision_iterator = self._create_log_revision_iterator() | 392 | revision_iterator = self._create_log_revision_iterator() |
34 | 389 | for revs in revision_iterator: | 393 | for revs in revision_iterator: |
35 | 390 | for (rev_id, revno, merge_depth), rev, delta in revs: | 394 | for (rev_id, revno, merge_depth), rev, delta in revs: |
36 | 391 | # 0 levels means show everything; merge_depth counts from 0 | 395 | # 0 levels means show everything; merge_depth counts from 0 |
37 | 392 | levels = rqst.get('levels') | ||
38 | 393 | if levels != 0 and merge_depth >= levels: | 396 | if levels != 0 and merge_depth >= levels: |
39 | 394 | continue | 397 | continue |
41 | 395 | diff = self._format_diff(rev, rev_id) | 398 | if diff_type is None: |
42 | 399 | diff = None | ||
43 | 400 | else: | ||
44 | 401 | diff = self._format_diff(rev, rev_id, diff_type) | ||
45 | 396 | yield LogRevision(rev, revno, merge_depth, delta, | 402 | yield LogRevision(rev, revno, merge_depth, delta, |
46 | 397 | self.rev_tag_dict.get(rev_id), diff) | 403 | self.rev_tag_dict.get(rev_id), diff) |
47 | 398 | limit = rqst.get('limit') | ||
48 | 399 | if limit: | 404 | if limit: |
49 | 400 | log_count += 1 | 405 | log_count += 1 |
50 | 401 | if log_count >= limit: | 406 | if log_count >= limit: |
51 | 402 | return | 407 | return |
52 | 403 | 408 | ||
57 | 404 | def _format_diff(self, rev, rev_id): | 409 | def _format_diff(self, rev, rev_id, diff_type): |
54 | 405 | diff_type = self.rqst.get('diff_type') | ||
55 | 406 | if diff_type is None: | ||
56 | 407 | return None | ||
58 | 408 | repo = self.branch.repository | 410 | repo = self.branch.repository |
59 | 409 | if len(rev.parent_ids) == 0: | 411 | if len(rev.parent_ids) == 0: |
60 | 410 | ancestor_id = _mod_revision.NULL_REVISION | 412 | ancestor_id = _mod_revision.NULL_REVISION |
61 | @@ -1291,7 +1293,7 @@ | |||
62 | 1291 | preferred_levels = 0 | 1293 | preferred_levels = 0 |
63 | 1292 | 1294 | ||
64 | 1293 | def __init__(self, to_file, show_ids=False, show_timezone='original', | 1295 | def __init__(self, to_file, show_ids=False, show_timezone='original', |
66 | 1294 | delta_format=None, levels=None, show_advice=False): | 1296 | delta_format=None, levels=None, show_advice=False): |
67 | 1295 | """Create a LogFormatter. | 1297 | """Create a LogFormatter. |
68 | 1296 | 1298 | ||
69 | 1297 | :param to_file: the file to output to | 1299 | :param to_file: the file to output to |
70 | @@ -1367,48 +1369,64 @@ | |||
71 | 1367 | else: | 1369 | else: |
72 | 1368 | return '' | 1370 | return '' |
73 | 1369 | 1371 | ||
75 | 1370 | def show_foreign_info(self, rev, indent): | 1372 | def show_properties(self, revision, indent): |
76 | 1373 | """Displays the custom properties returned by each registered handler. | ||
77 | 1374 | |||
78 | 1375 | If a registered handler raises an error it is propagated. | ||
79 | 1376 | """ | ||
80 | 1377 | for line in self.custom_properties(revision): | ||
81 | 1378 | self.to_file.write("%s%s\n" % (indent, line)) | ||
82 | 1379 | |||
83 | 1380 | def custom_properties(self, revision): | ||
84 | 1381 | """Format the custom properties returned by each registered handler. | ||
85 | 1382 | |||
86 | 1383 | If a registered handler raises an error it is propagated. | ||
87 | 1384 | |||
88 | 1385 | :return: a list of formatted lines (excluding trailing newlines) | ||
89 | 1386 | """ | ||
90 | 1387 | lines = self._foreign_info_properties(revision) | ||
91 | 1388 | for key, handler in properties_handler_registry.iteritems(): | ||
92 | 1389 | lines.extend(self._format_properties(handler(revision))) | ||
93 | 1390 | return lines | ||
94 | 1391 | |||
95 | 1392 | def _foreign_info_properties(self, rev): | ||
96 | 1371 | """Custom log displayer for foreign revision identifiers. | 1393 | """Custom log displayer for foreign revision identifiers. |
97 | 1372 | 1394 | ||
98 | 1373 | :param rev: Revision object. | 1395 | :param rev: Revision object. |
99 | 1374 | """ | 1396 | """ |
100 | 1375 | # Revision comes directly from a foreign repository | 1397 | # Revision comes directly from a foreign repository |
101 | 1376 | if isinstance(rev, foreign.ForeignRevision): | 1398 | if isinstance(rev, foreign.ForeignRevision): |
105 | 1377 | self._write_properties(indent, rev.mapping.vcs.show_foreign_revid( | 1399 | return rev.mapping.vcs.show_foreign_revid(rev.foreign_revid) |
103 | 1378 | rev.foreign_revid)) | ||
104 | 1379 | return | ||
106 | 1380 | 1400 | ||
107 | 1381 | # Imported foreign revision revision ids always contain : | 1401 | # Imported foreign revision revision ids always contain : |
108 | 1382 | if not ":" in rev.revision_id: | 1402 | if not ":" in rev.revision_id: |
110 | 1383 | return | 1403 | return [] |
111 | 1384 | 1404 | ||
112 | 1385 | # Revision was once imported from a foreign repository | 1405 | # Revision was once imported from a foreign repository |
113 | 1386 | try: | 1406 | try: |
114 | 1387 | foreign_revid, mapping = \ | 1407 | foreign_revid, mapping = \ |
115 | 1388 | foreign.foreign_vcs_registry.parse_revision_id(rev.revision_id) | 1408 | foreign.foreign_vcs_registry.parse_revision_id(rev.revision_id) |
116 | 1389 | except errors.InvalidRevisionId: | 1409 | except errors.InvalidRevisionId: |
118 | 1390 | return | 1410 | return [] |
119 | 1391 | 1411 | ||
121 | 1392 | self._write_properties(indent, | 1412 | return self._format_properties( |
122 | 1393 | mapping.vcs.show_foreign_revid(foreign_revid)) | 1413 | mapping.vcs.show_foreign_revid(foreign_revid)) |
123 | 1394 | 1414 | ||
133 | 1395 | def show_properties(self, revision, indent): | 1415 | def _format_properties(self, properties): |
134 | 1396 | """Displays the custom properties returned by each registered handler. | 1416 | lines = [] |
126 | 1397 | |||
127 | 1398 | If a registered handler raises an error it is propagated. | ||
128 | 1399 | """ | ||
129 | 1400 | for key, handler in properties_handler_registry.iteritems(): | ||
130 | 1401 | self._write_properties(indent, handler(revision)) | ||
131 | 1402 | |||
132 | 1403 | def _write_properties(self, indent, properties): | ||
135 | 1404 | for key, value in properties.items(): | 1417 | for key, value in properties.items(): |
137 | 1405 | self.to_file.write(indent + key + ': ' + value + '\n') | 1418 | lines.append(key + ': ' + value) |
138 | 1419 | return lines | ||
139 | 1406 | 1420 | ||
140 | 1407 | def show_diff(self, to_file, diff, indent): | 1421 | def show_diff(self, to_file, diff, indent): |
141 | 1408 | for l in diff.rstrip().split('\n'): | 1422 | for l in diff.rstrip().split('\n'): |
142 | 1409 | to_file.write(indent + '%s\n' % (l,)) | 1423 | to_file.write(indent + '%s\n' % (l,)) |
143 | 1410 | 1424 | ||
144 | 1411 | 1425 | ||
145 | 1426 | # Separator between revisions in long format | ||
146 | 1427 | _LONG_SEP = '-' * 60 | ||
147 | 1428 | |||
148 | 1429 | |||
149 | 1412 | class LongLogFormatter(LogFormatter): | 1430 | class LongLogFormatter(LogFormatter): |
150 | 1413 | 1431 | ||
151 | 1414 | supports_merge_revisions = True | 1432 | supports_merge_revisions = True |
152 | @@ -1417,46 +1435,59 @@ | |||
153 | 1417 | supports_tags = True | 1435 | supports_tags = True |
154 | 1418 | supports_diff = True | 1436 | supports_diff = True |
155 | 1419 | 1437 | ||
156 | 1438 | def __init__(self, *args, **kwargs): | ||
157 | 1439 | super(LongLogFormatter, self).__init__(*args, **kwargs) | ||
158 | 1440 | if self.show_timezone == 'original': | ||
159 | 1441 | self.date_string = self._date_string_original_timezone | ||
160 | 1442 | else: | ||
161 | 1443 | self.date_string = self._date_string_with_timezone | ||
162 | 1444 | |||
163 | 1445 | def _date_string_with_timezone(self, rev): | ||
164 | 1446 | return format_date(rev.timestamp, rev.timezone or 0, | ||
165 | 1447 | self.show_timezone) | ||
166 | 1448 | |||
167 | 1449 | def _date_string_original_timezone(self, rev): | ||
168 | 1450 | return format_date_with_offset_in_original_timezone(rev.timestamp, | ||
169 | 1451 | rev.timezone or 0) | ||
170 | 1452 | |||
171 | 1420 | def log_revision(self, revision): | 1453 | def log_revision(self, revision): |
172 | 1421 | """Log a revision, either merged or not.""" | 1454 | """Log a revision, either merged or not.""" |
173 | 1422 | indent = ' ' * revision.merge_depth | 1455 | indent = ' ' * revision.merge_depth |
176 | 1423 | to_file = self.to_file | 1456 | lines = [_LONG_SEP] |
175 | 1424 | to_file.write(indent + '-' * 60 + '\n') | ||
177 | 1425 | if revision.revno is not None: | 1457 | if revision.revno is not None: |
179 | 1426 | to_file.write(indent + 'revno: %s%s\n' % (revision.revno, | 1458 | lines.append('revno: %s%s' % (revision.revno, |
180 | 1427 | self.merge_marker(revision))) | 1459 | self.merge_marker(revision))) |
181 | 1428 | if revision.tags: | 1460 | if revision.tags: |
183 | 1429 | to_file.write(indent + 'tags: %s\n' % (', '.join(revision.tags))) | 1461 | lines.append('tags: %s' % (', '.join(revision.tags))) |
184 | 1430 | if self.show_ids: | 1462 | if self.show_ids: |
187 | 1431 | to_file.write(indent + 'revision-id: ' + revision.rev.revision_id) | 1463 | lines.append('revision-id: %s' % (revision.rev.revision_id,)) |
186 | 1432 | to_file.write('\n') | ||
188 | 1433 | for parent_id in revision.rev.parent_ids: | 1464 | for parent_id in revision.rev.parent_ids: |
192 | 1434 | to_file.write(indent + 'parent: %s\n' % (parent_id,)) | 1465 | lines.append('parent: %s' % (parent_id,)) |
193 | 1435 | self.show_foreign_info(revision.rev, indent) | 1466 | lines.extend(self.custom_properties(revision.rev)) |
191 | 1436 | self.show_properties(revision.rev, indent) | ||
194 | 1437 | 1467 | ||
195 | 1438 | committer = revision.rev.committer | 1468 | committer = revision.rev.committer |
196 | 1439 | authors = revision.rev.get_apparent_authors() | 1469 | authors = revision.rev.get_apparent_authors() |
197 | 1440 | if authors != [committer]: | 1470 | if authors != [committer]: |
200 | 1441 | to_file.write(indent + 'author: %s\n' % (", ".join(authors),)) | 1471 | lines.append('author: %s' % (", ".join(authors),)) |
201 | 1442 | to_file.write(indent + 'committer: %s\n' % (committer,)) | 1472 | lines.append('committer: %s' % (committer,)) |
202 | 1443 | 1473 | ||
203 | 1444 | branch_nick = revision.rev.properties.get('branch-nick', None) | 1474 | branch_nick = revision.rev.properties.get('branch-nick', None) |
204 | 1445 | if branch_nick is not None: | 1475 | if branch_nick is not None: |
213 | 1446 | to_file.write(indent + 'branch nick: %s\n' % (branch_nick,)) | 1476 | lines.append('branch nick: %s' % (branch_nick,)) |
214 | 1447 | 1477 | ||
215 | 1448 | date_str = format_date(revision.rev.timestamp, | 1478 | lines.append('timestamp: %s' % (self.date_string(revision.rev),)) |
216 | 1449 | revision.rev.timezone or 0, | 1479 | |
217 | 1450 | self.show_timezone) | 1480 | lines.append('message:') |
210 | 1451 | to_file.write(indent + 'timestamp: %s\n' % (date_str,)) | ||
211 | 1452 | |||
212 | 1453 | to_file.write(indent + 'message:\n') | ||
218 | 1454 | if not revision.rev.message: | 1481 | if not revision.rev.message: |
220 | 1455 | to_file.write(indent + ' (no message)\n') | 1482 | lines.append(' (no message)') |
221 | 1456 | else: | 1483 | else: |
222 | 1457 | message = revision.rev.message.rstrip('\r\n') | 1484 | message = revision.rev.message.rstrip('\r\n') |
223 | 1458 | for l in message.split('\n'): | 1485 | for l in message.split('\n'): |
225 | 1459 | to_file.write(indent + ' %s\n' % (l,)) | 1486 | lines.append(' %s' % (l,)) |
226 | 1487 | |||
227 | 1488 | # Dump the output, appending the delta and diff if requested | ||
228 | 1489 | to_file = self.to_file | ||
229 | 1490 | to_file.write("%s%s\n" % (indent, ('\n' + indent).join(lines))) | ||
230 | 1460 | if revision.delta is not None: | 1491 | if revision.delta is not None: |
231 | 1461 | # We don't respect delta_format for compatibility | 1492 | # We don't respect delta_format for compatibility |
232 | 1462 | revision.delta.show(to_file, self.show_ids, indent=indent, | 1493 | revision.delta.show(to_file, self.show_ids, indent=indent, |
233 | @@ -1515,7 +1546,6 @@ | |||
234 | 1515 | self.show_timezone, date_fmt="%Y-%m-%d", | 1546 | self.show_timezone, date_fmt="%Y-%m-%d", |
235 | 1516 | show_offset=False), | 1547 | show_offset=False), |
236 | 1517 | tags, self.merge_marker(revision))) | 1548 | tags, self.merge_marker(revision))) |
237 | 1518 | self.show_foreign_info(revision.rev, indent+offset) | ||
238 | 1519 | self.show_properties(revision.rev, indent+offset) | 1549 | self.show_properties(revision.rev, indent+offset) |
239 | 1520 | if self.show_ids: | 1550 | if self.show_ids: |
240 | 1521 | to_file.write(indent + offset + 'revision-id:%s\n' | 1551 | to_file.write(indent + offset + 'revision-id:%s\n' |
241 | 1522 | 1552 | ||
242 | === modified file 'bzrlib/osutils.py' | |||
243 | --- bzrlib/osutils.py 2009-11-10 07:01:56 +0000 | |||
244 | +++ bzrlib/osutils.py 2009-11-30 12:45:30 +0000 | |||
245 | @@ -695,6 +695,8 @@ | |||
246 | 695 | return offset.days * 86400 + offset.seconds | 695 | return offset.days * 86400 + offset.seconds |
247 | 696 | 696 | ||
248 | 697 | weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] | 697 | weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] |
249 | 698 | _default_format_by_weekday_num = [wd + " %Y-%m-%d %H:%M:%S" for wd in weekdays] | ||
250 | 699 | |||
251 | 698 | 700 | ||
252 | 699 | def format_date(t, offset=0, timezone='original', date_fmt=None, | 701 | def format_date(t, offset=0, timezone='original', date_fmt=None, |
253 | 700 | show_offset=True): | 702 | show_offset=True): |
254 | @@ -714,6 +716,32 @@ | |||
255 | 714 | date_str = time.strftime(date_fmt, tt) | 716 | date_str = time.strftime(date_fmt, tt) |
256 | 715 | return date_str + offset_str | 717 | return date_str + offset_str |
257 | 716 | 718 | ||
258 | 719 | |||
259 | 720 | # Cache of formatted offset strings | ||
260 | 721 | _offset_cache = {} | ||
261 | 722 | |||
262 | 723 | |||
263 | 724 | def format_date_with_offset_in_original_timezone(t, offset=0, | ||
264 | 725 | _cache=_offset_cache): | ||
265 | 726 | """Return a formatted date string in the original timezone. | ||
266 | 727 | |||
267 | 728 | This routine may be faster then format_date. | ||
268 | 729 | |||
269 | 730 | :param t: Seconds since the epoch. | ||
270 | 731 | :param offset: Timezone offset in seconds east of utc. | ||
271 | 732 | """ | ||
272 | 733 | if offset is None: | ||
273 | 734 | offset = 0 | ||
274 | 735 | tt = time.gmtime(t + offset) | ||
275 | 736 | date_fmt = _default_format_by_weekday_num[tt[6]] | ||
276 | 737 | date_str = time.strftime(date_fmt, tt) | ||
277 | 738 | offset_str = _cache.get(offset, None) | ||
278 | 739 | if offset_str is None: | ||
279 | 740 | offset_str = ' %+03d%02d' % (offset / 3600, (offset / 60) % 60) | ||
280 | 741 | _cache[offset] = offset_str | ||
281 | 742 | return date_str + offset_str | ||
282 | 743 | |||
283 | 744 | |||
284 | 717 | def format_local_date(t, offset=0, timezone='original', date_fmt=None, | 745 | def format_local_date(t, offset=0, timezone='original', date_fmt=None, |
285 | 718 | show_offset=True): | 746 | show_offset=True): |
286 | 719 | """Return an unicode date string formatted according to the current locale. | 747 | """Return an unicode date string formatted according to the current locale. |
287 | @@ -733,6 +761,7 @@ | |||
288 | 733 | date_str = date_str.decode(get_user_encoding(), 'replace') | 761 | date_str = date_str.decode(get_user_encoding(), 'replace') |
289 | 734 | return date_str + offset_str | 762 | return date_str + offset_str |
290 | 735 | 763 | ||
291 | 764 | |||
292 | 736 | def _format_date(t, offset, timezone, date_fmt, show_offset): | 765 | def _format_date(t, offset, timezone, date_fmt, show_offset): |
293 | 737 | if timezone == 'utc': | 766 | if timezone == 'utc': |
294 | 738 | tt = time.gmtime(t) | 767 | tt = time.gmtime(t) |
295 | 739 | 768 | ||
296 | === modified file 'bzrlib/revision.py' | |||
297 | --- bzrlib/revision.py 2009-09-01 12:39:21 +0000 | |||
298 | +++ bzrlib/revision.py 2009-11-30 12:45:30 +0000 | |||
299 | @@ -54,8 +54,11 @@ | |||
300 | 54 | 54 | ||
301 | 55 | def __init__(self, revision_id, properties=None, **args): | 55 | def __init__(self, revision_id, properties=None, **args): |
302 | 56 | self.revision_id = revision_id | 56 | self.revision_id = revision_id |
305 | 57 | self.properties = properties or {} | 57 | if properties is None: |
306 | 58 | self._check_properties() | 58 | self.properties = {} |
307 | 59 | else: | ||
308 | 60 | self.properties = properties | ||
309 | 61 | self._check_properties() | ||
310 | 59 | self.committer = None | 62 | self.committer = None |
311 | 60 | self.parent_ids = [] | 63 | self.parent_ids = [] |
312 | 61 | self.parent_sha1s = [] | 64 | self.parent_sha1s = [] |
313 | 62 | 65 | ||
314 | === modified file 'bzrlib/tests/test_osutils.py' | |||
315 | --- bzrlib/tests/test_osutils.py 2009-11-18 16:10:18 +0000 | |||
316 | +++ bzrlib/tests/test_osutils.py 2009-11-30 12:45:30 +0000 | |||
317 | @@ -378,6 +378,14 @@ | |||
318 | 378 | # Instead blackbox.test_locale should check for localized | 378 | # Instead blackbox.test_locale should check for localized |
319 | 379 | # dates once they do occur in output strings. | 379 | # dates once they do occur in output strings. |
320 | 380 | 380 | ||
321 | 381 | def test_format_date_with_offset_in_original_timezone(self): | ||
322 | 382 | self.assertEqual("Thu 1970-01-01 00:00:00 +0000", | ||
323 | 383 | osutils.format_date_with_offset_in_original_timezone(0)) | ||
324 | 384 | self.assertEqual("Fri 1970-01-02 03:46:40 +0000", | ||
325 | 385 | osutils.format_date_with_offset_in_original_timezone(100000)) | ||
326 | 386 | self.assertEqual("Fri 1970-01-02 05:46:40 +0200", | ||
327 | 387 | osutils.format_date_with_offset_in_original_timezone(100000, 7200)) | ||
328 | 388 | |||
329 | 381 | def test_local_time_offset(self): | 389 | def test_local_time_offset(self): |
330 | 382 | """Test that local_time_offset() returns a sane value.""" | 390 | """Test that local_time_offset() returns a sane value.""" |
331 | 383 | offset = osutils.local_time_offset() | 391 | offset = osutils.local_time_offset() |
This is an old patch that I still think we ought to land. The previous reviews asked for more tests because there's a small risk I might have broken something. I agree that additional tests would be nice. I disagree that they ought to block the patch because, IMO, the patch's value outweighs that risk.
Perhaps this weeks patch pilot could add some more tests if they still feel they are necessary?