)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Using mock_fixture.patch_mock_module() will enforce autospec\u003dTrue on all"},{"line_number":10,"context_line":"the mock.patch and similar calls. This will enforce signature checks on"},{"line_number":11,"context_line":"the mocked methods and functions, catching potential bugs missed by"},{"line_number":12,"context_line":"otherwise false positive unit tests."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: Icc4af149a63fac1c265e7006e188c2df8934d1cc"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"09a84f3b_6c123e25","line":11,"range":{"start_line":11,"start_character":34,"end_line":11,"end_character":57},"updated":"2026-06-28 23:57:45.000000000","message":"So did we catch any bugs!? I love catching bugs! But I can\u0027t tell which (if any) of the churn was supposed to be a bug.\n\nMaybe that\u0027s what the failing tests are about? Are those ones the remaining bugs?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Using mock_fixture.patch_mock_module() will enforce autospec\u003dTrue on all"},{"line_number":10,"context_line":"the mock.patch and similar calls. This will enforce signature checks on"},{"line_number":11,"context_line":"the mocked methods and functions, catching potential bugs missed by"},{"line_number":12,"context_line":"otherwise false positive unit tests."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: Icc4af149a63fac1c265e7006e188c2df8934d1cc"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3b0845f7_0a166b7f","line":11,"range":{"start_line":11,"start_character":34,"end_line":11,"end_character":57},"in_reply_to":"09a84f3b_6c123e25","updated":"2026-07-08 13:02:46.000000000","message":"Hello, and thanks for the review.\n\nFor this project, it seems that no bugs were found. That is good, it basically means that all / most of the code is well tested / used, and any rough edges have been smoothed over over time.\n\n\nHowever, I can point out several bugs in other projects, where we did the same thing, using the oslotest mock fixture. Here are a few examples:\n\n- https://review.opendev.org/c/openstack/trove/+/994673/6/trove/extensions/mgmt/upgrade/models.py\n\t- the original call is incorrect. `guest_agent` returns `trove.guestagent.api.API` (as seen here, because manager\u003dNone: https://github.com/openstack/trove/blob/e9489ce73e2415ed277eb51ab45394f9247acc30/trove/common/clients.py#L81). If we look here (https://github.com/openstack/trove/blob/e9489ce73e2415ed277eb51ab45394f9247acc30/trove/guestagent/api.py#L396), you can see that `upgrade` only takes one argument, not 3.\n\n- https://review.opendev.org/c/openstack/cinder/+/994152/8/cinder/volume/drivers/netapp/dataontap/block_base.py\n\t- `_create_lun` and `_clone_lun` were missing the `qos_policy_group_is_adaptive` parameter that the `block_cmode` subclass passes. Not a \"bug\" per se, but still an interface mismatch, which can still be an issue (it happened to me once quite recently).\n\n- https://review.opendev.org/c/openstack/cinder/+/994152/8/cinder/volume/drivers/open_e/jovian_common/driver.py\n\t- the actual signature is `def _ensure_target_volume(self, id, vid, provider_auth, ro\u003dFalse):`, but `mode\u003d\u0027ro\u0027` is given instead.\n\n- https://review.opendev.org/c/openstack/cinder/+/994152/8/cinder/volume/drivers/remotefs.py\n\t- `_qemu_img_info` has the signature: `def _qemu_img_info(self, path: str, volume_name: str):`. Only one argument was being passed. There even was a comment: \"TODO: something is wrong here\"\n\nSo, instead of \"So did we catch any bugs!?\", the better question is: \"How come the bugs above even existed in the first place?\". Nonetheless, these issues have been caught by autospecs, rather than silently passing.\n\nBut the best usage of autospecs is as a canary for when things change (including for external libraries, interface changes would be caught if they are autospec\u0027d). From my personal experience, there were too many cases in which I had to fix things that could have been caught by an autospec (https://review.opendev.org/c/openstack/nova/+/461689, https://review.opendev.org/c/openstack/compute-hyperv/+/500130, https://review.opendev.org/c/openstack/compute-hyperv/+/498740, https://review.opendev.org/c/openstack/compute-hyperv/+/425625, https://review.opendev.org/c/openstack/os-win/+/253084), and since then, it prevented a few other cases, before having to send a PR upstream.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"dd52979c_80a89590","updated":"2026-06-28 23:57:45.000000000","message":"This was a surprisingly tricky change to review. There were a number of broad classes of changes made:\n\n- Swap `new\u003dlambda: x` for `return_value\u003dx`\n- Add `create\u003dTrue` when patching builtins\n- Stop creating `mock.MagicMock()`/`mock.Mock()` instances ourselves when we don\u0027t have to\n- Use `.return_value` rather than `()` when navigating to some deeply nested part of a mock\n- Stop mocking things twice (`get_swift_info` in s3api tests, `sharder.int_client` in sharder tests)\n- Use `side_effect` to raise exceptions rather than defining a new function\n- Swap `spec\u003dx` for `autospec\u003dx`\n\nand it wasn\u0027t clear to me which were strictly necessary.\n\nI\u0027m not necessarily opposed to (some? most? of) the changes, but we\u0027ll definitely need to fix the failing tests before we can do much with this. It\u0027s also rather odd that the number of failing unit tests changes depending on which version of Python we\u0027re using to run them (8 for py37, 37 for py314)...","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"46e8f7e7b73a0d8f499fa9483b0ffd205a1c3ed0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"23a68c72_69b0523e","in_reply_to":"1546ad04_c3f1ee6d","updated":"2026-07-08 20:36:29.000000000","message":"PS: the double mock issue is clearly seen as an anti-pattern / test bug in the upstream community: https://github.com/python/cpython/issues/87644","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"17f0e9ce7e2deae8335991c6de2956b779007f3d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"1546ad04_c3f1ee6d","in_reply_to":"dd52979c_80a89590","updated":"2026-07-08 13:15:56.000000000","message":"Hello,\n\nIndeed, there were quite a few changes:\n\n- `new` is not being used, that effectively disables autospec. Plus, using `return_value\u003dx` instead of `new\u003dlamda: x` yields the same result, and it\u0027s more idiomatic.\n- `create\u003dTrue` / `autospec\u003dFalse` when patching builtins: This is related to how the `mock` library works. If no autospec is given, `mock` will simply create a `mock.Mock` and `setattr` it into the module. If `autospec\u003dTrue`, it will try to `getattr` it first... but there is no such attribute in that module (let\u0027s say `open` or `input`), resulting in an `AttributeError`. That\u0027s because those are builtins. I\u0027d argue the `mock` module would address this issue and do as expected, but it doesn\u0027t.\n- `.return_value` because if you call the autospec\u0027d method, the expectation is for the call to *respect* the signature (e.g.: because you `()` without any arguments, and the original method has a few arguments, it will fail with a `TypeError` as expected), but on the test side, you typically navigate the object to do some assertions at some level.\n- Yep, the `mock` module raises `InvalidSpecError` in those cases, you can\u0027t autospec mocks / something that was already `mock.patched`.\n- `side_effect`: yes, that is also more idiomatic.\n- `autospec\u003dx` instead of `spec\u003dx` - `autospec` is stricter than `spec`. A `spec` will only check for an attribute\u0027s existence, and that\u0027s it. `autospec` will also ensure that the thing you call are actually callable, and that they are really being called with the right signature. There are some corner cases in which that is not perfect (e.g.: decorators injecting parameters).","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"c8504935_c38d784e","updated":"2026-08-28 03:05:22.000000000","message":"I haven\u0027t got through all of it but I\u0027m getting a sense of it - I think there some hunks that could be better (mostly related to `patch(\u0027builitin....\u0027)`), but also there\u0027s LOTs of hunks that obviously an improvement\n\nI like the idea of enforcing `autospect\u003dTrue` and the outcome of better mock hygine.\n\nWhat I don\u0027t love is that the change adds a dependency coupled with a bunch of non-material style cleanup (even granting when I personally have a clear preference for the style in the cleanup) - it\u0027s possible some of the cleanup (`new\u003dlambda: ...`/`return_vlaue\u003d...`) could happen before OR after we enforce autospect on mock.patch and whater ever MagicMock fixture thing does - but doing ALL THE THINGS it one sha makes revert/backport management harder and history/regression tracing more un-wieldy.  In principle every commit should do one narrow thing - in practice it might be more practical to merge this more or less as-is and take the W\n\nit\u0027s test only, so I\u0027d be happy to wake up to:\n\n`ModuleNotFoundError: No module named \u0027oslotest\u0027` on all my dev vms!","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"e84594e6_2ddac7ec","updated":"2026-07-10 17:21:36.000000000","message":"I\u0027ll see about getting some other cores to take a look, too.","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"c4743fbda02b86d208d0c9e8b75e56e403ce4c43","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"8fb32979_7da0d828","updated":"2026-08-28 14:03:30.000000000","message":"Looks mostly good to me. There is a small issue, proposed a fix for it: 1002764: tests: Make autospec effective in TestInfoController | https://review.opendev.org/c/openstack/swift/+/1002764","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"},{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"d47bdd94d3db137e3a03d52723d07d557769d928","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"43bbac76_995b9d0c","updated":"2026-10-09 12:58:00.000000000","message":"This needs a bit of refactoring now because of other patches merged in the meantime. I rebased this patch, proposed ideas how to fix the issues in this patch (feel free to squash \u0026 abandon): 1009764: sq? tests: Enforce autospec\u003dTrue on mock patches | https://review.opendev.org/c/openstack/swift/+/1009764","commit_id":"d2f270ce964fc867188930cff09a8c18a5a529fd"}],"test-requirements.txt":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":9,"context_line":"pytest-subtests\u003e\u003d0.3.0  # MIT"},{"line_number":10,"context_line":"pytest-cov\u003e\u003d2.12.1  # MIT"},{"line_number":11,"context_line":"stestr\u003e\u003d2.0.0 # Apache-2.0"},{"line_number":12,"context_line":"oslotest\u003e\u003d3.2.0 # Apache-2.0"},{"line_number":13,"context_line":"python-swiftclient\u003e\u003d3.2.0"},{"line_number":14,"context_line":"python-keystoneclient\u003e\u003d3.19.0 # Apache-2.0"},{"line_number":15,"context_line":"boto\u003e\u003d2.32.1"}],"source_content_type":"text/plain","patch_set":3,"id":"fdc6103d_b25d618b","line":12,"updated":"2026-06-28 23:57:45.000000000","message":"OK, one new test requirement; it needs two transitive deps (`fixtures` and `testtools`), but `stestr` was already bringing those in.\n\nMinor annoyance for devs and their already-built envs, but probably tolerable. Gotta update `tools/playbooks/common/install_dependencies.yaml` though (or probe tests will continue to fail).","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":false,"context_lines":[{"line_number":9,"context_line":"pytest-subtests\u003e\u003d0.3.0  # MIT"},{"line_number":10,"context_line":"pytest-cov\u003e\u003d2.12.1  # MIT"},{"line_number":11,"context_line":"stestr\u003e\u003d2.0.0 # Apache-2.0"},{"line_number":12,"context_line":"oslotest\u003e\u003d3.2.0 # Apache-2.0"},{"line_number":13,"context_line":"python-swiftclient\u003e\u003d3.2.0"},{"line_number":14,"context_line":"python-keystoneclient\u003e\u003d3.19.0 # Apache-2.0"},{"line_number":15,"context_line":"boto\u003e\u003d2.32.1"}],"source_content_type":"text/plain","patch_set":3,"id":"e12539dc_62ecd0b2","line":12,"in_reply_to":"fdc6103d_b25d618b","updated":"2026-07-08 13:02:46.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":9,"context_line":"pytest-subtests\u003e\u003d0.3.0  # MIT"},{"line_number":10,"context_line":"pytest-cov\u003e\u003d2.12.1  # MIT"},{"line_number":11,"context_line":"stestr\u003e\u003d2.0.0 # Apache-2.0"},{"line_number":12,"context_line":"oslotest\u003e\u003d3.2.0 # Apache-2.0"},{"line_number":13,"context_line":"python-swiftclient\u003e\u003d3.2.0"},{"line_number":14,"context_line":"python-keystoneclient\u003e\u003d3.19.0 # Apache-2.0"},{"line_number":15,"context_line":"boto\u003e\u003d2.32.1"}],"source_content_type":"text/plain","patch_set":6,"id":"60005d49_f703591b","line":12,"updated":"2026-08-28 03:05:22.000000000","message":"my least favorite part of the change 😅","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test/__init__.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":30,"context_line":"from swift.common.utils import readconf"},{"line_number":31,"context_line":"from swift.common.utils.timestamp import Timestamp, NormalTimestamp"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"mock_fixture.patch_mock_module()"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"# Work around what seems to be a Python bug."},{"line_number":36,"context_line":"# c.f. https://bugs.launchpad.net/swift/+bug/820185."}],"source_content_type":"text/x-python","patch_set":6,"id":"06c7ca9d_c8d07330","line":33,"updated":"2026-08-28 03:05:22.000000000","message":"spooky action at a distance","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":78,"context_line":"    return sock"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"class BaseTestCase(fixtures.TestWithFixtures, unittest.TestCase):"},{"line_number":82,"context_line":"    def _assertDictContainsSubset(self, subset, dictionary, msg\u003dNone):"},{"line_number":83,"context_line":"        \"\"\"Checks whether dictionary is a superset of subset.\"\"\""},{"line_number":84,"context_line":"        # This is almost identical to the method in python3.4 version of"}],"source_content_type":"text/x-python","patch_set":6,"id":"4deb328c_c0a55e76","line":81,"updated":"2026-08-28 03:05:22.000000000","message":"is this a *different* thing than mock_fixture - or necessary to maek patch_mock_module work somehow?","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test/unit/__init__.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":66,"context_line":"class BaseUnitTestCase(BaseTestCase):"},{"line_number":67,"context_line":"    def setUp(self):"},{"line_number":68,"context_line":"        super().setUp()"},{"line_number":69,"context_line":"        self.useFixture(mock_fixture.MockAutospecFixture())"},{"line_number":70,"context_line":"        self.ts_iter \u003d make_timestamp_iter()"},{"line_number":71,"context_line":"        self.normal_ts_iter \u003d make_normal_timestamp_iter()"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5ba1bcf3_1d8d9de9","line":69,"updated":"2026-06-28 23:57:45.000000000","message":"Should this be here, or in `BaseTestCase`? Why should we choose one vs. the other?\n\nAlso, is this the big win? Or is it the `mock_fixture.patch_mock_module()` import side-effect? I guess I should go read up on both of them...","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":66,"context_line":"class BaseUnitTestCase(BaseTestCase):"},{"line_number":67,"context_line":"    def setUp(self):"},{"line_number":68,"context_line":"        super().setUp()"},{"line_number":69,"context_line":"        self.useFixture(mock_fixture.MockAutospecFixture())"},{"line_number":70,"context_line":"        self.ts_iter \u003d make_timestamp_iter()"},{"line_number":71,"context_line":"        self.normal_ts_iter \u003d make_normal_timestamp_iter()"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"1c06fdb5_e897fa44","line":69,"in_reply_to":"2dbc4761_f495b311","updated":"2026-08-28 03:05:22.000000000","message":"\u003e while functional tests not so much\n\nthat\u0027s a sesnible judgement - i don\u0027t I\u0027d noticed the monkey-patch import side-effect was applied to ALL tests\n\n\u003e There are 2 different things\n\nyou know what they said about the patch that was doing 2 different things 😉\n\n\u003e basically enforces autospec\u003dTrue on all mock.patch\n\nI would *prefer* to enforce that with linting if possible, but a mokeypatch might be more practical - in principle I think it\u0027s a reasonable aim autospec\u003dTrue is great!\n\n\u003e adds the autospec\u003d argument to mock.Mock and mock.MagicMock\n\nI don\u0027t really understand that\n\n\u003e you could use mock_fixture.patch_mock_module() without this\n\nthat good to know, it might be easier to absorb a change we understand","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":66,"context_line":"class BaseUnitTestCase(BaseTestCase):"},{"line_number":67,"context_line":"    def setUp(self):"},{"line_number":68,"context_line":"        super().setUp()"},{"line_number":69,"context_line":"        self.useFixture(mock_fixture.MockAutospecFixture())"},{"line_number":70,"context_line":"        self.ts_iter \u003d make_timestamp_iter()"},{"line_number":71,"context_line":"        self.normal_ts_iter \u003d make_normal_timestamp_iter()"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"2dbc4761_f495b311","line":69,"in_reply_to":"5ba1bcf3_1d8d9de9","updated":"2026-07-08 13:02:46.000000000","message":"`BaseTestCase` would be fine too. `BaseUnitTestCase` was chosen because unit tests typically use mocks / mock.patch, while functional tests not so much. We can move it to `BaseTestCase` if needed.\n\nThere are 2 different things being monkey patched. First of all, the change in `__init__.py` (`mock_fixture.patch_mock_module()`) - basically enforces `autospec\u003dTrue` on all `mock.patch`, `mock.patch.object`, `mock.patch.dict` calls. This needs to be done as early as possible (hence it is in `__init__.py`), otherwise the patcher doesn\u0027t work as intended (tests with `@mock.patch` / `@mock.patch.object` are \"initialized\" with `autospec\u003dNone`).\n\nMeanwhile, this fixture adds the `autospec\u003d` argument to `mock.Mock` and `mock.MagicMock`. It could be included in the `mock_fixture.patch_mock_module()` call, but the intent was to make them separate; you could use `mock_fixture.patch_mock_module()` without this.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":1531,"context_line":"                replicate_args \u003d self.path.lstrip(\u0027/\u0027).split(\u0027/\u0027)"},{"line_number":1532,"context_line":"                args \u003d [op] + copy.deepcopy(list(sync_args))"},{"line_number":1533,"context_line":"                with mock_check_drive(isdir\u003dnot rpc.mount_check,"},{"line_number":1534,"context_line":"                                      ismount\u003drpc.mount_check):"},{"line_number":1535,"context_line":"                    swob_response \u003d rpc.dispatch(replicate_args, args)"},{"line_number":1536,"context_line":"                resp \u003d FakeHTTPResponse(swob_response)"},{"line_number":1537,"context_line":"            if replicate_hook:"}],"source_content_type":"text/x-python","patch_set":6,"id":"88348057_9e3bb468","side":"PARENT","line":1534,"updated":"2026-08-28 03:05:22.000000000","message":"wtf was mock_check_drive - why do we want to get rid of it!?  what if it was awesome!?\n\n\u003e mock_check_drive is not itself vestigial. It models the filesystem predicate that Swift uses after deciding whether mount checking is enabled\n\n\u003e mock_check_drive(isdir\u003dTrue) means “pretend the device directory exists”; mock_check_drive(ismount\u003dTrue) means “pretend it is mounted.”\n\n```\nREPLICATE: /sdc/0/1bc27449c6de656c8327f841dd9d2651, sync, (-1, \u002700000000000000000000000000000000\u0027, \u00279643afac-fcc1-4114-9d54-c1cb6e131b43-sda\u0027, \u00271787882509.92553\u0027, \u00271787882509.00000\u0027, \u00270\u0027, \u0027\u0027, \u00271787882509.00000\u0027, 0, 0)\ntest ERROR: ERROR syncing with {\u0027ip\u0027: \u002710.0.0.2\u0027, \u0027replication_ip\u0027: \u002710.0.0.2\u0027, \u0027port\u0027: 1002, \u0027replication_port\u0027: 1002, \u0027device\u0027: \u0027sdc\u0027, \u0027zone\u0027: 2, \u0027region\u0027: 0, \u0027id\u0027: 2, \u0027weight\u0027: 1, \u0027index\u0027: 2}, path: a/c, db: /mnt/tmp/tmpzlrkhq6d/sda/containers/0\n/651/1bc27449c6de656c8327f841dd9d2651/1bc27449c6de656c8327f841dd9d2651.db: \nTraceback (most recent call last):\n  File \"/vagrant/swift/swift/common/db_replicator.py\", line 755, in _replicate_object\n    success \u003d self._repl_to_node(node, broker, partition, info,\n              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/vagrant/swift/swift/common/db_replicator.py\", line 545, in _repl_to_node\n    response \u003d http.replicate(\u0027sync\u0027, *sync_args)\n               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/vagrant/swift/test/unit/__init__.py\", line 1535, in replicate\n    with mock_check_drive(isdir\u003dnot rpc.mount_check,\n  File \"/usr/lib/python3.12/contextlib.py\", line 137, in __enter__\n    return next(self.gen)\n           ^^^^^^^^^^^^^^\n  File \"/vagrant/swift/test/unit/__init__.py\", line 738, in mock_check_drive\n    with mocklib.patch(mock_base + \u0027isdir\u0027) as mock_isdir, \\\n  File \"/usr/local/lib/python3.12/dist-packages/oslotest/mock_fixture.py\", line 197, in __enter__\n    _lazy_autospec_method(mocked_method, original_attr, eat_self)\n  File \"/usr/local/lib/python3.12/dist-packages/oslotest/mock_fixture.py\", line 35, in _lazy_autospec_method\n    _lazy_autospec: Any \u003d mock.create_autospec(original_method)\n                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/lib/python3.12/unittest/mock.py\", line 2707, in create_autospec\n    raise InvalidSpecError(f\u0027Cannot autospec a Mock object. \u0027\nunittest.mock.InvalidSpecError: Cannot autospec a Mock object. [object\u003d\u003c_AutospecMagicMock name\u003d\u0027isdir\u0027 id\u003d\u0027139703394632864\u0027\u003e]\n```\nWTF?\n\n\u003e Cannot autospec a Mock object.\n\n\u003e the fake connection’s historical hunk enters a second mock_check_drive(...) during rpc.dispatch(). That tries to autospec constraints.isdir,\n\n\n```\n  with mock.patch.object(db_replicator, \u0027ReplConnection\u0027,\n                         fake_repl_connection), \\\n          mock_check_drive(isdir\u003dTrue):\n      success \u003d daemon._repl_to_node(\n          remote_node, from_broker, part, info)\n```","commit_id":"b8f3c8b472bf00af594192b7697b420722192244"}],"test/unit/account/test_utils.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":72,"context_line":"            \u0027X-Timestamp\u0027: Timestamp(now).normal,"},{"line_number":73,"context_line":"            \u0027X-PUT-Timestamp\u0027: Timestamp(now).normal,"},{"line_number":74,"context_line":"        }"},{"line_number":75,"context_line":"        with mock.patch(\u0027time.time\u0027, return_value\u003dnow):"},{"line_number":76,"context_line":"            resp_headers \u003d utils.get_response_headers(broker)"},{"line_number":77,"context_line":"        self.assertEqual(resp_headers, expected)"},{"line_number":78,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"276fa4e6_6f0d5cc0","line":75,"updated":"2026-08-28 03:05:22.000000000","message":"i\u0027m guessing this is sort of unrelated clean-up?  I agree that the change is more idiomatic.  But to the extend that it does not change correctness or help get the autospec\u003dTrue change merged every hunk of a diff is a liability.\n\nIf this is orthogonal to the change it would be better on it\u0027s own - if it is necessary that would be useful to understand and a pre-req patch may yet still be able to cath 90% of churn with a smaller \"shore up delta and enforce\" while we\u0027re still trying to grok autospec and and the fixture and the new dependency...","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test/unit/cli/test_manage_shard_ranges.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":1002,"context_line":"            with mock.patch(\u0027sys.stdout\u0027, out), \\"},{"line_number":1003,"context_line":"                    mock.patch(\u0027sys.stderr\u0027, err), \\"},{"line_number":1004,"context_line":"                    mock.patch(to_patch, side_effect\u003d[user_input],"},{"line_number":1005,"context_line":"                               create\u003dTrue):"},{"line_number":1006,"context_line":"                ret \u003d main([broker.db_file, \u0027replace\u0027, input_file])"},{"line_number":1007,"context_line":"            self.assertEqual(3, ret)"},{"line_number":1008,"context_line":"            expected \u003d [\u0027This will delete existing 10 shard ranges.\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"3d9ce32e_deedfacc","line":1005,"updated":"2026-06-28 23:57:45.000000000","message":"Hrm. So we\u0027re losing some of the improvements of newer versions of Python?\n\n\u003e *Changed in version 3.5*: If you are patching builtins in a module then you don’t need to pass `create\u003dTrue`, it will be added by default.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[{"line_number":1002,"context_line":"            with mock.patch(\u0027sys.stdout\u0027, out), \\"},{"line_number":1003,"context_line":"                    mock.patch(\u0027sys.stderr\u0027, err), \\"},{"line_number":1004,"context_line":"                    mock.patch(to_patch, side_effect\u003d[user_input],"},{"line_number":1005,"context_line":"                               create\u003dTrue):"},{"line_number":1006,"context_line":"                ret \u003d main([broker.db_file, \u0027replace\u0027, input_file])"},{"line_number":1007,"context_line":"            self.assertEqual(3, ret)"},{"line_number":1008,"context_line":"            expected \u003d [\u0027This will delete existing 10 shard ranges.\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"499cb176_5df4d4fe","line":1005,"in_reply_to":"3aeb0a93_36ba1d57","updated":"2026-07-10 17:21:36.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":1002,"context_line":"            with mock.patch(\u0027sys.stdout\u0027, out), \\"},{"line_number":1003,"context_line":"                    mock.patch(\u0027sys.stderr\u0027, err), \\"},{"line_number":1004,"context_line":"                    mock.patch(to_patch, side_effect\u003d[user_input],"},{"line_number":1005,"context_line":"                               create\u003dTrue):"},{"line_number":1006,"context_line":"                ret \u003d main([broker.db_file, \u0027replace\u0027, input_file])"},{"line_number":1007,"context_line":"            self.assertEqual(3, ret)"},{"line_number":1008,"context_line":"            expected \u003d [\u0027This will delete existing 10 shard ranges.\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"3aeb0a93_36ba1d57","line":1005,"in_reply_to":"3d9ce32e_deedfacc","updated":"2026-07-08 13:02:46.000000000","message":"When `autospec\u003dTrue`, `mock` will try to `getattr` the attribute being patched. However, `input` is a builtin, it will get an `AttributeError` when trying to get it for patching. `create\u003dTrue` effectively disables autospec. We could set `autospec\u003dFalse` instead (this is one of the exceptions in which we cannot autospec).","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":1016,"context_line":"            with mock.patch(\u0027sys.stdout\u0027, out), \\"},{"line_number":1017,"context_line":"                    mock.patch(\u0027sys.stderr\u0027, err), \\"},{"line_number":1018,"context_line":"                    mock.patch(to_patch, side_effect\u003d[user_input],"},{"line_number":1019,"context_line":"                               autospec\u003dFalse):"},{"line_number":1020,"context_line":"                ret \u003d main([broker.db_file, \u0027replace\u0027, input_file])"},{"line_number":1021,"context_line":"            self.assertEqual(3, ret)"},{"line_number":1022,"context_line":"            expected \u003d [\u0027This will delete existing 10 shard ranges.\u0027]"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f6aa4f7_bd170a2c","line":1019,"updated":"2026-08-28 03:05:22.000000000","message":"I wonder 🤔\n\n```\n\u003e           original_attr \u003d getattr(target, self.attribute)\n                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nE           AttributeError: module \u0027swift.cli.manage_shard_ranges\u0027 has no attribute \u0027input\u0027\n```\n\nI mean... `to_patch \u003d \u0027swift.cli.manage_shard_ranges.input\u0027` - so, sure it does!?\n\n```\n\u003e\u003e\u003e manage_shard_ranges.input\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\nAttributeError: module \u0027swift.cli.manage_shard_ranges\u0027 has no attribute \u0027input\u0027\n```\n\nit does NOT ... so...\n\nis this like a legal way to patch a builtin?  but scoped to the module!?\n\nI don\u0027t think it *does* scope to the module.  I think with autospec\u003dFalse it\u0027s just patching the global?\n\n```\n@@ -1228,7 +1227,8 @@ class TestManageShardRanges(BaseUnitTestCase):\n             with mock.patch(\u0027sys.stdout\u0027, out), mock_normal_timestamp_now(), \\\n                     mock.patch(\u0027sys.stderr\u0027, err), \\\n                     mock.patch(to_patch, side_effect\u003d[user_input],\n-                               autospec\u003dFalse):\n+                               autospec\u003dFalse) as mock_input:\n+                self.assertTrue(manage_shard_ranges.input is mock_input)\n                 ret \u003d main([broker.db_file, \u0027find_and_replace\u0027, \u002710\u0027])\n             self.assertEqual(3, ret)\n             # Shard ranges haven\u0027t changed at all\n```\n\nThe more idiomatic spelling is probably:\n\n```\ndiff --git a/test/unit/cli/test_manage_shard_ranges.py b/test/unit/cli/test_manage_shard_ranges.py\nindex a2706a547..bbbbb86fe 100644\n--- a/test/unit/cli/test_manage_shard_ranges.py\n+++ b/test/unit/cli/test_manage_shard_ranges.py\n@@ -1012,11 +1012,9 @@ class TestManageShardRanges(BaseUnitTestCase):\n                 json.dump(self.overlap_shard_data_1, fd)\n             out \u003d StringIO()\n             err \u003d StringIO()\n-            to_patch \u003d \u0027swift.cli.manage_shard_ranges.input\u0027\n             with mock.patch(\u0027sys.stdout\u0027, out), \\\n                     mock.patch(\u0027sys.stderr\u0027, err), \\\n-                    mock.patch(to_patch, side_effect\u003d[user_input],\n-                               autospec\u003dFalse):\n+                    mock.patch(\u0027builtins.input\u0027, side_effect\u003d[user_input]):\n                 ret \u003d main([broker.db_file, \u0027replace\u0027, input_file])\n             self.assertEqual(3, ret)\n             expected \u003d [\u0027This will delete existing 10 shard ranges.\u0027]\n```\n\nand we should probably try to avoid `autospec\u003dFalse` when reasonable","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":1399,"context_line":"            with mock.patch(\u0027sys.stdout\u0027, out), \\"},{"line_number":1400,"context_line":"                    mock.patch(\u0027sys.stderr\u0027, err), \\"},{"line_number":1401,"context_line":"                    mock.patch(\u0027swift.cli.manage_shard_ranges.input\u0027,"},{"line_number":1402,"context_line":"                               side_effect\u003d[user_input], create\u003dTrue):"},{"line_number":1403,"context_line":"                ret \u003d main([broker.db_file, \u0027compact\u0027,"},{"line_number":1404,"context_line":"                            \u0027--max-shrinking\u0027, \u002799\u0027] + options)"},{"line_number":1405,"context_line":"            self.assertEqual(exit_code, ret)"}],"source_content_type":"text/x-python","patch_set":6,"id":"0550eeaa_1b03492d","line":1402,"updated":"2026-08-28 03:05:22.000000000","message":"I\u0027m starting to suspect this is *necessary* - it will be useful to understand the tracebacks that tell me WHY (so I can debug my failing mocks in the future!)\n\n```\nE           AttributeError: module \u0027swift.cli.manage_shard_ranges\u0027 has no attribute \u0027input\u0027\n```\n\n*interesting* - same traceback different solution, and again it seems like the idiomatic diff is just to explicitly say were mocking the builtin:\n\n```\ndiff --git a/test/unit/cli/test_manage_shard_ranges.py b/test/unit/cli/test_manage_shard_ranges.py\nindex a2706a547..c36be5ed8 100644\n--- a/test/unit/cli/test_manage_shard_ranges.py\n+++ b/test/unit/cli/test_manage_shard_ranges.py\n@@ -1398,8 +1398,7 @@ class TestManageShardRanges(BaseUnitTestCase):\n             err \u003d StringIO()\n             with mock.patch(\u0027sys.stdout\u0027, out), \\\n                     mock.patch(\u0027sys.stderr\u0027, err), \\\n-                    mock.patch(\u0027swift.cli.manage_shard_ranges.input\u0027,\n-                               side_effect\u003d[user_input], create\u003dTrue):\n+                    mock.patch(\u0027builtins.input\u0027, side_effect\u003d[user_input]):\n                 ret \u003d main([broker.db_file, \u0027compact\u0027,\n                             \u0027--max-shrinking\u0027, \u002799\u0027] + options)\n             self.assertEqual(exit_code, ret)\n@@ -2443,8 +2442,7 @@ class TestManageShardRanges(BaseUnitTestCase):\n             with mock.patch(\u0027sys.stdout\u0027, out), \\\n                     mock.patch(\u0027sys.stderr\u0027, err), \\\n                     mock_normal_timestamp_now(ts_now), \\\n-                    mock.patch(\u0027swift.cli.manage_shard_ranges.input\u0027,\n-                               side_effect\u003d[user_input], create\u003dTrue):\n+                    mock.patch(\u0027builtins.input\u0027, side_effect\u003d[user_input]):\n                 ret \u003d main(\n                     [broker.db_file, \u0027repair\u0027, \u0027--min-shard-age\u0027, \u00270\u0027] +\n                     options)\n```","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test/unit/cli/test_recon.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":322,"context_line":"                self.recon_instance.server_type \u003d server_type"},{"line_number":323,"context_line":"                stdout \u003d StringIO()"},{"line_number":324,"context_line":"                with mock.patch(\u0027sys.stdout\u0027, new\u003dstdout), \\"},{"line_number":325,"context_line":"                        mock.patch(\u0027swift.common.utils.md5\u0027) as mock_hash:"},{"line_number":326,"context_line":"                    mock_hash.return_value.hexdigest.return_value \u003d \\"},{"line_number":327,"context_line":"                        empty_file_hash"},{"line_number":328,"context_line":"                    self.recon_instance.get_ringmd5(hosts, self.swift_dir)"}],"source_content_type":"text/x-python","patch_set":6,"id":"13ddadb2_5215a086","line":325,"updated":"2026-08-28 03:05:22.000000000","message":"this again just looks like iodiomatic cleanup - useful - but different (maybe?  unless it\u0027s needed?  i can\u0027t revert ALL the hunks!?)","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test/unit/cli/test_reload.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":46,"context_line":""},{"line_number":47,"context_line":"    def test_open_error(self, mock_stderr):"},{"line_number":48,"context_line":"        with mock.patch.object(reload, \u0027open\u0027,"},{"line_number":49,"context_line":"                               new_callable\u003dmock.mock_open) as mock_open, \\"},{"line_number":50,"context_line":"                self.assertRaises(SystemExit) as caught:"},{"line_number":51,"context_line":"            mock_open.side_effect \u003d OSError"},{"line_number":52,"context_line":"            reload.validate_manager_pid(123)"}],"source_content_type":"text/x-python","patch_set":6,"id":"1103aa58_5b44d325","line":49,"updated":"2026-08-28 03:05:22.000000000","message":"`mock.mock_open` is cool\n\nhttps://docs.python.org/3/library/unittest.mock.html#mock-open\n\nFWIW AFAICT `side_effect` as kwarg in general is still fine with `autospect\u003dTrue` but `open` builtin is a weird beast, builtin, callable, context-manager, it has everything going for it.\n\nI think this would be more idiomatic:\n\n```\ndiff --git a/test/unit/cli/test_reload.py b/test/unit/cli/test_reload.py\nindex 86789bbd4..c6c5941fb 100644\n--- a/test/unit/cli/test_reload.py\n+++ b/test/unit/cli/test_reload.py\n@@ -45,10 +45,8 @@ class TestValidateManagerPid(unittest.TestCase):\n                          mock.call(\u0027/proc/123/cmdline\u0027, \u0027r\u0027))\n \n     def test_open_error(self, mock_stderr):\n-        with mock.patch.object(reload, \u0027open\u0027,\n-                               new_callable\u003dmock.mock_open) as mock_open, \\\n+        with mock.patch(\u0027builtins.open\u0027, side_effect\u003dOSError), \\\n                 self.assertRaises(SystemExit) as caught:\n-            mock_open.side_effect \u003d OSError\n             reload.validate_manager_pid(123)\n         self.assertEqual(caught.exception.args, (reload.EXIT_BAD_PID,))\n         self.assertEqual(mock_stderr.getvalue(),\n```","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":142,"context_line":"            \u0027swift-proxy-server\u0027,"},{"line_number":143,"context_line":"        )"},{"line_number":144,"context_line":"        mock_server_ctx \u003d self.mock_notify_server.return_value"},{"line_number":145,"context_line":"        mock_server_ctx.__enter__.return_value.receive.side_effect \u003d ["},{"line_number":146,"context_line":"            b\u0027RELOADING\u003d1\u0027,"},{"line_number":147,"context_line":"            b\u0027READY\u003d1\u0027,"},{"line_number":148,"context_line":"        ]"}],"source_content_type":"text/x-python","patch_set":6,"id":"ba3b0783_e88830f5","line":145,"updated":"2026-08-28 03:05:22.000000000","message":"I think i\u0027m fine with this, `__enter__().` \u003d\u003e `__enter__.return_value`\n\nI don\u0027t know why it *matters* tho?\n\noh - I misundertood this:\n\n\u003e `self.mock_notify_server().__enter__().receive.side_effect \u003d ...`\n\n\u003e  That calls the patched NotificationServer with no arguments merely to configure it. Since `NotificationServer.__init__(self, pid, read_timeout)` now has autospec enforcement, that invalid zero-argument constructor call fails.\n\nI don\u0027t see a big reason to have a strong preference here:\n\n```\ndiff --git a/test/unit/cli/test_reload.py b/test/unit/cli/test_reload.py\nindex 86789bbd4..25a29cd91 100644\n--- a/test/unit/cli/test_reload.py\n+++ b/test/unit/cli/test_reload.py\n@@ -142,7 +142,7 @@ class TestMain(unittest.TestCase):\n             \u0027swift-proxy-server\u0027,\n         )\n         mock_server_ctx \u003d self.mock_notify_server.return_value\n-        mock_server_ctx.__enter__.return_value.receive.side_effect \u003d [\n+        mock_server_ctx.__enter__().receive.side_effect \u003d [\n             b\u0027RELOADING\u003d1\u0027,\n             b\u0027READY\u003d1\u0027,\n         ]\n```\n\nthis is fine/necessary as written","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test/unit/common/middleware/s3api/test_obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":527,"context_line":"                            headers\u003d{\u0027Authorization\u0027: \u0027AWS test:tester:hmac\u0027,"},{"line_number":528,"context_line":"                                     \u0027Date\u0027: self.get_date_header()})"},{"line_number":529,"context_line":""},{"line_number":530,"context_line":"        self.mock_get_swift_info_result.clear()"},{"line_number":531,"context_line":"        status, headers, body \u003d self.call_s3api(req)"},{"line_number":532,"context_line":"        self.assertEqual(status.split()[0], \u0027501\u0027, body)"},{"line_number":533,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"b942b452_a7de4542","line":530,"updated":"2026-08-28 03:05:22.000000000","message":"I think what\u0027s goin on here is that the mock is getting .start()\u0027d (in another test module\u0027s base class - this is raw object, it\u0027s *combined* with TestS3ApiBase below with a MixIn pattern)\n\n... and `autospect\u003dTrue` doesn\u0027t like us to double-mock - that\u0027s *actually* a pretty nice hygine behavior.\n\nWhen a theory can be used to make prediction is a pretty good theory:\n\nhttps://opendev.org/openstack/swift/src/branch/master/test/unit/common/middleware/s3api/__init__.py#L161\n\n```\nE           unittest.mock.InvalidSpecError: Cannot autospec a Mock object. [object\u003d\u003c_AutospecMagicMock name\u003d\u0027get_swift_info\u0027 id\u003d\u0027131279166333984\u0027\u003e]\n```","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test/unit/common/ring/test_ring.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":108,"context_line":"        rd.save(ring_fname)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        real_fh \u003d open(ring_fname, \u0027rb\u0027)"},{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"}],"source_content_type":"text/x-python","patch_set":3,"id":"dfb0e3bf_e1dedaca","line":111,"updated":"2026-06-28 23:57:45.000000000","message":"We can\u0027t just say\n```\nwith open(ring_fname, \u0027rb\u0027) as real_fh:\n    ...\n```\nand let the context manager handle clean up?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        rd.save(ring_fname)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        real_fh \u003d open(ring_fname, \u0027rb\u0027)"},{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"}],"source_content_type":"text/x-python","patch_set":3,"id":"f8b95221_519a4b74","line":111,"in_reply_to":"39d95b74_b13f8f44","updated":"2026-07-10 17:21:36.000000000","message":"Acknowledged","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":108,"context_line":"        rd.save(ring_fname)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        real_fh \u003d open(ring_fname, \u0027rb\u0027)"},{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"}],"source_content_type":"text/x-python","patch_set":3,"id":"39d95b74_b13f8f44","line":111,"in_reply_to":"dfb0e3bf_e1dedaca","updated":"2026-07-08 13:02:46.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"},{"line_number":115,"context_line":"            self.assertFalse(real_fh.closed)  # sanity"},{"line_number":116,"context_line":"            ring.RingData.load(ring_fname)"},{"line_number":117,"context_line":"            self.assertTrue(real_fh.closed)"}],"source_content_type":"text/x-python","patch_set":3,"id":"72b78ca9_6618965b","line":114,"updated":"2026-06-28 23:57:45.000000000","message":"How much of the `mock.mock_open` benefit remains once we do this? How much of it did we really *need*, given that we\u0027re subbing in an actual open return value?\n\nIf we want to use `mock.mock_open`, would it be better to do something like\n```\nwith open(ring_fname, \u0027rb\u0027) as fh:\n    mock_open \u003d mock.mock_open(read_data\u003dfh.read())\nwith mock.patch(\u0027swift.common.ring.io.open\u0027, mock_open):\n    ...\n```\nand then make assertions about whether `mock_open.close()` (and/or `mock_open.__exit__()`) have been called?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"},{"line_number":115,"context_line":"            self.assertFalse(real_fh.closed)  # sanity"},{"line_number":116,"context_line":"            ring.RingData.load(ring_fname)"},{"line_number":117,"context_line":"            self.assertTrue(real_fh.closed)"}],"source_content_type":"text/x-python","patch_set":3,"id":"ef4f59ef_df6698e3","line":114,"in_reply_to":"72b78ca9_6618965b","updated":"2026-07-08 13:02:46.000000000","message":"Fair enough.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"},{"line_number":115,"context_line":"            self.assertFalse(real_fh.closed)  # sanity"},{"line_number":116,"context_line":"            ring.RingData.load(ring_fname)"},{"line_number":117,"context_line":"            self.assertTrue(real_fh.closed)"}],"source_content_type":"text/x-python","patch_set":3,"id":"b5c711a4_b3ab634a","line":114,"in_reply_to":"ef4f59ef_df6698e3","updated":"2026-07-10 17:21:36.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"f0a7f0a06c00c946518be745666c5a86a9321c48","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        with open(ring_fname, \u0027rb\u0027) as real_fh, \\"},{"line_number":111,"context_line":"                mock.patch(\u0027swift.common.ring.io.open\u0027, autospec\u003dFalse,"},{"line_number":112,"context_line":"                          return_value\u003dreal_fh):"},{"line_number":113,"context_line":"            self.assertFalse(real_fh.closed)  # sanity"},{"line_number":114,"context_line":"            ring.RingData.load(ring_fname)"},{"line_number":115,"context_line":"            self.assertTrue(real_fh.closed)"}],"source_content_type":"text/x-python","patch_set":5,"id":"8c12aec8_f55c0c72","line":112,"updated":"2026-07-08 14:29:37.000000000","message":"pep8: E128 continuation line under-indented for visual indent","commit_id":"55a05708d02e1dba45459e61ed54463a7c2f0423"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        with open(ring_fname, \u0027rb\u0027) as real_fh, \\"},{"line_number":111,"context_line":"                mock.patch(\u0027swift.common.ring.io.open\u0027, autospec\u003dFalse,"},{"line_number":112,"context_line":"                           return_value\u003dreal_fh):"},{"line_number":113,"context_line":"            self.assertFalse(real_fh.closed)  # sanity"},{"line_number":114,"context_line":"            ring.RingData.load(ring_fname)"},{"line_number":115,"context_line":"            self.assertTrue(real_fh.closed)"}],"source_content_type":"text/x-python","patch_set":6,"id":"6be85f32_065787e9","line":112,"updated":"2026-08-28 03:05:22.000000000","message":"missed oppertunity for builtin.open\n\nmore idiomatic as:\n\n```\ndiff --git a/test/unit/common/ring/test_ring.py b/test/unit/common/ring/test_ring.py\nindex 8ed84a01f..31870e1ea 100644\n--- a/test/unit/common/ring/test_ring.py\n+++ b/test/unit/common/ring/test_ring.py\n@@ -108,8 +108,7 @@ class TestRingData(unittest.TestCase):\n         rd.save(ring_fname)\n \n         with open(ring_fname, \u0027rb\u0027) as real_fh, \\\n-                mock.patch(\u0027swift.common.ring.io.open\u0027, autospec\u003dFalse,\n-                           return_value\u003dreal_fh):\n+                mock.patch(\u0027builtins.open\u0027, return_value\u003dreal_fh):\n             self.assertFalse(real_fh.closed)  # sanity\n             ring.RingData.load(ring_fname)\n             self.assertTrue(real_fh.closed)\n```","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test/unit/common/test_direct_client.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":91,"context_line":"    mocked \u003d kwargs.pop(\u0027mocked\u0027, \u0027swift.common.bufferedhttp.http_connect_raw\u0027)"},{"line_number":92,"context_line":"    fake_conn \u003d FakeConn(*args, **kwargs)"},{"line_number":93,"context_line":"    with mock.patch(mocked,"},{"line_number":94,"context_line":"                    side_effect\u003dfake_conn._update_raw_call_args):"},{"line_number":95,"context_line":"        yield fake_conn"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"10f4773e_361bf27c","line":94,"updated":"2026-06-28 23:57:45.000000000","message":"OK, this is some nice cleanup. 👍","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":5802,"context_line":"@mock.patch(\u0027swift.common.utils.open\u0027, new_callable\u003dmock.mock_open)"},{"line_number":5803,"context_line":"class TestGetPpid(unittest.TestCase):"},{"line_number":5804,"context_line":"    def test_happy_path(self, mock_open):"},{"line_number":5805,"context_line":"        mock_open.return_value.__enter__().read.return_value \u003d \\"},{"line_number":5806,"context_line":"            \u0027pid comm stat 456 see the procfs(5) man page for more info\\n\u0027"},{"line_number":5807,"context_line":"        self.assertEqual(utils.get_ppid(123), 456)"},{"line_number":5808,"context_line":"        self.assertIn(mock.call(\u0027/proc/123/stat\u0027), mock_open.mock_calls)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1df1bd4e_bd20c9b0","line":5805,"range":{"start_line":5805,"start_character":31,"end_line":5805,"end_character":42},"updated":"2026-06-28 23:57:45.000000000","message":"We don\u0027t want/need to use `__enter__.return_value` to navigate here? I guess because it takes no args?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":false,"context_lines":[{"line_number":5802,"context_line":"@mock.patch(\u0027swift.common.utils.open\u0027, new_callable\u003dmock.mock_open)"},{"line_number":5803,"context_line":"class TestGetPpid(unittest.TestCase):"},{"line_number":5804,"context_line":"    def test_happy_path(self, mock_open):"},{"line_number":5805,"context_line":"        mock_open.return_value.__enter__().read.return_value \u003d \\"},{"line_number":5806,"context_line":"            \u0027pid comm stat 456 see the procfs(5) man page for more info\\n\u0027"},{"line_number":5807,"context_line":"        self.assertEqual(utils.get_ppid(123), 456)"},{"line_number":5808,"context_line":"        self.assertIn(mock.call(\u0027/proc/123/stat\u0027), mock_open.mock_calls)"}],"source_content_type":"text/x-python","patch_set":3,"id":"a6f50c66_ceff62b4","line":5805,"range":{"start_line":5805,"start_character":31,"end_line":5805,"end_character":42},"in_reply_to":"1df1bd4e_bd20c9b0","updated":"2026-07-08 13:02:46.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"test/unit/container/test_replicator.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":291,"context_line":"        node \u003d random.choice([n for n in self._ring.devs"},{"line_number":292,"context_line":"                              if n[\u0027id\u0027] !\u003d local_node[\u0027id\u0027]])"},{"line_number":293,"context_line":"        info \u003d broker.get_replication_info()"},{"line_number":294,"context_line":"        with mock_check_drive(isdir\u003dTrue, ismount\u003dTrue):"},{"line_number":295,"context_line":"            success \u003d daemon._repl_to_node(node, broker, part, info)"},{"line_number":296,"context_line":"        self.assertFalse(success)"},{"line_number":297,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"081d68c4_c9fc631a","line":294,"updated":"2026-08-28 03:05:22.000000000","message":"ok sure, cause the base doesn\u0027t do it anymore.","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5895fcd08d89e5c740f7058706e35540e7779372","unresolved":true,"context_lines":[{"line_number":2068,"context_line":""},{"line_number":2069,"context_line":"        with mock.patch.object(db_replicator, \u0027ReplConnection\u0027,"},{"line_number":2070,"context_line":"                               fake_repl_connection), \\"},{"line_number":2071,"context_line":"                mock_check_drive(isdir\u003dTrue):"},{"line_number":2072,"context_line":"            success \u003d daemon._repl_to_node("},{"line_number":2073,"context_line":"                remote_node, from_broker, part, info)"},{"line_number":2074,"context_line":"        self.assertEqual(expect_success, success)"}],"source_content_type":"text/x-python","patch_set":6,"id":"700e834d_ef2a2bf9","line":2071,"updated":"2026-08-28 03:05:22.000000000","message":"and BOBs your uncle!  mock at the site.","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test/unit/container/test_server.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"0878d461b38749b91cda37a7b0d798f7f5b0cf6e","unresolved":false,"context_lines":[{"line_number":40,"context_line":"from swift.container import server as container_server"},{"line_number":41,"context_line":"from swift.common import constraints"},{"line_number":42,"context_line":"from swift.common.utils.timestamp import Timestamp"},{"line_number":43,"context_line":"from swift.common.utils import (mkdirs, public, replication,"},{"line_number":44,"context_line":"                                storage_directory, lock_parent_directory,"},{"line_number":45,"context_line":"                                ShardRange, RESERVED_STR, Namespace)"},{"line_number":46,"context_line":"from test.debug_logger import debug_logger"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a6dfd66_01917ff9","line":43,"updated":"2026-06-24 18:54:08.000000000","message":"pep8: F401 \u0027swift.common.utils.replication\u0027 imported but unused","commit_id":"443d9ee538bfe24c78585582ccc9371026319e24"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":39,"context_line":"import swift.container"},{"line_number":40,"context_line":"from swift.common import constraints"},{"line_number":41,"context_line":"from swift.common.utils.timestamp import Timestamp"},{"line_number":42,"context_line":"from swift.common.utils import (mkdirs, public, replication,"},{"line_number":43,"context_line":"                                storage_directory, lock_parent_directory,"},{"line_number":44,"context_line":"                                ShardRange, RESERVED_STR, Namespace)"},{"line_number":45,"context_line":"from test.debug_logger import debug_logger"}],"source_content_type":"text/x-python","patch_set":2,"id":"efa309ee_2ebe1140","line":42,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F401 \u0027swift.common.utils.replication\u0027 imported but unused","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        mkdirs(os.path.join(self.testdir, \u0027sda1\u0027))"},{"line_number":74,"context_line":"        mkdirs(os.path.join(self.testdir, \u0027sda1\u0027, \u0027tmp\u0027))"},{"line_number":75,"context_line":"        self.logger \u003d debug_logger()"},{"line_number":76,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":77,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027},"},{"line_number":78,"context_line":"            logger\u003dself.logger)"},{"line_number":79,"context_line":"        # some of the policy tests want at least two policies"}],"source_content_type":"text/x-python","patch_set":2,"id":"f60ba545_a89f39c8","line":76,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    def test_creation(self):"},{"line_number":117,"context_line":"        # later config should be extended to assert more config options"},{"line_number":118,"context_line":"        app \u003d container_server.ContainerController("},{"line_number":119,"context_line":"            {\u0027node_timeout\u0027: \u00273.5\u0027}, logger\u003dself.logger)"},{"line_number":120,"context_line":"        self.assertEqual(app.node_timeout, 3.5)"},{"line_number":121,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027warning\u0027), [])"}],"source_content_type":"text/x-python","patch_set":2,"id":"1167caaa_c8dcdef8","line":118,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":376,"context_line":"        self.assertEqual(resp.status_int, 400)"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"    def test_OPTIONS(self):"},{"line_number":379,"context_line":"        server_handler \u003d container_server.ContainerController("},{"line_number":380,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027})"},{"line_number":381,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a/c/o\u0027, {\u0027REQUEST_METHOD\u0027: \u0027OPTIONS\u0027})"},{"line_number":382,"context_line":"        req.content_length \u003d 0"}],"source_content_type":"text/x-python","patch_set":2,"id":"f966ec4c_0a4d99ef","line":379,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":389,"context_line":""},{"line_number":390,"context_line":"    def test_insufficient_storage_mount_check_true(self):"},{"line_number":391,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027true\u0027}"},{"line_number":392,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":393,"context_line":"        self.assertTrue(container_controller.mount_check)"},{"line_number":394,"context_line":"        for method in container_controller.allowed_methods:"},{"line_number":395,"context_line":"            if method \u003d\u003d \u0027OPTIONS\u0027:"}],"source_content_type":"text/x-python","patch_set":2,"id":"2ab507ba_e077a3ec","line":392,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":416,"context_line":""},{"line_number":417,"context_line":"    def test_insufficient_storage_mount_check_false(self):"},{"line_number":418,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027}"},{"line_number":419,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":420,"context_line":"        self.assertFalse(container_controller.mount_check)"},{"line_number":421,"context_line":"        for method in container_controller.allowed_methods:"},{"line_number":422,"context_line":"            if method \u003d\u003d \u0027OPTIONS\u0027:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3ffb6ea6_8295f608","line":419,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":516,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir,"},{"line_number":517,"context_line":"                \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":518,"context_line":"                \u0027fallocate_reserve\u0027: \u00272%\u0027}"},{"line_number":519,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"        req \u003d Request.blank("},{"line_number":522,"context_line":"            \u0027/sda1/p/a/c\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"e37f8938_6ac571f3","line":519,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":1196,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir,"},{"line_number":1197,"context_line":"                \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":1198,"context_line":"                \u0027fallocate_reserve\u0027: \u00272%\u0027}"},{"line_number":1199,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":1200,"context_line":""},{"line_number":1201,"context_line":"        req \u003d Request.blank("},{"line_number":1202,"context_line":"            \u0027/sda1/p/a/c\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"6335e7fe_dcc38299","line":1199,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":1231,"context_line":"        self.assertEqual(resp.status_int, 400)"},{"line_number":1232,"context_line":""},{"line_number":1233,"context_line":"    def test_POST_invalid_container_sync_to(self):"},{"line_number":1234,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":1235,"context_line":"            {\u0027devices\u0027: self.testdir})"},{"line_number":1236,"context_line":"        req \u003d Request.blank("},{"line_number":1237,"context_line":"            \u0027/sda-null/p/a/c\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"b8631c43_16190caa","line":1234,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":1618,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir,"},{"line_number":1619,"context_line":"                \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":1620,"context_line":"                \u0027fallocate_reserve\u0027: \u00272%\u0027}"},{"line_number":1621,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":1622,"context_line":""},{"line_number":1623,"context_line":"        req \u003d Request.blank("},{"line_number":1624,"context_line":"            \u0027/sda1/p/a/\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"302698db_f43d577e","line":1621,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":2034,"context_line":""},{"line_number":2035,"context_line":"        req \u003d Request.blank(path, method\u003d\u0027PUT\u0027,"},{"line_number":2036,"context_line":"                            headers\u003d{\u0027X-Timestamp\u0027: \u00274\u0027})"},{"line_number":2037,"context_line":"        with mock.patch.object(container_server.os.path, \u0027exists\u0027,"},{"line_number":2038,"context_line":"                               mock_exists):"},{"line_number":2039,"context_line":"            resp \u003d req.get_response(self.controller)"},{"line_number":2040,"context_line":"        # db was successfully created"}],"source_content_type":"text/x-python","patch_set":2,"id":"73ec7ef2_b3b4485f","line":2037,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6042,"context_line":"                     \u0027X-Account-Host\u0027: \u00271.2.3.4:5, 6.7.8.9:10\u0027,"},{"line_number":6043,"context_line":"                     \u0027X-Account-Device\u0027: \u0027sdb1, sdf1\u0027})"},{"line_number":6044,"context_line":""},{"line_number":6045,"context_line":"        orig_http_connect \u003d container_server.http_connect"},{"line_number":6046,"context_line":"        try:"},{"line_number":6047,"context_line":"            container_server.http_connect \u003d fake_http_connect"},{"line_number":6048,"context_line":"            req.get_response(self.controller)"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa0ae853_1f6a2f03","line":6045,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6044,"context_line":""},{"line_number":6045,"context_line":"        orig_http_connect \u003d container_server.http_connect"},{"line_number":6046,"context_line":"        try:"},{"line_number":6047,"context_line":"            container_server.http_connect \u003d fake_http_connect"},{"line_number":6048,"context_line":"            req.get_response(self.controller)"},{"line_number":6049,"context_line":"        finally:"},{"line_number":6050,"context_line":"            container_server.http_connect \u003d orig_http_connect"}],"source_content_type":"text/x-python","patch_set":2,"id":"68518829_755292d1","line":6047,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6047,"context_line":"            container_server.http_connect \u003d fake_http_connect"},{"line_number":6048,"context_line":"            req.get_response(self.controller)"},{"line_number":6049,"context_line":"        finally:"},{"line_number":6050,"context_line":"            container_server.http_connect \u003d orig_http_connect"},{"line_number":6051,"context_line":""},{"line_number":6052,"context_line":"        http_connect_args.sort(key\u003doperator.itemgetter(\u0027ipaddr\u0027))"},{"line_number":6053,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1af260df_9b84ef26","line":6050,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6091,"context_line":""},{"line_number":6092,"context_line":"    def test_serv_reserv(self):"},{"line_number":6093,"context_line":"        # Test replication_server flag was set from configuration file."},{"line_number":6094,"context_line":"        container_controller \u003d container_server.ContainerController"},{"line_number":6095,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027}"},{"line_number":6096,"context_line":"        self.assertTrue(container_controller(conf).replication_server)"},{"line_number":6097,"context_line":"        for val in [True, \u00271\u0027, \u0027True\u0027, \u0027true\u0027]:"}],"source_content_type":"text/x-python","patch_set":2,"id":"b31452ef_38aea27b","line":6094,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6118,"context_line":"        inbuf \u003d BytesIO()"},{"line_number":6119,"context_line":"        errbuf \u003d StringIO()"},{"line_number":6120,"context_line":"        outbuf \u003d StringIO()"},{"line_number":6121,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":6122,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":6123,"context_line":"             \u0027replication_server\u0027: \u0027false\u0027})"},{"line_number":6124,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9dee13e3_ddacd6cc","line":6121,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6159,"context_line":"        inbuf \u003d BytesIO()"},{"line_number":6160,"context_line":"        errbuf \u003d StringIO()"},{"line_number":6161,"context_line":"        outbuf \u003d StringIO()"},{"line_number":6162,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":6163,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":6164,"context_line":"             \u0027replication_server\u0027: \u0027false\u0027})"},{"line_number":6165,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"87a24f24_38e25bb0","line":6162,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6197,"context_line":"        inbuf \u003d BytesIO()"},{"line_number":6198,"context_line":"        errbuf \u003d StringIO()"},{"line_number":6199,"context_line":"        outbuf \u003d StringIO()"},{"line_number":6200,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":6201,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":6202,"context_line":"             \u0027replication_server\u0027: \u0027true\u0027})"},{"line_number":6203,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"6e2a2f22_ba145fcb","line":6200,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6231,"context_line":"        errbuf \u003d StringIO()"},{"line_number":6232,"context_line":"        outbuf \u003d StringIO()"},{"line_number":6233,"context_line":"        self.logger \u003d debug_logger(\u0027test\u0027)"},{"line_number":6234,"context_line":"        self.container_controller \u003d container_server.ContainerController("},{"line_number":6235,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":6236,"context_line":"             \u0027replication_server\u0027: \u0027false\u0027, \u0027log_requests\u0027: \u0027false\u0027},"},{"line_number":6237,"context_line":"            logger\u003dself.logger)"}],"source_content_type":"text/x-python","patch_set":2,"id":"125ec6c6_991be54c","line":6234,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":6189,"context_line":"                  b\u0027allowed for this resource.\u003c/p\u003e\u003c/html\u003e\u0027]"},{"line_number":6190,"context_line":"        with mock.patch.object(self.controller, method) as mock_method:"},{"line_number":6191,"context_line":"            mock_method.replication \u003d True"},{"line_number":6192,"context_line":"            mock_method.publicly_accessible \u003d True"},{"line_number":6193,"context_line":"            response \u003d self.controller.__call__(env, start_response)"},{"line_number":6194,"context_line":"            self.assertEqual(response, answer)"},{"line_number":6195,"context_line":"            self.assertEqual(outbuf.getvalue()[:4], \u0027405 \u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"6f252b91_9f9eb1e0","line":6192,"updated":"2026-06-28 23:57:45.000000000","message":"Are we sure we really want to go reimplementing `@public` and `@replication` in tests?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":6189,"context_line":"                  b\u0027allowed for this resource.\u003c/p\u003e\u003c/html\u003e\u0027]"},{"line_number":6190,"context_line":"        with mock.patch.object(self.controller, method) as mock_method:"},{"line_number":6191,"context_line":"            mock_method.replication \u003d True"},{"line_number":6192,"context_line":"            mock_method.publicly_accessible \u003d True"},{"line_number":6193,"context_line":"            response \u003d self.controller.__call__(env, start_response)"},{"line_number":6194,"context_line":"            self.assertEqual(response, answer)"},{"line_number":6195,"context_line":"            self.assertEqual(outbuf.getvalue()[:4], \u0027405 \u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"b1927690_70a44d35","line":6192,"in_reply_to":"6f252b91_9f9eb1e0","updated":"2026-07-08 13:02:46.000000000","message":"Right, I\u0027ve updated those.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[{"line_number":6189,"context_line":"                  b\u0027allowed for this resource.\u003c/p\u003e\u003c/html\u003e\u0027]"},{"line_number":6190,"context_line":"        with mock.patch.object(self.controller, method) as mock_method:"},{"line_number":6191,"context_line":"            mock_method.replication \u003d True"},{"line_number":6192,"context_line":"            mock_method.publicly_accessible \u003d True"},{"line_number":6193,"context_line":"            response \u003d self.controller.__call__(env, start_response)"},{"line_number":6194,"context_line":"            self.assertEqual(response, answer)"},{"line_number":6195,"context_line":"            self.assertEqual(outbuf.getvalue()[:4], \u0027405 \u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"c8232608_2395748e","line":6192,"in_reply_to":"b1927690_70a44d35","updated":"2026-07-10 17:21:36.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":6258,"context_line":"               \u0027wsgi.multiprocess\u0027: False,"},{"line_number":6259,"context_line":"               \u0027wsgi.run_once\u0027: False}"},{"line_number":6260,"context_line":""},{"line_number":6261,"context_line":"        @public"},{"line_number":6262,"context_line":"        def mock_put_method(*args, **kwargs):"},{"line_number":6263,"context_line":"            raise Exception()"},{"line_number":6264,"context_line":""},{"line_number":6265,"context_line":"        with mock.patch.object(self.container_controller, method,"},{"line_number":6266,"context_line":"                               new\u003dmock_put_method):"},{"line_number":6267,"context_line":"            response \u003d self.container_controller.__call__(env, start_response)"},{"line_number":6268,"context_line":"            self.assertTrue(response[0].startswith("},{"line_number":6269,"context_line":"                b\u0027Traceback (most recent call last):\u0027))"}],"source_content_type":"text/x-python","patch_set":3,"id":"7779ca4b_b84aea34","line":6266,"range":{"start_line":6261,"start_character":0,"end_line":6266,"end_character":52},"updated":"2026-06-28 23:57:45.000000000","message":"I\u0027m a little surprised this didn\u0027t get rewritten, too.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":false,"context_lines":[{"line_number":6258,"context_line":"               \u0027wsgi.multiprocess\u0027: False,"},{"line_number":6259,"context_line":"               \u0027wsgi.run_once\u0027: False}"},{"line_number":6260,"context_line":""},{"line_number":6261,"context_line":"        @public"},{"line_number":6262,"context_line":"        def mock_put_method(*args, **kwargs):"},{"line_number":6263,"context_line":"            raise Exception()"},{"line_number":6264,"context_line":""},{"line_number":6265,"context_line":"        with mock.patch.object(self.container_controller, method,"},{"line_number":6266,"context_line":"                               new\u003dmock_put_method):"},{"line_number":6267,"context_line":"            response \u003d self.container_controller.__call__(env, start_response)"},{"line_number":6268,"context_line":"            self.assertTrue(response[0].startswith("},{"line_number":6269,"context_line":"                b\u0027Traceback (most recent call last):\u0027))"}],"source_content_type":"text/x-python","patch_set":3,"id":"ed5653f6_015bc5eb","line":6266,"range":{"start_line":6261,"start_character":0,"end_line":6266,"end_character":52},"in_reply_to":"7779ca4b_b84aea34","updated":"2026-07-08 13:02:46.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"44a244f799759404f24b99158930217356fa616f","unresolved":false,"context_lines":[{"line_number":6151,"context_line":"        method_res \u003d mock.MagicMock()"},{"line_number":6152,"context_line":"        with mock.patch.object(self.controller, method) as mock_method:"},{"line_number":6153,"context_line":"            mock_method.publicly_accessible \u003d True"},{"line_number":6154,"context_line":"            # Mock attributes are truthy by default; without this, allowed_methods"},{"line_number":6155,"context_line":"            # would treat PUT as a replication-only method and return 405."},{"line_number":6156,"context_line":"            mock_method.replication \u003d False"},{"line_number":6157,"context_line":"            mock_method.return_value.return_value \u003d method_res"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a6ada9d_2a4b02e7","line":6154,"updated":"2026-07-08 11:17:02.000000000","message":"pep8: E501 line too long (82 \u003e 79 characters)","commit_id":"ca35b53f0a033f600ec9dcae3f8e6b4138b49dfb"}],"test/unit/obj/test_diskfile.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":1139,"context_line":"        with temptree([]) as tmpdir:"},{"line_number":1140,"context_line":"            os.makedirs(os.path.join(tmpdir, \"sdf\", \"objects\", \"1\", \"a\", \"b\"))"},{"line_number":1141,"context_line":"            with mock.patch(\u0027swift.obj.diskfile.open\u0027,"},{"line_number":1142,"context_line":"                            new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":1143,"context_line":"                # File does not exist yet - write expected"},{"line_number":1144,"context_line":"                update_auditor_status(tmpdir, None, [\u002742\u0027], \"ALL\")"},{"line_number":1145,"context_line":"                self.assertEqual(1, mock_open.call_count)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a9a6b68_92339d8e","line":1142,"updated":"2026-06-28 23:57:45.000000000","message":"We don\u0027t need a `create\u003dTrue` on this one?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":1139,"context_line":"        with temptree([]) as tmpdir:"},{"line_number":1140,"context_line":"            os.makedirs(os.path.join(tmpdir, \"sdf\", \"objects\", \"1\", \"a\", \"b\"))"},{"line_number":1141,"context_line":"            with mock.patch(\u0027swift.obj.diskfile.open\u0027,"},{"line_number":1142,"context_line":"                            new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":1143,"context_line":"                # File does not exist yet - write expected"},{"line_number":1144,"context_line":"                update_auditor_status(tmpdir, None, [\u002742\u0027], \"ALL\")"},{"line_number":1145,"context_line":"                self.assertEqual(1, mock_open.call_count)"}],"source_content_type":"text/x-python","patch_set":3,"id":"f7c23c1f_56a71273","line":1142,"in_reply_to":"5a9a6b68_92339d8e","updated":"2026-07-08 13:02:46.000000000","message":"For `open`, no. `mock.mock_open` create a very `open`-like mock, and it is the best way to mock `open`.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"test/unit/proxy/controllers/test_info.py":[{"author":{"_account_id":6968,"name":"Christian Schwede","email":"cschwede@nvidia.com","username":"cschwede"},"change_message_id":"c4743fbda02b86d208d0c9e8b75e56e403ce4c43","unresolved":true,"context_lines":[{"line_number":35,"context_line":"                       admin_key\u003dNone):"},{"line_number":36,"context_line":"        disallowed_sections \u003d disallowed_sections or []"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"        app \u003d mock.Mock(autospec\u003dProxyApp, logger\u003ddebug_logger())"},{"line_number":39,"context_line":"        return InfoController(app, None, expose_info,"},{"line_number":40,"context_line":"                              disallowed_sections, admin_key)"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"654ff335_6035b0c0","line":38,"updated":"2026-08-28 14:03:30.000000000","message":"This change is weakening actual tests. `mock.Mock` has no `autospec` parameter, because the class is not inherited from `test.unit.BaseUnitTestCase`.\n\nLook at this simple example - this would silently pass all tests, besides being wrong (`check_config` takes no args):\n\n```\n$ git diff\ndiff --git a/swift/proxy/controllers/info.py b/swift/proxy/controllers/info.py\nindex 2435849c7..29524cc06 100644\n--- a/swift/proxy/controllers/info.py\n+++ b/swift/proxy/controllers/info.py\n@@ -63,6 +63,8 @@ class InfoController(Controller):\n         if not self.expose_info:\n             return HTTPForbidden(request\u003dreq)\n \n+        self.app.check_config(req)\n+\n         admin_request \u003d False\n         sig \u003d req.params.get(\u0027swiftinfo_sig\u0027, \u0027\u0027)\n         expires \u003d req.params.get(\u0027swiftinfo_expires\u0027, \u0027\u0027)\n```\n\nFix proposed: 1002764: tests: Make autospec effective in TestInfoController | https://review.opendev.org/c/openstack/swift/+/1002764","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}]}
