)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6bdac947517195c3094a085fca41f126d75bc633","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"41f4323d_167eac16","updated":"2025-11-26 04:13:56.000000000","message":"I think we want this in more places.","commit_id":"a3982a92d97f7f49077930064100b78e89ade55f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c2b2f87f48252cfddbba354f6df4623ede3b5b9c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"8ab1545d_137db9b7","updated":"2025-11-26 12:55:33.000000000","message":"I\u0027m going to break out the miscellaneous test_db changes from this Timestamp.zero change","commit_id":"a3982a92d97f7f49077930064100b78e89ade55f"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"20850115bb005107e3b3cdb5a73386c556430a7b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"c202cb1a_ca43527d","updated":"2025-11-26 02:38:54.000000000","message":"The zero method really makes more sense in light of the v2 changes later in the chain. So might seem out of place at the moment, but is important later.","commit_id":"a3982a92d97f7f49077930064100b78e89ade55f"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2bc6387ebe4e16c7792bc4cfb0ce978862a45450","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"b9956d45_b2eeabb6","updated":"2025-12-01 19:07:31.000000000","message":"Still debating about how hard to look for other things like `Timestamp(dict.get(key, 0))`... maybe I could do some one-off thing using `ast`...","commit_id":"cb480a5bcc19ce3edb63f5e34a42a4915bcd61de"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f4810e76f593580913dc1f3e38c2976c80c08d9f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"a1f667f9_3b7bf2c5","updated":"2025-12-03 05:33:09.000000000","message":"Tests are failing for valid reasons. I\u0027ve got afix in a patch that can be squashed if need be: https://review.opendev.org/c/openstack/swift/+/969341","commit_id":"08a4215345439bf227d381f8a12192970494ad6f"},{"author":{"_account_id":35790,"name":"Shreeya Deshpande","email":"shreeyad@nvidia.com","username":"shreeyad"},"change_message_id":"ed7cbf4bfa9b68e535a253c629dd5c3c07dce766","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"5d41c90b_23556a29","updated":"2025-12-02 18:43:32.000000000","message":"recheck","commit_id":"08a4215345439bf227d381f8a12192970494ad6f"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a6fdeac6bf4c679e19015cb700abca8b7bb2d27b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"7fd078da_5e108d61","updated":"2025-12-12 00:19:54.000000000","message":"kk, I do like that this all now passes and agree we can always come back and look at the default or 0 stuff later. At the moment this is blocking all the other patches, and it\u0027s now working so nice one Al.\n\nThere were more `get(\u003cts key\u003e, Timestamp.zero())` then I expected, but still like it as a KISS for now.","commit_id":"db578c1077d25aa28ef704df94caa7de6cf782bb"}],"swift/common/db.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ad67e56cc0c4a6598a27ed92887a3fd9e3a80a02","unresolved":true,"context_lines":[{"line_number":181,"context_line":"    :param old: hex representation of the current DB hash"},{"line_number":182,"context_line":"    :param name: name of the object or container being inserted"},{"line_number":183,"context_line":"    :param timestamp: a string representation of attributes of the item being"},{"line_number":184,"context_line":"        inserted, for example the string representation of the items\u0027s"},{"line_number":185,"context_line":"        timestamp."},{"line_number":186,"context_line":"    \"\"\""},{"line_number":187,"context_line":"    if name is None:"}],"source_content_type":"text/x-python","patch_set":2,"id":"6db1e858_758f4bb0","line":184,"range":{"start_line":184,"start_character":63,"end_line":184,"end_character":70},"updated":"2025-11-25 10:53:26.000000000","message":"typo","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2bc6387ebe4e16c7792bc4cfb0ce978862a45450","unresolved":false,"context_lines":[{"line_number":181,"context_line":"    :param old: hex representation of the current DB hash"},{"line_number":182,"context_line":"    :param name: name of the object or container being inserted"},{"line_number":183,"context_line":"    :param timestamp: a string representation of attributes of the item being"},{"line_number":184,"context_line":"        inserted, for example the string representation of the items\u0027s"},{"line_number":185,"context_line":"        timestamp."},{"line_number":186,"context_line":"    \"\"\""},{"line_number":187,"context_line":"    if name is None:"}],"source_content_type":"text/x-python","patch_set":2,"id":"49fc17fd_5614d1b3","line":184,"range":{"start_line":184,"start_character":63,"end_line":184,"end_character":70},"in_reply_to":"6db1e858_758f4bb0","updated":"2025-12-01 19:07:31.000000000","message":"Done","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"951e8901e1739834171f38ac822473b0262168fd","unresolved":true,"context_lines":[{"line_number":413,"context_line":"            END;"},{"line_number":414,"context_line":"        \"\"\")"},{"line_number":415,"context_line":"        if not put_timestamp:"},{"line_number":416,"context_line":"            put_timestamp \u003d Timestamp.zero().internal"},{"line_number":417,"context_line":"        self._initialize(conn, put_timestamp,"},{"line_number":418,"context_line":"                         storage_policy_index\u003dstorage_policy_index)"},{"line_number":419,"context_line":"        conn.commit()"}],"source_content_type":"text/x-python","patch_set":2,"id":"13d115cd_b78cdd74","line":416,"updated":"2025-11-24 22:19:48.000000000","message":"\\**shrug*\\*\n\nSure, why not?","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ad67e56cc0c4a6598a27ed92887a3fd9e3a80a02","unresolved":true,"context_lines":[{"line_number":413,"context_line":"            END;"},{"line_number":414,"context_line":"        \"\"\")"},{"line_number":415,"context_line":"        if not put_timestamp:"},{"line_number":416,"context_line":"            put_timestamp \u003d Timestamp.zero().internal"},{"line_number":417,"context_line":"        self._initialize(conn, put_timestamp,"},{"line_number":418,"context_line":"                         storage_policy_index\u003dstorage_policy_index)"},{"line_number":419,"context_line":"        conn.commit()"}],"source_content_type":"text/x-python","patch_set":2,"id":"4b1877af_9a182d1a","line":416,"in_reply_to":"13d115cd_b78cdd74","updated":"2025-11-25 10:53:26.000000000","message":"with a v2 Timestamp, Timestamp(0) will give a different timestamp every time (0 and random jitter), which seems at best confusing when someone decided that there should be a fixed default.","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6bdac947517195c3094a085fca41f126d75bc633","unresolved":true,"context_lines":[{"line_number":413,"context_line":"            END;"},{"line_number":414,"context_line":"        \"\"\")"},{"line_number":415,"context_line":"        if not put_timestamp:"},{"line_number":416,"context_line":"            put_timestamp \u003d Timestamp.zero().internal"},{"line_number":417,"context_line":"        self._initialize(conn, put_timestamp,"},{"line_number":418,"context_line":"                         storage_policy_index\u003dstorage_policy_index)"},{"line_number":419,"context_line":"        conn.commit()"}],"source_content_type":"text/x-python","patch_set":2,"id":"be9d21de_506094a5","line":416,"in_reply_to":"4b1877af_9a182d1a","updated":"2025-11-26 04:13:56.000000000","message":"\u003e Timestamp(0) will give a different timestamp every time (0 and random jitter) \n\n💡\n\nIn addition to this, should we update any of these other places?\n```\nswift/obj/server.py\n850:            orig_timestamp \u003d Timestamp(0)\n\nswift/proxy/controllers/base.py\n1415:        self.latest_404_timestamp \u003d Timestamp(0)\n\nswift/container/backend.py\n591:            put_timestamp \u003d Timestamp(0).internal\n\nswift/container/reconciler.py\n80:                Timestamp(0))\n115:    default_timestamp \u003d Timestamp(0).internal\n\nswift/common/middleware/s3api/s3request.py\n1325:        epoch \u003d S3Timestamp(0)\n```\nSeems like at least swift/container should all probably be updated... proxy *probably* doesn\u0027t matter, but also couldn\u0027t hurt? I can\u0027t quite decide on the other two.","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c2b2f87f48252cfddbba354f6df4623ede3b5b9c","unresolved":false,"context_lines":[{"line_number":413,"context_line":"            END;"},{"line_number":414,"context_line":"        \"\"\")"},{"line_number":415,"context_line":"        if not put_timestamp:"},{"line_number":416,"context_line":"            put_timestamp \u003d Timestamp.zero().internal"},{"line_number":417,"context_line":"        self._initialize(conn, put_timestamp,"},{"line_number":418,"context_line":"                         storage_policy_index\u003dstorage_policy_index)"},{"line_number":419,"context_line":"        conn.commit()"}],"source_content_type":"text/x-python","patch_set":2,"id":"31c9cff3_95d84e74","line":416,"in_reply_to":"be9d21de_506094a5","updated":"2025-11-26 12:55:33.000000000","message":"Done","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"}],"swift/common/exceptions.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5182e69a8ab03e8be57471d52470829b243bec3b","unresolved":true,"context_lines":[{"line_number":94,"context_line":"    def __init__(self, metadata\u003dNone):"},{"line_number":95,"context_line":"        self.metadata \u003d metadata or {}"},{"line_number":96,"context_line":"        self.timestamp \u003d Timestamp("},{"line_number":97,"context_line":"            self.metadata.get(\u0027X-Timestamp\u0027, Timestamp.zero()))"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"class DiskFileExpired(DiskFileDeleted):"}],"source_content_type":"text/x-python","patch_set":12,"id":"d2857022_b2f62bfb","line":97,"updated":"2025-12-05 18:47:57.000000000","message":"ok, so this isn\u0027t the most elegant solution but it avoids getting bogged down designing a default-to-zero interface to Timestamp. We can come back to that when all the other problems have been fixed!","commit_id":"db578c1077d25aa28ef704df94caa7de6cf782bb"}],"swift/common/utils/timestamp.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d72622cb6dc73e1ca15a96562193661700bc62db","unresolved":true,"context_lines":[{"line_number":134,"context_line":"        \"\"\""},{"line_number":135,"context_line":"        Returns an instance of the smallest possible Timestamp."},{"line_number":136,"context_line":"        \"\"\""},{"line_number":137,"context_line":"        return cls(0)"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def __repr__(self):"},{"line_number":140,"context_line":"        return INTERNAL_FORMAT % (self.timestamp, self.offset)"}],"source_content_type":"text/x-python","patch_set":5,"id":"c2a37467_ffb7b2d6","line":137,"updated":"2025-11-26 14:59:50.000000000","message":"hmmm, I\u0027m finding places (e.g. [1]) where we have patterns like \n``Timestamp(headers.get(\u0027x-backend-timestamp\u0027, 0))``\n which is going to unwieldy to replace. \n \n Maybe we\u0027ll write \n ``Timestamp(headers.get(\u0027x-backend-timestamp\u0027, Timestamp.zero()))``\n but that\u0027s quite verbose.\n \nOr we could special case float 0 such that Timestamp(0) returns Timestamp.zero()??\n \n [1] https://github.com/openstack/swift/blob/98005fad9297fef279926255976640ead3cc7a93/swift/container/server.py#L59-L85","commit_id":"9bc468b56ef41d003c7ced833aa0fdd763dc9d21"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a2915d2f1ce637326e6a93bf7f700e1442bac23d","unresolved":true,"context_lines":[{"line_number":134,"context_line":"        \"\"\""},{"line_number":135,"context_line":"        Returns an instance of the smallest possible Timestamp."},{"line_number":136,"context_line":"        \"\"\""},{"line_number":137,"context_line":"        return cls(0)"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def __repr__(self):"},{"line_number":140,"context_line":"        return INTERNAL_FORMAT % (self.timestamp, self.offset)"}],"source_content_type":"text/x-python","patch_set":5,"id":"de385a10_aa941790","line":137,"in_reply_to":"961b7423_3ae0bfa6","updated":"2025-12-01 22:21:01.000000000","message":"`ast` FTW! https://paste.opendev.org/show/brCn0NTXcragCsXAvaqZ/\n\nSo, how much do we care about these?\n```\nswift/proxy/controllers/base.py:1618:                    not Timestamp(src_headers.get(\u0027x-backend-timestamp\u0027, 0)):\nswift/proxy/controllers/base.py:1625:                    not Timestamp(src_headers.get(\u0027x-backend-timestamp\u0027, 0)):\nswift/proxy/controllers/base.py:1641:                ts \u003d Timestamp(hdrs.get(\u0027X-Backend-Timestamp\u0027, 0))\nswift/proxy/controllers/obj.py:2708:                not Timestamp(src_headers.get(\u0027x-backend-timestamp\u0027, 0)):\nswift/obj/server.py:692:        orig_timestamp \u003d Timestamp(orig_metadata.get(\u0027X-Timestamp\u0027, 0))\nswift/container/sync.py:496:            remote_ts \u003d Timestamp(metadata.get(\u0027x-timestamp\u0027, 0))\nswift/container/sync.py:593:                timestamp \u003d Timestamp(headers.get(\u0027x-timestamp\u0027, 0))\nswift/container/reconciler.py:541:        dest_ts \u003d Timestamp(dest_obj.get(\u0027x-backend-timestamp\u0027, 0))\nswift/container/reconciler.py:569:        source_ts \u003d Timestamp(source_obj_info.get(\u0027x-backend-timestamp\u0027, 0))\n```\nI should maybe extend that to look for `Timestamp(... or 0)` constructs...","commit_id":"9bc468b56ef41d003c7ced833aa0fdd763dc9d21"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f884cf11b3af1555a87d8a32d6161ca353e5de5c","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        \"\"\""},{"line_number":135,"context_line":"        Returns an instance of the smallest possible Timestamp."},{"line_number":136,"context_line":"        \"\"\""},{"line_number":137,"context_line":"        return cls(0)"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def __repr__(self):"},{"line_number":140,"context_line":"        return INTERNAL_FORMAT % (self.timestamp, self.offset)"}],"source_content_type":"text/x-python","patch_set":5,"id":"4dae85d2_b21b6114","line":137,"in_reply_to":"b9df4193_b96f208e","updated":"2025-12-02 17:44:15.000000000","message":"Still, I missed things like `utils.Timestamp(...)` -- getting really *good* `ast` searches is hard! I think that only added https://github.com/openstack/swift/blob/master/swift/common/exceptions.py#L96-L97 though.","commit_id":"9bc468b56ef41d003c7ced833aa0fdd763dc9d21"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2bc6387ebe4e16c7792bc4cfb0ce978862a45450","unresolved":true,"context_lines":[{"line_number":134,"context_line":"        \"\"\""},{"line_number":135,"context_line":"        Returns an instance of the smallest possible Timestamp."},{"line_number":136,"context_line":"        \"\"\""},{"line_number":137,"context_line":"        return cls(0)"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def __repr__(self):"},{"line_number":140,"context_line":"        return INTERNAL_FORMAT % (self.timestamp, self.offset)"}],"source_content_type":"text/x-python","patch_set":5,"id":"961b7423_3ae0bfa6","line":137,"in_reply_to":"c2a37467_ffb7b2d6","updated":"2025-12-01 19:07:31.000000000","message":"\u003e we have patterns like\n`Timestamp(headers.get(\u0027x-backend-timestamp\u0027, 0))`\nwhich is going to unwieldy to replace.\n\nOr grep for :-/","commit_id":"9bc468b56ef41d003c7ced833aa0fdd763dc9d21"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5e7d97763f72f11a783fd787d34ad24613784edb","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        \"\"\""},{"line_number":135,"context_line":"        Returns an instance of the smallest possible Timestamp."},{"line_number":136,"context_line":"        \"\"\""},{"line_number":137,"context_line":"        return cls(0)"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def __repr__(self):"},{"line_number":140,"context_line":"        return INTERNAL_FORMAT % (self.timestamp, self.offset)"}],"source_content_type":"text/x-python","patch_set":5,"id":"b9df4193_b96f208e","line":137,"in_reply_to":"d5bd0ea1_51c4b856","updated":"2025-12-02 16:54:35.000000000","message":"nice Grepper\n\nI also found some other cases by IDE-search","commit_id":"9bc468b56ef41d003c7ced833aa0fdd763dc9d21"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fa21730b3805ce5cb8f261dc183422c928fb7a89","unresolved":true,"context_lines":[{"line_number":134,"context_line":"        \"\"\""},{"line_number":135,"context_line":"        Returns an instance of the smallest possible Timestamp."},{"line_number":136,"context_line":"        \"\"\""},{"line_number":137,"context_line":"        return cls(0)"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"    def __repr__(self):"},{"line_number":140,"context_line":"        return INTERNAL_FORMAT % (self.timestamp, self.offset)"}],"source_content_type":"text/x-python","patch_set":5,"id":"d5bd0ea1_51c4b856","line":137,"in_reply_to":"de385a10_aa941790","updated":"2025-12-01 22:43:22.000000000","message":"https://paste.opendev.org/show/bLp511JIY8x2finiJhoQ/ \u003c-- better version","commit_id":"9bc468b56ef41d003c7ced833aa0fdd763dc9d21"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e89489474e1ceeaf50ae9a8eb02b675171628a7d","unresolved":true,"context_lines":[{"line_number":87,"context_line":"        \"\"\""},{"line_number":88,"context_line":"        if timestamp in (None, \u0027\u0027, b\u0027\u0027):"},{"line_number":89,"context_line":"            # alias null values to zero"},{"line_number":90,"context_line":"            timestamp \u003d 0"},{"line_number":91,"context_line":"        if isinstance(timestamp, bytes):"},{"line_number":92,"context_line":"            timestamp \u003d timestamp.decode(\u0027ascii\u0027)"},{"line_number":93,"context_line":"        if isinstance(timestamp, str):"}],"source_content_type":"text/x-python","patch_set":9,"id":"9c92e9d9_48a949aa","line":90,"updated":"2025-12-04 19:19:58.000000000","message":"I\u0027ve realised that this risks masking bugs (see the follow-up sq patch change in test_utils.py for example) https://review.opendev.org/c/openstack/swift/+/969341\n\nAlternatives would be:\n\n``Timestamp(0) \u003d\u003d Timestamp.zero()``\n\n...but that also worries me that there\u0027s some tests that get distorted by making Timestamp(0) jitterless???\n\nor\n\n``Timestamp(timestamp, default_to_zero\u003dTrue)``\n\nwhich is verbose.\n\nor\n\n``Timestamp.parse(timestamp)`` which implicitly defaults to Timestamp.zero, but \u0027implicit\u0027 is often a bad idea.\n\nor \n\n``\nTimestamp.parse_or_zero(timestamp)\n``\n\nwhich is explicit but is it better than ``Timestamp(timestamp, default_to_zero\u003dTrue)``?","commit_id":"08a4215345439bf227d381f8a12192970494ad6f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7c0acbd164708dec0ee15757d2415dc6f65e28f3","unresolved":true,"context_lines":[{"line_number":87,"context_line":"        \"\"\""},{"line_number":88,"context_line":"        if timestamp in (None, \u0027\u0027, b\u0027\u0027):"},{"line_number":89,"context_line":"            # alias null values to zero"},{"line_number":90,"context_line":"            timestamp \u003d 0"},{"line_number":91,"context_line":"        if isinstance(timestamp, bytes):"},{"line_number":92,"context_line":"            timestamp \u003d timestamp.decode(\u0027ascii\u0027)"},{"line_number":93,"context_line":"        if isinstance(timestamp, str):"}],"source_content_type":"text/x-python","patch_set":9,"id":"2cf20315_5cb9db82","line":90,"in_reply_to":"9c92e9d9_48a949aa","updated":"2025-12-05 13:06:56.000000000","message":"I decided to avoid all of this by writing out \n\n``Timestamp(headers.get(key, Timestamp.zero())```\n\nin place of \n\n``Timestamp(headers.get(key, 0)```\n\nThere\u0027s no so many locations where we have that pattern and it avoids trying, and possibly failing, to be too clever in the Timestamp class. KISS!","commit_id":"08a4215345439bf227d381f8a12192970494ad6f"}],"swift/container/server.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a6fdeac6bf4c679e19015cb700abca8b7bb2d27b","unresolved":true,"context_lines":[{"line_number":70,"context_line":"        \u0027X-Backend-DELETE-Timestamp\u0027: Timestamp("},{"line_number":71,"context_line":"            info.get(\u0027delete_timestamp\u0027, ts_zero)).internal,"},{"line_number":72,"context_line":"        \u0027X-Backend-Status-Changed-At\u0027: Timestamp("},{"line_number":73,"context_line":"            info.get(\u0027status_changed_at\u0027, ts_zero)).internal,"},{"line_number":74,"context_line":"        \u0027X-Backend-Storage-Policy-Index\u0027: info.get(\u0027storage_policy_index\u0027, 0),"},{"line_number":75,"context_line":"    }"},{"line_number":76,"context_line":"    if not is_deleted:"}],"source_content_type":"text/x-python","patch_set":12,"id":"e2f09c8f_e9b2dd94","line":73,"updated":"2025-12-12 00:19:54.000000000","message":"I like how all the 0 timestamps will now match, nice one","commit_id":"db578c1077d25aa28ef704df94caa7de6cf782bb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8856ff22da33f962b034fce41d1acfa779ef6e13","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        \u0027X-Backend-DELETE-Timestamp\u0027: Timestamp("},{"line_number":71,"context_line":"            info.get(\u0027delete_timestamp\u0027, ts_zero)).internal,"},{"line_number":72,"context_line":"        \u0027X-Backend-Status-Changed-At\u0027: Timestamp("},{"line_number":73,"context_line":"            info.get(\u0027status_changed_at\u0027, ts_zero)).internal,"},{"line_number":74,"context_line":"        \u0027X-Backend-Storage-Policy-Index\u0027: info.get(\u0027storage_policy_index\u0027, 0),"},{"line_number":75,"context_line":"    }"},{"line_number":76,"context_line":"    if not is_deleted:"}],"source_content_type":"text/x-python","patch_set":12,"id":"2844bd9b_e7f206d3","line":73,"in_reply_to":"e2f09c8f_e9b2dd94","updated":"2025-12-12 17:30:39.000000000","message":"Acknowledged","commit_id":"db578c1077d25aa28ef704df94caa7de6cf782bb"}],"swift/obj/server.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a6fdeac6bf4c679e19015cb700abca8b7bb2d27b","unresolved":true,"context_lines":[{"line_number":1311,"context_line":"                response_class \u003d HTTPConflict"},{"line_number":1312,"context_line":"        response_timestamp \u003d max(orig_timestamp, req_timestamp)"},{"line_number":1313,"context_line":"        orig_delete_at \u003d Timestamp("},{"line_number":1314,"context_line":"            orig_metadata.get(\u0027X-Delete-At\u0027) or Timestamp.zero())"},{"line_number":1315,"context_line":"        try:"},{"line_number":1316,"context_line":"            req_if_delete_at_val \u003d request.headers[\u0027x-if-delete-at\u0027]"},{"line_number":1317,"context_line":"            req_if_delete_at \u003d Timestamp(req_if_delete_at_val)"}],"source_content_type":"text/x-python","patch_set":12,"id":"03b210eb_f4485113","line":1314,"updated":"2025-12-12 00:19:54.000000000","message":"In all the others you\u0027ve gone an:\n```\nTimestamp(orig_metadata.get(\u003cts key\u003e, Timestamp.zero()))\n```\n\nBut this is using `or` so seems like an odd change. Same thing though, so will only treaat this as a NIT.","commit_id":"db578c1077d25aa28ef704df94caa7de6cf782bb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8856ff22da33f962b034fce41d1acfa779ef6e13","unresolved":true,"context_lines":[{"line_number":1311,"context_line":"                response_class \u003d HTTPConflict"},{"line_number":1312,"context_line":"        response_timestamp \u003d max(orig_timestamp, req_timestamp)"},{"line_number":1313,"context_line":"        orig_delete_at \u003d Timestamp("},{"line_number":1314,"context_line":"            orig_metadata.get(\u0027X-Delete-At\u0027) or Timestamp.zero())"},{"line_number":1315,"context_line":"        try:"},{"line_number":1316,"context_line":"            req_if_delete_at_val \u003d request.headers[\u0027x-if-delete-at\u0027]"},{"line_number":1317,"context_line":"            req_if_delete_at \u003d Timestamp(req_if_delete_at_val)"}],"source_content_type":"text/x-python","patch_set":12,"id":"c3410697_bdedbe20","line":1314,"in_reply_to":"03b210eb_f4485113","updated":"2025-12-12 17:30:39.000000000","message":"Yep, that struck me as odd, but it is how it is on master and they\u0027re not strictly equivalent. If orig_metadata has ``x-delete-at: None``  then this will give you ``Timestamp.zero()`` whereas ``Timestamp(orig_metadata.get(\u003cts key\u003e, Timestamp.zero()))`` would blow up.\n\nI don\u0027t know if that is possible but I\u0027m inclined to just leave it as it is on master.","commit_id":"db578c1077d25aa28ef704df94caa7de6cf782bb"}],"test/unit/common/test_db.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"951e8901e1739834171f38ac822473b0262168fd","unresolved":true,"context_lines":[{"line_number":105,"context_line":"        self.assertEqual("},{"line_number":106,"context_line":"            chexor(\u0027d41d8cd98f00b204e9800998ecf8427e\u0027,"},{"line_number":107,"context_line":"                   \u0027new name\u0027, \u00271234567890.12345_200000000a123456\u0027),"},{"line_number":108,"context_line":"            \u0027d33f407fa725c862cc795d1f81c1710a\u0027)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def test_invalid_old_hash(self):"},{"line_number":111,"context_line":"        self.assertRaises(ValueError, chexor, \u0027oldhash\u0027, \u0027name\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"531d04f2_dae3e23f","line":108,"updated":"2025-11-24 22:19:48.000000000","message":"What\u0027s this have to do with `Timestamp.zero()`?\n\nAlso, seems like the sort of thing where we could add the new case while keeping the old...","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2bc6387ebe4e16c7792bc4cfb0ce978862a45450","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        self.assertEqual("},{"line_number":106,"context_line":"            chexor(\u0027d41d8cd98f00b204e9800998ecf8427e\u0027,"},{"line_number":107,"context_line":"                   \u0027new name\u0027, \u00271234567890.12345_200000000a123456\u0027),"},{"line_number":108,"context_line":"            \u0027d33f407fa725c862cc795d1f81c1710a\u0027)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def test_invalid_old_hash(self):"},{"line_number":111,"context_line":"        self.assertRaises(ValueError, chexor, \u0027oldhash\u0027, \u0027name\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"31633fdd_82550f3c","line":108,"in_reply_to":"41c22a5d_4309a7a9","updated":"2025-12-01 19:07:31.000000000","message":"Done","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5e7d97763f72f11a783fd787d34ad24613784edb","unresolved":false,"context_lines":[{"line_number":105,"context_line":"        self.assertEqual("},{"line_number":106,"context_line":"            chexor(\u0027d41d8cd98f00b204e9800998ecf8427e\u0027,"},{"line_number":107,"context_line":"                   \u0027new name\u0027, \u00271234567890.12345_200000000a123456\u0027),"},{"line_number":108,"context_line":"            \u0027d33f407fa725c862cc795d1f81c1710a\u0027)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def test_invalid_old_hash(self):"},{"line_number":111,"context_line":"        self.assertRaises(ValueError, chexor, \u0027oldhash\u0027, \u0027name\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"7d9a0097_6f1697e8","line":108,"in_reply_to":"41c22a5d_4309a7a9","updated":"2025-12-02 16:54:35.000000000","message":"Done","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ad67e56cc0c4a6598a27ed92887a3fd9e3a80a02","unresolved":true,"context_lines":[{"line_number":105,"context_line":"        self.assertEqual("},{"line_number":106,"context_line":"            chexor(\u0027d41d8cd98f00b204e9800998ecf8427e\u0027,"},{"line_number":107,"context_line":"                   \u0027new name\u0027, \u00271234567890.12345_200000000a123456\u0027),"},{"line_number":108,"context_line":"            \u0027d33f407fa725c862cc795d1f81c1710a\u0027)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def test_invalid_old_hash(self):"},{"line_number":111,"context_line":"        self.assertRaises(ValueError, chexor, \u0027oldhash\u0027, \u0027name\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"41c22a5d_4309a7a9","line":108,"in_reply_to":"531d04f2_dae3e23f","updated":"2025-11-25 10:53:26.000000000","message":"oops, this is a little premature w.r.t. following v2 timestamp patch (although not invalid).\n\nThis change isn\u0027t to do with Timestamp.zero() rather the test cleanup alluded to by \"Also clarify use of Timestamp string formats in test_db.py.\" \n\n``normalize_timestamp(1)`` is going to return a different value each time with a v2 timestamp.","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"951e8901e1739834171f38ac822473b0262168fd","unresolved":true,"context_lines":[{"line_number":125,"context_line":"            (\u0027tom\u0027, next(ts).internal),"},{"line_number":126,"context_line":"            (\u0027frank\u0027, next(ts).internal),"},{"line_number":127,"context_line":"            (\u0027tom\u0027, next(ts).internal),"},{"line_number":128,"context_line":"            (\u0027bob\u0027, next(ts).internal),"},{"line_number":129,"context_line":"        ]"},{"line_number":130,"context_line":"        hash_ \u003d \u00270\u0027"},{"line_number":131,"context_line":"        random.shuffle(objects)"}],"source_content_type":"text/x-python","patch_set":2,"id":"e96272d3_c113d34e","line":128,"updated":"2025-11-24 22:19:48.000000000","message":"This is all maybe more tolerable in the context of the previous patches in the chain...","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2bc6387ebe4e16c7792bc4cfb0ce978862a45450","unresolved":false,"context_lines":[{"line_number":125,"context_line":"            (\u0027tom\u0027, next(ts).internal),"},{"line_number":126,"context_line":"            (\u0027frank\u0027, next(ts).internal),"},{"line_number":127,"context_line":"            (\u0027tom\u0027, next(ts).internal),"},{"line_number":128,"context_line":"            (\u0027bob\u0027, next(ts).internal),"},{"line_number":129,"context_line":"        ]"},{"line_number":130,"context_line":"        hash_ \u003d \u00270\u0027"},{"line_number":131,"context_line":"        random.shuffle(objects)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3e7826db_bb96bd80","line":128,"in_reply_to":"e96272d3_c113d34e","updated":"2025-12-01 19:07:31.000000000","message":"Acknowledged","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5e7d97763f72f11a783fd787d34ad24613784edb","unresolved":false,"context_lines":[{"line_number":125,"context_line":"            (\u0027tom\u0027, next(ts).internal),"},{"line_number":126,"context_line":"            (\u0027frank\u0027, next(ts).internal),"},{"line_number":127,"context_line":"            (\u0027tom\u0027, next(ts).internal),"},{"line_number":128,"context_line":"            (\u0027bob\u0027, next(ts).internal),"},{"line_number":129,"context_line":"        ]"},{"line_number":130,"context_line":"        hash_ \u003d \u00270\u0027"},{"line_number":131,"context_line":"        random.shuffle(objects)"}],"source_content_type":"text/x-python","patch_set":2,"id":"64840005_4642b026","line":128,"in_reply_to":"e96272d3_c113d34e","updated":"2025-12-02 16:54:35.000000000","message":"Acknowledged","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"951e8901e1739834171f38ac822473b0262168fd","unresolved":true,"context_lines":[{"line_number":375,"context_line":"        info \u003d broker.get_info()"},{"line_number":376,"context_line":"        self.assertEqual(info[\u0027created_at\u0027], created_at.internal)"},{"line_number":377,"context_line":"        self.assertEqual(info[\u0027put_timestamp\u0027], Timestamp.zero().internal)"},{"line_number":378,"context_line":"        self.assertEqual(info[\u0027delete_timestamp\u0027], \u00270\u0027)"},{"line_number":379,"context_line":"        self.assertEqual(info[\u0027status_changed_at\u0027], Timestamp.zero().internal)"},{"line_number":380,"context_line":"        self.assertFalse(broker.is_deleted())"},{"line_number":381,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"489dfba9_5e5ce381","line":378,"updated":"2025-11-24 22:19:48.000000000","message":"Hmm... explicitly **not** `Timestamp.zero().internal`... That\u0027s an interesting wart of ours...","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ad67e56cc0c4a6598a27ed92887a3fd9e3a80a02","unresolved":true,"context_lines":[{"line_number":375,"context_line":"        info \u003d broker.get_info()"},{"line_number":376,"context_line":"        self.assertEqual(info[\u0027created_at\u0027], created_at.internal)"},{"line_number":377,"context_line":"        self.assertEqual(info[\u0027put_timestamp\u0027], Timestamp.zero().internal)"},{"line_number":378,"context_line":"        self.assertEqual(info[\u0027delete_timestamp\u0027], \u00270\u0027)"},{"line_number":379,"context_line":"        self.assertEqual(info[\u0027status_changed_at\u0027], Timestamp.zero().internal)"},{"line_number":380,"context_line":"        self.assertFalse(broker.is_deleted())"},{"line_number":381,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9959a220_702f8e73","line":378,"in_reply_to":"489dfba9_5e5ce381","updated":"2025-11-25 10:53:26.000000000","message":"yeah, also odd that both put_timestamp and delete_timestamp have default column values of \u00270\u0027 but only put_timestamp gets explicitly defaulted to Timestamp(0) :shrug:","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6bdac947517195c3094a085fca41f126d75bc633","unresolved":true,"context_lines":[{"line_number":375,"context_line":"        info \u003d broker.get_info()"},{"line_number":376,"context_line":"        self.assertEqual(info[\u0027created_at\u0027], created_at.internal)"},{"line_number":377,"context_line":"        self.assertEqual(info[\u0027put_timestamp\u0027], Timestamp.zero().internal)"},{"line_number":378,"context_line":"        self.assertEqual(info[\u0027delete_timestamp\u0027], \u00270\u0027)"},{"line_number":379,"context_line":"        self.assertEqual(info[\u0027status_changed_at\u0027], Timestamp.zero().internal)"},{"line_number":380,"context_line":"        self.assertFalse(broker.is_deleted())"},{"line_number":381,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"085b7a1b_8de8f32a","line":378,"in_reply_to":"9959a220_702f8e73","updated":"2025-11-26 04:13:56.000000000","message":"Part of me wonders whether we could set things up to migrate towards the full internal representation... I think it would sort after, which is nice... meh.","commit_id":"08d0ff2b503393af01e564cee75229f97d7f6429"}]}
