)]}'
{"glance/common/exception.py":[{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":461,"context_line":"    message \u003d _(\"Operator %(op)s is not supported\")"},{"line_number":462,"context_line":""},{"line_number":463,"context_line":""},{"line_number":464,"context_line":"class ArtifactUnsupportedShowLevel(Invalid):"},{"line_number":465,"context_line":"    message \u003d _(\"Show level %(shl)s is not supported in this operation\")"},{"line_number":466,"context_line":""},{"line_number":467,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_1e1799a4","line":464,"updated":"2014-11-06 09:16:51.000000000","message":"Would it be better to name this ArtifactUnsupportedVisibilityLevel?","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"e58a9828b50a6220b831a249582ca934774001fb","unresolved":false,"context_lines":[{"line_number":461,"context_line":"    message \u003d _(\"Operator %(op)s is not supported\")"},{"line_number":462,"context_line":""},{"line_number":463,"context_line":""},{"line_number":464,"context_line":"class ArtifactUnsupportedShowLevel(Invalid):"},{"line_number":465,"context_line":"    message \u003d _(\"Show level %(shl)s is not supported in this operation\")"},{"line_number":466,"context_line":""},{"line_number":467,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_34b9d1e9","line":464,"in_reply_to":"7a8c0949_1e1799a4","updated":"2014-11-06 14:12:31.000000000","message":"Nope. These are different concepts.\nVisibility is access level to artifact: public, private, shared, etc.\nShow level is a level of artifact detail:\nNone - do not show additional properties and blobs with locations;\nBasic - show all artifact fields except dependencies;\nDirect - show all artifact fields with only direct dependencies;\nTransitive - show all artifact fields with all of dependencies.\n\nBecause of the potential performance problems we rejected the last two options (Direct and Transitive) with artifacts_get_all call. It\u0027s exactly the place where this exception may be raised.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"}],"glance/db/sqlalchemy/api.py":[{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":1657,"context_line":""},{"line_number":1658,"context_line":""},{"line_number":1659,"context_line":"def artifact_get_all(context, marker\u003dNone, limit\u003dNone, sort_key\u003dNone,"},{"line_number":1660,"context_line":"                     sort_dir\u003dNone, filters\u003d{},"},{"line_number":1661,"context_line":"                     show_level\u003dartifacts.Dependency.NONE, session\u003dNone):"},{"line_number":1662,"context_line":"    session \u003d session or get_session()"},{"line_number":1663,"context_line":"    return artifacts.get_all(context, session, marker, limit, sort_key,"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_ded7d1eb","line":1660,"updated":"2014-11-06 09:16:51.000000000","message":"Do you really want to set a mutable datastructure here?","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"e58a9828b50a6220b831a249582ca934774001fb","unresolved":false,"context_lines":[{"line_number":1657,"context_line":""},{"line_number":1658,"context_line":""},{"line_number":1659,"context_line":"def artifact_get_all(context, marker\u003dNone, limit\u003dNone, sort_key\u003dNone,"},{"line_number":1660,"context_line":"                     sort_dir\u003dNone, filters\u003d{},"},{"line_number":1661,"context_line":"                     show_level\u003dartifacts.Dependency.NONE, session\u003dNone):"},{"line_number":1662,"context_line":"    session \u003d session or get_session()"},{"line_number":1663,"context_line":"    return artifacts.get_all(context, session, marker, limit, sort_key,"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_a7ff51a9","line":1660,"in_reply_to":"7a8c0949_ded7d1eb","updated":"2014-11-06 14:12:31.000000000","message":"Yep, some examples of the filters are in tests. \nIn artifacts.py it\u0027s done in the same way as in the images: filters \u003d filters or {}\nSo, we can safely set it to None here. I\u0027ll fix it in the next commit.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"}],"glance/db/sqlalchemy/artifacts.py":[{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"6f8c6bc4e5c4b748ff13f865f7440345316dc6b1","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    PRIVATE \u003d \u0027private\u0027"},{"line_number":40,"context_line":"    PUBLIC \u003d \u0027public\u0027"},{"line_number":41,"context_line":"    SHARED \u003d \u0027shared\u0027"},{"line_number":42,"context_line":"    COMMUNITY \u003d \u0027community\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"class State(object):"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_3fad2f9d","line":42,"updated":"2014-11-06 10:32:16.000000000","message":"Can you define what each of these mean and the differences between them? for example public vs community. These names are not obvious.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"e58a9828b50a6220b831a249582ca934774001fb","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    PRIVATE \u003d \u0027private\u0027"},{"line_number":40,"context_line":"    PUBLIC \u003d \u0027public\u0027"},{"line_number":41,"context_line":"    SHARED \u003d \u0027shared\u0027"},{"line_number":42,"context_line":"    COMMUNITY \u003d \u0027community\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"class State(object):"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_6778092c","line":42,"in_reply_to":"7a8c0949_3fad2f9d","updated":"2014-11-06 14:12:31.000000000","message":"Community level is added for future development and currently is not supported.\nThere is a bp \"Add community-level image sharing\" from Louis Taylor https://review.openstack.org/#/c/124050/. We want to do the same thing with artifacts.\nBut I repeat, it is not yet supported and we discuss different ideas how to implement it correctly.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"ff1d5026aeb941b6bced40fea401e773c3a3bc60","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    PRIVATE \u003d \u0027private\u0027"},{"line_number":40,"context_line":"    PUBLIC \u003d \u0027public\u0027"},{"line_number":41,"context_line":"    SHARED \u003d \u0027shared\u0027"},{"line_number":42,"context_line":"    COMMUNITY \u003d \u0027community\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"class State(object):"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_8064fbe5","line":42,"in_reply_to":"7a8c0949_6778092c","updated":"2014-11-06 14:23:37.000000000","message":"I would suggest we either don\u0027t include it until it is needed/supported or we add a comment here.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        if \u0027tags\u0027 in values:"},{"line_number":125,"context_line":"            tags \u003d values[\u0027tags\u0027]"},{"line_number":126,"context_line":"            del values[\u0027tags\u0027]"},{"line_number":127,"context_line":"            artifact.tags \u003d _do_tags(artifact, tags)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        if \u0027properties\u0027 in values:"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_3e5c557e","line":126,"updated":"2014-11-06 09:16:51.000000000","message":"This line and the above can be replaced with:\n\n    tags \u003d values.pop(\u0027tags\u0027)","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"e58a9828b50a6220b831a249582ca934774001fb","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        if \u0027tags\u0027 in values:"},{"line_number":125,"context_line":"            tags \u003d values[\u0027tags\u0027]"},{"line_number":126,"context_line":"            del values[\u0027tags\u0027]"},{"line_number":127,"context_line":"            artifact.tags \u003d _do_tags(artifact, tags)"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        if \u0027properties\u0027 in values:"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_a72bd192","line":126,"in_reply_to":"7a8c0949_3e5c557e","updated":"2014-11-06 14:12:31.000000000","message":"thanks! you\u0027re right - it\u0027ll look better.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        if \u0027properties\u0027 in values:"},{"line_number":130,"context_line":"            properties \u003d values[\u0027properties\u0027]"},{"line_number":131,"context_line":"            del values[\u0027properties\u0027]"},{"line_number":132,"context_line":"            artifact.properties \u003d _do_properties(artifact, properties)"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        if \u0027blobs\u0027 in values:"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_5e5f6172","line":131,"updated":"2014-11-06 09:16:51.000000000","message":"As above.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        if \u0027blobs\u0027 in values:"},{"line_number":135,"context_line":"            blobs \u003d values[\u0027blobs\u0027]"},{"line_number":136,"context_line":"            del values[\u0027blobs\u0027]"},{"line_number":137,"context_line":"            artifact.blobs \u003d _do_blobs(artifact, blobs)"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        if \u0027dependencies\u0027 in values:"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_7e55fd4e","line":136,"updated":"2014-11-06 09:16:51.000000000","message":"again.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        if \u0027dependencies\u0027 in values:"},{"line_number":140,"context_line":"            dependencies \u003d values[\u0027dependencies\u0027]"},{"line_number":141,"context_line":"            del values[\u0027dependencies\u0027]"},{"line_number":142,"context_line":"            artifact.dependencies \u003d _do_dependencies(artifact,"},{"line_number":143,"context_line":"                                                     dependencies)"},{"line_number":144,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_fec80d24","line":141,"updated":"2014-11-06 09:16:51.000000000","message":"and again.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":160,"context_line":""},{"line_number":161,"context_line":"def create_transitive_dependecies(context, artifact_id, session):"},{"line_number":162,"context_line":"    \"\"\"creates transitive dependencies for the given artifact_id and saves"},{"line_number":163,"context_line":"       them in DB"},{"line_number":164,"context_line":"    \"\"\""},{"line_number":165,"context_line":"    artifact \u003d _get(context, artifact_id, session,"},{"line_number":166,"context_line":"                    show_level\u003dDependency.DIRECT)"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_3ea1b547","line":163,"updated":"2014-11-06 09:16:51.000000000","message":"This docstring doesn\u0027t tell me anything the method name and arguments tell me. It should describe what the method does.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"e58a9828b50a6220b831a249582ca934774001fb","unresolved":false,"context_lines":[{"line_number":160,"context_line":""},{"line_number":161,"context_line":"def create_transitive_dependecies(context, artifact_id, session):"},{"line_number":162,"context_line":"    \"\"\"creates transitive dependencies for the given artifact_id and saves"},{"line_number":163,"context_line":"       them in DB"},{"line_number":164,"context_line":"    \"\"\""},{"line_number":165,"context_line":"    artifact \u003d _get(context, artifact_id, session,"},{"line_number":166,"context_line":"                    show_level\u003dDependency.DIRECT)"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_8a789cf3","line":163,"in_reply_to":"7a8c0949_3ea1b547","updated":"2014-11-06 14:12:31.000000000","message":"Of course. I didn\u0027t add a lot of information here because api may change and I have to rewrite all docstrings. So I left it for later. \nBut I think I could write something if you insist :)","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":184,"context_line":"                                                       target\u003dtarget_state)"},{"line_number":185,"context_line":""},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"def _out(artifact, show_level\u003dDependency.BASIC, show_text_properties\u003dTrue):"},{"line_number":188,"context_line":"    res \u003d artifact.to_dict(show_level\u003dshow_level,"},{"line_number":189,"context_line":"                           show_text_properties\u003dshow_text_properties)"},{"line_number":190,"context_line":"    type_version \u003d semver.from_long(res[\u0027type_version_prefix\u0027],"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_5e8841e7","line":187,"updated":"2014-11-06 09:16:51.000000000","message":"_out? I have no idea what this method does from the name. Can we make it more descriptive and add a docstring?","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":273,"context_line":""},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"def get_all(context, session, marker\u003dNone, limit\u003dNone,"},{"line_number":276,"context_line":"            sort_key\u003dNone, sort_dir\u003dNone, filters\u003d{},"},{"line_number":277,"context_line":"            show_level\u003dDependency.NONE):"},{"line_number":278,"context_line":"    \"\"\"List all visible artifacts\"\"\""},{"line_number":279,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_5925bba9","line":276,"updated":"2014-11-06 09:16:51.000000000","message":"This should be filters\u003dNone since you check for it and set the default below.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"e58a9828b50a6220b831a249582ca934774001fb","unresolved":false,"context_lines":[{"line_number":273,"context_line":""},{"line_number":274,"context_line":""},{"line_number":275,"context_line":"def get_all(context, session, marker\u003dNone, limit\u003dNone,"},{"line_number":276,"context_line":"            sort_key\u003dNone, sort_dir\u003dNone, filters\u003d{},"},{"line_number":277,"context_line":"            show_level\u003dDependency.NONE):"},{"line_number":278,"context_line":"    \"\"\"List all visible artifacts\"\"\""},{"line_number":279,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_8a56dcd0","line":276,"in_reply_to":"7a8c0949_5925bba9","updated":"2014-11-06 14:12:31.000000000","message":"I answered in api.py. Yep, I\u0027ll change it.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        conds \u003d [models.ArtifactProperty.name \u003d\u003d filtername]"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"        if db_prop_op \u003d\u003d \u0027EQ\u0027:"},{"line_number":460,"context_line":"            cond \u003d ["},{"line_number":461,"context_line":"                getattr("},{"line_number":462,"context_line":"                    models.ArtifactProperty,"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_f9002703","line":459,"updated":"2014-11-06 09:16:51.000000000","message":"I have big concerns about implementing our own query language at all. However, this code can be massively simplified by using the Python operator module. At the moment this has loads of duplication which should be removed.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"cf08a4614a356bbc7ad5fd53c9dd982453a5eb37","unresolved":false,"context_lines":[{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        conds \u003d [models.ArtifactProperty.name \u003d\u003d filtername]"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"        if db_prop_op \u003d\u003d \u0027EQ\u0027:"},{"line_number":460,"context_line":"            cond \u003d ["},{"line_number":461,"context_line":"                getattr("},{"line_number":462,"context_line":"                    models.ArtifactProperty,"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_9bc46d60","line":459,"in_reply_to":"7a8c0949_20598736","updated":"2014-11-06 16:22:08.000000000","message":"Oh, I understand what you mean. I agree, it looks much better. I\u0027ll fix it tomorrow along with the other remarks.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"ff1d5026aeb941b6bced40fea401e773c3a3bc60","unresolved":false,"context_lines":[{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        conds \u003d [models.ArtifactProperty.name \u003d\u003d filtername]"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"        if db_prop_op \u003d\u003d \u0027EQ\u0027:"},{"line_number":460,"context_line":"            cond \u003d ["},{"line_number":461,"context_line":"                getattr("},{"line_number":462,"context_line":"                    models.ArtifactProperty,"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_20598736","line":459,"in_reply_to":"7a8c0949_85224dff","updated":"2014-11-06 14:23:37.000000000","message":"Something like this would be the start of a generic implementation that doesn\u0027t require as much code. Obviously far from complete but it might help, let me know if I can add more detail.\n\n    import operator\n\n    mapping \u003d {\n        \u0027GT\u0027: operator.gt,\n        \u0027NE\u0027: operator.ne,\n        # ...\n    }\n\n    fn \u003d mapping[db_prop_op]\n    result \u003d fn(getattr(models.ArtifactProperty, db_prop_type), db_prop_value)","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"e58a9828b50a6220b831a249582ca934774001fb","unresolved":false,"context_lines":[{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        conds \u003d [models.ArtifactProperty.name \u003d\u003d filtername]"},{"line_number":458,"context_line":""},{"line_number":459,"context_line":"        if db_prop_op \u003d\u003d \u0027EQ\u0027:"},{"line_number":460,"context_line":"            cond \u003d ["},{"line_number":461,"context_line":"                getattr("},{"line_number":462,"context_line":"                    models.ArtifactProperty,"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_85224dff","line":459,"in_reply_to":"7a8c0949_f9002703","updated":"2014-11-06 14:12:31.000000000","message":"I agree with you, but I have no idea how to do it correctly. These things are done for filters, and, for example, images don\u0027t support these operators.\ncurrent syntax for filters is:\n{\u0027property_name\u0027:\n    {\u0027value\u0027: 5,\n      \u0027type\u0027: int,\n      \u0027operator\u0027: \u0027GT\u0027\n    }\n}\nand get_all will return all artifacts that have property with a name \u0027property_name\u0027, which value is greater than 5.\nor\n{\u0027property_array\u0027:\n    {\u0027value\u0027: \u0027foo\u0027,\n      \u0027type\u0027: string,\n      \u0027operator\u0027: \u0027IN\u0027\n    }\n}\nhere get_all returns all artifacts with array \u0027property_array\u0027 that has string \u0027foo\u0027\nor\n{\u0027property_array\u0027:\n    {\u0027value\u0027: \u0027bar\u0027,\n      \u0027type\u0027: string,\n      \u0027operator\u0027: \u0027EQ\u0027,\n      \u0027position\u0027: 2\n    }\n}\nget_all returns all artifacts with array \u0027property_array\u0027 that has string \u0027bar\u0027 in position 2.\nThese filters originally come to us from json in POST request.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"99b3477834c03f1c3e02cd1cf97360696663d1fe","unresolved":false,"context_lines":[{"line_number":86,"context_line":"SHOWLEVELS \u003d [Showlevel.NONE, Showlevel.BASIC, Showlevel.DIRECT,"},{"line_number":87,"context_line":"              Showlevel.TRANSITIVE]"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"def create(context, values, session):"},{"line_number":91,"context_line":"    return _out(_create_or_update(context, values, None, session))"},{"line_number":92,"context_line":""}],"source_content_type":"text/x-python","patch_set":31,"id":"5a890539_f76f46c3","line":89,"updated":"2014-11-13 12:05:03.000000000","message":"I think collections.namedtuple would be a better fit for Visibility, State and Showlevel.","commit_id":"fabd8989779cba7dfc9582939bb12c9fb5881c45"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"99b3477834c03f1c3e02cd1cf97360696663d1fe","unresolved":false,"context_lines":[{"line_number":666,"context_line":"    if context.is_admin:"},{"line_number":667,"context_line":"        return True"},{"line_number":668,"context_line":""},{"line_number":669,"context_line":"    if not artifact.owner:"},{"line_number":670,"context_line":"        return True"},{"line_number":671,"context_line":""},{"line_number":672,"context_line":"    if artifact.visibility \u003d\u003d Visibility.PUBLIC:"}],"source_content_type":"text/x-python","patch_set":31,"id":"5a890539_37bb8f73","line":669,"updated":"2014-11-13 12:05:03.000000000","message":"Why would an artifact ever not have an owner? Making it visible in this case seems odd. Also, what would you expect it to be? None? If so, this might be better:\n\n    if artifact.owner is None:","commit_id":"fabd8989779cba7dfc9582939bb12c9fb5881c45"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"99b3477834c03f1c3e02cd1cf97360696663d1fe","unresolved":false,"context_lines":[{"line_number":679,"context_line":"            return False"},{"line_number":680,"context_line":""},{"line_number":681,"context_line":"    if artifact.visibility \u003d\u003d Visibility.SHARED:"},{"line_number":682,"context_line":"        return False"},{"line_number":683,"context_line":""},{"line_number":684,"context_line":""},{"line_number":685,"context_line":"def _get_scope(state, visibility, owner):"}],"source_content_type":"text/x-python","patch_set":31,"id":"5a890539_d7324b0f","line":682,"updated":"2014-11-13 12:05:03.000000000","message":"There should probably be a return False at the end if all of these fail for some reason.","commit_id":"fabd8989779cba7dfc9582939bb12c9fb5881c45"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from sqlalchemy.orm import joinedload"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"import operator"},{"line_number":25,"context_line":"import uuid"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"import glance.artifacts as ga"},{"line_number":28,"context_line":"from glance.common import exception"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_512e118d","line":25,"updated":"2015-03-13 20:51:32.000000000","message":"I believe this group should be the first one","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":22,"context_line":"from sqlalchemy.orm import joinedload"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"import operator"},{"line_number":25,"context_line":"import uuid"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"import glance.artifacts as ga"},{"line_number":28,"context_line":"from glance.common import exception"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_1d747a34","line":25,"in_reply_to":"9a80dd14_512e118d","updated":"2015-03-16 11:28:25.000000000","message":"Done","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":38,"context_line":"CONF \u003d cfg.CONF"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"class Visibility(object):"},{"line_number":42,"context_line":"    PRIVATE \u003d \u0027private\u0027"},{"line_number":43,"context_line":"    PUBLIC \u003d \u0027public\u0027"},{"line_number":44,"context_line":"    SHARED \u003d \u0027shared\u0027"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_f168e5bb","line":41,"updated":"2015-03-13 20:51:32.000000000","message":"we could probably use an enum here.","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":38,"context_line":"CONF \u003d cfg.CONF"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"class Visibility(object):"},{"line_number":42,"context_line":"    PRIVATE \u003d \u0027private\u0027"},{"line_number":43,"context_line":"    PUBLIC \u003d \u0027public\u0027"},{"line_number":44,"context_line":"    SHARED \u003d \u0027shared\u0027"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_dd5f423f","line":41,"in_reply_to":"9a80dd14_f168e5bb","updated":"2015-03-16 11:28:25.000000000","message":"Done","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    SHARED \u003d \u0027shared\u0027"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"class State(object):"},{"line_number":48,"context_line":"    CREATING \u003d \u0027creating\u0027"},{"line_number":49,"context_line":"    ACTIVE \u003d \u0027active\u0027"},{"line_number":50,"context_line":"    DEACTIVATED \u003d \u0027deactivated\u0027"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_315fdd10","line":47,"updated":"2015-03-13 20:51:32.000000000","message":"and here","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":44,"context_line":"    SHARED \u003d \u0027shared\u0027"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":""},{"line_number":47,"context_line":"class State(object):"},{"line_number":48,"context_line":"    CREATING \u003d \u0027creating\u0027"},{"line_number":49,"context_line":"    ACTIVE \u003d \u0027active\u0027"},{"line_number":50,"context_line":"    DEACTIVATED \u003d \u0027deactivated\u0027"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_1d563a2a","line":47,"in_reply_to":"9a80dd14_315fdd10","updated":"2015-03-16 11:28:25.000000000","message":"Done","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    DELETED \u003d \u0027deleted\u0027"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"VISIBILITIES \u003d (Visibility.PRIVATE, Visibility.PUBLIC, Visibility.SHARED)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"STATES \u003d [State.CREATING, State.ACTIVE, State.DEACTIVATED, State.DELETED]"},{"line_number":57,"context_line":"TRANSITIONS \u003d {"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_f1af05e1","line":54,"updated":"2015-03-13 20:51:32.000000000","message":"With an enum, this shouldn\u0027t be necessary. You can access its variants.","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    DELETED \u003d \u0027deleted\u0027"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"VISIBILITIES \u003d (Visibility.PRIVATE, Visibility.PUBLIC, Visibility.SHARED)"},{"line_number":55,"context_line":""},{"line_number":56,"context_line":"STATES \u003d [State.CREATING, State.ACTIVE, State.DEACTIVATED, State.DELETED]"},{"line_number":57,"context_line":"TRANSITIONS \u003d {"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_5d335213","line":54,"in_reply_to":"9a80dd14_f1af05e1","updated":"2015-03-16 11:28:25.000000000","message":"Done","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def _create_or_update(context, values, artifact_id, session, type_name,"},{"line_number":83,"context_line":"                      type_version\u003dNone):"},{"line_number":84,"context_line":"    values \u003d values.copy()"},{"line_number":85,"context_line":"    with session.begin():"},{"line_number":86,"context_line":"        _set_version_fields(values)"},{"line_number":87,"context_line":"        _validate_values(values)"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_31d8bd1d","line":84,"updated":"2015-03-13 20:51:32.000000000","message":"should we deepcopy this?","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def _create_or_update(context, values, artifact_id, session, type_name,"},{"line_number":83,"context_line":"                      type_version\u003dNone):"},{"line_number":84,"context_line":"    values \u003d values.copy()"},{"line_number":85,"context_line":"    with session.begin():"},{"line_number":86,"context_line":"        _set_version_fields(values)"},{"line_number":87,"context_line":"        _validate_values(values)"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_1d2d5aa8","line":84,"in_reply_to":"9a80dd14_31d8bd1d","updated":"2015-03-16 11:28:25.000000000","message":"Done","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        _drop_protected_attrs(models.Artifact, values)"},{"line_number":89,"context_line":"        if artifact_id:"},{"line_number":90,"context_line":"            # update existing artifact"},{"line_number":91,"context_line":"            state \u003d values.get(\u0027state\u0027, None)"},{"line_number":92,"context_line":"            show_level \u003d ga.Showlevel.BASIC"},{"line_number":93,"context_line":"            if state is not None:"},{"line_number":94,"context_line":"                if state \u003d\u003d \u0027active\u0027:"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_b1b3cd98","line":91,"updated":"2015-03-13 20:51:32.000000000","message":"What happens if the `state` is `None` ? What does it mean from an artifact perspective?\n\n(hint: `.get`\u0027s default return value is None for non-existent keys)","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        _drop_protected_attrs(models.Artifact, values)"},{"line_number":89,"context_line":"        if artifact_id:"},{"line_number":90,"context_line":"            # update existing artifact"},{"line_number":91,"context_line":"            state \u003d values.get(\u0027state\u0027, None)"},{"line_number":92,"context_line":"            show_level \u003d ga.Showlevel.BASIC"},{"line_number":93,"context_line":"            if state is not None:"},{"line_number":94,"context_line":"                if state \u003d\u003d \u0027active\u0027:"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_b8553cfb","line":91,"in_reply_to":"9a80dd14_b1b3cd98","updated":"2015-03-16 11:28:25.000000000","message":"In the current implementation state may never be none. However, there is an optimization planned to pass only the modified values to this method so having state as \"none\" means that the state haven\u0027t been changed.\n\nFixed the default, btw, thanks.","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":100,"context_line":"            artifact \u003d _get(context, artifact_id, session, type_name,"},{"line_number":101,"context_line":"                            type_version, show_level\u003dshow_level)"},{"line_number":102,"context_line":"            _validate_transition(artifact.state,"},{"line_number":103,"context_line":"                                 values.get(\u0027state\u0027, artifact.state))"},{"line_number":104,"context_line":"        else:"},{"line_number":105,"context_line":"            # create new artifact"},{"line_number":106,"context_line":"            artifact \u003d models.Artifact()"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_046619ed","line":103,"updated":"2015-03-13 20:51:32.000000000","message":"nit: `values.get(...)` could be replaced with `state or artifact.state`","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":100,"context_line":"            artifact \u003d _get(context, artifact_id, session, type_name,"},{"line_number":101,"context_line":"                            type_version, show_level\u003dshow_level)"},{"line_number":102,"context_line":"            _validate_transition(artifact.state,"},{"line_number":103,"context_line":"                                 values.get(\u0027state\u0027, artifact.state))"},{"line_number":104,"context_line":"        else:"},{"line_number":105,"context_line":"            # create new artifact"},{"line_number":106,"context_line":"            artifact \u003d models.Artifact()"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_58444046","line":103,"in_reply_to":"9a80dd14_046619ed","updated":"2015-03-16 11:28:25.000000000","message":"Done","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        else:"},{"line_number":105,"context_line":"            # create new artifact"},{"line_number":106,"context_line":"            artifact \u003d models.Artifact()"},{"line_number":107,"context_line":"            if \u0027id\u0027 not in values:"},{"line_number":108,"context_line":"                artifact.id \u003d str(uuid.uuid4())"},{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                artifact.id \u003d values[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_04d9b9f2","line":107,"updated":"2015-03-13 20:51:32.000000000","message":"do we allow people to set their own id? Is this consistent with what we do for images? Do we want to make it consistent?\n\nI guess the real question here is: What\u0027s the use case?","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        else:"},{"line_number":105,"context_line":"            # create new artifact"},{"line_number":106,"context_line":"            artifact \u003d models.Artifact()"},{"line_number":107,"context_line":"            if \u0027id\u0027 not in values:"},{"line_number":108,"context_line":"                artifact.id \u003d str(uuid.uuid4())"},{"line_number":109,"context_line":"            else:"},{"line_number":110,"context_line":"                artifact.id \u003d values[\u0027id\u0027]"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_58b28049","line":107,"in_reply_to":"9a80dd14_04d9b9f2","updated":"2015-03-16 11:28:25.000000000","message":"Here, in the DB API we do allow this: for testing/debugging purposes.\n\nIn later commits (starting from the declarative definition framework, which defines id as readonly and following the REST API which does not allow to specify ID in the creation post request) we forbid this.\n\nThis isn\u0027t consistent with Images API, and that\u0027s intentional: current use-case for manual setting of image id is manual synchronization of Images across different repositories. \nFor artifacts we plan to do it in a diffrent way (by adding a \"namespace\" field and enforcing the uniqueness of namespace + name + version combination). This will be discussed later when we add appropriate spec for that.","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    them in DB."},{"line_number":157,"context_line":"    :returns artifact dict with Transitive show level"},{"line_number":158,"context_line":"    \"\"\""},{"line_number":159,"context_line":"    values \u003d {\u0027state\u0027: \u0027active\u0027}"},{"line_number":160,"context_line":"    return _out(_create_or_update(context, values, artifact_id, session,"},{"line_number":161,"context_line":"                                  type_name, type_version))"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_278ddf7c","line":159,"updated":"2015-03-13 20:51:32.000000000","message":"I\u0027m afraid this is not race-free. Based on this code, it\u0027d be possible to publish an artifact that has been deleted if the delete happens after the artifact data has been read from the database in the transaction.\n\nThere are other cases like this in Glance and we need to fix them. I don;t think you should fix this in this patch but a note would be nice so we don\u0027t forget about it.","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    them in DB."},{"line_number":157,"context_line":"    :returns artifact dict with Transitive show level"},{"line_number":158,"context_line":"    \"\"\""},{"line_number":159,"context_line":"    values \u003d {\u0027state\u0027: \u0027active\u0027}"},{"line_number":160,"context_line":"    return _out(_create_or_update(context, values, artifact_id, session,"},{"line_number":161,"context_line":"                                  type_name, type_version))"},{"line_number":162,"context_line":""}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_98eeb820","line":159,"in_reply_to":"9a80dd14_278ddf7c","updated":"2015-03-16 11:28:25.000000000","message":"Yup, thanks. Logged into the etherpad to be fixed later.","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":188,"context_line":"        dependencies.sort(key\u003dlambda elem: (elem.artifact_origin,"},{"line_number":189,"context_line":"                                            elem.name, elem.position))"},{"line_number":190,"context_line":"        res[\u0027dependencies\u0027] \u003d {}"},{"line_number":191,"context_line":"        new_show_level \u003d ga.Showlevel.BASIC \\"},{"line_number":192,"context_line":"            if show_level \u003d\u003d ga.Showlevel.DIRECT \\"},{"line_number":193,"context_line":"            else ga.Showlevel.TRANSITIVE"},{"line_number":194,"context_line":"        for dep in dependencies:"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_33435db0","line":191,"updated":"2015-03-13 20:51:32.000000000","message":"nit: Things like this are the ones that I\u0027d personally prefer to have written using expanded if statements.","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":188,"context_line":"        dependencies.sort(key\u003dlambda elem: (elem.artifact_origin,"},{"line_number":189,"context_line":"                                            elem.name, elem.position))"},{"line_number":190,"context_line":"        res[\u0027dependencies\u0027] \u003d {}"},{"line_number":191,"context_line":"        new_show_level \u003d ga.Showlevel.BASIC \\"},{"line_number":192,"context_line":"            if show_level \u003d\u003d ga.Showlevel.DIRECT \\"},{"line_number":193,"context_line":"            else ga.Showlevel.TRANSITIVE"},{"line_number":194,"context_line":"        for dep in dependencies:"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_f8c5f48d","line":191,"in_reply_to":"9a80dd14_33435db0","updated":"2015-03-16 11:28:25.000000000","message":"Agree.","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6484,"name":"Feilong Wang","email":"hustemb@gmail.com","username":"flwang"},"change_message_id":"052354dab2f6f4f4fef8a2ab021b4f3e355d7e44","unresolved":false,"context_lines":[{"line_number":746,"context_line":"        _validate_values_tags(values[\u0027tags\u0027])"},{"line_number":747,"context_line":""},{"line_number":748,"context_line":""},{"line_number":749,"context_line":"def _validate_values_tags(tags):"},{"line_number":750,"context_line":"    # NOTE(mfedosin): it\u0027s an idea to check that all tags match the regexp"},{"line_number":751,"context_line":"    # regexp \u003d"},{"line_number":752,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":105,"id":"1a6ced46_14e2d92e","line":749,"updated":"2015-03-26 10:55:17.000000000","message":"This method is used at line 746, but it\u0027s not implemented yet. Any plan to do this? Otherwise we may don\u0027t need it for now.","commit_id":"ce2e02c015d47602b79a17c9cf39ce7a09306f18"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"07df4219ec9bb885c26105c81350069fd990919a","unresolved":false,"context_lines":[{"line_number":746,"context_line":"        _validate_values_tags(values[\u0027tags\u0027])"},{"line_number":747,"context_line":""},{"line_number":748,"context_line":""},{"line_number":749,"context_line":"def _validate_values_tags(tags):"},{"line_number":750,"context_line":"    # NOTE(mfedosin): it\u0027s an idea to check that all tags match the regexp"},{"line_number":751,"context_line":"    # regexp \u003d"},{"line_number":752,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":105,"id":"fa963961_8e927856","line":749,"in_reply_to":"1a6ced46_14e2d92e","updated":"2015-03-26 19:06:25.000000000","message":"Done","commit_id":"ce2e02c015d47602b79a17c9cf39ce7a09306f18"}],"glance/db/sqlalchemy/migrate_repo/versions/037_add_artifact_tables.py":[{"author":{"_account_id":12363,"name":"Oleksii Chuprykov","email":"a.chuprikoff@gmail.com","username":"ochuprykov"},"change_message_id":"28e07747979290e8be846f9756c9e5ba47c08b4d","unresolved":false,"context_lines":[{"line_number":70,"context_line":"                          Column(\u0027value\u0027, String(255), nullable\u003dFalse),"},{"line_number":71,"context_line":"                          Column(\u0027created_at\u0027, DateTime(), nullable\u003dFalse),"},{"line_number":72,"context_line":"                          Column(\u0027updated_at\u0027, DateTime()),"},{"line_number":73,"context_line":"                          mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":74,"context_line":"                          extend_existing\u003dTrue)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    Index(\u0027ix_artifact_tags_artifact_id\u0027, artifact_tags.c.artifact_id)"}],"source_content_type":"text/x-python","patch_set":22,"id":"9aa7fdbe_39e598a8","line":73,"updated":"2014-10-20 14:46:25.000000000","message":"We have this column nullable\u003dFalse in models. What is the reason of such inconsistency?\nThe same for each updated_at column below.","commit_id":"40ce0d1a491e5cad283c0a1a0f325b4d28935dba"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"ab0ae36db6f514daab5bd88ecf1a1110c78739b3","unresolved":false,"context_lines":[{"line_number":70,"context_line":"                          Column(\u0027value\u0027, String(255), nullable\u003dFalse),"},{"line_number":71,"context_line":"                          Column(\u0027created_at\u0027, DateTime(), nullable\u003dFalse),"},{"line_number":72,"context_line":"                          Column(\u0027updated_at\u0027, DateTime()),"},{"line_number":73,"context_line":"                          mysql_engine\u003d\u0027InnoDB\u0027,"},{"line_number":74,"context_line":"                          extend_existing\u003dTrue)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    Index(\u0027ix_artifact_tags_artifact_id\u0027, artifact_tags.c.artifact_id)"}],"source_content_type":"text/x-python","patch_set":22,"id":"9aa7fdbe_ab74cd9c","line":73,"in_reply_to":"9aa7fdbe_39e598a8","updated":"2014-10-20 15:48:32.000000000","message":"Thanks! I missed that.\nCurrently there is a lot of work here, fine-tuning will stay for dessert :)","commit_id":"40ce0d1a491e5cad283c0a1a0f325b4d28935dba"}],"glance/db/sqlalchemy/models_artifacts.py":[{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"3d2e2c2cba736aa487de6dec8b31ccedbe46b95a","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                             nullable\u003dFalse)"},{"line_number":120,"context_line":"    artifact_dest \u003d Column(String(36), ForeignKey(\u0027artifacts.id\u0027),"},{"line_number":121,"context_line":"                           nullable\u003dFalse)"},{"line_number":122,"context_line":"    is_strict \u003d Column(Boolean, nullable\u003dFalse, default\u003dFalse)"},{"line_number":123,"context_line":"    position \u003d Column(Integer)"},{"line_number":124,"context_line":"    type \u003d Column(String(36))"},{"line_number":125,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"baa201ad_603fa5b4","line":122,"updated":"2014-10-08 09:23:12.000000000","message":"\"is_direct\" is probably more appropriate name here. And I don\u0027t think that default makes any sense here.","commit_id":"be16ac4eeded9bdb42928e12b65a7f4cbc47969d"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"3d2e2c2cba736aa487de6dec8b31ccedbe46b95a","unresolved":false,"context_lines":[{"line_number":121,"context_line":"                           nullable\u003dFalse)"},{"line_number":122,"context_line":"    is_strict \u003d Column(Boolean, nullable\u003dFalse, default\u003dFalse)"},{"line_number":123,"context_line":"    position \u003d Column(Integer)"},{"line_number":124,"context_line":"    type \u003d Column(String(36))"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"class ArtifactTag(BASE, ArtifactBase):"}],"source_content_type":"text/x-python","patch_set":13,"id":"baa201ad_40754162","line":124,"updated":"2014-10-08 09:23:12.000000000","message":"Let\u0027s call this \"name\", so it is the same for Properties and Blobs","commit_id":"be16ac4eeded9bdb42928e12b65a7f4cbc47969d"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"2484ed862baf6fb163d08c7a7fb090538aa6f891","unresolved":false,"context_lines":[{"line_number":168,"context_line":"                         nullable\u003dFalse)"},{"line_number":169,"context_line":"    name \u003d Column(String(255), nullable\u003dFalse)"},{"line_number":170,"context_line":"    size \u003d Column(BigInteger())"},{"line_number":171,"context_line":"    position \u003d Column(Integer)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"def register_models(engine):"}],"source_content_type":"text/x-python","patch_set":16,"id":"baa201ad_344ddcc4","line":171,"updated":"2014-10-08 11:37:52.000000000","message":"there should be a location column i suppose","commit_id":"2f624892137ba3e96b9cda216548da8ea56038ba"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"c561bce656cdcc03d5c7ec4c7e21ed711c306c61","unresolved":false,"context_lines":[{"line_number":168,"context_line":"                         nullable\u003dFalse)"},{"line_number":169,"context_line":"    name \u003d Column(String(255), nullable\u003dFalse)"},{"line_number":170,"context_line":"    size \u003d Column(BigInteger())"},{"line_number":171,"context_line":"    position \u003d Column(Integer)"},{"line_number":172,"context_line":""},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"def register_models(engine):"}],"source_content_type":"text/x-python","patch_set":16,"id":"baa201ad_f73c36ca","line":171,"in_reply_to":"baa201ad_344ddcc4","updated":"2014-10-08 11:53:05.000000000","message":"Agree, but not the column but a table instead - same as for Images, so we may store multiple locations per blob","commit_id":"2f624892137ba3e96b9cda216548da8ea56038ba"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        tags \u003d []"},{"line_number":135,"context_line":"        for tag in self.tags:"},{"line_number":136,"context_line":"            tags.append(tag.value)"},{"line_number":137,"context_line":"        d[\u0027tags\u0027] \u003d tags"},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"        if show_level \u003d\u003d 0:"},{"line_number":140,"context_line":"            return d"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_99aba3d5","line":137,"updated":"2014-11-06 09:16:51.000000000","message":"This can be changed to:\n\n    d[\u0027tags\u0027] \u003d [tag.value for tag in self.tags]","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":172,"context_line":"                                             value\u003dpropvalue)"},{"line_number":173,"context_line":"        d[\u0027properties\u0027] \u003d properties"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":"        blobs \u003d {}"},{"line_number":176,"context_line":"        # sort blobs"},{"line_number":177,"context_line":"        self.blobs.sort(key\u003dlambda elem: elem.position)"},{"line_number":178,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_190a53d2","line":175,"updated":"2014-11-06 09:16:51.000000000","message":"A defaultdict(list) would make this easier to work with in the loop.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":183,"context_line":"            for loc in blob.locations:"},{"line_number":184,"context_line":"                locations.append(dict(value\u003dloc.value,"},{"line_number":185,"context_line":"                                      status\u003dloc.status))"},{"line_number":186,"context_line":"            if blob.name in blobs:"},{"line_number":187,"context_line":"                blobs[blob.name].append(dict(size\u003dblob.size,"},{"line_number":188,"context_line":"                                             locations\u003dlocations))"},{"line_number":189,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_3911cf05","line":186,"updated":"2014-11-06 09:16:51.000000000","message":"With the above suggestion this if should be removed.","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        super(ArtifactBase, self).save(session or db_api.get_session())"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    created_at \u003d Column(DateTime, default\u003dlambda: timeutils.utcnow(),"},{"line_number":58,"context_line":"                        nullable\u003dFalse)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    updated_at \u003d Column(DateTime, default\u003dlambda: timeutils.utcnow(),"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_1f0bbb7d","line":57,"updated":"2015-03-13 20:51:32.000000000","message":"Could you please move the field definitions above the save method?","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        super(ArtifactBase, self).save(session or db_api.get_session())"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    created_at \u003d Column(DateTime, default\u003dlambda: timeutils.utcnow(),"},{"line_number":58,"context_line":"                        nullable\u003dFalse)"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    updated_at \u003d Column(DateTime, default\u003dlambda: timeutils.utcnow(),"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_7d8d7630","line":57,"in_reply_to":"9a80dd14_1f0bbb7d","updated":"2015-03-16 11:28:25.000000000","message":"Done","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":6159,"name":"Flavio Percoco Premoli","display_name":"flaper87","email":"flavio.percoco@flyrlabs.com","username":"flaper87"},"change_message_id":"c96258b4c21eac2d3af7aed3010bc244d8e8a5d9","unresolved":false,"context_lines":[{"line_number":94,"context_line":""},{"line_number":95,"context_line":"class Artifact(BASE, ArtifactBase):"},{"line_number":96,"context_line":"    __tablename__ \u003d \u0027artifacts\u0027"},{"line_number":97,"context_line":"    __table_args__ \u003d ("},{"line_number":98,"context_line":"        Index(\u0027ix_artifact_name_and_version\u0027, \u0027name\u0027, \u0027version_prefix\u0027,"},{"line_number":99,"context_line":"              \u0027version_suffix\u0027),"},{"line_number":100,"context_line":"        Index(\u0027ix_artifact_type\u0027, \u0027type_name\u0027, \u0027type_version_prefix\u0027,"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_3f84ff09","line":97,"updated":"2015-03-13 20:51:32.000000000","message":"This overrides the `__table_args__` in the `ArtifactBase` class, doesn\u0027t it?","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"},{"author":{"_account_id":8127,"name":"Alexander Tivelkov","email":"locher@yandex.ru","username":"ativelkov"},"change_message_id":"9bf446e3a44ddd2f9e23ebd017b948d92e995eac","unresolved":false,"context_lines":[{"line_number":94,"context_line":""},{"line_number":95,"context_line":"class Artifact(BASE, ArtifactBase):"},{"line_number":96,"context_line":"    __tablename__ \u003d \u0027artifacts\u0027"},{"line_number":97,"context_line":"    __table_args__ \u003d ("},{"line_number":98,"context_line":"        Index(\u0027ix_artifact_name_and_version\u0027, \u0027name\u0027, \u0027version_prefix\u0027,"},{"line_number":99,"context_line":"              \u0027version_suffix\u0027),"},{"line_number":100,"context_line":"        Index(\u0027ix_artifact_type\u0027, \u0027type_name\u0027, \u0027type_version_prefix\u0027,"}],"source_content_type":"text/x-python","patch_set":101,"id":"9a80dd14_a4e6ffad","line":97,"in_reply_to":"9a80dd14_3f84ff09","updated":"2015-03-16 11:28:25.000000000","message":"Hm. You are right, it does. I was pretty sure that SQLAlchemy handles it in a smarter way (as this code is copyied from the Images model, they have the same __table_args__ separation between GlanceBase base and concrete classes), but it looks like it does not do it and it actually hides the args from the base.\n\nMost probably not a big deal, but still better to fix that.","commit_id":"8fab19d03574da326569fa3ca30adc940a783fd0"}],"glance/tests/functional/db/base_artifacts.py":[{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"92ff4eb51f0d7fa5b5ae5f075b9fc82e82046c0a","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from glance.tests import utils as test_utils"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"UUID1, UUID2 \u003d sorted([str(uuid.uuid4()) for x in range(2)])"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class ArtifactsTestDriver(test_utils.BaseTestCase):"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_d9160bf1","line":22,"updated":"2014-11-06 09:16:51.000000000","message":"Why do this? I don\u0027t understand. If anything I don\u0027t think it needs to be sorted?","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":9712,"name":"Dougal Matthews","email":"dougal.matthews@canonical.com","username":"dougal"},"change_message_id":"ff1d5026aeb941b6bced40fea401e773c3a3bc60","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from glance.tests import utils as test_utils"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"UUID1, UUID2 \u003d sorted([str(uuid.uuid4()) for x in range(2)])"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class ArtifactsTestDriver(test_utils.BaseTestCase):"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_a04c9771","line":22,"in_reply_to":"7a8c0949_c7bd3d6a","updated":"2014-11-06 14:23:37.000000000","message":"ok, thanks - it just struck me as somewhat odd :)","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"e58a9828b50a6220b831a249582ca934774001fb","unresolved":false,"context_lines":[{"line_number":19,"context_line":"from glance.tests import utils as test_utils"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"UUID1, UUID2 \u003d sorted([str(uuid.uuid4()) for x in range(2)])"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"class ArtifactsTestDriver(test_utils.BaseTestCase):"}],"source_content_type":"text/x-python","patch_set":27,"id":"7a8c0949_c7bd3d6a","line":22,"in_reply_to":"7a8c0949_d9160bf1","updated":"2014-11-06 14:12:31.000000000","message":"Alex Tivelkov wrote this and I suppose he would answer your question better than me. I think it was done for get_all testing: UUID1 is always first in results.\nBut I don\u0027t need it, so I\u0027ll remove \"sorted\".","commit_id":"66bc7c938bd1c0177e285a18fa5781c3e493b4e8"},{"author":{"_account_id":11391,"name":"Mikhail Fedosin","email":"mfedosin@redhat.com","username":"fedosinme"},"change_message_id":"e6f631ec0d6dd4d4607619963135329db947269e","unresolved":false,"context_lines":[{"line_number":290,"context_line":"            \u0027visibility\u0027: u\u0027private\u0027,"},{"line_number":291,"context_line":"            \u0027state\u0027: u\u0027creating\u0027,"},{"line_number":292,"context_line":"            \u0027owner\u0027: u\u0027test-tenant\u0027,"},{"line_number":293,"context_line":"            \u0027tags\u0027: [\u0027lalala\u0027, \u0027gugugu\u0027],"},{"line_number":294,"context_line":"            \u0027published_at\u0027: None,"},{"line_number":295,"context_line":"            \u0027deleted_at\u0027: None,"},{"line_number":296,"context_line":"            \u0027properties\u0027: {"}],"source_content_type":"text/x-python","patch_set":41,"id":"5a890539_d3dae849","line":293,"updated":"2014-12-04 14:30:46.000000000","message":"logically tags is a set and you can not compare it this way.","commit_id":"846529aefa303b5ba3427160ed1b330d0ed217ed"},{"author":{"_account_id":6484,"name":"Feilong Wang","email":"hustemb@gmail.com","username":"flwang"},"change_message_id":"052354dab2f6f4f4fef8a2ab021b4f3e355d7e44","unresolved":false,"context_lines":[{"line_number":21,"context_line":"from glance.tests import utils as test_utils"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"UUID1, UUID2 \u003d \u00271\u0027, \u00272\u0027"},{"line_number":25,"context_line":"TYPE_NAME \u003d u\u0027TestArtifactType\u0027"},{"line_number":26,"context_line":"TYPE_VERSION \u003d u\u00271.0.0\u0027"},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"1a6ced46_e938033f","line":24,"updated":"2015-03-26 10:55:17.000000000","message":"(nit): How about using real UUID?","commit_id":"ce2e02c015d47602b79a17c9cf39ce7a09306f18"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"07df4219ec9bb885c26105c81350069fd990919a","unresolved":false,"context_lines":[{"line_number":21,"context_line":"from glance.tests import utils as test_utils"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"UUID1, UUID2 \u003d \u00271\u0027, \u00272\u0027"},{"line_number":25,"context_line":"TYPE_NAME \u003d u\u0027TestArtifactType\u0027"},{"line_number":26,"context_line":"TYPE_VERSION \u003d u\u00271.0.0\u0027"},{"line_number":27,"context_line":""}],"source_content_type":"text/x-python","patch_set":105,"id":"fa963961_6edbb41c","line":24,"in_reply_to":"1a6ced46_e938033f","updated":"2015-03-26 19:06:25.000000000","message":"Done","commit_id":"ce2e02c015d47602b79a17c9cf39ce7a09306f18"},{"author":{"_account_id":6484,"name":"Feilong Wang","email":"hustemb@gmail.com","username":"flwang"},"change_message_id":"54f003cf824e21e5c11d9a6ac3735975423eb7ae","unresolved":false,"context_lines":[{"line_number":391,"context_line":"            \u0027dependencies\u0027: {"},{"line_number":392,"context_line":"                \u0027new-\u003e2\u0027: ["},{"line_number":393,"context_line":"                    {"},{"line_number":394,"context_line":"                        \u0027id\u0027: \u00272\u0027,"},{"line_number":395,"context_line":"                        \u0027created_at\u0027: self.art2[\u0027created_at\u0027],"},{"line_number":396,"context_line":"                        \u0027updated_at\u0027: self.art2[\u0027updated_at\u0027],"},{"line_number":397,"context_line":"                        \u0027published_at\u0027: None,"}],"source_content_type":"text/x-python","patch_set":106,"id":"fa963961_ea868912","line":394,"updated":"2015-03-26 21:45:24.000000000","message":"This line need to be updated as well. It would be nice if we can use UUID2 instead of hardcode.","commit_id":"975b1c37efccad1a6e359f274575e6fa03eeac69"}]}
