)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"93e60def0b26c2b2aaa6781c7d9baceed9ceb398","unresolved":true,"context_lines":[{"line_number":7,"context_line":"tests: LabeledStatsdClient sample_rate kwarg"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Like StatsdClient our implemenation supports individual metrics sending"},{"line_number":10,"context_line":"a sample_rate kwarg, but we never do that with LabeledStatsdClient"},{"line_number":11,"context_line":"either.  Some deployers may use the default_sample_rate options and"},{"line_number":12,"context_line":"those are already tested with LabeledStatsdClient."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I68a24d9467e58994abbac82a5e741f5bb578976c"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"0d7d554e_ead31ebe","line":11,"range":{"start_line":10,"start_character":21,"end_line":11,"end_character":6},"updated":"2025-04-04 10:58:04.000000000","message":"we *will* do it though https://review.opendev.org/c/openstack/swift/+/944506/6/swift/obj/server.py","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a4d48faa7237a676d9b787b9b7aa008930c4079a","unresolved":false,"context_lines":[{"line_number":7,"context_line":"tests: LabeledStatsdClient sample_rate kwarg"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Like StatsdClient our implemenation supports individual metrics sending"},{"line_number":10,"context_line":"a sample_rate kwarg, but we never do that with LabeledStatsdClient"},{"line_number":11,"context_line":"either.  Some deployers may use the default_sample_rate options and"},{"line_number":12,"context_line":"those are already tested with LabeledStatsdClient."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I68a24d9467e58994abbac82a5e741f5bb578976c"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"003014a3_44ea8c7c","line":11,"range":{"start_line":10,"start_character":21,"end_line":11,"end_character":6},"in_reply_to":"0d7d554e_ead31ebe","updated":"2025-04-07 22:15:14.000000000","message":"Acknowledged","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aea47d44ffb0c815d941438be3323916ee3ddfbf","unresolved":true,"context_lines":[{"line_number":10,"context_line":"methods."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Drive-by: clean up and tighten some existing StatsdClient unit tests to"},{"line_number":13,"context_line":"share a CommonBaseTestsMixin, as was expedient perhaps to the chagrin of"},{"line_number":14,"context_line":"the co-author."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"Related-Change: I115ffb1dc601652a979895d7944e011b951a91c1"},{"line_number":17,"context_line":"Co-Authored-By: Alistair Coles \u003calistairncoles@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":6,"id":"1b4472c8_e9812263","line":14,"range":{"start_line":13,"start_character":62,"end_line":14,"end_character":14},"updated":"2025-04-09 10:30:07.000000000","message":"😄\n\n\"chagrin\" - love it!","commit_id":"ed0ef357135b0baadfabaa67774f00bfd6a7ebd4"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"93e60def0b26c2b2aaa6781c7d9baceed9ceb398","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"490b8c74_5895d24f","updated":"2025-04-04 10:58:04.000000000","message":"@Clay you inspired me, but we may disagree on style so I pushed a separate patch https://review.opendev.org/c/openstack/swift/+/946335","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8df7b86420b7b28594ae50ac54356239e1a79e1c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"1bd15e79_91c16743","updated":"2025-04-04 15:32:57.000000000","message":"Al, it looked like you fixed most of the nits you found in your alternative patch - which I think is perfectly reasonable and I am very much +2 on there.\n\nThis update to your patch attempts to go back to the ABC/Common/MixIn test pattern in a way that might be a compromise on style (I think we\u0027ve gone back and forth on the \"best\" way to achieve this test pattern some over the years, with different/but-not-strongly-held preferences - so it seemed worth it to try yet-another-approach just in case there\u0027s any common ground to be had).","commit_id":"31d492adabf9d1b748d354ba72799d0fa064e49f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6fc639e8be15327246bbfe10ecec61f9639167df","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"4b8a96f0_fd3871aa","updated":"2025-04-07 11:37:36.000000000","message":"Neat trick, but needs to be undone in the subclasses.\n\nThis addresses one of my concerns with Mixin (unresolved references). It changes the behavior in pycharm when I right click on a test in the abstract class: \n\n```\nERROR: not found: /Users/acoles/0dev/openstack/swift/test/unit/common/test_statsd_client.py::CommonBaseTests::test_sample_rates_with_sample_rate_factor\n(no match in any of [\u003cUnitTestCase CommonBaseTests\u003e])\n```\n\nTBH, even with the subclass approach there\u0027s a compromise in that I can only click-and-run the test where it is defined *in the superclass*.\n\nI do prefer an abstract superclass over a Mixin.\n\nI\u0027m a little nevrous about the workaround being pytest specific - we *do* specify pytest as the test runner but I might solicit input from other cores as to whether we ought to be compatible with other test runners.\n\nIf we adopt the ``__test__ \u003d True`` I think it would be good to provide a decorator like ``pytest_run_tests(False|True)``","commit_id":"31d492adabf9d1b748d354ba72799d0fa064e49f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a4d48faa7237a676d9b787b9b7aa008930c4079a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"283aff75_a44a6b5d","updated":"2025-04-07 22:15:14.000000000","message":"I think this works in Alistair\u0027s editor and should provide a fairly maintainable pattern we could apply to the rest of the CommonBaseTests across the test suite if we were sufficiently motivated:\n\n```\nvagrant@saio:~/swift$ pytest test/unit/common/test_statsd_client.py \n...\n52 passed, 6 warnings in 9.16s\nvagrant@saio:~/swift$ python3 -m unittest test/unit/common/test_statsd_client.py -v\n...\nRan 60 tests in 6.463s\n\nOK (skipped\u003d8)\nvagrant@saio:~/swift$ stestr --test-path ./test/unit/common run test.unit.common.test_statsd_client\n...\n\u003d\u003d\u003d\u003d\u003d\u003d\nTotals\n\u003d\u003d\u003d\u003d\u003d\u003d\nRan: 60 tests in 8.5885 sec.\n - Passed: 52\n - Skipped: 8\n - Expected Fail: 0\n - Unexpected Success: 0\n - Failed: 0\nSum of execute time for each test: 8.5680 sec.\n\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\nWorker Balance\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n - Worker 0 (60 tests) \u003d\u003e 0:00:08.588483\n```","commit_id":"3a05b2588fd601fb0bab475fcda31ea637fc5182"}],"test/unit/common/test_statsd_client.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"93e60def0b26c2b2aaa6781c7d9baceed9ceb398","unresolved":true,"context_lines":[{"line_number":470,"context_line":"        return statsd_client.get_labeled_statsd_client(conf, logger\u003dlogger)"},{"line_number":471,"context_line":""},{"line_number":472,"context_line":""},{"line_number":473,"context_line":"class BaseTestSending(object):"},{"line_number":474,"context_line":"    def test_sending_ipv6(self):"},{"line_number":475,"context_line":"        def fake_getaddrinfo(host, port, *args):"},{"line_number":476,"context_line":"            # this is what a real getaddrinfo(\u0027::1\u0027, port,"}],"source_content_type":"text/x-python","patch_set":1,"id":"37071906_09754d69","line":473,"range":{"start_line":473,"start_character":6,"end_line":473,"end_character":21},"updated":"2025-04-04 10:58:04.000000000","message":"we already have a class for test cases that apply to both legacy and labeled clients (TestGetStatsdClientSocket) so rather than adding more classes let\u0027s just expand the existing.\n\nTBH, IIRC I probably just gave up trying to unify the tests when I ran into the prefix discrepancy. I\u0027m glad you\u0027ve spotted that it\u0027s reasonably trivial to re-use these test cases too 😊","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8df7b86420b7b28594ae50ac54356239e1a79e1c","unresolved":false,"context_lines":[{"line_number":470,"context_line":"        return statsd_client.get_labeled_statsd_client(conf, logger\u003dlogger)"},{"line_number":471,"context_line":""},{"line_number":472,"context_line":""},{"line_number":473,"context_line":"class BaseTestSending(object):"},{"line_number":474,"context_line":"    def test_sending_ipv6(self):"},{"line_number":475,"context_line":"        def fake_getaddrinfo(host, port, *args):"},{"line_number":476,"context_line":"            # this is what a real getaddrinfo(\u0027::1\u0027, port,"}],"source_content_type":"text/x-python","patch_set":1,"id":"2cffd3d6_ac3ae3de","line":473,"range":{"start_line":473,"start_character":6,"end_line":473,"end_character":21},"in_reply_to":"37071906_09754d69","updated":"2025-04-04 15:32:57.000000000","message":"Acknowledged","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"93e60def0b26c2b2aaa6781c7d9baceed9ceb398","unresolved":true,"context_lines":[{"line_number":530,"context_line":"        self.assertEqual(len(mock_socket.sent), 1)"},{"line_number":531,"context_line":""},{"line_number":532,"context_line":"        payload \u003d mock_socket.sent[0][0]"},{"line_number":533,"context_line":"        self.assertTrue(payload.endswith(b\"|@0.5\"))"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"    def test_sample_rates_with_sample_rate_factor(self):"},{"line_number":536,"context_line":"        client \u003d self.make_test_client({"}],"source_content_type":"text/x-python","patch_set":1,"id":"73ff2c77_68891973","line":533,"updated":"2025-04-04 10:58:04.000000000","message":"existing: hmmm, why are we only asserting the suffix?","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8df7b86420b7b28594ae50ac54356239e1a79e1c","unresolved":false,"context_lines":[{"line_number":530,"context_line":"        self.assertEqual(len(mock_socket.sent), 1)"},{"line_number":531,"context_line":""},{"line_number":532,"context_line":"        payload \u003d mock_socket.sent[0][0]"},{"line_number":533,"context_line":"        self.assertTrue(payload.endswith(b\"|@0.5\"))"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"    def test_sample_rates_with_sample_rate_factor(self):"},{"line_number":536,"context_line":"        client \u003d self.make_test_client({"}],"source_content_type":"text/x-python","patch_set":1,"id":"006b5266_44faf666","line":533,"in_reply_to":"73ff2c77_68891973","updated":"2025-04-04 15:32:57.000000000","message":"Done","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"93e60def0b26c2b2aaa6781c7d9baceed9ceb398","unresolved":true,"context_lines":[{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        effective_sample_rate \u003d 0.587 * 0.91"},{"line_number":561,"context_line":"        client.random \u003d lambda: effective_sample_rate - 0.001"},{"line_number":562,"context_line":"        client.increment(\u0027tribbles\u0027, sample_rate\u003d0.587)"},{"line_number":563,"context_line":"        self.assertEqual(len(mock_socket.sent), 2)"},{"line_number":564,"context_line":""},{"line_number":565,"context_line":"        payload \u003d mock_socket.sent[1][0]"}],"source_content_type":"text/x-python","patch_set":1,"id":"77ed43a0_c302ad8c","line":562,"range":{"start_line":562,"start_character":37,"end_line":562,"end_character":54},"updated":"2025-04-04 10:58:04.000000000","message":"existing: test is going to pass even if sample_rate is not sent by the caller because random is still less than the default! there should also be the opposite assertion with ``client.random \u003d lambda: effective_sample_rate + 0.001``","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8df7b86420b7b28594ae50ac54356239e1a79e1c","unresolved":false,"context_lines":[{"line_number":559,"context_line":""},{"line_number":560,"context_line":"        effective_sample_rate \u003d 0.587 * 0.91"},{"line_number":561,"context_line":"        client.random \u003d lambda: effective_sample_rate - 0.001"},{"line_number":562,"context_line":"        client.increment(\u0027tribbles\u0027, sample_rate\u003d0.587)"},{"line_number":563,"context_line":"        self.assertEqual(len(mock_socket.sent), 2)"},{"line_number":564,"context_line":""},{"line_number":565,"context_line":"        payload \u003d mock_socket.sent[1][0]"}],"source_content_type":"text/x-python","patch_set":1,"id":"48b186cb_94c0ec36","line":562,"range":{"start_line":562,"start_character":37,"end_line":562,"end_character":54},"in_reply_to":"77ed43a0_c302ad8c","updated":"2025-04-04 15:32:57.000000000","message":"Done","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"93e60def0b26c2b2aaa6781c7d9baceed9ceb398","unresolved":true,"context_lines":[{"line_number":566,"context_line":"        suffix \u003d (\"|@%s\" % effective_sample_rate).encode(\u0027utf-8\u0027)"},{"line_number":567,"context_line":"        self.assertTrue(payload.endswith(suffix), payload)"},{"line_number":568,"context_line":""},{"line_number":569,"context_line":"    def assertSent(self, mock_socket, metrics):"},{"line_number":570,"context_line":"        self.assertEqual(mock_socket.sent, ["},{"line_number":571,"context_line":"            (self.expected_prefix_bytes + m, addr)"},{"line_number":572,"context_line":"            for (m, addr) in metrics"}],"source_content_type":"text/x-python","patch_set":1,"id":"d6d61856_97faaee2","line":569,"updated":"2025-04-04 10:58:04.000000000","message":"nit: I instinctively look to the *top* of the class for these helpers","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8df7b86420b7b28594ae50ac54356239e1a79e1c","unresolved":false,"context_lines":[{"line_number":566,"context_line":"        suffix \u003d (\"|@%s\" % effective_sample_rate).encode(\u0027utf-8\u0027)"},{"line_number":567,"context_line":"        self.assertTrue(payload.endswith(suffix), payload)"},{"line_number":568,"context_line":""},{"line_number":569,"context_line":"    def assertSent(self, mock_socket, metrics):"},{"line_number":570,"context_line":"        self.assertEqual(mock_socket.sent, ["},{"line_number":571,"context_line":"            (self.expected_prefix_bytes + m, addr)"},{"line_number":572,"context_line":"            for (m, addr) in metrics"}],"source_content_type":"text/x-python","patch_set":1,"id":"822613ba_21ec2c7f","line":569,"in_reply_to":"d6d61856_97faaee2","updated":"2025-04-04 15:32:57.000000000","message":"Acknowledged","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"93e60def0b26c2b2aaa6781c7d9baceed9ceb398","unresolved":true,"context_lines":[{"line_number":570,"context_line":"        self.assertEqual(mock_socket.sent, ["},{"line_number":571,"context_line":"            (self.expected_prefix_bytes + m, addr)"},{"line_number":572,"context_line":"            for (m, addr) in metrics"},{"line_number":573,"context_line":"        ])"},{"line_number":574,"context_line":""},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"class TestGetStatsdClientSending(BaseTestStatsdClient, BaseTestSending):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5d281d46_d0a084e7","line":573,"updated":"2025-04-04 10:58:04.000000000","message":"I love that we can re-use this class to get coverage for LabeledStatsdClient too. But I\u0027d much prefer if ``assertSent`` did exactly what it says w.r.t. the metrics arg and not shim in the prefix.\n\nThere\u0027s only one test, ``test_sending_ipv6``, in this class that sets ``tail_prefix``. We could just prefix the expected value with self.expected_prefix_bytes in the one place it is used","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8df7b86420b7b28594ae50ac54356239e1a79e1c","unresolved":false,"context_lines":[{"line_number":570,"context_line":"        self.assertEqual(mock_socket.sent, ["},{"line_number":571,"context_line":"            (self.expected_prefix_bytes + m, addr)"},{"line_number":572,"context_line":"            for (m, addr) in metrics"},{"line_number":573,"context_line":"        ])"},{"line_number":574,"context_line":""},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"class TestGetStatsdClientSending(BaseTestStatsdClient, BaseTestSending):"}],"source_content_type":"text/x-python","patch_set":1,"id":"a42303be_d2fd8b07","line":573,"in_reply_to":"5d281d46_d0a084e7","updated":"2025-04-04 15:32:57.000000000","message":"Acknowledged","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"93e60def0b26c2b2aaa6781c7d9baceed9ceb398","unresolved":true,"context_lines":[{"line_number":573,"context_line":"        ])"},{"line_number":574,"context_line":""},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"class TestGetStatsdClientSending(BaseTestStatsdClient, BaseTestSending):"},{"line_number":577,"context_line":"    \"\"\""},{"line_number":578,"context_line":"    Tests here use get_statsd_client to make a StatsdClient."},{"line_number":579,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"f03d9a39_48a69f88","line":576,"updated":"2025-04-04 10:58:04.000000000","message":"I think we have different instincts when it comes to Mixins :) ... I tend to avoid them whenever possible because they mess up assisted navigation, and leave code littered with warning about unresolved references (because the Mixin doesn\u0027t have self.assertEqual etc.).\n\nBut most of all (and purely selfish) - when I right-click in pycharm to run a single test in a Mixin(object) it runs all the tests in a module because it doesn\u0027t know that the test is scoped to a TestCase, so the scope defaults to the module.","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8df7b86420b7b28594ae50ac54356239e1a79e1c","unresolved":false,"context_lines":[{"line_number":573,"context_line":"        ])"},{"line_number":574,"context_line":""},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"class TestGetStatsdClientSending(BaseTestStatsdClient, BaseTestSending):"},{"line_number":577,"context_line":"    \"\"\""},{"line_number":578,"context_line":"    Tests here use get_statsd_client to make a StatsdClient."},{"line_number":579,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"16775509_db003153","line":576,"in_reply_to":"f03d9a39_48a69f88","updated":"2025-04-04 15:32:57.000000000","message":"Acknowledged","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"93e60def0b26c2b2aaa6781c7d9baceed9ceb398","unresolved":true,"context_lines":[{"line_number":1067,"context_line":"        self.assertStat(\u0027the.counter:1|c|@0.9912\u0027,"},{"line_number":1068,"context_line":"                        labeled_statsd.increment, \u0027the.counter\u0027, labels\u003d{},"},{"line_number":1069,"context_line":"                        sample_rate\u003d0.9912)"},{"line_number":1070,"context_line":"        self.assertStat("},{"line_number":1071,"context_line":"            \u0027the.timing:6280.0|ms\u0027,"},{"line_number":1072,"context_line":"            labeled_statsd.timing, \u0027the.timing\u0027, 6.28 * 1000, labels\u003d{})"},{"line_number":1073,"context_line":"        self.assertStat("},{"line_number":1074,"context_line":"            \u0027the.timing:6280.0|ms\u0027,"},{"line_number":1075,"context_line":"            labeled_statsd.timing, \u0027the.timing\u0027, 6.28 * 1000, labels\u003d{})"}],"source_content_type":"text/x-python","patch_set":1,"id":"f7f28fc1_f82a7114","line":1072,"range":{"start_line":1070,"start_character":0,"end_line":1072,"end_character":72},"updated":"2025-04-04 10:58:04.000000000","message":"duplicates following lines","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aea47d44ffb0c815d941438be3323916ee3ddfbf","unresolved":false,"context_lines":[{"line_number":1067,"context_line":"        self.assertStat(\u0027the.counter:1|c|@0.9912\u0027,"},{"line_number":1068,"context_line":"                        labeled_statsd.increment, \u0027the.counter\u0027, labels\u003d{},"},{"line_number":1069,"context_line":"                        sample_rate\u003d0.9912)"},{"line_number":1070,"context_line":"        self.assertStat("},{"line_number":1071,"context_line":"            \u0027the.timing:6280.0|ms\u0027,"},{"line_number":1072,"context_line":"            labeled_statsd.timing, \u0027the.timing\u0027, 6.28 * 1000, labels\u003d{})"},{"line_number":1073,"context_line":"        self.assertStat("},{"line_number":1074,"context_line":"            \u0027the.timing:6280.0|ms\u0027,"},{"line_number":1075,"context_line":"            labeled_statsd.timing, \u0027the.timing\u0027, 6.28 * 1000, labels\u003d{})"}],"source_content_type":"text/x-python","patch_set":1,"id":"a3cae03d_f8087ac6","line":1072,"range":{"start_line":1070,"start_character":0,"end_line":1072,"end_character":72},"in_reply_to":"92c3f3fb_48c63391","updated":"2025-04-09 10:30:07.000000000","message":"no, in patchset 1. IIRC I de-duped in https://review.opendev.org/c/openstack/swift/+/946335 and that\u0027s found its way here so all good.","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8df7b86420b7b28594ae50ac54356239e1a79e1c","unresolved":true,"context_lines":[{"line_number":1067,"context_line":"        self.assertStat(\u0027the.counter:1|c|@0.9912\u0027,"},{"line_number":1068,"context_line":"                        labeled_statsd.increment, \u0027the.counter\u0027, labels\u003d{},"},{"line_number":1069,"context_line":"                        sample_rate\u003d0.9912)"},{"line_number":1070,"context_line":"        self.assertStat("},{"line_number":1071,"context_line":"            \u0027the.timing:6280.0|ms\u0027,"},{"line_number":1072,"context_line":"            labeled_statsd.timing, \u0027the.timing\u0027, 6.28 * 1000, labels\u003d{})"},{"line_number":1073,"context_line":"        self.assertStat("},{"line_number":1074,"context_line":"            \u0027the.timing:6280.0|ms\u0027,"},{"line_number":1075,"context_line":"            labeled_statsd.timing, \u0027the.timing\u0027, 6.28 * 1000, labels\u003d{})"}],"source_content_type":"text/x-python","patch_set":1,"id":"92c3f3fb_48c63391","line":1072,"range":{"start_line":1070,"start_character":0,"end_line":1072,"end_character":72},"in_reply_to":"f7f28fc1_f82a7114","updated":"2025-04-04 15:32:57.000000000","message":"what now?","commit_id":"07f8560974c8ad250442ce4eb7cfa7397cd41402"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6fc639e8be15327246bbfe10ecec61f9639167df","unresolved":true,"context_lines":[{"line_number":371,"context_line":"                             str(ctx.exception))"},{"line_number":372,"context_line":""},{"line_number":373,"context_line":""},{"line_number":374,"context_line":"class ComonBaseTests(BaseTestStatsdClient):"},{"line_number":375,"context_line":"    # work-around https://github.com/python/cpython/issues/120665 (pytest-only)"},{"line_number":376,"context_line":"    __test__ \u003d False"},{"line_number":377,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"721976da_d5cdfdfc","line":374,"range":{"start_line":374,"start_character":6,"end_line":374,"end_character":11},"updated":"2025-04-07 11:37:36.000000000","message":"s/Comon/Common/","commit_id":"31d492adabf9d1b748d354ba72799d0fa064e49f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a4d48faa7237a676d9b787b9b7aa008930c4079a","unresolved":false,"context_lines":[{"line_number":371,"context_line":"                             str(ctx.exception))"},{"line_number":372,"context_line":""},{"line_number":373,"context_line":""},{"line_number":374,"context_line":"class ComonBaseTests(BaseTestStatsdClient):"},{"line_number":375,"context_line":"    # work-around https://github.com/python/cpython/issues/120665 (pytest-only)"},{"line_number":376,"context_line":"    __test__ \u003d False"},{"line_number":377,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"00e13e03_e7c548b7","line":374,"range":{"start_line":374,"start_character":6,"end_line":374,"end_character":11},"in_reply_to":"721976da_d5cdfdfc","updated":"2025-04-07 22:15:14.000000000","message":"Done","commit_id":"31d492adabf9d1b748d354ba72799d0fa064e49f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8df7b86420b7b28594ae50ac54356239e1a79e1c","unresolved":true,"context_lines":[{"line_number":373,"context_line":""},{"line_number":374,"context_line":"class ComonBaseTests(BaseTestStatsdClient):"},{"line_number":375,"context_line":"    # work-around https://github.com/python/cpython/issues/120665 (pytest-only)"},{"line_number":376,"context_line":"    __test__ \u003d False"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"    def test_ipv4_or_ipv6_hostname_defaults_to_ipv4(self):"},{"line_number":379,"context_line":"        def stub_getaddrinfo_both_ipv4_and_ipv6(host, port, family, *rest):"}],"source_content_type":"text/x-python","patch_set":2,"id":"a50af523_13f0af55","line":376,"updated":"2025-04-04 15:32:57.000000000","message":"there\u0027s a note at the bottom of https://docs.pytest.org/en/stable/example/pythoncollection.html# that seems to suggest this is a supported pytest interface.","commit_id":"31d492adabf9d1b748d354ba72799d0fa064e49f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a4d48faa7237a676d9b787b9b7aa008930c4079a","unresolved":false,"context_lines":[{"line_number":373,"context_line":""},{"line_number":374,"context_line":"class ComonBaseTests(BaseTestStatsdClient):"},{"line_number":375,"context_line":"    # work-around https://github.com/python/cpython/issues/120665 (pytest-only)"},{"line_number":376,"context_line":"    __test__ \u003d False"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"    def test_ipv4_or_ipv6_hostname_defaults_to_ipv4(self):"},{"line_number":379,"context_line":"        def stub_getaddrinfo_both_ipv4_and_ipv6(host, port, family, *rest):"}],"source_content_type":"text/x-python","patch_set":2,"id":"65514f74_8d6e7201","line":376,"in_reply_to":"000b181c_f5e1a8c4","updated":"2025-04-07 22:15:14.000000000","message":"Done","commit_id":"31d492adabf9d1b748d354ba72799d0fa064e49f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6fc639e8be15327246bbfe10ecec61f9639167df","unresolved":true,"context_lines":[{"line_number":373,"context_line":""},{"line_number":374,"context_line":"class ComonBaseTests(BaseTestStatsdClient):"},{"line_number":375,"context_line":"    # work-around https://github.com/python/cpython/issues/120665 (pytest-only)"},{"line_number":376,"context_line":"    __test__ \u003d False"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"    def test_ipv4_or_ipv6_hostname_defaults_to_ipv4(self):"},{"line_number":379,"context_line":"        def stub_getaddrinfo_both_ipv4_and_ipv6(host, port, family, *rest):"}],"source_content_type":"text/x-python","patch_set":2,"id":"000b181c_f5e1a8c4","line":376,"in_reply_to":"a50af523_13f0af55","updated":"2025-04-07 11:37:36.000000000","message":"``__test__`` is inherited by the subclasses so the subclass tests don\u0027t run:. We\u0027d need to set it back to True in the subclasses.\n\n```\n2025-04-04 15:32:10.651272 | ubuntu-focal | test/unit/common/test_splice.py::TestTee::test_unavailable_in_libc PASSED [ 47%]\n2025-04-04 15:32:10.656300 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestStatsdClient::test_init_host PASSED [ 47%]\n2025-04-04 15:32:10.658104 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestStatsdClient::test_init_host_is_none PASSED [ 47%]\n2025-04-04 15:32:10.659405 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestStatsdClient::test_statsd_set_prefix_deprecation PASSED [ 47%]\n2025-04-04 15:32:10.662835 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetStatsdClientConfParsing::test_emit_legacy PASSED [ 47%]\n2025-04-04 15:32:10.664435 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetStatsdClientConfParsing::test_get_statsd_client_defaults PASSED [ 47%]\n2025-04-04 15:32:10.666001 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetStatsdClientConfParsing::test_get_statsd_client_options PASSED [ 47%]\n2025-04-04 15:32:10.667669 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_conf_defaults PASSED [ 47%]\n2025-04-04 15:32:10.670909 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_conf_non_defaults PASSED [ 47%]\n2025-04-04 15:32:10.672410 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_disabled_by_default PASSED [ 47%]\n2025-04-04 15:32:10.673636 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_invalid_label_mode PASSED [ 47%]\n2025-04-04 15:32:10.676327 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_label_values_to_str PASSED [ 47%]\n2025-04-04 15:32:10.677882 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_user_label PASSED [ 47%]\n2025-04-04 15:32:10.679164 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_user_label_invalid_chars PASSED [ 47%]\n2025-04-04 15:32:10.680694 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_user_label_overridden_by_call_label PASSED [ 47%]\n2025-04-04 15:32:10.682344 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_user_label_sorting PASSED [ 47%]\n2025-04-04 15:32:10.683771 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_user_label_value_invalid_chars PASSED [ 47%]\n2025-04-04 15:32:10.685151 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_valid_label_mode PASSED [ 47%]\n2025-04-04 15:32:10.686372 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientConfParsing::test_weird_invalid_attrname_label_mode PASSED [ 47%]\n2025-04-04 15:32:10.691604 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetStatsdClientOutput::test_delegate_methods_with_default_sample_rate PASSED [ 47%]\n2025-04-04 15:32:10.694749 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetStatsdClientOutput::test_delegate_methods_with_metric_prefix PASSED [ 47%]\n2025-04-04 15:32:10.698709 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetStatsdClientOutput::test_delegate_methods_with_no_default_sample_rate PASSED [ 47%]\n2025-04-04 15:32:14.700881 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetStatsdClientOutput::test_methods_are_no_ops_when_not_enabled PASSED [ 47%]\n2025-04-04 15:32:14.704335 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetStatsdClientOutput::test_statsd_methods_legacy_disabled PASSED [ 47%]\n2025-04-04 15:32:14.707502 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_disabled PASSED [ 47%]\n2025-04-04 15:32:14.710150 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_dogstatsd PASSED [ 47%]\n2025-04-04 15:32:14.713507 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_dogstatsd_no_labels PASSED [ 47%]\n2025-04-04 15:32:14.715550 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_dogstatsd_sample_rate PASSED [ 47%]\n2025-04-04 15:32:14.718023 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_graphite PASSED [ 47%]\n2025-04-04 15:32:14.722024 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_graphite_no_labels PASSED [ 47%]\n2025-04-04 15:32:14.723275 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_graphite_sample_rate PASSED [ 47%]\n2025-04-04 15:32:14.725536 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_influxdb PASSED [ 47%]\n2025-04-04 15:32:14.728928 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_influxdb_no_labels PASSED [ 47%]\n2025-04-04 15:32:15.933367 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_influxdb_sample_rate PASSED [ 47%]\n2025-04-04 15:32:15.937328 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_librato PASSED [ 47%]\n2025-04-04 15:32:15.941188 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_librato_no_labels PASSED [ 47%]\n2025-04-04 15:32:15.943140 | ubuntu-focal | test/unit/common/test_statsd_client.py::TestGetLabeledStatsdClientOutput::test_statsd_methods_librato_sample_rate PASSED [ 47%]\n2025-04-04 15:32:15.944573 | ubuntu-focal | test/unit/common/test_storage_policy.py::TestStoragePolicies::test_add_remove_names PASSED [ 47%]\n```\n\nhttps://ae9ea825fe544927ab0b-14c47b0c762b46266aadd7f2c624d382.ssl.cf1.rackcdn.com/openstack/951696efa49e4cf0b98c36591c3a54b8/job-output.txt","commit_id":"31d492adabf9d1b748d354ba72799d0fa064e49f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6fc639e8be15327246bbfe10ecec61f9639167df","unresolved":true,"context_lines":[{"line_number":579,"context_line":"        return statsd_client.get_statsd_client(conf, tail_prefix, **kwargs)"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":""},{"line_number":582,"context_line":"class TestGetLabeledStatsdClient(TestGetStatsdClient):"},{"line_number":583,"context_line":"    \"\"\""},{"line_number":584,"context_line":"    Tests here use get_labeled_statsd_client to make a LabeledStatsdClient."},{"line_number":585,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"db526294_ae0d77d7","line":582,"range":{"start_line":582,"start_character":33,"end_line":582,"end_character":52},"updated":"2025-04-07 11:37:36.000000000","message":"@Clay IIUC you\u0027d mean this to be CommonBaseTest","commit_id":"31d492adabf9d1b748d354ba72799d0fa064e49f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a4d48faa7237a676d9b787b9b7aa008930c4079a","unresolved":false,"context_lines":[{"line_number":579,"context_line":"        return statsd_client.get_statsd_client(conf, tail_prefix, **kwargs)"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":""},{"line_number":582,"context_line":"class TestGetLabeledStatsdClient(TestGetStatsdClient):"},{"line_number":583,"context_line":"    \"\"\""},{"line_number":584,"context_line":"    Tests here use get_labeled_statsd_client to make a LabeledStatsdClient."},{"line_number":585,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"021f269f_871f1225","line":582,"range":{"start_line":582,"start_character":33,"end_line":582,"end_character":52},"in_reply_to":"db526294_ae0d77d7","updated":"2025-04-07 22:15:14.000000000","message":"Done","commit_id":"31d492adabf9d1b748d354ba72799d0fa064e49f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"44167fa314bddd1baf99e196118ca091b4008a6c","unresolved":true,"context_lines":[{"line_number":576,"context_line":"    \"\"\""},{"line_number":577,"context_line":"    Tests here use get_statsd_client to make a LabeledStatsdClient."},{"line_number":578,"context_line":"    \"\"\""},{"line_number":579,"context_line":"    __test__ \u003d True"},{"line_number":580,"context_line":"    tail_prefix \u003d \u0027some-name\u0027"},{"line_number":581,"context_line":"    expected_prefix_bytes \u003d (\u0027%s.\u0027 % tail_prefix).encode()"},{"line_number":582,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"063ba668_435d93d2","line":579,"updated":"2025-04-07 12:06:05.000000000","message":"this could alternatively be defined in another superclass","commit_id":"c6c3e8f19a6828676f0e22a591e2d623e162fa78"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a4d48faa7237a676d9b787b9b7aa008930c4079a","unresolved":false,"context_lines":[{"line_number":576,"context_line":"    \"\"\""},{"line_number":577,"context_line":"    Tests here use get_statsd_client to make a LabeledStatsdClient."},{"line_number":578,"context_line":"    \"\"\""},{"line_number":579,"context_line":"    __test__ \u003d True"},{"line_number":580,"context_line":"    tail_prefix \u003d \u0027some-name\u0027"},{"line_number":581,"context_line":"    expected_prefix_bytes \u003d (\u0027%s.\u0027 % tail_prefix).encode()"},{"line_number":582,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3397eb6b_38468274","line":579,"in_reply_to":"063ba668_435d93d2","updated":"2025-04-07 22:15:14.000000000","message":"Acknowledged","commit_id":"c6c3e8f19a6828676f0e22a591e2d623e162fa78"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"aea47d44ffb0c815d941438be3323916ee3ddfbf","unresolved":true,"context_lines":[{"line_number":479,"context_line":"class TestGetStatsdClientSending(BaseTestStatsdClient):"},{"line_number":480,"context_line":"    \"\"\""},{"line_number":481,"context_line":"    Tests here use get_statsd_client to make a StatsdClient."},{"line_number":482,"context_line":"    \"\"\""},{"line_number":483,"context_line":"    def test_sending_ipv6(self):"},{"line_number":484,"context_line":"        def fake_getaddrinfo(host, port, *args):"},{"line_number":485,"context_line":"            # this is what a real getaddrinfo(\u0027::1\u0027, port,"}],"source_content_type":"text/x-python","patch_set":5,"id":"817e21e5_340f69b6","side":"PARENT","line":482,"updated":"2025-04-09 10:30:07.000000000","message":"lest we lose sight of it amid the shenangians over getting pytest to ignore the abstract tests...\n\nThis is the big win of this patch i.e. that these StatsdClient specific tests are now included in a common class of tests that are also run against LabeledStatsdClient","commit_id":"0e2791a88a9199006880bbbe31ff4e6d27c58e88"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a4d48faa7237a676d9b787b9b7aa008930c4079a","unresolved":true,"context_lines":[{"line_number":379,"context_line":""},{"line_number":380,"context_line":"    # this should work back to py3.6 https://peps.python.org/pep-0487/"},{"line_number":381,"context_line":"    def __init_subclass__(cls):"},{"line_number":382,"context_line":"        cls.__test__ \u003d True"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"    def setUp(self):"},{"line_number":385,"context_line":"        # work-around https://github.com/python/cpython/issues/120665"}],"source_content_type":"text/x-python","patch_set":5,"id":"7c0b4333_b9ba5bf6","line":382,"updated":"2025-04-07 22:15:14.000000000","message":"I think this is the cleanest way to handle the \"subclass inherits super class attribute __test__\" problem - it\u0027s not *too* \"meta\" for me and it makes it hard to get wrong in the concrete subclasses\n\nI *do* think the attribute, __init_subclass__ metaclass method and setUp\u003d\u003eskip base method could be moved to a SwiftAbstractCommonBaseTests helper and applied consistently across the code-base\n\n... but I\u0027m hoping it\u0027s mostly orthogonal to this change, which does need *some* kind of solution.","commit_id":"3a05b2588fd601fb0bab475fcda31ea637fc5182"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"a4d48faa7237a676d9b787b9b7aa008930c4079a","unresolved":true,"context_lines":[{"line_number":384,"context_line":"    def setUp(self):"},{"line_number":385,"context_line":"        # work-around https://github.com/python/cpython/issues/120665"},{"line_number":386,"context_line":"        if not self.__class__.__test__:"},{"line_number":387,"context_line":"            raise unittest.SkipTest(\u0027skip CommonBaseTests\u0027)"},{"line_number":388,"context_line":"        super().setUp()"},{"line_number":389,"context_line":""},{"line_number":390,"context_line":"    # N.B. we don\u0027t use a \"proper\" abc.ABC to make sure pytest tries (and"}],"source_content_type":"text/x-python","patch_set":5,"id":"9ccfd85e_3637e029","line":387,"updated":"2025-04-07 22:15:14.000000000","message":"I couldn\u0027t get a unittest/stestr failure mode that I was happy with - so I decided to just skip them based on the `__test__` class attribute (which I got working with `__init_subclass__`)","commit_id":"3a05b2588fd601fb0bab475fcda31ea637fc5182"}]}
