)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"eaacef64432c182d6b23194c0b58051e3ad57caa","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Alistair Coles \u003calistairncoles@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2026-04-10 11:37:39 +0000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"s3api: fix inventory timestamp usage"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: Ib994ff59f9da80811c08686d33a778a906f1dc62"},{"line_number":10,"context_line":"Signed-off-by: Alistair Coles \u003calistairncoles@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"7f47e714_d222f500","line":7,"updated":"2026-04-10 12:46:57.000000000","message":"I made this up quickly when I split out the patch from its parent, but given the discussion about x-timestamp in my other comment, I wonder if this would be better as:\n\n```\ns3api: fix inventory config modified_time\n```","commit_id":"ce4ede80278ec51194289abb32f796e36285995e"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"cb0504c45d8dac8935b136c50952b3ebb9cc18b9","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Alistair Coles \u003calistairncoles@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2026-04-10 11:37:39 +0000"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"s3api: fix inventory timestamp usage"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: Ib994ff59f9da80811c08686d33a778a906f1dc62"},{"line_number":10,"context_line":"Signed-off-by: Alistair Coles \u003calistairncoles@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"d2f8cb1b_e2a96900","line":7,"in_reply_to":"7f47e714_d222f500","updated":"2026-05-05 21:16:37.000000000","message":"Acknowledged","commit_id":"ce4ede80278ec51194289abb32f796e36285995e"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6a6a79221341f3fe6c570124bc73cf259c63a2e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"955a6cc2_3092ceec","updated":"2026-05-07 14:54:54.000000000","message":"Using time() is less surprising than using a client-provide Date header (or whatever the auth signing header is).\n\nUnit tests fail when I revert the change.\n\nThere\u0027s some nits I addressed in a follow-on patch https://review.opendev.org/c/openstack/swift/+/987677\n\n@Yan review and then (if happy) squash https://review.opendev.org/c/openstack/swift/+/987677 into this patch. Then squash this patch into the parent. Thanks","commit_id":"8b5bf592a289581861b6ad4f979827f30d5054db"}],"swift/common/middleware/s3api/controllers/inventory.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"eaacef64432c182d6b23194c0b58051e3ad57caa","unresolved":true,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"def add_sysmeta_header(req, config):"},{"line_number":170,"context_line":"    config_data \u003d config.to_dict()"},{"line_number":171,"context_line":"    req.ensure_x_timestamp()"},{"line_number":172,"context_line":"    config_data[\u0027modified_time\u0027] \u003d float(swob_request.timestamp.fget(req))"},{"line_number":173,"context_line":"    key \u003d \u0027X-Container-Sysmeta-Inventory-%s-Config\u0027 % config.inventory_id"},{"line_number":174,"context_line":"    req.headers[key] \u003d json.dumps(config_data)"}],"source_content_type":"text/x-python","patch_set":2,"id":"baf5e32e_6415fba0","line":171,"updated":"2026-04-10 12:46:57.000000000","message":"Yan - this comment builds on the concern I mentioned in our conversation...\n\nIn this context ``req`` is the client s3 request, not the swift \"sub\" request that will be forwarded to the container server.\n\n``add_sysmeta_header`` is called while handling client PUTs and DELETEs. When we have v2 timestamps [1], ensure_x_timestamp will give the PUT request a v2 timestamp with jitter whereas the DELETE will get a normal timestamp with no jitter.\n\nHowever, in both cases the inventory middleware then forwards the request as POSTs, and POSTs should NOT have v2 timestamps with jitter. So we have done the wrong thing by calling ensure_x_timestamp before the backend request method has been finalised.\n\nThis is one reason why we\u0027ve tried to minimise the places that set x-timestamp header, ideally only in the proxy app at the very end of the WSGI pipeline i.e. until the final method of the request to the backend is known, we don\u0027t know which timestamp format is appropriate.\n\nIt therefore seems worth avoiding setting x-timestamp here just to derive a somewhat arbitrary modified-time for the inventory config. It would be *nice to have* because in the container DB metadata, the time at which the inventory config dict was persisted (based on the POST x-timestamp) would be the same as the modified-time encapsulated in the inventory config. i.e.\n\n```\ncontainer metadata \u003d {\n  X-Container-Sysmeta-Inventory-Config: ({\n    modified_time: ts_x_timestamp,\n    ...\n  }, ts_x_timestamp),  \n}\n```\n\nBut it\u0027s not *necessary to have* that for the correct operation of the inventory API or daemon. And in fact it has not been true before anyway, because until this patch we had:\n\n```\ncontainer metadata \u003d {\n  X-Container-Sysmeta-Inventory-Config: ({\n    modified_time: ts_date_header,\n    ...\n  }, ts_x_timestamp),\n}\n\n```\n\nSo, as a pragmatic avoidance of the x-timestamp-vs-request-method complexity, I think it would be fine to just use time.time() for modified_time here, which results in:\n\n```\ncontainer metadata \u003d {\n  X-Container-Sysmeta-Inventory-Config: ({\n    modified_time: time.time(),\n    ...\n  }, ts_x_timestamp),\n}\n\n```\n\nThis patch is therefore \"Stop using a client defined time as modified_time\" but is NOT \"Use x-timestamp as the modified_time\".\n\nIdeally, to cater for cases like this, a middleware at the start of the pipeline would install an abstract request \"ID\" data structure in the environ which defined the float time of the request (but not the x-timestamp header). We could then use that time here and the proxy app at the end of the pipeline would use the same time to construct an x-timestamp header of whichever format is required. We can revisit this is that ever becomes available.\n\n[1] https://review.opendev.org/c/openstack/swift/+/967738?usp\u003demail","commit_id":"ce4ede80278ec51194289abb32f796e36285995e"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"cb0504c45d8dac8935b136c50952b3ebb9cc18b9","unresolved":false,"context_lines":[{"line_number":168,"context_line":""},{"line_number":169,"context_line":"def add_sysmeta_header(req, config):"},{"line_number":170,"context_line":"    config_data \u003d config.to_dict()"},{"line_number":171,"context_line":"    req.ensure_x_timestamp()"},{"line_number":172,"context_line":"    config_data[\u0027modified_time\u0027] \u003d float(swob_request.timestamp.fget(req))"},{"line_number":173,"context_line":"    key \u003d \u0027X-Container-Sysmeta-Inventory-%s-Config\u0027 % config.inventory_id"},{"line_number":174,"context_line":"    req.headers[key] \u003d json.dumps(config_data)"}],"source_content_type":"text/x-python","patch_set":2,"id":"213f0b1a_8656d3a5","line":171,"in_reply_to":"baf5e32e_6415fba0","updated":"2026-05-05 21:16:37.000000000","message":"Good point! using time.time() seems reasonable","commit_id":"ce4ede80278ec51194289abb32f796e36285995e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"eaacef64432c182d6b23194c0b58051e3ad57caa","unresolved":true,"context_lines":[{"line_number":169,"context_line":"def add_sysmeta_header(req, config):"},{"line_number":170,"context_line":"    config_data \u003d config.to_dict()"},{"line_number":171,"context_line":"    req.ensure_x_timestamp()"},{"line_number":172,"context_line":"    config_data[\u0027modified_time\u0027] \u003d float(swob_request.timestamp.fget(req))"},{"line_number":173,"context_line":"    key \u003d \u0027X-Container-Sysmeta-Inventory-%s-Config\u0027 % config.inventory_id"},{"line_number":174,"context_line":"    req.headers[key] \u003d json.dumps(config_data)"},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"87b41c85_45875d7f","line":172,"range":{"start_line":172,"start_character":64,"end_line":172,"end_character":73},"updated":"2026-04-10 12:46:57.000000000","message":"TIL ``fget`` is a method of a property.\n\nI\u0027ve never seen this before. I\u0027m not sure I like it because it assumes that swob_request.timestamp IS and will remain a property (rather than ever becoming a plain attribute of the swob.Request) and that feels like it is breaking encapsulation.\n\nAnyway, it\u0027s not necessary because ``ensure_x_timestamp`` returns the timestamp 😊\n\nSo\n\n```\nts \u003d req.ensure_x_timestamp()\nconfig_data[\u0027modified_time\u0027] \u003d float(ts)\n```","commit_id":"ce4ede80278ec51194289abb32f796e36285995e"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"cb0504c45d8dac8935b136c50952b3ebb9cc18b9","unresolved":false,"context_lines":[{"line_number":169,"context_line":"def add_sysmeta_header(req, config):"},{"line_number":170,"context_line":"    config_data \u003d config.to_dict()"},{"line_number":171,"context_line":"    req.ensure_x_timestamp()"},{"line_number":172,"context_line":"    config_data[\u0027modified_time\u0027] \u003d float(swob_request.timestamp.fget(req))"},{"line_number":173,"context_line":"    key \u003d \u0027X-Container-Sysmeta-Inventory-%s-Config\u0027 % config.inventory_id"},{"line_number":174,"context_line":"    req.headers[key] \u003d json.dumps(config_data)"},{"line_number":175,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"eab2457f_7b5fe455","line":172,"range":{"start_line":172,"start_character":64,"end_line":172,"end_character":73},"in_reply_to":"87b41c85_45875d7f","updated":"2026-05-05 21:16:37.000000000","message":"Acknowledged","commit_id":"ce4ede80278ec51194289abb32f796e36285995e"}],"test/unit/common/middleware/s3api/test_inventory.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"eaacef64432c182d6b23194c0b58051e3ad57caa","unresolved":true,"context_lines":[{"line_number":486,"context_line":"            \u0027period\u0027: \u0027Daily\u0027,"},{"line_number":487,"context_line":"            \u0027source\u0027: \u0027s3api\u0027,"},{"line_number":488,"context_line":"            \u0027dest_container\u0027: \u0027destination-bucket\u0027,"},{"line_number":489,"context_line":"            \u0027modified_time\u0027: ts,"},{"line_number":490,"context_line":"            \u0027enabled\u0027: True,"},{"line_number":491,"context_line":"            \u0027deleted\u0027: False,"},{"line_number":492,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":2,"id":"de159734_96db34c7","line":489,"updated":"2026-04-10 12:46:57.000000000","message":"I expect this to fail once we have v2 timestamps with a hex part. It should be more accurately expressed as ``float(ts)``\n\nIt\u0027s curious that this is all that needed changing. I guess the previous rounding to int catered for the Date header not being the same time as the x-timestamp ??\n\nI think we could make the test more robust by deliberately setting the Date header to a very different time than the x-timestamp.\n\n```\ndiff --git a/test/unit/common/middleware/s3api/__init__.py b/test/unit/common/middleware/s3api/__init__.py\nindex 82d398ab4..67cdb958f 100644\n--- a/test/unit/common/middleware/s3api/__init__.py\n+++ b/test/unit/common/middleware/s3api/__init__.py\n@@ -206,9 +206,10 @@ class S3ApiTestCase(BaseUnitTestCase):\n                              {x.tag for x in elem})\n         return self._get_error_code(body)\n \n-    def get_date_header(self, skew\u003d0):\n+    def get_date_header(self, now\u003dNone, skew\u003d0):\n         # email.utils.formatdate returns utc timestamp in default\n-        return email.utils.formatdate(time.time() + skew)\n+        now \u003d time.time() if now is None else now\n+        return email.utils.formatdate(now + skew)\n \n     def get_v4_amz_date_header(self, offset\u003dNone):\n         when \u003d datetime.now(timezone.utc)\ndiff --git a/test/unit/common/middleware/s3api/test_inventory.py b/test/unit/common/middleware/s3api/test_inventory.py\nindex 6acf877a0..fc6037d6b 100644\n--- a/test/unit/common/middleware/s3api/test_inventory.py\n+++ b/test/unit/common/middleware/s3api/test_inventory.py\n@@ -466,16 +466,18 @@ class TestS3ApiInventory(S3ApiTestCase):\n         self.assertEqual([], self.swift.calls_with_headers)\n \n     def test_PUT_enable_inventory(self):\n+        ts_now \u003d self.ts()\n         self.s3api.conf[\u0027s3_inventory_enabled\u0027] \u003d \u0027yes\u0027\n         self.swift.register(\n             \u0027POST\u0027, \u0027/v1/AUTH_test/bucket\u0027, HTTPNoContent, {}, None)\n \n-        req \u003d Request.blank(\u0027/bucket?inventory\u0026id\u003d0\u0027,\n-                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},\n-                            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,\n-                                     \u0027Date\u0027: self.get_date_header()},\n-                            body\u003dSUPPORTED_XML)\n-        with mock_timestamp_now() as ts:\n+        req \u003d Request.blank(\n+            \u0027/bucket?inventory\u0026id\u003d0\u0027,\n+            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},\n+            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,\n+                     \u0027Date\u0027: self.get_date_header(float(ts_now), skew\u003d-10)},\n+            body\u003dSUPPORTED_XML)\n+        with mock_timestamp_now(ts_now):\n             status, headers, body \u003d self.call_s3api(req)\n         self.assertEqual(\u0027204\u0027, status.split()[0])\n \n@@ -486,7 +488,7 @@ class TestS3ApiInventory(S3ApiTestCase):\n             \u0027period\u0027: \u0027Daily\u0027,\n             \u0027source\u0027: \u0027s3api\u0027,\n             \u0027dest_container\u0027: \u0027destination-bucket\u0027,\n-            \u0027modified_time\u0027: ts,\n+            \u0027modified_time\u0027: float(ts_now),\n             \u0027enabled\u0027: True,\n             \u0027deleted\u0027: False,\n         }\n\n```","commit_id":"ce4ede80278ec51194289abb32f796e36285995e"},{"author":{"_account_id":36606,"name":"Yan Xiao","display_name":"Yan","email":"yanxiao@nvidia.com","username":"yanxiao"},"change_message_id":"cb0504c45d8dac8935b136c50952b3ebb9cc18b9","unresolved":false,"context_lines":[{"line_number":486,"context_line":"            \u0027period\u0027: \u0027Daily\u0027,"},{"line_number":487,"context_line":"            \u0027source\u0027: \u0027s3api\u0027,"},{"line_number":488,"context_line":"            \u0027dest_container\u0027: \u0027destination-bucket\u0027,"},{"line_number":489,"context_line":"            \u0027modified_time\u0027: ts,"},{"line_number":490,"context_line":"            \u0027enabled\u0027: True,"},{"line_number":491,"context_line":"            \u0027deleted\u0027: False,"},{"line_number":492,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":2,"id":"6c5ca7e6_49a6f32a","line":489,"in_reply_to":"de159734_96db34c7","updated":"2026-05-05 21:16:37.000000000","message":"Acknowledged","commit_id":"ce4ede80278ec51194289abb32f796e36285995e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6a6a79221341f3fe6c570124bc73cf259c63a2e","unresolved":true,"context_lines":[{"line_number":486,"context_line":"            \u0027period\u0027: \u0027Daily\u0027,"},{"line_number":487,"context_line":"            \u0027source\u0027: \u0027s3api\u0027,"},{"line_number":488,"context_line":"            \u0027dest_container\u0027: \u0027destination-bucket\u0027,"},{"line_number":489,"context_line":"            \u0027modified_time\u0027: int(ts),"},{"line_number":490,"context_line":"            \u0027enabled\u0027: True,"},{"line_number":491,"context_line":"            \u0027deleted\u0027: False,"},{"line_number":492,"context_line":"        }"}],"source_content_type":"text/x-python","patch_set":4,"id":"6c16bee9_b8d06b2e","side":"PARENT","line":489,"updated":"2026-05-07 14:54:54.000000000","message":"seems it was only by chance that the int() was ever correct: self.get_data_header() returns a date precise to 1 second, that just happened to be the same second as ts","commit_id":"3bbd002284d76d381d731b543927f70a6c4ee9ca"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6a6a79221341f3fe6c570124bc73cf259c63a2e","unresolved":true,"context_lines":[{"line_number":466,"context_line":"        self.assertEqual(\u0027501\u0027, status.split()[0])"},{"line_number":467,"context_line":"        self.assertEqual([], self.swift.calls_with_headers)"},{"line_number":468,"context_line":""},{"line_number":469,"context_line":"    def test_PUT_enable_inventory(self):"},{"line_number":470,"context_line":"        ts_now \u003d self.ts()"},{"line_number":471,"context_line":"        self.s3api.conf[\u0027s3_inventory_enabled\u0027] \u003d \u0027yes\u0027"},{"line_number":472,"context_line":"        self.swift.register("}],"source_content_type":"text/x-python","patch_set":4,"id":"08dcab00_db1bfe22","line":469,"updated":"2026-05-07 14:54:54.000000000","message":"I think it would be useful to have a test where the request DOES have an x-timestamp, to verify that it is not used","commit_id":"8b5bf592a289581861b6ad4f979827f30d5054db"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6a6a79221341f3fe6c570124bc73cf259c63a2e","unresolved":true,"context_lines":[{"line_number":478,"context_line":"            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,"},{"line_number":479,"context_line":"                     \u0027Date\u0027: self.get_date_header(float(ts_now), skew\u003d-10)},"},{"line_number":480,"context_line":"            body\u003dSUPPORTED_XML)"},{"line_number":481,"context_line":"        ts_plus \u003d float(ts_now) + 1.0"},{"line_number":482,"context_line":"        with mock_timestamp_now(ts_now), \\"},{"line_number":483,"context_line":"                mock.patch(\u0027swift.common.middleware.s3api.controllers.\u0027"},{"line_number":484,"context_line":"                           \u0027inventory.time\u0027, return_value\u003dts_plus):"}],"source_content_type":"text/x-python","patch_set":4,"id":"94353f5f_ca1e7635","line":481,"updated":"2026-05-07 14:54:54.000000000","message":"ok, make the expected time be explicitly different from the x-timestamp time","commit_id":"8b5bf592a289581861b6ad4f979827f30d5054db"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6a6a79221341f3fe6c570124bc73cf259c63a2e","unresolved":true,"context_lines":[{"line_number":479,"context_line":"                     \u0027Date\u0027: self.get_date_header(float(ts_now), skew\u003d-10)},"},{"line_number":480,"context_line":"            body\u003dSUPPORTED_XML)"},{"line_number":481,"context_line":"        ts_plus \u003d float(ts_now) + 1.0"},{"line_number":482,"context_line":"        with mock_timestamp_now(ts_now), \\"},{"line_number":483,"context_line":"                mock.patch(\u0027swift.common.middleware.s3api.controllers.\u0027"},{"line_number":484,"context_line":"                           \u0027inventory.time\u0027, return_value\u003dts_plus):"},{"line_number":485,"context_line":"            status, headers, body \u003d self.call_s3api(req)"}],"source_content_type":"text/x-python","patch_set":4,"id":"f5a28ccd_023b1654","line":482,"updated":"2026-05-07 14:54:54.000000000","message":"nit: it\u0027s no longer (never was!?) necessary to mock_timestamp_now","commit_id":"8b5bf592a289581861b6ad4f979827f30d5054db"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6a6a79221341f3fe6c570124bc73cf259c63a2e","unresolved":true,"context_lines":[{"line_number":500,"context_line":"        self.assertIn(\u0027X-Container-Sysmeta-Inventory-0-Config\u0027, actual_hdrs)"},{"line_number":501,"context_line":"        self.assertEqual("},{"line_number":502,"context_line":"            exp_config,"},{"line_number":503,"context_line":"            json.loads(actual_hdrs[\u0027X-Container-Sysmeta-Inventory-0-Config\u0027]))"},{"line_number":504,"context_line":""},{"line_number":505,"context_line":"    def test_PUT_enable_inventory_abbreviated_dest_bucket(self):"},{"line_number":506,"context_line":"        self.s3api.conf[\u0027s3_inventory_enabled\u0027] \u003d \u0027yes\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"b7b6cc6a_688de57a","line":503,"updated":"2026-05-07 14:54:54.000000000","message":"nit: assert that x-timestamp has NOT been added","commit_id":"8b5bf592a289581861b6ad4f979827f30d5054db"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6a6a79221341f3fe6c570124bc73cf259c63a2e","unresolved":true,"context_lines":[{"line_number":515,"context_line":"        req \u003d Request.blank(\u0027/bucket?inventory\u0026id\u003d0\u0027,"},{"line_number":516,"context_line":"                            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":517,"context_line":"                            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,"},{"line_number":518,"context_line":"                                     \u0027Date\u0027: self.get_date_header()},"},{"line_number":519,"context_line":"                            body\u003dbody)"},{"line_number":520,"context_line":"        ts_now \u003d self.ts()"},{"line_number":521,"context_line":"        ts_plus \u003d float(ts_now) + 1.0"}],"source_content_type":"text/x-python","patch_set":4,"id":"0dc3ddec_734dc564","line":518,"updated":"2026-05-07 14:54:54.000000000","message":"the Date header should be forced to ts_now ?","commit_id":"8b5bf592a289581861b6ad4f979827f30d5054db"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6a6a79221341f3fe6c570124bc73cf259c63a2e","unresolved":true,"context_lines":[{"line_number":558,"context_line":"                            body\u003dbody)"},{"line_number":559,"context_line":"        ts_now \u003d self.ts()"},{"line_number":560,"context_line":"        ts_plus \u003d float(ts_now) + 1.0"},{"line_number":561,"context_line":"        with mock_timestamp_now(ts_now), \\"},{"line_number":562,"context_line":"                mock.patch(\u0027swift.common.middleware.s3api.controllers.\u0027"},{"line_number":563,"context_line":"                           \u0027inventory.time\u0027, return_value\u003dts_plus):"},{"line_number":564,"context_line":"            status, headers, body \u003d self.call_s3api(req)"}],"source_content_type":"text/x-python","patch_set":4,"id":"e90c91b4_223e233f","line":561,"updated":"2026-05-07 14:54:54.000000000","message":"nit: I don\u0027t think it is necessary to mock the timestamp class now because it isn\u0027t being used to generate modified_time","commit_id":"8b5bf592a289581861b6ad4f979827f30d5054db"}]}
