)]}'
{"swift/common/utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d9f98e8e4461c04549ed14425f0d7fff8aaa75c7","unresolved":false,"context_lines":[{"line_number":4740,"context_line":"        else:"},{"line_number":4741,"context_line":"            return self.lower \u003c item \u003c\u003d self.upper"},{"line_number":4742,"context_line":""},{"line_number":4743,"context_line":"    def __lt__(self, other):"},{"line_number":4744,"context_line":"        if self.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4745,"context_line":"            return False"},{"line_number":4746,"context_line":"        if isinstance(other, ShardRange):"},{"line_number":4747,"context_line":"            return self.lower \u003c other.lower"},{"line_number":4748,"context_line":"        elif other is None:"},{"line_number":4749,"context_line":"            return True"},{"line_number":4750,"context_line":"        else:"},{"line_number":4751,"context_line":"            return self.upper \u003c other"},{"line_number":4752,"context_line":""},{"line_number":4753,"context_line":"    def __gt__(self, other):"},{"line_number":4754,"context_line":"        if self.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4755,"context_line":"            return False"},{"line_number":4756,"context_line":"        if isinstance(other, ShardRange):"},{"line_number":4757,"context_line":"            if other.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4758,"context_line":"                return False"},{"line_number":4759,"context_line":"            upper \u003d self.upper or other.upper + \u0027\\x00\u0027"},{"line_number":4760,"context_line":"            return self.lower \u003e\u003d other.upper or upper \u003e other.upper"},{"line_number":4761,"context_line":"        elif other is None:"},{"line_number":4762,"context_line":"            return False"},{"line_number":4763,"context_line":"        else:"},{"line_number":4764,"context_line":"            return self.lower \u003e\u003d other"},{"line_number":4765,"context_line":""},{"line_number":4766,"context_line":"    def __eq__(self, other):"},{"line_number":4767,"context_line":"        if not isinstance(other, ShardRange):"}],"source_content_type":"text/x-python","patch_set":1,"id":"9f6a8fd7_4d54afca","line":4764,"range":{"start_line":4743,"start_character":1,"end_line":4764,"end_character":38},"updated":"2018-05-08 13:43:55.000000000","message":"I think these are used in only one place (in ContainerBroker.get_shard_ranges()) and in that case the comparison is with a marker (object name) not another shard range. If that is true then we could simplify these methods.","commit_id":"a7d1b7a674edaf77b9167ec7eab62f0e92464c2f"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"9304028ab82043b513920dbbf2429b00da5058fe","unresolved":false,"context_lines":[{"line_number":4391,"context_line":""},{"line_number":4392,"context_line":"    class OuterBound(object):"},{"line_number":4393,"context_line":"        def __eq__(self, other):"},{"line_number":4394,"context_line":"            return isinstance(other, type(self)) or other is \u0027\u0027"},{"line_number":4395,"context_line":""},{"line_number":4396,"context_line":"        def __ne__(self, other):"},{"line_number":4397,"context_line":"            return not self.__eq__(other)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_373f7026","line":4394,"range":{"start_line":4394,"start_character":58,"end_line":4394,"end_character":60},"updated":"2018-05-08 01:09:35.000000000","message":"\u003d\u003d would be better here, otherwise we rely on CPython implementation details","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d9f98e8e4461c04549ed14425f0d7fff8aaa75c7","unresolved":false,"context_lines":[{"line_number":4391,"context_line":""},{"line_number":4392,"context_line":"    class OuterBound(object):"},{"line_number":4393,"context_line":"        def __eq__(self, other):"},{"line_number":4394,"context_line":"            return isinstance(other, type(self)) or other is \u0027\u0027"},{"line_number":4395,"context_line":""},{"line_number":4396,"context_line":"        def __ne__(self, other):"},{"line_number":4397,"context_line":"            return not self.__eq__(other)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_0ead7130","line":4394,"range":{"start_line":4394,"start_character":58,"end_line":4394,"end_character":60},"in_reply_to":"5f7c97a3_373f7026","updated":"2018-05-08 13:43:55.000000000","message":"Done","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"9304028ab82043b513920dbbf2429b00da5058fe","unresolved":false,"context_lines":[{"line_number":4541,"context_line":""},{"line_number":4542,"context_line":"    @lower.setter"},{"line_number":4543,"context_line":"    def lower(self, value):"},{"line_number":4544,"context_line":"        if not value and value is not ShardRange.MAX:"},{"line_number":4545,"context_line":"            value \u003d ShardRange.MIN"},{"line_number":4546,"context_line":"        try:"},{"line_number":4547,"context_line":"            value \u003d self._encode_bound(value)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_b28aae18","line":4544,"range":{"start_line":4544,"start_character":31,"end_line":4544,"end_character":37},"updated":"2018-05-08 01:09:35.000000000","message":"How certain are we that ShardRange.MAX is a singleton? Would it cause problems to use \"!\u003d\" here?","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d9f98e8e4461c04549ed14425f0d7fff8aaa75c7","unresolved":false,"context_lines":[{"line_number":4541,"context_line":""},{"line_number":4542,"context_line":"    @lower.setter"},{"line_number":4543,"context_line":"    def lower(self, value):"},{"line_number":4544,"context_line":"        if not value and value is not ShardRange.MAX:"},{"line_number":4545,"context_line":"            value \u003d ShardRange.MIN"},{"line_number":4546,"context_line":"        try:"},{"line_number":4547,"context_line":"            value \u003d self._encode_bound(value)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_8e666129","line":4544,"range":{"start_line":4544,"start_character":31,"end_line":4544,"end_character":37},"in_reply_to":"5f7c97a3_b28aae18","updated":"2018-05-08 13:43:55.000000000","message":"I used \u0027is not\u0027 because \u0027\u0027 *does* equal ShardRange.MAX, but I think there is another approach that avoids the comparison with ShardRange.MAX altogether.","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"9304028ab82043b513920dbbf2429b00da5058fe","unresolved":false,"context_lines":[{"line_number":4567,"context_line":""},{"line_number":4568,"context_line":"    @upper.setter"},{"line_number":4569,"context_line":"    def upper(self, value):"},{"line_number":4570,"context_line":"        if not value and value is not ShardRange.MIN:"},{"line_number":4571,"context_line":"            value \u003d ShardRange.MAX"},{"line_number":4572,"context_line":"        try:"},{"line_number":4573,"context_line":"            value \u003d self._encode_bound(value)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_b28f0e22","line":4570,"range":{"start_line":4570,"start_character":31,"end_line":4570,"end_character":37},"updated":"2018-05-08 01:09:35.000000000","message":"Same thing about singletons again","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d9f98e8e4461c04549ed14425f0d7fff8aaa75c7","unresolved":false,"context_lines":[{"line_number":4567,"context_line":""},{"line_number":4568,"context_line":"    @upper.setter"},{"line_number":4569,"context_line":"    def upper(self, value):"},{"line_number":4570,"context_line":"        if not value and value is not ShardRange.MIN:"},{"line_number":4571,"context_line":"            value \u003d ShardRange.MAX"},{"line_number":4572,"context_line":"        try:"},{"line_number":4573,"context_line":"            value \u003d self._encode_bound(value)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_5181ce49","line":4570,"range":{"start_line":4570,"start_character":31,"end_line":4570,"end_character":37},"in_reply_to":"5f7c97a3_b28f0e22","updated":"2018-05-08 13:43:55.000000000","message":"Done","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"9304028ab82043b513920dbbf2429b00da5058fe","unresolved":false,"context_lines":[{"line_number":4616,"context_line":"        \"\"\""},{"line_number":4617,"context_line":"        self.object_count \u003d int(object_count)"},{"line_number":4618,"context_line":"        self.bytes_used \u003d int(bytes_used)"},{"line_number":4619,"context_line":"        self.meta_timestamp \u003d meta_timestamp or Timestamp.now()"},{"line_number":4620,"context_line":""},{"line_number":4621,"context_line":"    def increment_meta(self, object_count, bytes_used, meta_timestamp\u003dNone):"},{"line_number":4622,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_72b2d6e8","line":4619,"range":{"start_line":4619,"start_character":30,"end_line":4619,"end_character":63},"updated":"2018-05-08 01:09:35.000000000","message":"This won\u0027t let you set a timestamp of 0. I don\u0027t know how much we care, though.","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d9f98e8e4461c04549ed14425f0d7fff8aaa75c7","unresolved":false,"context_lines":[{"line_number":4616,"context_line":"        \"\"\""},{"line_number":4617,"context_line":"        self.object_count \u003d int(object_count)"},{"line_number":4618,"context_line":"        self.bytes_used \u003d int(bytes_used)"},{"line_number":4619,"context_line":"        self.meta_timestamp \u003d meta_timestamp or Timestamp.now()"},{"line_number":4620,"context_line":""},{"line_number":4621,"context_line":"    def increment_meta(self, object_count, bytes_used, meta_timestamp\u003dNone):"},{"line_number":4622,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_913a0696","line":4619,"range":{"start_line":4619,"start_character":30,"end_line":4619,"end_character":63},"in_reply_to":"5f7c97a3_72b2d6e8","updated":"2018-05-08 13:43:55.000000000","message":"Done","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"9304028ab82043b513920dbbf2429b00da5058fe","unresolved":false,"context_lines":[{"line_number":4742,"context_line":""},{"line_number":4743,"context_line":"    def __lt__(self, other):"},{"line_number":4744,"context_line":"        # a ShardRange is less than other if its entire namespace is less than"},{"line_number":4745,"context_line":"        # other; if other is another ShardRage that implies that this"},{"line_number":4746,"context_line":"        # ShardRange\u0027s upper must be less than or equal to the other"},{"line_number":4747,"context_line":"        # ShardRange\u0027s lower"},{"line_number":4748,"context_line":"        if self.upper \u003d\u003d ShardRange.MAX:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_d2664a2a","line":4745,"range":{"start_line":4745,"start_character":37,"end_line":4745,"end_character":46},"updated":"2018-05-08 01:09:35.000000000","message":"nit: ShardRange","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d9f98e8e4461c04549ed14425f0d7fff8aaa75c7","unresolved":false,"context_lines":[{"line_number":4742,"context_line":""},{"line_number":4743,"context_line":"    def __lt__(self, other):"},{"line_number":4744,"context_line":"        # a ShardRange is less than other if its entire namespace is less than"},{"line_number":4745,"context_line":"        # other; if other is another ShardRage that implies that this"},{"line_number":4746,"context_line":"        # ShardRange\u0027s upper must be less than or equal to the other"},{"line_number":4747,"context_line":"        # ShardRange\u0027s lower"},{"line_number":4748,"context_line":"        if self.upper \u003d\u003d ShardRange.MAX:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_b154e2cb","line":4745,"range":{"start_line":4745,"start_character":37,"end_line":4745,"end_character":46},"in_reply_to":"5f7c97a3_d2664a2a","updated":"2018-05-08 13:43:55.000000000","message":"Done","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"9304028ab82043b513920dbbf2429b00da5058fe","unresolved":false,"context_lines":[{"line_number":4756,"context_line":""},{"line_number":4757,"context_line":"    def __gt__(self, other):"},{"line_number":4758,"context_line":"        # a ShardRange is greater than other if its entire namespace is greater"},{"line_number":4759,"context_line":"        # than other; if other is another ShardRage that implies that this"},{"line_number":4760,"context_line":"        # ShardRange\u0027s lower must be less greater than or equal to the other"},{"line_number":4761,"context_line":"        # ShardRange\u0027s upper"},{"line_number":4762,"context_line":"        if self.lower \u003d\u003d ShardRange.MIN:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_9270d2de","line":4759,"range":{"start_line":4759,"start_character":42,"end_line":4759,"end_character":51},"updated":"2018-05-08 01:09:35.000000000","message":"nit: ShardRange (again)","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d9f98e8e4461c04549ed14425f0d7fff8aaa75c7","unresolved":false,"context_lines":[{"line_number":4756,"context_line":""},{"line_number":4757,"context_line":"    def __gt__(self, other):"},{"line_number":4758,"context_line":"        # a ShardRange is greater than other if its entire namespace is greater"},{"line_number":4759,"context_line":"        # than other; if other is another ShardRage that implies that this"},{"line_number":4760,"context_line":"        # ShardRange\u0027s lower must be less greater than or equal to the other"},{"line_number":4761,"context_line":"        # ShardRange\u0027s upper"},{"line_number":4762,"context_line":"        if self.lower \u003d\u003d ShardRange.MIN:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_d14f1e32","line":4759,"range":{"start_line":4759,"start_character":42,"end_line":4759,"end_character":51},"in_reply_to":"5f7c97a3_9270d2de","updated":"2018-05-08 13:43:55.000000000","message":"Done","commit_id":"5eb9e7e3cfd3969090f9298aa29a964426e9aff8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4405,"context_line":"            return \u0027\u0027"},{"line_number":4406,"context_line":""},{"line_number":4407,"context_line":"        def __repr__(self):"},{"line_number":4408,"context_line":"            return \"\u0027\u0027\""},{"line_number":4409,"context_line":""},{"line_number":4410,"context_line":"        def __bool__(self):"},{"line_number":4411,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_19e29002","line":4408,"updated":"2018-05-08 22:55:45.000000000","message":"IDK about this -- the repr can\u0027t distinguish between MIN and MAX.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4405,"context_line":"            return \u0027\u0027"},{"line_number":4406,"context_line":""},{"line_number":4407,"context_line":"        def __repr__(self):"},{"line_number":4408,"context_line":"            return \"\u0027\u0027\""},{"line_number":4409,"context_line":""},{"line_number":4410,"context_line":"        def __bool__(self):"},{"line_number":4411,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_9b644fe6","line":4408,"in_reply_to":"5f7c97a3_19e29002","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4449,"context_line":"            CREATED"},{"line_number":4450,"context_line":"        :param state_timestamp: the timestamp at which the shard state was last"},{"line_number":4451,"context_line":"            updated; defaults to the value of ``timestamp``."},{"line_number":4452,"context_line":"        :param epoch: optional epoch timestamp"},{"line_number":4453,"context_line":"        \"\"\""},{"line_number":4454,"context_line":"        self.name \u003d self._validate_path(name)"},{"line_number":4455,"context_line":"        self.account, self.container \u003d self.name.split(\u0027/\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_79bce4db","line":4452,"updated":"2018-05-08 22:55:45.000000000","message":"This deserves more explanation.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4449,"context_line":"            CREATED"},{"line_number":4450,"context_line":"        :param state_timestamp: the timestamp at which the shard state was last"},{"line_number":4451,"context_line":"            updated; defaults to the value of ``timestamp``."},{"line_number":4452,"context_line":"        :param epoch: optional epoch timestamp"},{"line_number":4453,"context_line":"        \"\"\""},{"line_number":4454,"context_line":"        self.name \u003d self._validate_path(name)"},{"line_number":4455,"context_line":"        self.account, self.container \u003d self.name.split(\u0027/\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_3b4adb7f","line":4452,"in_reply_to":"5f7c97a3_79bce4db","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4452,"context_line":"        :param epoch: optional epoch timestamp"},{"line_number":4453,"context_line":"        \"\"\""},{"line_number":4454,"context_line":"        self.name \u003d self._validate_path(name)"},{"line_number":4455,"context_line":"        self.account, self.container \u003d self.name.split(\u0027/\u0027)"},{"line_number":4456,"context_line":"        self._lower \u003d ShardRange.MIN"},{"line_number":4457,"context_line":"        self._upper \u003d ShardRange.MAX"},{"line_number":4458,"context_line":"        self.lower \u003d lower"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_99bf80cf","line":4455,"updated":"2018-05-08 22:55:45.000000000","message":"Might be worth having name be a @property so these three can\u0027t get out of sync.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4452,"context_line":"        :param epoch: optional epoch timestamp"},{"line_number":4453,"context_line":"        \"\"\""},{"line_number":4454,"context_line":"        self.name \u003d self._validate_path(name)"},{"line_number":4455,"context_line":"        self.account, self.container \u003d self.name.split(\u0027/\u0027)"},{"line_number":4456,"context_line":"        self._lower \u003d ShardRange.MIN"},{"line_number":4457,"context_line":"        self._upper \u003d ShardRange.MAX"},{"line_number":4458,"context_line":"        self.lower \u003d lower"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_1b47df7a","line":4455,"in_reply_to":"5f7c97a3_99bf80cf","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4466,"context_line":"        self.deleted \u003d deleted"},{"line_number":4467,"context_line":"        self._state \u003d None"},{"line_number":4468,"context_line":"        self.state \u003d self.FOUND if state is None else state"},{"line_number":4469,"context_line":"        self._state_timestamp \u003d None"},{"line_number":4470,"context_line":"        self.state_timestamp \u003d state_timestamp"},{"line_number":4471,"context_line":"        self.epoch \u003d epoch"},{"line_number":4472,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_39b66cfc","line":4469,"range":{"start_line":4469,"start_character":8,"end_line":4469,"end_character":36},"updated":"2018-05-08 22:55:45.000000000","message":"Already done on line 4461.\n\nWhy do we do this song-and-dance for _meta_timestamp, _state_timestamp, and _epoch, but not _timestamp?","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4466,"context_line":"        self.deleted \u003d deleted"},{"line_number":4467,"context_line":"        self._state \u003d None"},{"line_number":4468,"context_line":"        self.state \u003d self.FOUND if state is None else state"},{"line_number":4469,"context_line":"        self._state_timestamp \u003d None"},{"line_number":4470,"context_line":"        self.state_timestamp \u003d state_timestamp"},{"line_number":4471,"context_line":"        self.epoch \u003d epoch"},{"line_number":4472,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_56776ea1","line":4469,"range":{"start_line":4469,"start_character":8,"end_line":4469,"end_character":36},"in_reply_to":"5f7c97a3_39b66cfc","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4472,"context_line":""},{"line_number":4473,"context_line":"    @classmethod"},{"line_number":4474,"context_line":"    def _encode(cls, value):"},{"line_number":4475,"context_line":"        if value is not None and six.PY2 and isinstance(value, six.text_type):"},{"line_number":4476,"context_line":"            return value.encode(\u0027utf-8\u0027)"},{"line_number":4477,"context_line":"        return value"},{"line_number":4478,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_d9c41862","line":4475,"range":{"start_line":4475,"start_character":11,"end_line":4475,"end_character":28},"updated":"2018-05-08 22:55:45.000000000","message":"nit: Not really necessary with the isinstance check later.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4472,"context_line":""},{"line_number":4473,"context_line":"    @classmethod"},{"line_number":4474,"context_line":"    def _encode(cls, value):"},{"line_number":4475,"context_line":"        if value is not None and six.PY2 and isinstance(value, six.text_type):"},{"line_number":4476,"context_line":"            return value.encode(\u0027utf-8\u0027)"},{"line_number":4477,"context_line":"        return value"},{"line_number":4478,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_d66a9eb1","line":4475,"range":{"start_line":4475,"start_character":11,"end_line":4475,"end_character":28},"in_reply_to":"5f7c97a3_d9c41862","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4479,"context_line":"    def _encode_bound(self, bound):"},{"line_number":4480,"context_line":"        if isinstance(bound, ShardRange.OuterBound):"},{"line_number":4481,"context_line":"            return bound"},{"line_number":4482,"context_line":"        if not isinstance(bound, string_types):"},{"line_number":4483,"context_line":"            raise TypeError(\u0027must be a string type\u0027)"},{"line_number":4484,"context_line":"        return self._encode(bound)"},{"line_number":4485,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_39abcc89","line":4482,"range":{"start_line":4482,"start_character":33,"end_line":4482,"end_character":45},"updated":"2018-05-08 22:55:45.000000000","message":"OK, so you can pass either bytes *or* unicode on py2, but on py3 *it must be unicode*.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4496,"context_line":"    def _make_container_name(cls, root_container, parent_container, timestamp,"},{"line_number":4497,"context_line":"                             index):"},{"line_number":4498,"context_line":"        if index is None:"},{"line_number":4499,"context_line":"            raise ValueError(\u0027index must not be None\u0027)"},{"line_number":4500,"context_line":"        if not isinstance(parent_container, bytes):"},{"line_number":4501,"context_line":"            parent_container \u003d parent_container.encode(\u0027utf-8\u0027)"},{"line_number":4502,"context_line":"        return \"%s-%s-%s-%s\" % (root_container,"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_59aec898","line":4499,"updated":"2018-05-08 22:55:45.000000000","message":"...\n\nWhy?\n\nI mean, I guess it seems reasonable, but we don\u0027t expect it to be a proxy.server.Application or something, either, right? What makes None special?","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4496,"context_line":"    def _make_container_name(cls, root_container, parent_container, timestamp,"},{"line_number":4497,"context_line":"                             index):"},{"line_number":4498,"context_line":"        if index is None:"},{"line_number":4499,"context_line":"            raise ValueError(\u0027index must not be None\u0027)"},{"line_number":4500,"context_line":"        if not isinstance(parent_container, bytes):"},{"line_number":4501,"context_line":"            parent_container \u003d parent_container.encode(\u0027utf-8\u0027)"},{"line_number":4502,"context_line":"        return \"%s-%s-%s-%s\" % (root_container,"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_b69a826b","line":4499,"in_reply_to":"5f7c97a3_59aec898","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4513,"context_line":""},{"line_number":4514,"context_line":"    @classmethod"},{"line_number":4515,"context_line":"    def _to_timestamp(cls, timestamp):"},{"line_number":4516,"context_line":"        if timestamp:"},{"line_number":4517,"context_line":"            if not isinstance(timestamp, Timestamp):"},{"line_number":4518,"context_line":"                return Timestamp(timestamp)"},{"line_number":4519,"context_line":"            return timestamp"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_f9947446","line":4516,"updated":"2018-05-08 22:55:45.000000000","message":"Related to what Sam pointed out in update_meta, this won\u0027t handle 0 or even Timestamp(0) well. But again, we may not actually care.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4513,"context_line":""},{"line_number":4514,"context_line":"    @classmethod"},{"line_number":4515,"context_line":"    def _to_timestamp(cls, timestamp):"},{"line_number":4516,"context_line":"        if timestamp:"},{"line_number":4517,"context_line":"            if not isinstance(timestamp, Timestamp):"},{"line_number":4518,"context_line":"                return Timestamp(timestamp)"},{"line_number":4519,"context_line":"            return timestamp"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_96f42688","line":4516,"in_reply_to":"5f7c97a3_f9947446","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4628,"context_line":"        else:"},{"line_number":4629,"context_line":"            self.meta_timestamp \u003d meta_timestamp"},{"line_number":4630,"context_line":""},{"line_number":4631,"context_line":"    def increment_meta(self, object_count, bytes_used, meta_timestamp\u003dNone):"},{"line_number":4632,"context_line":"        \"\"\""},{"line_number":4633,"context_line":"        Increment the object stats metadata by the given values and update the"},{"line_number":4634,"context_line":"        meta_timestamp to the current time."}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_b99efc60","line":4631,"range":{"start_line":4631,"start_character":55,"end_line":4631,"end_character":74},"updated":"2018-05-08 22:55:45.000000000","message":"Never used, I think.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4628,"context_line":"        else:"},{"line_number":4629,"context_line":"            self.meta_timestamp \u003d meta_timestamp"},{"line_number":4630,"context_line":""},{"line_number":4631,"context_line":"    def increment_meta(self, object_count, bytes_used, meta_timestamp\u003dNone):"},{"line_number":4632,"context_line":"        \"\"\""},{"line_number":4633,"context_line":"        Increment the object stats metadata by the given values and update the"},{"line_number":4634,"context_line":"        meta_timestamp to the current time."}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_2a9cc2be","line":4631,"range":{"start_line":4631,"start_character":55,"end_line":4631,"end_character":74},"in_reply_to":"5f7c97a3_b99efc60","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4661,"context_line":"            state_num \u003d cls.STATES_BY_NAME[state]"},{"line_number":4662,"context_line":"        except (KeyError, AttributeError):"},{"line_number":4663,"context_line":"            try:"},{"line_number":4664,"context_line":"                state_name \u003d cls.STATES[state]"},{"line_number":4665,"context_line":"            except KeyError:"},{"line_number":4666,"context_line":"                raise ValueError(\u0027Invalid state %r\u0027 % state)"},{"line_number":4667,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_798aa41b","line":4664,"range":{"start_line":4664,"start_character":16,"end_line":4664,"end_character":46},"updated":"2018-05-08 22:55:45.000000000","message":"Never actually used. Probably still a useful interface, though?","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4668,"context_line":"                state_num \u003d state"},{"line_number":4669,"context_line":"        else:"},{"line_number":4670,"context_line":"            state_name \u003d state"},{"line_number":4671,"context_line":"        return state_num, state_name"},{"line_number":4672,"context_line":""},{"line_number":4673,"context_line":"    @property"},{"line_number":4674,"context_line":"    def state(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_998d4033","line":4671,"range":{"start_line":4671,"start_character":24,"end_line":4671,"end_character":36},"updated":"2018-05-08 22:55:45.000000000","message":"Similarly, unused. We only ever call this like\n\n ShardRange.resolve_state(state)[0]\n\nAssuming we keep it, I almost want this to be a namedtuple, but that\u0027s almost certainly overkill.\n\nAll this kinda makes me wonder if we should just go ahead and have a dep on enum34... and where else we might find a use for that. w/e -- later","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4711,"context_line":"        to the given time."},{"line_number":4712,"context_line":""},{"line_number":4713,"context_line":"        :param state: new state, should be an integer"},{"line_number":4714,"context_line":"        :param state_timestamp: timestamp for state; if not given the"},{"line_number":4715,"context_line":"            state_timestamp will not be changed."},{"line_number":4716,"context_line":"        :return: True if the state or state_timestamp was changed, False"},{"line_number":4717,"context_line":"            otherwise"},{"line_number":4718,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_798f0423","line":4715,"range":{"start_line":4714,"start_character":53,"end_line":4715,"end_character":47},"updated":"2018-05-08 22:55:45.000000000","message":"Why don\u0027t we want to change this? Why do we only include state_timestamp when going to ACTIVE and SHARDING?","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4711,"context_line":"        to the given time."},{"line_number":4712,"context_line":""},{"line_number":4713,"context_line":"        :param state: new state, should be an integer"},{"line_number":4714,"context_line":"        :param state_timestamp: timestamp for state; if not given the"},{"line_number":4715,"context_line":"            state_timestamp will not be changed."},{"line_number":4716,"context_line":"        :return: True if the state or state_timestamp was changed, False"},{"line_number":4717,"context_line":"            otherwise"},{"line_number":4718,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_ea000a6a","line":4715,"range":{"start_line":4714,"start_character":53,"end_line":4715,"end_character":47},"in_reply_to":"5f7c97a3_798f0423","updated":"2018-05-10 13:56:09.000000000","message":"In general the most advanced shard range state is persisted when merging shard ranges. This is overridden if one instance has a greater state_timestamp than another, in which case the state with greater timestamp is persisted. That only happens when a \u0027leader\u0027 is enabling sharding or shrinking, or moving a collapsed root back to active.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4731,"context_line":"    def deleted(self, value):"},{"line_number":4732,"context_line":"        self._deleted \u003d bool(value)"},{"line_number":4733,"context_line":""},{"line_number":4734,"context_line":"    def set_deleted(self, timestamp\u003dNone):"},{"line_number":4735,"context_line":"        \"\"\""},{"line_number":4736,"context_line":"        Mark the shard range deleted and set timestamp to the current time."},{"line_number":4737,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_39998c6d","line":4734,"range":{"start_line":4734,"start_character":26,"end_line":4734,"end_character":40},"updated":"2018-05-08 22:55:45.000000000","message":"Never used.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4731,"context_line":"    def deleted(self, value):"},{"line_number":4732,"context_line":"        self._deleted \u003d bool(value)"},{"line_number":4733,"context_line":""},{"line_number":4734,"context_line":"    def set_deleted(self, timestamp\u003dNone):"},{"line_number":4735,"context_line":"        \"\"\""},{"line_number":4736,"context_line":"        Mark the shard range deleted and set timestamp to the current time."},{"line_number":4737,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_aa3f7223","line":4734,"range":{"start_line":4734,"start_character":26,"end_line":4734,"end_character":40},"in_reply_to":"5f7c97a3_39998c6d","updated":"2018-05-10 13:56:09.000000000","message":"It is used in tests. It could be replaced with mocking in the tests, but I\u0027ll leave it here for now.","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4826,"context_line":"            return other.lower \u003c self.upper"},{"line_number":4827,"context_line":"        elif other.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4828,"context_line":"            return self.lower \u003c other.upper"},{"line_number":4829,"context_line":"        return other.upper \u003e self.upper \u003e other.lower or \\"},{"line_number":4830,"context_line":"            other.upper \u003e self.lower \u003e other.lower or \\"},{"line_number":4831,"context_line":"            self.upper \u003e other.upper \u003e self.lower or \\"},{"line_number":4832,"context_line":"            self.upper \u003e other.lower \u003e self.lower or \\"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_4d03580e","line":4829,"range":{"start_line":4829,"start_character":27,"end_line":4829,"end_character":29},"updated":"2018-05-10 13:56:09.000000000","message":"should be \u003e\u003d","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4830,"context_line":"            other.upper \u003e self.lower \u003e other.lower or \\"},{"line_number":4831,"context_line":"            self.upper \u003e other.upper \u003e self.lower or \\"},{"line_number":4832,"context_line":"            self.upper \u003e other.lower \u003e self.lower or \\"},{"line_number":4833,"context_line":"            (self.upper \u003e other.upper and self.lower \u003c other.lower) or \\"},{"line_number":4834,"context_line":"            (other.lower \u003c self.lower and other.upper \u003e self.upper)"},{"line_number":4835,"context_line":""},{"line_number":4836,"context_line":"    def includes(self, other):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_599c885c","line":4833,"range":{"start_line":4833,"start_character":13,"end_line":4833,"end_character":66},"updated":"2018-05-08 22:55:45.000000000","message":"But other.upper \u003e other.lower, yeah? Isn\u0027t this covered by either of the two lines above?\n\nSimilar comment for the next line, but swapping self for other...","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4830,"context_line":"            other.upper \u003e self.lower \u003e other.lower or \\"},{"line_number":4831,"context_line":"            self.upper \u003e other.upper \u003e self.lower or \\"},{"line_number":4832,"context_line":"            self.upper \u003e other.lower \u003e self.lower or \\"},{"line_number":4833,"context_line":"            (self.upper \u003e other.upper and self.lower \u003c other.lower) or \\"},{"line_number":4834,"context_line":"            (other.lower \u003c self.lower and other.upper \u003e self.upper)"},{"line_number":4835,"context_line":""},{"line_number":4836,"context_line":"    def includes(self, other):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_ea148a50","line":4833,"range":{"start_line":4833,"start_character":13,"end_line":4833,"end_character":66},"in_reply_to":"5f7c97a3_599c885c","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4843,"context_line":"        includes_lower \u003d self.lower \u003d\u003d other.lower or other.lower in self"},{"line_number":4844,"context_line":"        includes_upper \u003d ("},{"line_number":4845,"context_line":"            self.upper \u003d\u003d other.upper or"},{"line_number":4846,"context_line":"            other.upper !\u003d ShardRange.MAX and other.upper in self)"},{"line_number":4847,"context_line":"        return includes_lower and includes_upper"},{"line_number":4848,"context_line":""},{"line_number":4849,"context_line":"    def __iter__(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_19c7f047","line":4846,"updated":"2018-05-08 22:55:45.000000000","message":"How is this different from just\n\n includes_upper \u003d other.upper in self\n\n? No tests break if I switch to that...","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4843,"context_line":"        includes_lower \u003d self.lower \u003d\u003d other.lower or other.lower in self"},{"line_number":4844,"context_line":"        includes_upper \u003d ("},{"line_number":4845,"context_line":"            self.upper \u003d\u003d other.upper or"},{"line_number":4846,"context_line":"            other.upper !\u003d ShardRange.MAX and other.upper in self)"},{"line_number":4847,"context_line":"        return includes_lower and includes_upper"},{"line_number":4848,"context_line":""},{"line_number":4849,"context_line":"    def __iter__(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_edb264e6","line":4846,"in_reply_to":"5f7c97a3_19c7f047","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":4857,"context_line":"        yield \u0027deleted\u0027, 1 if self.deleted else 0"},{"line_number":4858,"context_line":"        yield \u0027state\u0027, self.state"},{"line_number":4859,"context_line":"        yield \u0027state_timestamp\u0027, self.state_timestamp.internal"},{"line_number":4860,"context_line":"        yield \u0027epoch\u0027, self.epoch.internal if self.epoch else None"},{"line_number":4861,"context_line":""},{"line_number":4862,"context_line":"    def copy(self, timestamp\u003dNone, **kwargs):"},{"line_number":4863,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_59ea48ac","line":4860,"range":{"start_line":4860,"start_character":46,"end_line":4860,"end_character":56},"updated":"2018-05-08 22:55:45.000000000","message":"Any concerns about this being Timestamp(0)?","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4857,"context_line":"        yield \u0027deleted\u0027, 1 if self.deleted else 0"},{"line_number":4858,"context_line":"        yield \u0027state\u0027, self.state"},{"line_number":4859,"context_line":"        yield \u0027state_timestamp\u0027, self.state_timestamp.internal"},{"line_number":4860,"context_line":"        yield \u0027epoch\u0027, self.epoch.internal if self.epoch else None"},{"line_number":4861,"context_line":""},{"line_number":4862,"context_line":"    def copy(self, timestamp\u003dNone, **kwargs):"},{"line_number":4863,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_0db6c0da","line":4860,"range":{"start_line":4860,"start_character":46,"end_line":4860,"end_character":56},"in_reply_to":"5f7c97a3_59ea48ac","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4373,"context_line":""},{"line_number":4374,"context_line":""},{"line_number":4375,"context_line":"class ShardRange(object):"},{"line_number":4376,"context_line":"    FOUND \u003d 0"},{"line_number":4377,"context_line":"    CREATED \u003d 1"},{"line_number":4378,"context_line":"    CLEAVED \u003d 2"},{"line_number":4379,"context_line":"    ACTIVE \u003d 3"},{"line_number":4380,"context_line":"    SHRINKING \u003d 5"},{"line_number":4381,"context_line":"    SHARDING \u003d 6"},{"line_number":4382,"context_line":"    SHARDED \u003d 7"},{"line_number":4383,"context_line":"    STATES \u003d {FOUND: \u0027found\u0027,"},{"line_number":4384,"context_line":"              CREATED: \u0027created\u0027,"},{"line_number":4385,"context_line":"              CLEAVED: \u0027cleaved\u0027,"},{"line_number":4386,"context_line":"              ACTIVE: \u0027active\u0027,"},{"line_number":4387,"context_line":"              SHRINKING: \u0027shrinking\u0027,"},{"line_number":4388,"context_line":"              SHARDING: \u0027sharding\u0027,"},{"line_number":4389,"context_line":"              SHARDED: \u0027sharded\u0027}"},{"line_number":4390,"context_line":"    STATES_BY_NAME \u003d dict((v, k) for k, v in STATES.items())"},{"line_number":4391,"context_line":""},{"line_number":4392,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_c82f3f3d","line":4389,"range":{"start_line":4376,"start_character":0,"end_line":4389,"end_character":33},"updated":"2018-05-10 04:30:51.000000000","message":"Do state constants need to be intergers?\nIf we can use strings directly, I think implementation will be more simple.","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4373,"context_line":""},{"line_number":4374,"context_line":""},{"line_number":4375,"context_line":"class ShardRange(object):"},{"line_number":4376,"context_line":"    FOUND \u003d 0"},{"line_number":4377,"context_line":"    CREATED \u003d 1"},{"line_number":4378,"context_line":"    CLEAVED \u003d 2"},{"line_number":4379,"context_line":"    ACTIVE \u003d 3"},{"line_number":4380,"context_line":"    SHRINKING \u003d 5"},{"line_number":4381,"context_line":"    SHARDING \u003d 6"},{"line_number":4382,"context_line":"    SHARDED \u003d 7"},{"line_number":4383,"context_line":"    STATES \u003d {FOUND: \u0027found\u0027,"},{"line_number":4384,"context_line":"              CREATED: \u0027created\u0027,"},{"line_number":4385,"context_line":"              CLEAVED: \u0027cleaved\u0027,"},{"line_number":4386,"context_line":"              ACTIVE: \u0027active\u0027,"},{"line_number":4387,"context_line":"              SHRINKING: \u0027shrinking\u0027,"},{"line_number":4388,"context_line":"              SHARDING: \u0027sharding\u0027,"},{"line_number":4389,"context_line":"              SHARDED: \u0027sharded\u0027}"},{"line_number":4390,"context_line":"    STATES_BY_NAME \u003d dict((v, k) for k, v in STATES.items())"},{"line_number":4391,"context_line":""},{"line_number":4392,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_da906146","line":4389,"range":{"start_line":4376,"start_character":0,"end_line":4389,"end_character":33},"in_reply_to":"5f7c97a3_c82f3f3d","updated":"2018-05-10 13:56:09.000000000","message":"It is useful to be able to sort using the state: https://review.openstack.org/#/c/565744/4/swift/container/backend.py@1679","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4391,"context_line":""},{"line_number":4392,"context_line":"    @classmethod"},{"line_number":4393,"context_line":"    def _is_empty_string(cls, value):"},{"line_number":4394,"context_line":"        return isinstance(value, six.string_types) and value \u003d\u003d \u0027\u0027"},{"line_number":4395,"context_line":""},{"line_number":4396,"context_line":"    class OuterBound(object):"},{"line_number":4397,"context_line":"        def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_474b23af","line":4394,"range":{"start_line":4394,"start_character":15,"end_line":4394,"end_character":50},"updated":"2018-05-10 04:30:51.000000000","message":"Is this type-check required?\nI think `value \u003d\u003d \u0027\u0027` implies the type check...","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1ba135313072d9a48d03186ce43bdad7782c034b","unresolved":false,"context_lines":[{"line_number":4391,"context_line":""},{"line_number":4392,"context_line":"    @classmethod"},{"line_number":4393,"context_line":"    def _is_empty_string(cls, value):"},{"line_number":4394,"context_line":"        return isinstance(value, six.string_types) and value \u003d\u003d \u0027\u0027"},{"line_number":4395,"context_line":""},{"line_number":4396,"context_line":"    class OuterBound(object):"},{"line_number":4397,"context_line":"        def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_994de49b","line":4394,"range":{"start_line":4394,"start_character":15,"end_line":4394,"end_character":50},"in_reply_to":"5f7c97a3_3aee35b4","updated":"2018-05-14 10:10:22.000000000","message":"I see.\nUmm... now I feel that the OuterBound\u0027s `__eq__` definition is very strange...\nBecause, `ShardRange.MAX \u003d\u003d \u0027\u0027` and `ShardRange.MIN \u003d\u003d \u0027\u0027`, although `ShardRange.MAX !\u003d ShardRange.MIN`.\nThis breaks mathematical total order definition.\nThen, I got following results in my environment @ Python2.7.6:\n\n\u003e\u003e\u003e sorted([\u0027\u0027, ShardRange.MAX, \u0027\u0027, ShardRange.MIN])\n[\u0027\u0027, MaxBound, \u0027\u0027, MinBound]\n\n\u003e\u003e\u003e max(\u0027\u0027, ShardRange.MAX, \u0027foo\u0027)\n\u0027foo\u0027\n\nThis may not cause any problem for now. But I think this is code smell.\n\nIn my opinion, OuterBounds should not be equal to \u0027\u0027...","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4391,"context_line":""},{"line_number":4392,"context_line":"    @classmethod"},{"line_number":4393,"context_line":"    def _is_empty_string(cls, value):"},{"line_number":4394,"context_line":"        return isinstance(value, six.string_types) and value \u003d\u003d \u0027\u0027"},{"line_number":4395,"context_line":""},{"line_number":4396,"context_line":"    class OuterBound(object):"},{"line_number":4397,"context_line":"        def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_3aee35b4","line":4394,"range":{"start_line":4394,"start_character":15,"end_line":4394,"end_character":50},"in_reply_to":"5f7c97a3_474b23af","updated":"2018-05-10 13:56:09.000000000","message":"It is necessary because OuterBound \u003d\u003d \u0027\u0027 so we need to a string type and \u003d\u003d \u0027\u0027","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"37eda08a19721160044bbccf4ca137fee7cf5c93","unresolved":false,"context_lines":[{"line_number":4391,"context_line":""},{"line_number":4392,"context_line":"    @classmethod"},{"line_number":4393,"context_line":"    def _is_empty_string(cls, value):"},{"line_number":4394,"context_line":"        return isinstance(value, six.string_types) and value \u003d\u003d \u0027\u0027"},{"line_number":4395,"context_line":""},{"line_number":4396,"context_line":"    class OuterBound(object):"},{"line_number":4397,"context_line":"        def __eq__(self, other):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_70281696","line":4394,"range":{"start_line":4394,"start_character":15,"end_line":4394,"end_character":50},"in_reply_to":"5f7c97a3_994de49b","updated":"2018-05-14 13:01:28.000000000","message":"OK, so although the OuterBounds serialize as \u0027\u0027 I agree that we do not need them to be equal to \u0027\u0027. Thanks!","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4398,"context_line":"            return (isinstance(other, type(self)) or"},{"line_number":4399,"context_line":"                    ShardRange._is_empty_string(other))"},{"line_number":4400,"context_line":""},{"line_number":4401,"context_line":"        def __ne__(self, other):"},{"line_number":4402,"context_line":"            return not self.__eq__(other)"},{"line_number":4403,"context_line":""},{"line_number":4404,"context_line":"        def __str__(self):"},{"line_number":4405,"context_line":"            return \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_7d3cb0be","line":4402,"range":{"start_line":4401,"start_character":0,"end_line":4402,"end_character":41},"updated":"2018-05-10 04:30:51.000000000","message":"I think this is automatically defined from __eq__ by Python.","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4398,"context_line":"            return (isinstance(other, type(self)) or"},{"line_number":4399,"context_line":"                    ShardRange._is_empty_string(other))"},{"line_number":4400,"context_line":""},{"line_number":4401,"context_line":"        def __ne__(self, other):"},{"line_number":4402,"context_line":"            return not self.__eq__(other)"},{"line_number":4403,"context_line":""},{"line_number":4404,"context_line":"        def __str__(self):"},{"line_number":4405,"context_line":"            return \u0027\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_9a0bc97b","line":4402,"range":{"start_line":4401,"start_character":0,"end_line":4402,"end_character":41},"in_reply_to":"5f7c97a3_7d3cb0be","updated":"2018-05-10 13:56:09.000000000","message":"It is in Python3, but not Python2 :/\n\nhttps://docs.python.org/2/reference/datamodel.html#object.__eq__","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4410,"context_line":"        def __bool__(self):"},{"line_number":4411,"context_line":"            return False"},{"line_number":4412,"context_line":""},{"line_number":4413,"context_line":"        __nonzero__ \u003d __bool__"},{"line_number":4414,"context_line":""},{"line_number":4415,"context_line":"    @functools.total_ordering"},{"line_number":4416,"context_line":"    class MaxBound(OuterBound):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_484c8f41","line":4413,"range":{"start_line":4413,"start_character":0,"end_line":4413,"end_character":30},"updated":"2018-05-10 04:30:51.000000000","message":"Is `__nonzero__` used?","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4410,"context_line":"        def __bool__(self):"},{"line_number":4411,"context_line":"            return False"},{"line_number":4412,"context_line":""},{"line_number":4413,"context_line":"        __nonzero__ \u003d __bool__"},{"line_number":4414,"context_line":""},{"line_number":4415,"context_line":"    @functools.total_ordering"},{"line_number":4416,"context_line":"    class MaxBound(OuterBound):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_7a54ad53","line":4413,"range":{"start_line":4413,"start_character":0,"end_line":4413,"end_character":30},"in_reply_to":"5f7c97a3_484c8f41","updated":"2018-05-10 13:56:09.000000000","message":"In Python 2 __nonzero__ implements truth testing, in Python 3 __bool__ is used\n\nhttps://docs.python.org/2/reference/datamodel.html#object.__nonzero__\n\nIt is used for example at line 4590","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4536,"context_line":"    @name.setter"},{"line_number":4537,"context_line":"    def name(self, path):"},{"line_number":4538,"context_line":"        path \u003d self._encode(path)"},{"line_number":4539,"context_line":"        if not path or path.count(\u0027/\u0027) !\u003d 1 or path.strip(\u0027/\u0027).count(\u0027/\u0027) \u003d\u003d 0:"},{"line_number":4540,"context_line":"            raise ValueError("},{"line_number":4541,"context_line":"                \"Name must be of the form \u0027\u003caccount\u003e/\u003ccontainer\u003e\u0027, got %r\" %"},{"line_number":4542,"context_line":"                path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_dd62a43e","line":4539,"range":{"start_line":4539,"start_character":11,"end_line":4539,"end_character":78},"updated":"2018-05-10 04:30:51.000000000","message":"IMO,\n`if len(path.split(\u0027/\u0027)) !\u003d 2 or not all(path.split(\u0027/\u0027)):`\nis more intuitive.","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4536,"context_line":"    @name.setter"},{"line_number":4537,"context_line":"    def name(self, path):"},{"line_number":4538,"context_line":"        path \u003d self._encode(path)"},{"line_number":4539,"context_line":"        if not path or path.count(\u0027/\u0027) !\u003d 1 or path.strip(\u0027/\u0027).count(\u0027/\u0027) \u003d\u003d 0:"},{"line_number":4540,"context_line":"            raise ValueError("},{"line_number":4541,"context_line":"                \"Name must be of the form \u0027\u003caccount\u003e/\u003ccontainer\u003e\u0027, got %r\" %"},{"line_number":4542,"context_line":"                path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_da1b817e","line":4539,"range":{"start_line":4539,"start_character":11,"end_line":4539,"end_character":78},"in_reply_to":"5f7c97a3_dd62a43e","updated":"2018-05-10 13:56:09.000000000","message":"Done","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4750,"context_line":"    def deleted(self):"},{"line_number":4751,"context_line":"        return self._deleted"},{"line_number":4752,"context_line":""},{"line_number":4753,"context_line":"    @deleted.setter"},{"line_number":4754,"context_line":"    def deleted(self, value):"},{"line_number":4755,"context_line":"        self._deleted \u003d bool(value)"},{"line_number":4756,"context_line":""},{"line_number":4757,"context_line":"    def set_deleted(self, timestamp\u003dNone):"},{"line_number":4758,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_7d84b0b1","line":4755,"range":{"start_line":4753,"start_character":0,"end_line":4755,"end_character":35},"updated":"2018-05-10 04:30:51.000000000","message":"It looks like that we may do `shard_range.deleted \u003d 123` and then we expect `shard_range.deleted \u003d\u003d True`.\nI think its strange behavior.\nAre there any reason why the value is casted to boolean in this setter?","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4750,"context_line":"    def deleted(self):"},{"line_number":4751,"context_line":"        return self._deleted"},{"line_number":4752,"context_line":""},{"line_number":4753,"context_line":"    @deleted.setter"},{"line_number":4754,"context_line":"    def deleted(self, value):"},{"line_number":4755,"context_line":"        self._deleted \u003d bool(value)"},{"line_number":4756,"context_line":""},{"line_number":4757,"context_line":"    def set_deleted(self, timestamp\u003dNone):"},{"line_number":4758,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_3a02b50c","line":4755,"range":{"start_line":4753,"start_character":0,"end_line":4755,"end_character":35},"in_reply_to":"5f7c97a3_7d84b0b1","updated":"2018-05-10 13:56:09.000000000","message":"I prefer to know that the type returned by the getter is a boolean, but wanted to tolerate 0/1 to be used when setting because that is a pattern used in other places.","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4770,"context_line":"        return True"},{"line_number":4771,"context_line":""},{"line_number":4772,"context_line":"    def __contains__(self, item):"},{"line_number":4773,"context_line":"        if self.lower \u003d\u003d ShardRange.MIN and self.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4774,"context_line":"            # No limits so must match"},{"line_number":4775,"context_line":"            return True"},{"line_number":4776,"context_line":"        if self._is_empty_string(item):"},{"line_number":4777,"context_line":"            return self.upper \u003d\u003d ShardRange.MAX"},{"line_number":4778,"context_line":"        item \u003d self._encode_bound(item)"},{"line_number":4779,"context_line":"        if self.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4780,"context_line":"            return item \u003c\u003d self.upper"},{"line_number":4781,"context_line":"        elif self.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4782,"context_line":"            return self.lower \u003c item"},{"line_number":4783,"context_line":"        else:"},{"line_number":4784,"context_line":"            return self.lower \u003c item \u003c\u003d self.upper"},{"line_number":4785,"context_line":""},{"line_number":4786,"context_line":"    def __lt__(self, other):"},{"line_number":4787,"context_line":"        # a ShardRange is less than other if its entire namespace is less than"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_0533e2f7","line":4784,"range":{"start_line":4773,"start_character":0,"end_line":4784,"end_character":50},"updated":"2018-05-10 04:30:51.000000000","message":"I think we can implement this as following because MAX and MIN has order functions:\n\ndef __contains__(self, item):\n    if self._is_empty_string(item):\n        return self.upper \u003d\u003d ShardRange.MAX\n    item \u003d self._encode_bound(item)\n    return self.lower \u003c item and self.upper \u003e\u003d item\n\nBut... if we change order definition to `MIN \u003c \"\" \u003c (other strings) \u003c MAX`, we can implement as following:\n\ndef __contains__(self, item):\n    item \u003d self._encode_bound(item)\n    return self.lower \u003c item and self.upper \u003e\u003d item\n\nI think the definition change doesn\u0027t impact the container-sharding design, because object name \"\" cannot happen.","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4770,"context_line":"        return True"},{"line_number":4771,"context_line":""},{"line_number":4772,"context_line":"    def __contains__(self, item):"},{"line_number":4773,"context_line":"        if self.lower \u003d\u003d ShardRange.MIN and self.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4774,"context_line":"            # No limits so must match"},{"line_number":4775,"context_line":"            return True"},{"line_number":4776,"context_line":"        if self._is_empty_string(item):"},{"line_number":4777,"context_line":"            return self.upper \u003d\u003d ShardRange.MAX"},{"line_number":4778,"context_line":"        item \u003d self._encode_bound(item)"},{"line_number":4779,"context_line":"        if self.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4780,"context_line":"            return item \u003c\u003d self.upper"},{"line_number":4781,"context_line":"        elif self.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4782,"context_line":"            return self.lower \u003c item"},{"line_number":4783,"context_line":"        else:"},{"line_number":4784,"context_line":"            return self.lower \u003c item \u003c\u003d self.upper"},{"line_number":4785,"context_line":""},{"line_number":4786,"context_line":"    def __lt__(self, other):"},{"line_number":4787,"context_line":"        # a ShardRange is less than other if its entire namespace is less than"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_8edb8a7a","line":4784,"range":{"start_line":4773,"start_character":0,"end_line":4784,"end_character":50},"in_reply_to":"5f7c97a3_0533e2f7","updated":"2018-05-10 13:56:09.000000000","message":"Thanks, I agree this can be simpler, but unfortunately I think we need to keep the special case for \u0027\u0027 because although \u0027\u0027 sorts less than any other string, it also represents the MAX bound which is *inclusive* so it makes sense for range \u0027m\u0027 - MAX to contain \u0027\u0027","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4818,"context_line":"        # but it may prove useful to be able to test for equality of range only"},{"line_number":4819,"context_line":"        return self.lower \u003d\u003d other.lower and self.upper \u003d\u003d other.upper"},{"line_number":4820,"context_line":""},{"line_number":4821,"context_line":"    def __ne__(self, other):"},{"line_number":4822,"context_line":"        return not (self \u003d\u003d other)"},{"line_number":4823,"context_line":""},{"line_number":4824,"context_line":"    def __repr__(self):"},{"line_number":4825,"context_line":"        return \u0027%s\u003c%r to %r as of %s, (%d, %d) as of %s, %s as of %s\u003e\u0027 % ("}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_88a2a7fb","line":4822,"range":{"start_line":4821,"start_character":0,"end_line":4822,"end_character":34},"updated":"2018-05-10 04:30:51.000000000","message":"Same as line 4401.","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4818,"context_line":"        # but it may prove useful to be able to test for equality of range only"},{"line_number":4819,"context_line":"        return self.lower \u003d\u003d other.lower and self.upper \u003d\u003d other.upper"},{"line_number":4820,"context_line":""},{"line_number":4821,"context_line":"    def __ne__(self, other):"},{"line_number":4822,"context_line":"        return not (self \u003d\u003d other)"},{"line_number":4823,"context_line":""},{"line_number":4824,"context_line":"    def __repr__(self):"},{"line_number":4825,"context_line":"        return \u0027%s\u003c%r to %r as of %s, (%d, %d) as of %s, %s as of %s\u003e\u0027 % ("}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_ae3e8688","line":4822,"range":{"start_line":4821,"start_character":0,"end_line":4822,"end_character":34},"in_reply_to":"5f7c97a3_88a2a7fb","updated":"2018-05-10 13:56:09.000000000","message":"Python 2","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4832,"context_line":"        return (self.lower \u003d\u003d ShardRange.MIN and"},{"line_number":4833,"context_line":"                self.upper \u003d\u003d ShardRange.MAX)"},{"line_number":4834,"context_line":""},{"line_number":4835,"context_line":"    def overlaps(self, other):"},{"line_number":4836,"context_line":"        if not isinstance(other, ShardRange):"},{"line_number":4837,"context_line":"            return False"},{"line_number":4838,"context_line":"        if self.lower \u003d\u003d other.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4839,"context_line":"            return True"},{"line_number":4840,"context_line":"        elif self.upper \u003d\u003d other.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4841,"context_line":"            return True"},{"line_number":4842,"context_line":"        elif self.entire_namespace() or other.entire_namespace():"},{"line_number":4843,"context_line":"            return True"},{"line_number":4844,"context_line":"        elif self.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4845,"context_line":"            return other.upper \u003e self.lower"},{"line_number":4846,"context_line":"        elif other.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4847,"context_line":"            return self.upper \u003e other.lower"},{"line_number":4848,"context_line":"        elif self.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4849,"context_line":"            return other.lower \u003c self.upper"},{"line_number":4850,"context_line":"        elif other.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4851,"context_line":"            return self.lower \u003c other.upper"},{"line_number":4852,"context_line":"        return other.upper \u003e\u003d self.upper \u003e other.lower or \\"},{"line_number":4853,"context_line":"            other.upper \u003e self.lower \u003e other.lower or \\"},{"line_number":4854,"context_line":"            self.upper \u003e\u003d other.upper \u003e self.lower or \\"},{"line_number":4855,"context_line":"            self.upper \u003e other.lower \u003e self.lower"},{"line_number":4856,"context_line":""},{"line_number":4857,"context_line":"    def includes(self, other):"},{"line_number":4858,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_c8eadf0d","line":4855,"range":{"start_line":4835,"start_character":0,"end_line":4855,"end_character":49},"updated":"2018-05-10 04:30:51.000000000","message":"I think we can implement it as follows:\n\ndef overlaps(self, other):\n    if not isinstance(other, ShardRange):\n        return False\n    return max(self.lower, other.lower) \u003c min(self.upper, other.upper)\n\nBecause, MIN and MAX has order functions. So we can use max func and min func.","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4832,"context_line":"        return (self.lower \u003d\u003d ShardRange.MIN and"},{"line_number":4833,"context_line":"                self.upper \u003d\u003d ShardRange.MAX)"},{"line_number":4834,"context_line":""},{"line_number":4835,"context_line":"    def overlaps(self, other):"},{"line_number":4836,"context_line":"        if not isinstance(other, ShardRange):"},{"line_number":4837,"context_line":"            return False"},{"line_number":4838,"context_line":"        if self.lower \u003d\u003d other.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4839,"context_line":"            return True"},{"line_number":4840,"context_line":"        elif self.upper \u003d\u003d other.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4841,"context_line":"            return True"},{"line_number":4842,"context_line":"        elif self.entire_namespace() or other.entire_namespace():"},{"line_number":4843,"context_line":"            return True"},{"line_number":4844,"context_line":"        elif self.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4845,"context_line":"            return other.upper \u003e self.lower"},{"line_number":4846,"context_line":"        elif other.upper \u003d\u003d ShardRange.MAX:"},{"line_number":4847,"context_line":"            return self.upper \u003e other.lower"},{"line_number":4848,"context_line":"        elif self.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4849,"context_line":"            return other.lower \u003c self.upper"},{"line_number":4850,"context_line":"        elif other.lower \u003d\u003d ShardRange.MIN:"},{"line_number":4851,"context_line":"            return self.lower \u003c other.upper"},{"line_number":4852,"context_line":"        return other.upper \u003e\u003d self.upper \u003e other.lower or \\"},{"line_number":4853,"context_line":"            other.upper \u003e self.lower \u003e other.lower or \\"},{"line_number":4854,"context_line":"            self.upper \u003e\u003d other.upper \u003e self.lower or \\"},{"line_number":4855,"context_line":"            self.upper \u003e other.lower \u003e self.lower"},{"line_number":4856,"context_line":""},{"line_number":4857,"context_line":"    def includes(self, other):"},{"line_number":4858,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_8e206a4a","line":4855,"range":{"start_line":4835,"start_character":0,"end_line":4855,"end_character":49},"in_reply_to":"5f7c97a3_c8eadf0d","updated":"2018-05-10 13:56:09.000000000","message":"excellent!","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":14766,"name":"Kazuhiro MIYAHARA","email":"miyahara.kazuhiro@lab.ntt.co.jp","username":"miyahara"},"change_message_id":"1d84c79bced23b1652c109cc5e064edfc894c34a","unresolved":false,"context_lines":[{"line_number":4854,"context_line":"            self.upper \u003e\u003d other.upper \u003e self.lower or \\"},{"line_number":4855,"context_line":"            self.upper \u003e other.lower \u003e self.lower"},{"line_number":4856,"context_line":""},{"line_number":4857,"context_line":"    def includes(self, other):"},{"line_number":4858,"context_line":"        \"\"\""},{"line_number":4859,"context_line":"        Returns True if this namespace includes the whole of the other"},{"line_number":4860,"context_line":"        namespace, False otherwise."},{"line_number":4861,"context_line":"        \"\"\""},{"line_number":4862,"context_line":"        if self.entire_namespace():"},{"line_number":4863,"context_line":"            return True"},{"line_number":4864,"context_line":"        includes_lower \u003d self.lower \u003d\u003d other.lower or other.lower in self"},{"line_number":4865,"context_line":"        includes_upper \u003d other.upper in self"},{"line_number":4866,"context_line":"        return includes_lower and includes_upper"},{"line_number":4867,"context_line":""},{"line_number":4868,"context_line":"    def __iter__(self):"},{"line_number":4869,"context_line":"        yield \u0027name\u0027, self.name"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_08e4573b","line":4866,"range":{"start_line":4857,"start_character":0,"end_line":4866,"end_character":48},"updated":"2018-05-10 04:30:51.000000000","message":"I think we can implement it as follows:\n\ndef includes(self, other):\n    return (self.lower \u003c\u003d other.lower) and (other.upper \u003c\u003d self.upper)","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f9f28c8cfb690abad981e66824d8bf6d7dd4c90f","unresolved":false,"context_lines":[{"line_number":4854,"context_line":"            self.upper \u003e\u003d other.upper \u003e self.lower or \\"},{"line_number":4855,"context_line":"            self.upper \u003e other.lower \u003e self.lower"},{"line_number":4856,"context_line":""},{"line_number":4857,"context_line":"    def includes(self, other):"},{"line_number":4858,"context_line":"        \"\"\""},{"line_number":4859,"context_line":"        Returns True if this namespace includes the whole of the other"},{"line_number":4860,"context_line":"        namespace, False otherwise."},{"line_number":4861,"context_line":"        \"\"\""},{"line_number":4862,"context_line":"        if self.entire_namespace():"},{"line_number":4863,"context_line":"            return True"},{"line_number":4864,"context_line":"        includes_lower \u003d self.lower \u003d\u003d other.lower or other.lower in self"},{"line_number":4865,"context_line":"        includes_upper \u003d other.upper in self"},{"line_number":4866,"context_line":"        return includes_lower and includes_upper"},{"line_number":4867,"context_line":""},{"line_number":4868,"context_line":"    def __iter__(self):"},{"line_number":4869,"context_line":"        yield \u0027name\u0027, self.name"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_8ee5ca0b","line":4866,"range":{"start_line":4857,"start_character":0,"end_line":4866,"end_character":48},"in_reply_to":"5f7c97a3_08e4573b","updated":"2018-05-10 13:56:09.000000000","message":"Done. thanks","commit_id":"5e9f6048759a55bf9fff0fa2cb019ed21bee0f50"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f0d32e889dd477fb82a16be2121c3154b77154ec","unresolved":false,"context_lines":[{"line_number":4379,"context_line":"    ACTIVE \u003d 40"},{"line_number":4380,"context_line":"    SHRINKING \u003d 50"},{"line_number":4381,"context_line":"    SHARDING \u003d 60"},{"line_number":4382,"context_line":"    SHARDED \u003d 70"},{"line_number":4383,"context_line":"    STATES \u003d {FOUND: \u0027found\u0027,"},{"line_number":4384,"context_line":"              CREATED: \u0027created\u0027,"},{"line_number":4385,"context_line":"              CLEAVED: \u0027cleaved\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_42fbfa45","line":4382,"updated":"2018-05-10 23:39:54.000000000","message":"BASIC lives again!","commit_id":"7414233d4758f3978551a70b817b1ddbb5b0c3d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"abda0e6c92480074077e44f84fb381eb104ffbcd","unresolved":false,"context_lines":[{"line_number":4379,"context_line":"    ACTIVE \u003d 40"},{"line_number":4380,"context_line":"    SHRINKING \u003d 50"},{"line_number":4381,"context_line":"    SHARDING \u003d 60"},{"line_number":4382,"context_line":"    SHARDED \u003d 70"},{"line_number":4383,"context_line":"    STATES \u003d {FOUND: \u0027found\u0027,"},{"line_number":4384,"context_line":"              CREATED: \u0027created\u0027,"},{"line_number":4385,"context_line":"              CLEAVED: \u0027cleaved\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_ef98e1c0","line":4382,"in_reply_to":"5f7c97a3_42fbfa45","updated":"2018-05-11 14:38:16.000000000","message":"one day we may be glad of some gaps to add new states","commit_id":"7414233d4758f3978551a70b817b1ddbb5b0c3d0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f0d32e889dd477fb82a16be2121c3154b77154ec","unresolved":false,"context_lines":[{"line_number":4531,"context_line":""},{"line_number":4532,"context_line":"    @property"},{"line_number":4533,"context_line":"    def name(self):"},{"line_number":4534,"context_line":"        return self._name"},{"line_number":4535,"context_line":""},{"line_number":4536,"context_line":"    @name.setter"},{"line_number":4537,"context_line":"    def name(self, path):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_42577a27","line":4534,"updated":"2018-05-10 23:39:54.000000000","message":"I was thinking something more like\n\n diff --git a/swift/common/utils.py b/swift/common/utils.py\n index 56aa53018..c89c22f75 100644\n --- a/swift/common/utils.py\n +++ b/swift/common/utils.py\n @@ -4456,7 +4456,7 @@ class ShardRange(object):\n          :param epoch: optional epoch timestamp which represents the time at\n              which sharding was enabled for a container.\n          \"\"\"\n -        self._name \u003d self.account \u003d self.container \u003d self._timestamp \u003d \\\n +        self.account \u003d self.container \u003d self._timestamp \u003d \\\n              self._meta_timestamp \u003d self._state_timestamp \u003d self._epoch \u003d None\n          self._lower \u003d ShardRange.MIN\n          self._upper \u003d ShardRange.MAX\n @@ -4531,7 +4531,7 @@ class ShardRange(object):\n  \n      @property\n      def name(self):\n -        return self._name\n +        return \u0027%s/%s\u0027 % (self.account, self.container)\n  \n      @name.setter\n      def name(self, path):\n @@ -4540,8 +4540,7 @@ class ShardRange(object):\n              raise ValueError(\n                  \"Name must be of the form \u0027\u003caccount\u003e/\u003ccontainer\u003e\u0027, got %r\" %\n                  path)\n -        self._name \u003d path\n -        self.account, self.container \u003d self.name.split(\u0027/\u0027)\n +        self.account, self.container \u003d path.split(\u0027/\u0027)\n  \n      @property\n      def timestamp(self):","commit_id":"7414233d4758f3978551a70b817b1ddbb5b0c3d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"abda0e6c92480074077e44f84fb381eb104ffbcd","unresolved":false,"context_lines":[{"line_number":4531,"context_line":""},{"line_number":4532,"context_line":"    @property"},{"line_number":4533,"context_line":"    def name(self):"},{"line_number":4534,"context_line":"        return self._name"},{"line_number":4535,"context_line":""},{"line_number":4536,"context_line":"    @name.setter"},{"line_number":4537,"context_line":"    def name(self, path):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_2f57b9cc","line":4534,"in_reply_to":"5f7c97a3_42577a27","updated":"2018-05-11 14:38:16.000000000","message":"Done","commit_id":"7414233d4758f3978551a70b817b1ddbb5b0c3d0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f0d32e889dd477fb82a16be2121c3154b77154ec","unresolved":false,"context_lines":[{"line_number":4822,"context_line":""},{"line_number":4823,"context_line":"    def entire_namespace(self):"},{"line_number":4824,"context_line":"        \"\"\""},{"line_number":4825,"context_line":"        Returns True is the ShardRange includes the entire namespace, False"},{"line_number":4826,"context_line":"        otherwise."},{"line_number":4827,"context_line":"        \"\"\""},{"line_number":4828,"context_line":"        return (self.lower \u003d\u003d ShardRange.MIN and"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_e216c655","line":4825,"range":{"start_line":4825,"start_character":21,"end_line":4825,"end_character":23},"updated":"2018-05-10 23:39:54.000000000","message":"s/is/if/","commit_id":"7414233d4758f3978551a70b817b1ddbb5b0c3d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"abda0e6c92480074077e44f84fb381eb104ffbcd","unresolved":false,"context_lines":[{"line_number":4822,"context_line":""},{"line_number":4823,"context_line":"    def entire_namespace(self):"},{"line_number":4824,"context_line":"        \"\"\""},{"line_number":4825,"context_line":"        Returns True is the ShardRange includes the entire namespace, False"},{"line_number":4826,"context_line":"        otherwise."},{"line_number":4827,"context_line":"        \"\"\""},{"line_number":4828,"context_line":"        return (self.lower \u003d\u003d ShardRange.MIN and"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_6f0611d1","line":4825,"range":{"start_line":4825,"start_character":21,"end_line":4825,"end_character":23},"in_reply_to":"5f7c97a3_e216c655","updated":"2018-05-11 14:38:16.000000000","message":"Done","commit_id":"7414233d4758f3978551a70b817b1ddbb5b0c3d0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f0d32e889dd477fb82a16be2121c3154b77154ec","unresolved":false,"context_lines":[{"line_number":4837,"context_line":"        \"\"\""},{"line_number":4838,"context_line":"        if not isinstance(other, ShardRange):"},{"line_number":4839,"context_line":"            return False"},{"line_number":4840,"context_line":"        return max(self.lower, other.lower) \u003c min(self.upper, other.upper)"},{"line_number":4841,"context_line":""},{"line_number":4842,"context_line":"    def includes(self, other):"},{"line_number":4843,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_ed0b1721","line":4840,"updated":"2018-05-10 23:39:54.000000000","message":"+100, loads better! Thanks Kazuhiro!","commit_id":"7414233d4758f3978551a70b817b1ddbb5b0c3d0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"db58914874e5ab851f5a09ace3850493782d0d8c","unresolved":false,"context_lines":[{"line_number":4452,"context_line":"        :param state: the state, must be one of ShardRange.STATES, defaults to"},{"line_number":4453,"context_line":"            CREATED."},{"line_number":4454,"context_line":"        :param state_timestamp: the timestamp at which the shard state was last"},{"line_number":4455,"context_line":"            updated; defaults to the value of ``timestamp``."},{"line_number":4456,"context_line":"        :param epoch: optional epoch timestamp which represents the time at"},{"line_number":4457,"context_line":"            which sharding was enabled for a container."},{"line_number":4458,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_88ffdea9","line":4455,"updated":"2018-05-11 21:19:52.000000000","message":"This should probably have some reference to \"leader actions\".","commit_id":"03442512ee3a586ea4ea893011c3572130d99840"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"34b7db228c3752c3caaa07054da29e0590df9137","unresolved":false,"context_lines":[{"line_number":4470,"context_line":"        self.meta_timestamp \u003d meta_timestamp"},{"line_number":4471,"context_line":"        self.object_count \u003d object_count"},{"line_number":4472,"context_line":"        self.bytes_used \u003d bytes_used"},{"line_number":4473,"context_line":"        self.deleted \u003d deleted"},{"line_number":4474,"context_line":"        self.state \u003d self.FOUND if state is None else state"},{"line_number":4475,"context_line":"        self.state_timestamp \u003d state_timestamp"},{"line_number":4476,"context_line":"        self.epoch \u003d epoch"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_8b2b5893","line":4473,"updated":"2018-05-11 23:33:47.000000000","message":"nit: maybe move this up to just after setting lower/upper -- that\u0027s where it\u0027s logically grouped, yeah?","commit_id":"03442512ee3a586ea4ea893011c3572130d99840"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cd4ee6ab620bb7a20cdc94578695bb19f98fb5f7","unresolved":false,"context_lines":[{"line_number":4470,"context_line":"        self.meta_timestamp \u003d meta_timestamp"},{"line_number":4471,"context_line":"        self.object_count \u003d object_count"},{"line_number":4472,"context_line":"        self.bytes_used \u003d bytes_used"},{"line_number":4473,"context_line":"        self.deleted \u003d deleted"},{"line_number":4474,"context_line":"        self.state \u003d self.FOUND if state is None else state"},{"line_number":4475,"context_line":"        self.state_timestamp \u003d state_timestamp"},{"line_number":4476,"context_line":"        self.epoch \u003d epoch"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_59e3bed9","line":4473,"in_reply_to":"5f7c97a3_4538bbec","updated":"2018-05-14 19:03:43.000000000","message":"Should we just change the method signature?\n\nAh, gets a bit complicated with the\n\n ShardRange(*row)\n\nin swift/container/backend.py ...","commit_id":"03442512ee3a586ea4ea893011c3572130d99840"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"37eda08a19721160044bbccf4ca137fee7cf5c93","unresolved":false,"context_lines":[{"line_number":4470,"context_line":"        self.meta_timestamp \u003d meta_timestamp"},{"line_number":4471,"context_line":"        self.object_count \u003d object_count"},{"line_number":4472,"context_line":"        self.bytes_used \u003d bytes_used"},{"line_number":4473,"context_line":"        self.deleted \u003d deleted"},{"line_number":4474,"context_line":"        self.state \u003d self.FOUND if state is None else state"},{"line_number":4475,"context_line":"        self.state_timestamp \u003d state_timestamp"},{"line_number":4476,"context_line":"        self.epoch \u003d epoch"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_4538bbec","line":4473,"in_reply_to":"5f7c97a3_8b2b5893","updated":"2018-05-14 13:01:28.000000000","message":"Done, although the order still doesn\u0027t match the method signature :/","commit_id":"03442512ee3a586ea4ea893011c3572130d99840"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cd4ee6ab620bb7a20cdc94578695bb19f98fb5f7","unresolved":false,"context_lines":[{"line_number":4447,"context_line":"            deleted."},{"line_number":4448,"context_line":"        :param state: the state, must be one of ShardRange.STATES, defaults to"},{"line_number":4449,"context_line":"            CREATED."},{"line_number":4450,"context_line":"        :param state_timestamp: the timestamp at which the shard state was last"},{"line_number":4451,"context_line":"            updated; defaults to the value of ``timestamp``."},{"line_number":4452,"context_line":"        :param epoch: optional epoch timestamp which represents the time at"},{"line_number":4453,"context_line":"            which sharding was enabled for a container."},{"line_number":4454,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_4f53ec17","line":4451,"range":{"start_line":4450,"start_character":55,"end_line":4451,"end_character":19},"updated":"2018-05-14 19:03:43.000000000","message":"Still think it\u0027s worth being more specific here:\n\n the timestamp at which some \"leader\" forced a state change;\n this includes\n \n  - deciding that an active shard (or root container) should\n    move to sharding and\n  - deciding that an active shard should move to shrinking.","commit_id":"5f4b17792bcfd1433f93e4bf17c09cb2f4edc168"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f64ffe22d7d6402c23b6c82a85a78e26d291e2f","unresolved":false,"context_lines":[{"line_number":4447,"context_line":"            deleted."},{"line_number":4448,"context_line":"        :param state: the state, must be one of ShardRange.STATES, defaults to"},{"line_number":4449,"context_line":"            CREATED."},{"line_number":4450,"context_line":"        :param state_timestamp: the timestamp at which the shard state was last"},{"line_number":4451,"context_line":"            updated; defaults to the value of ``timestamp``."},{"line_number":4452,"context_line":"        :param epoch: optional epoch timestamp which represents the time at"},{"line_number":4453,"context_line":"            which sharding was enabled for a container."},{"line_number":4454,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_faeb8a0f","line":4451,"range":{"start_line":4450,"start_character":55,"end_line":4451,"end_character":19},"in_reply_to":"5f7c97a3_4f53ec17","updated":"2018-05-15 10:02:01.000000000","message":"IDK, that seems a little too much like documenting leader behaviour rather than ShardRange behaviour, and I fear someone else will ask me to then define what a \u0027leader\u0027 is.\nOf course,  a docstring often carries some implication for caller behaviour, I\u0027m just not sure about the balance, given that there is no defined concept of a leader.\n\nI acknowledge that the current text is not accurate. I\u0027ll try to find a compromise.","commit_id":"5f4b17792bcfd1433f93e4bf17c09cb2f4edc168"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7743a581cc082ca5848f6017793a01b64cb0570a","unresolved":false,"context_lines":[{"line_number":4467,"context_line":"            older ``state`` value."},{"line_number":4468,"context_line":"        :param epoch: optional epoch timestamp which represents the time at"},{"line_number":4469,"context_line":"            which sharding was enabled for a container."},{"line_number":4470,"context_line":"        \"\"\""},{"line_number":4471,"context_line":"        self.account \u003d self.container \u003d self._timestamp \u003d \\"},{"line_number":4472,"context_line":"            self._meta_timestamp \u003d self._state_timestamp \u003d self._epoch \u003d None"},{"line_number":4473,"context_line":"        self._lower \u003d ShardRange.MIN"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f7c97a3_221759f0","line":4470,"updated":"2018-05-17 18:36:26.000000000","message":"So find_shard_range shows up in docs (http://logs.openstack.org/43/565743/8/check/build-openstack-sphinx-docs/86c3c25/html/misc.html#swift.common.utils.find_shard_range) but this doesn\u0027t... I think we maybe need to move a lot of this up to be a docstring of the class, rather than __init__? See the docstrings for Timestamp, for example.","commit_id":"e039156e06e7a17754e3acedb67f5af74ea30bdc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f7a709d65226454b674f74d0e64ab7356551bd93","unresolved":false,"context_lines":[{"line_number":4467,"context_line":"            older ``state`` value."},{"line_number":4468,"context_line":"        :param epoch: optional epoch timestamp which represents the time at"},{"line_number":4469,"context_line":"            which sharding was enabled for a container."},{"line_number":4470,"context_line":"        \"\"\""},{"line_number":4471,"context_line":"        self.account \u003d self.container \u003d self._timestamp \u003d \\"},{"line_number":4472,"context_line":"            self._meta_timestamp \u003d self._state_timestamp \u003d self._epoch \u003d None"},{"line_number":4473,"context_line":"        self._lower \u003d ShardRange.MIN"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f7c97a3_423db52a","line":4470,"in_reply_to":"5f7c97a3_221759f0","updated":"2018-05-17 18:47:52.000000000","message":"moved it, let\u0027s see what sphinx does with it","commit_id":"e039156e06e7a17754e3acedb67f5af74ea30bdc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b8fdd1a2995d3282f4efee7138196b69ce403287","unresolved":false,"context_lines":[{"line_number":4542,"context_line":"        return Timestamp(timestamp)"},{"line_number":4543,"context_line":""},{"line_number":4544,"context_line":"    @property"},{"line_number":4545,"context_line":"    def name(self):"},{"line_number":4546,"context_line":"        return \u0027%s/%s\u0027 % (self.account, self.container)"},{"line_number":4547,"context_line":""},{"line_number":4548,"context_line":"    @name.setter"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f7c97a3_30da7577","line":4545,"range":{"start_line":4545,"start_character":8,"end_line":4545,"end_character":12},"updated":"2018-05-15 20:24:06.000000000","message":"Maybe better as \u0027path\u0027, to be more like ContainerBroker?\n\n*shrug* I suppose it\u0027s a lot of renaming for a relatively minor gain in consistency...","commit_id":"e039156e06e7a17754e3acedb67f5af74ea30bdc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"969c8475da88e741dc32e82c19fc43bfa403a12a","unresolved":false,"context_lines":[{"line_number":4542,"context_line":"        return Timestamp(timestamp)"},{"line_number":4543,"context_line":""},{"line_number":4544,"context_line":"    @property"},{"line_number":4545,"context_line":"    def name(self):"},{"line_number":4546,"context_line":"        return \u0027%s/%s\u0027 % (self.account, self.container)"},{"line_number":4547,"context_line":""},{"line_number":4548,"context_line":"    @name.setter"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f7c97a3_483f3d86","line":4545,"range":{"start_line":4545,"start_character":8,"end_line":4545,"end_character":12},"in_reply_to":"5f7c97a3_30da7577","updated":"2018-05-16 08:30:01.000000000","message":"YES! I have flirted with that change but fear the churn. IDK, maybe we should bite the bullet... the setter reveals my true bias :)","commit_id":"e039156e06e7a17754e3acedb67f5af74ea30bdc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"05ecb5fc40e069fc84e8a1a019af5534a08084f0","unresolved":false,"context_lines":[{"line_number":4799,"context_line":"        elif other is None:"},{"line_number":4800,"context_line":"            return True"},{"line_number":4801,"context_line":"        else:"},{"line_number":4802,"context_line":"            return self.upper \u003c other"},{"line_number":4803,"context_line":""},{"line_number":4804,"context_line":"    def __gt__(self, other):"},{"line_number":4805,"context_line":"        # a ShardRange is greater than other if its entire namespace is greater"}],"source_content_type":"text/x-python","patch_set":8,"id":"5f7c97a3_d229b3e5","line":4802,"updated":"2018-05-16 16:54:40.000000000","message":"Oh good! bisect only uses __lt__ [1], so the ordering at https://review.openstack.org/#/c/565744/8/swift/container/backend.py@1694 *is* well-ordered with respect to *items*, just not *each other*. I.e., for all strings x, there exists an index i such that \n\n all(sr \u003c x for sr in shard_ranges[:i]) and \\\n all(not (sr \u003c x) for sr in shard_ranges[i:])\n\n[1] https://github.com/python/cpython/blob/v2.7.15/Lib/bisect.py#L84 and https://github.com/python/cpython/blob/v2.7.15/Modules/_bisectmodule.c#L137","commit_id":"e039156e06e7a17754e3acedb67f5af74ea30bdc"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"445830801687ac5019fb0030fdea84a2c8d9a52a","unresolved":false,"context_lines":[{"line_number":7333,"context_line":"        self.assertTrue(\u0027x\u0027 in entire)"},{"line_number":7334,"context_line":""},{"line_number":7335,"context_line":"        self.assertFalse(\u0027\u0027 in lower)"},{"line_number":7336,"context_line":"        self.assertTrue(\u0027\u0027 in upper)"},{"line_number":7337,"context_line":""},{"line_number":7338,"context_line":"        self.assertTrue(\u0027a\u0027 in lower)"},{"line_number":7339,"context_line":"        self.assertTrue(\u0027h\u0027 in lower)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_39dd0c42","line":7336,"updated":"2018-05-08 22:55:45.000000000","message":"This makes sense given the docstring, but seems weird conceptually. Empty string sorts *before* all other strings, so why would it be in upper?\n\nMaybe the more important part of the docstring is the \"of object names\" part, and the fact that no object can be named the empty string...\n\nMaybe we should just have a\n\n if not item:\n     return False\n\nat the start of __contains__, even before the check for entire_namespace...","commit_id":"0b1c0ff92688891665349579d22f974e5e4c209c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f0d32e889dd477fb82a16be2121c3154b77154ec","unresolved":false,"context_lines":[{"line_number":7368,"context_line":"        self.assertTrue(\u0027x\u0027 in entire)"},{"line_number":7369,"context_line":""},{"line_number":7370,"context_line":"        self.assertFalse(\u0027\u0027 in lower)"},{"line_number":7371,"context_line":"        self.assertTrue(\u0027\u0027 in upper)"},{"line_number":7372,"context_line":""},{"line_number":7373,"context_line":"        self.assertTrue(\u0027a\u0027 in lower)"},{"line_number":7374,"context_line":"        self.assertTrue(\u0027h\u0027 in lower)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_6d45c742","line":7371,"updated":"2018-05-10 23:39:54.000000000","message":"This still seems weird... we\u0027ve got these nicely-ordered bounds that behave just as you\u0027d expect -- except for this one edge case that should never come up in practice where instead of appearing at the *start* of all strings like you\u0027d expect, the empty string is at the *end*. I kinda wish we\u0027d just *throw it out* -- maybe even\n\n raise ValueError(\u0027The empty string is not a valid object name\u0027)\n\nto make it painfully obvious??","commit_id":"7414233d4758f3978551a70b817b1ddbb5b0c3d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"abda0e6c92480074077e44f84fb381eb104ffbcd","unresolved":false,"context_lines":[{"line_number":7368,"context_line":"        self.assertTrue(\u0027x\u0027 in entire)"},{"line_number":7369,"context_line":""},{"line_number":7370,"context_line":"        self.assertFalse(\u0027\u0027 in lower)"},{"line_number":7371,"context_line":"        self.assertTrue(\u0027\u0027 in upper)"},{"line_number":7372,"context_line":""},{"line_number":7373,"context_line":"        self.assertTrue(\u0027a\u0027 in lower)"},{"line_number":7374,"context_line":"        self.assertTrue(\u0027h\u0027 in lower)"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_afed09f1","line":7371,"in_reply_to":"5f7c97a3_6d45c742","updated":"2018-05-11 14:38:16.000000000","message":"Done but just returning False","commit_id":"7414233d4758f3978551a70b817b1ddbb5b0c3d0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"db58914874e5ab851f5a09ace3850493782d0d8c","unresolved":false,"context_lines":[{"line_number":7370,"context_line":"        # the empty string is not a valid object name, so it cannot be in any"},{"line_number":7371,"context_line":"        # range"},{"line_number":7372,"context_line":"        self.assertFalse(\u0027\u0027 in lower)"},{"line_number":7373,"context_line":"        self.assertFalse(\u0027\u0027 in upper)"},{"line_number":7374,"context_line":""},{"line_number":7375,"context_line":"        self.assertTrue(\u0027a\u0027 in lower)"},{"line_number":7376,"context_line":"        self.assertTrue(\u0027h\u0027 in lower)"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_4838e69e","line":7373,"updated":"2018-05-11 21:19:52.000000000","message":"Might even be worth having\n\n self.assertFalse(\u0027\u0027 in entire)","commit_id":"03442512ee3a586ea4ea893011c3572130d99840"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"cd4ee6ab620bb7a20cdc94578695bb19f98fb5f7","unresolved":false,"context_lines":[{"line_number":3839,"context_line":"        found \u003d utils.find_shard_range(\u0027b\u0027, ranges)"},{"line_number":3840,"context_line":"        self.assertEqual(found, atof)"},{"line_number":3841,"context_line":"        found \u003d utils.find_shard_range(\u0027f\u0027, ranges)"},{"line_number":3842,"context_line":"        self.assertEqual(found, atof)"},{"line_number":3843,"context_line":"        found \u003d utils.find_shard_range(\u0027x\u0027, ranges)"},{"line_number":3844,"context_line":"        self.assertEqual(found, rtoz)"},{"line_number":3845,"context_line":"        found \u003d utils.find_shard_range(\u0027r\u0027, ranges)"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_efa3d8fe","line":3842,"updated":"2018-05-14 19:03:43.000000000","message":"Maybe add\n\n found \u003d utils.find_shard_range(\u0027f\\x00\u0027, ranges)\n self.assertEqual(found, ftol)\n\n?","commit_id":"5f4b17792bcfd1433f93e4bf17c09cb2f4edc168"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2f64ffe22d7d6402c23b6c82a85a78e26d291e2f","unresolved":false,"context_lines":[{"line_number":3839,"context_line":"        found \u003d utils.find_shard_range(\u0027b\u0027, ranges)"},{"line_number":3840,"context_line":"        self.assertEqual(found, atof)"},{"line_number":3841,"context_line":"        found \u003d utils.find_shard_range(\u0027f\u0027, ranges)"},{"line_number":3842,"context_line":"        self.assertEqual(found, atof)"},{"line_number":3843,"context_line":"        found \u003d utils.find_shard_range(\u0027x\u0027, ranges)"},{"line_number":3844,"context_line":"        self.assertEqual(found, rtoz)"},{"line_number":3845,"context_line":"        found \u003d utils.find_shard_range(\u0027r\u0027, ranges)"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_7d8bf4c1","line":3842,"in_reply_to":"5f7c97a3_efa3d8fe","updated":"2018-05-15 10:02:01.000000000","message":"Done","commit_id":"5f4b17792bcfd1433f93e4bf17c09cb2f4edc168"}]}
