)]}'
{"dragonflow/db/field_types.py":[{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"58c20d60f7ed1a9bae9b4590b8454b5fa95074cd","unresolved":false,"context_lines":[{"line_number":37,"context_line":"    def __init__(self, model, lazy\u003dTrue, *args, **kwargs):"},{"line_number":38,"context_line":"        super(ReferenceField, self).__init__(*args, **kwargs)"},{"line_number":39,"context_line":"        self._model \u003d model"},{"line_number":40,"context_line":"        self._lazy \u003d lazy"},{"line_number":41,"context_line":"        # We delay type creation until first access in case model is not"},{"line_number":42,"context_line":"        # available yet - i.e we got a string"},{"line_number":43,"context_line":"        self._types \u003d None"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_e58c18dc","line":40,"range":{"start_line":40,"start_character":0,"end_line":40,"end_character":25},"updated":"2017-02-15 02:24:41.000000000","message":"Where is this value used?","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"c3ba5de0b6963980bbdbb241d3d6c7f0820f11fa","unresolved":false,"context_lines":[{"line_number":37,"context_line":"    def __init__(self, model, lazy\u003dTrue, *args, **kwargs):"},{"line_number":38,"context_line":"        super(ReferenceField, self).__init__(*args, **kwargs)"},{"line_number":39,"context_line":"        self._model \u003d model"},{"line_number":40,"context_line":"        self._lazy \u003d lazy"},{"line_number":41,"context_line":"        # We delay type creation until first access in case model is not"},{"line_number":42,"context_line":"        # available yet - i.e we got a string"},{"line_number":43,"context_line":"        self._types \u003d None"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_57858557","line":40,"range":{"start_line":40,"start_character":0,"end_line":40,"end_character":25},"in_reply_to":"fa31d9ce_e58c18dc","updated":"2017-02-15 13:30:59.000000000","message":"You\u0027re right, it should be passed on L60","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"58c20d60f7ed1a9bae9b4590b8454b5fa95074cd","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    @property"},{"line_number":49,"context_line":"    def types(self):"},{"line_number":50,"context_line":"        if self._types is None:"},{"line_number":51,"context_line":"            self._types \u003d ("},{"line_number":52,"context_line":"                model_proxy.create_model_proxy("},{"line_number":53,"context_line":"                    model_framework.get_model(self._model),"},{"line_number":54,"context_line":"                ),"},{"line_number":55,"context_line":"            )"},{"line_number":56,"context_line":"        return self._types"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def parse_value(self, value):"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_a59ea004","line":55,"range":{"start_line":51,"start_character":0,"end_line":55,"end_character":13},"updated":"2017-02-15 02:24:41.000000000","message":"why does the types have to be a tuple? Is it possible for a ref to have multiple types?","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"c3ba5de0b6963980bbdbb241d3d6c7f0820f11fa","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    @property"},{"line_number":49,"context_line":"    def types(self):"},{"line_number":50,"context_line":"        if self._types is None:"},{"line_number":51,"context_line":"            self._types \u003d ("},{"line_number":52,"context_line":"                model_proxy.create_model_proxy("},{"line_number":53,"context_line":"                    model_framework.get_model(self._model),"},{"line_number":54,"context_line":"                ),"},{"line_number":55,"context_line":"            )"},{"line_number":56,"context_line":"        return self._types"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def parse_value(self, value):"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_d798957a","line":55,"range":{"start_line":51,"start_character":0,"end_line":55,"end_character":13},"in_reply_to":"fa31d9ce_a59ea004","updated":"2017-02-15 13:30:59.000000000","message":"types is an attribute used in jsonmodels (see [1]), and it is used to validate field content. A single field can have several time, for instance StringField can take both str and unicode (in python2.x).\n\n\n[1]  https://github.com/beregond/jsonmodels/blob/master/jsonmodels/fields.py","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"58c20d60f7ed1a9bae9b4590b8454b5fa95074cd","unresolved":false,"context_lines":[{"line_number":55,"context_line":"            )"},{"line_number":56,"context_line":"        return self._types"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def parse_value(self, value):"},{"line_number":59,"context_line":"        if value:"},{"line_number":60,"context_line":"            return self.types[0](id\u003dvalue)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def to_struct(self, value):"},{"line_number":63,"context_line":"        return value.id"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"class ReferenceListField(fields.ListField):"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_c56f14fa","line":63,"range":{"start_line":58,"start_character":0,"end_line":63,"end_character":23},"updated":"2017-02-15 02:24:41.000000000","message":"Not sure I understand it, the value in these 2 methods are different, one is string, the other is object, right?","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"c3ba5de0b6963980bbdbb241d3d6c7f0820f11fa","unresolved":false,"context_lines":[{"line_number":55,"context_line":"            )"},{"line_number":56,"context_line":"        return self._types"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def parse_value(self, value):"},{"line_number":59,"context_line":"        if value:"},{"line_number":60,"context_line":"            return self.types[0](id\u003dvalue)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def to_struct(self, value):"},{"line_number":63,"context_line":"        return value.id"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"class ReferenceListField(fields.ListField):"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_570825da","line":63,"range":{"start_line":58,"start_character":0,"end_line":63,"end_character":23},"in_reply_to":"fa31d9ce_c56f14fa","updated":"2017-02-15 13:30:59.000000000","message":"to_struct converts the object to primitive, and parse_value parses it from primitive to a model object.\n\nConsider we have a ref field to lswitch, then in the serialized object we\u0027ll have:\n\n {\n   ...\n   \"lswitch\": \"lswitch-id1\",\n   ...\n }\n\nlswitch here is the name of the field and id is the proxy field in the serialized form.","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"58c20d60f7ed1a9bae9b4590b8454b5fa95074cd","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        return [self._proxy_type(v) for v in values or []]"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def to_struct(self, values):"},{"line_number":91,"context_line":"        if values:"},{"line_number":92,"context_line":"            return [v.id for v in values]"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"class IpAddressField(fields.BaseField):"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_05768cd6","line":92,"range":{"start_line":91,"start_character":0,"end_line":92,"end_character":41},"updated":"2017-02-15 02:24:41.000000000","message":"why not use the list comprehension as line 88?","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"c3ba5de0b6963980bbdbb241d3d6c7f0820f11fa","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        return [self._proxy_type(v) for v in values or []]"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def to_struct(self, values):"},{"line_number":91,"context_line":"        if values:"},{"line_number":92,"context_line":"            return [v.id for v in values]"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"class IpAddressField(fields.BaseField):"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_374491b5","line":92,"range":{"start_line":91,"start_character":0,"end_line":92,"end_character":41},"in_reply_to":"fa31d9ce_05768cd6","updated":"2017-02-15 13:30:59.000000000","message":"In line 88 we either get a list of IDs or None, where None represents a lack of value. \n\nI thought it would be more convenient to always return a list there always, that way you can always append and iterate straight away without checking if its initialized.\n\n\nIn this function we\u0027re serializing our list so in case its empty we return None and the field is omitted from the serialized result (which is fine because it will be present after parsing).","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"58c20d60f7ed1a9bae9b4590b8454b5fa95074cd","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    In serialized form it is stored as IP address string:"},{"line_number":99,"context_line":"        \"ip\": \"10.0.0.12\","},{"line_number":100,"context_line":"    \u0027\u0027\u0027"},{"line_number":101,"context_line":"    types \u003d (netaddr.IPAddress)"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    def parse_value(self, value):"},{"line_number":104,"context_line":"        if value is not None:"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_e83dcfc4","line":101,"range":{"start_line":101,"start_character":12,"end_line":101,"end_character":31},"updated":"2017-02-15 02:24:41.000000000","message":"Why need this parentheses?","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"c3ba5de0b6963980bbdbb241d3d6c7f0820f11fa","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    In serialized form it is stored as IP address string:"},{"line_number":99,"context_line":"        \"ip\": \"10.0.0.12\","},{"line_number":100,"context_line":"    \u0027\u0027\u0027"},{"line_number":101,"context_line":"    types \u003d (netaddr.IPAddress)"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"    def parse_value(self, value):"},{"line_number":104,"context_line":"        if value is not None:"}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_b7b241e3","line":101,"range":{"start_line":101,"start_character":12,"end_line":101,"end_character":31},"in_reply_to":"fa31d9ce_e83dcfc4","updated":"2017-02-15 13:30:59.000000000","message":"Forgot a comma to make it a tuple but it works both way (passed a second parameter to isinstance). Will add commas here and in the class below.","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"ae9bb522196cdb0bbf714633301449683e5aedcd","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        if value:"},{"line_number":60,"context_line":"            return self.types[0](id\u003dvalue, lazy\u003dself._lazy)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def to_struct(self, value):"},{"line_number":63,"context_line":"        return value.id"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":33,"id":"fa31d9ce_5b111551","line":62,"range":{"start_line":62,"start_character":24,"end_line":62,"end_character":29},"updated":"2017-02-16 01:25:44.000000000","message":"If it converts obj to primitive, maybe rename the \u0027value\u0027 to obj?(though jsonmodels uses value as parameter name)","commit_id":"db67396639d35d7d2d3fda57bdbf7f584bfb7508"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"3aed844ad21c656dad0763ce7dbe71e5a727cc8b","unresolved":false,"context_lines":[{"line_number":59,"context_line":"        if value:"},{"line_number":60,"context_line":"            return self.types[0](id\u003dvalue, lazy\u003dself._lazy)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def to_struct(self, value):"},{"line_number":63,"context_line":"        return value.id"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""}],"source_content_type":"text/x-python","patch_set":33,"id":"fa31d9ce_edea01ac","line":62,"range":{"start_line":62,"start_character":24,"end_line":62,"end_character":29},"in_reply_to":"fa31d9ce_5b111551","updated":"2017-02-16 09:04:18.000000000","message":"I don\u0027t mind, will update","commit_id":"db67396639d35d7d2d3fda57bdbf7f584bfb7508"}],"dragonflow/tests/unit/test_model_fields.py":[{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"58c20d60f7ed1a9bae9b4590b8454b5fa95074cd","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        self.assertEqual(\u00271.1.1.1/24\u0027, m.to_struct().get(\u0027ipnetwork\u0027))"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def test_ref(self):"},{"line_number":65,"context_line":"        m \u003d FieldTestModel(ref\u003d\u0027id1\u0027)"},{"line_number":66,"context_line":"        self.assertEqual(\u0027id1\u0027, m.to_struct().get(\u0027ref\u0027))"},{"line_number":67,"context_line":"        self.assertEqual(\u0027id1\u0027, m.ref.id)"},{"line_number":68,"context_line":"        m.ref._fetch_obj \u003d mock.MagicMock("}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_6563c842","line":65,"range":{"start_line":65,"start_character":32,"end_line":65,"end_character":35},"updated":"2017-02-15 02:24:41.000000000","message":"FieldTestModel will have \u0027id1\u0027 as id by default. Is it more appropriate to use other string as id for the ref?","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"c3ba5de0b6963980bbdbb241d3d6c7f0820f11fa","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        self.assertEqual(\u00271.1.1.1/24\u0027, m.to_struct().get(\u0027ipnetwork\u0027))"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def test_ref(self):"},{"line_number":65,"context_line":"        m \u003d FieldTestModel(ref\u003d\u0027id1\u0027)"},{"line_number":66,"context_line":"        self.assertEqual(\u0027id1\u0027, m.to_struct().get(\u0027ref\u0027))"},{"line_number":67,"context_line":"        self.assertEqual(\u0027id1\u0027, m.ref.id)"},{"line_number":68,"context_line":"        m.ref._fetch_obj \u003d mock.MagicMock("}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_779b6918","line":65,"range":{"start_line":65,"start_character":32,"end_line":65,"end_character":35},"in_reply_to":"fa31d9ce_6563c842","updated":"2017-02-15 13:30:59.000000000","message":"Will change","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"58c20d60f7ed1a9bae9b4590b8454b5fa95074cd","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_ref_list(self):"},{"line_number":73,"context_line":"        m \u003d FieldTestModel(ref_list\u003d[\u0027id1\u0027, \u0027id2\u0027])"},{"line_number":74,"context_line":"        self.assertItemsEqual((\u0027id1\u0027, \u0027id2\u0027), m.to_struct().get(\u0027ref_list\u0027))"},{"line_number":75,"context_line":"        self.assertEqual(\u0027id1\u0027, m.ref_list[0].id)"},{"line_number":76,"context_line":"        self.assertEqual(\u0027id2\u0027, m.ref_list[1].id)"},{"line_number":77,"context_line":"        m.ref_list[0]._fetch_obj \u003d mock.MagicMock("}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_a58220c6","line":74,"range":{"start_line":74,"start_character":0,"end_line":74,"end_character":76},"updated":"2017-02-15 02:24:41.000000000","message":"If it is list, it should be ordered. Why not just use assertEqual([\u0027id1\u0027, \u0027id2\u0027],  m.to_struct().get(\u0027ref_list\u0027))","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"},{"author":{"_account_id":23766,"name":"Dima Kuznetsov","email":"dima.kuznetsov@toganetworks.com","username":"dimak"},"change_message_id":"c3ba5de0b6963980bbdbb241d3d6c7f0820f11fa","unresolved":false,"context_lines":[{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_ref_list(self):"},{"line_number":73,"context_line":"        m \u003d FieldTestModel(ref_list\u003d[\u0027id1\u0027, \u0027id2\u0027])"},{"line_number":74,"context_line":"        self.assertItemsEqual((\u0027id1\u0027, \u0027id2\u0027), m.to_struct().get(\u0027ref_list\u0027))"},{"line_number":75,"context_line":"        self.assertEqual(\u0027id1\u0027, m.ref_list[0].id)"},{"line_number":76,"context_line":"        self.assertEqual(\u0027id2\u0027, m.ref_list[1].id)"},{"line_number":77,"context_line":"        m.ref_list[0]._fetch_obj \u003d mock.MagicMock("}],"source_content_type":"text/x-python","patch_set":32,"id":"fa31d9ce_77f4495a","line":74,"range":{"start_line":74,"start_character":0,"end_line":74,"end_character":76},"in_reply_to":"fa31d9ce_a58220c6","updated":"2017-02-15 13:30:59.000000000","message":"Will change","commit_id":"ebf06ffd15ecf7066e68c7203a089e573abfbefe"}]}
