)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"154adc43acaa829e7dbd6cdf682ed894901f27fa","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Comparision of database models and migrations."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"We shouldn\u0027t allow declaration of models and migrations with"},{"line_number":10,"context_line":"differences. Furthermore we should take into account all the engines"},{"line_number":11,"context_line":"implementation singularity and achieve maximum models and migrations"},{"line_number":12,"context_line":"conformity."},{"line_number":13,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"AAAAXH%2F%2FqIU%3D","line":10,"updated":"2014-04-18 13:57:31.000000000","message":"s/engines/backends","commit_id":"d58d877a7af15524af428bc50401e1b41f4e78d0"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"154adc43acaa829e7dbd6cdf682ed894901f27fa","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"We shouldn\u0027t allow declaration of models and migrations with"},{"line_number":10,"context_line":"differences. Furthermore we should take into account all the engines"},{"line_number":11,"context_line":"implementation singularity and achieve maximum models and migrations"},{"line_number":12,"context_line":"conformity."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Closes-Bug: #1292591"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"AAAAXH%2F%2FqIg%3D","line":11,"updated":"2014-04-18 13:57:31.000000000","message":"s/singularity/traits :)","commit_id":"d58d877a7af15524af428bc50401e1b41f4e78d0"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"bcc573a9837980fc690dc0087e5aafd9d916fb09","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Ilya Pekelny \u003cipekelny@mirantis.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2014-10-07 11:31:49 +0300"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Comparision of database models and migrations."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"We shouldn\u0027t allow declaration of models and migrations with"},{"line_number":10,"context_line":"differences. Furthermore we should take into account all the backends"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":68,"id":"baa201ad_ae5afb27","line":7,"updated":"2014-10-12 21:04:09.000000000","message":"Change \"Comparision\" to \"Comparison\"","commit_id":"b78d008ef849f8d9c0d03494206c81f1a620d5e9"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"7ddf56f5903af307a4b0f534e4f1c38482af5180","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Ilya Pekelny \u003cipekelny@mirantis.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2014-10-07 11:31:49 +0300"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Comparision of database models and migrations."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"We shouldn\u0027t allow declaration of models and migrations with"},{"line_number":10,"context_line":"differences. Furthermore we should take into account all the backends"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":68,"id":"baa201ad_02c91679","line":7,"in_reply_to":"baa201ad_ae5afb27","updated":"2014-10-13 07:47:27.000000000","message":"Done","commit_id":"b78d008ef849f8d9c0d03494206c81f1a620d5e9"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"db4e159e42a11a9b2cdd885a358257359c971e43","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Comparision of database models and migrations."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"We shouldn\u0027t allow declaration of models and migrations with"},{"line_number":10,"context_line":"differences. Furthermore we should take into account all the backends"},{"line_number":11,"context_line":"implementation traits and achieve maximum models and migrations"},{"line_number":12,"context_line":"conformity."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":88,"id":"9aa53dc9_16c62e48","line":9,"updated":"2015-04-08 12:32:15.000000000","message":"why shouldn\u0027t we?","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"944b8cbe1c5f7036583ad30ba211e38d2a3d1c3d","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Comparision of database models and migrations."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"We shouldn\u0027t allow declaration of models and migrations with"},{"line_number":10,"context_line":"differences. Furthermore we should take into account all the backends"},{"line_number":11,"context_line":"implementation traits and achieve maximum models and migrations"},{"line_number":12,"context_line":"conformity."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":88,"id":"9aa53dc9_9c513811","line":9,"in_reply_to":"9aa53dc9_16c62e48","updated":"2015-04-08 14:31:41.000000000","message":"In a few words, as a developer I want to be sure, that DB state is the same as SQLA models description. Also, will reduce SQLite usage, allow us to generate DB from SQLA metadata (not from migrations), tune DB migrations, etc.","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"0909ceb56cd7cccdd1cf6ee0b7afc9ee07d74086","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Comparision of database models and migrations."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"We shouldn\u0027t allow declaration of models and migrations with"},{"line_number":10,"context_line":"differences. Furthermore we should take into account all the backends"},{"line_number":11,"context_line":"implementation traits and achieve maximum models and migrations"},{"line_number":12,"context_line":"conformity."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":88,"id":"9aa53dc9_fc2164fc","line":9,"in_reply_to":"9aa53dc9_9c513811","updated":"2015-04-08 14:47:01.000000000","message":"this should be in commit message","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"02f9c22c348398424c452fe4b5ea8cd78ae315be","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Comparision of database models and migrations."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"We shouldn\u0027t allow declaration of models and migrations with"},{"line_number":10,"context_line":"differences. Furthermore we should take into account all the backends"},{"line_number":11,"context_line":"implementation traits and achieve maximum models and migrations"},{"line_number":12,"context_line":"conformity."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":88,"id":"5aa745d1_0a252caa","line":9,"in_reply_to":"9aa53dc9_fc2164fc","updated":"2015-04-16 11:25:25.000000000","message":"oups, I miss this one. Will fix in the nets patch set","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"}],"keystone/catalog/backends/sql.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"a0bfade47e24036dc84da9ddc66b245eef82fa75","unresolved":false,"context_lines":[{"line_number":32,"context_line":"    __tablename__ \u003d \u0027region\u0027"},{"line_number":33,"context_line":"    attributes \u003d [\u0027id\u0027, \u0027description\u0027, \u0027parent_region_id\u0027]"},{"line_number":34,"context_line":"    id \u003d sql.Column(sql.String(64), primary_key\u003dTrue)"},{"line_number":35,"context_line":"    description \u003d sql.Column(sql.String(255), nullable\u003dFalse)"},{"line_number":36,"context_line":"    # NOTE(jaypipes): Right now, using an adjacency list model for"},{"line_number":37,"context_line":"    #                 storing the hierarchy of regions is fine, since"},{"line_number":38,"context_line":"    #                 the API does not support any kind of querying for"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAWH%2F%2BA1g%3D","line":35,"updated":"2014-03-31 15:04:09.000000000","message":"This looks correct, but we should split 3 different changes here into 3 separate patches:\n\n1) fix boolean default values (no migrations required)\n\n2) add a \"missing\" index (it\u0027s not really missing, but rather MySQL creates it implicitly when a FK is created, so the \u0027simplest\u0027 fix would be to create this index on all backends)\n\n3) fix nullable values","commit_id":"68bba6186bf163ae524bf14d669d57defd9c0510"}],"keystone/contrib/oauth1/backends/sql.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"a0bfade47e24036dc84da9ddc66b245eef82fa75","unresolved":false,"context_lines":[{"line_number":77,"context_line":"                             nullable\u003dFalse)"},{"line_number":78,"context_line":"    expires_at \u003d sql.Column(sql.String(64), nullable\u003dTrue)"},{"line_number":79,"context_line":"    __table_args__ \u003d ("},{"line_number":80,"context_line":"        sqlalchemy.Index(\u0027access_token_consumer_id_fkey\u0027, \u0027consumer_id\u0027), )"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"    @classmethod"},{"line_number":83,"context_line":"    def from_dict(cls, user_dict):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAWH%2F%2BA1M%3D","line":80,"updated":"2014-03-31 15:04:09.000000000","message":"ditto: put this into a separate patch","commit_id":"68bba6186bf163ae524bf14d669d57defd9c0510"}],"keystone/openstack/common/db/sqlalchemy/test_migrations.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"a0bfade47e24036dc84da9ddc66b245eef82fa75","unresolved":false,"context_lines":[{"line_number":360,"context_line":""},{"line_number":361,"context_line":"        return None  # tells alembic to use the default comparison method"},{"line_number":362,"context_line":""},{"line_number":363,"context_line":"    def compare_server_default(self, ctxt, ins_col, meta_col,"},{"line_number":364,"context_line":"                               insp_def, meta_def, rendered_meta_def):"},{"line_number":365,"context_line":"        \"\"\"Compare default values between model and db table."},{"line_number":366,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAWH%2F%2BA0w%3D","line":363,"updated":"2014-03-31 15:04:09.000000000","message":"this should land to oslo-incubator first\n\n(for now, you could put this into a \u0027sync\u0027 patch to keystone)","commit_id":"68bba6186bf163ae524bf14d669d57defd9c0510"}],"keystone/tests/test_sync_migrations.py":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"2c33cafd26cb762e8a6d84367318b2a7f86c32da","unresolved":false,"context_lines":[{"line_number":18,"context_line":"import pkgutil"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"import mock"},{"line_number":21,"context_line":"from sqlalchemy import MetaData"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from keystone.common import sql"},{"line_number":24,"context_line":"from keystone.common.sql import migration_helpers"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FGRg%3D","line":21,"updated":"2014-03-20 10:12:45.000000000","message":"nit: we usually import modules rather than classes","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"77a152d4e35bc7063b1720232d8588712a7734c0","unresolved":false,"context_lines":[{"line_number":18,"context_line":"import pkgutil"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"import mock"},{"line_number":21,"context_line":"from sqlalchemy import MetaData"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"from keystone.common import sql"},{"line_number":24,"context_line":"from keystone.common.sql import migration_helpers"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FF18%3D","line":21,"in_reply_to":"AAAAWH%2F%2FGRg%3D","updated":"2014-03-20 14:27:55.000000000","message":"Done","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"2c33cafd26cb762e8a6d84367318b2a7f86c32da","unresolved":false,"context_lines":[{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def _clean_db(self):"},{"line_number":51,"context_line":"        meta \u003d self.get_metadata()"},{"line_number":52,"context_line":"        meta.reflect()"},{"line_number":53,"context_line":"        meta.drop_all()"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def _load_models(self, loaders\u003dNone):"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FGQo%3D","line":52,"updated":"2014-03-20 10:12:45.000000000","message":"I\u0027m not sure why you need reflection here, as you already have metadata defined in terms of model definitions","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"2c33cafd26cb762e8a6d84367318b2a7f86c32da","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    def _clean_db(self):"},{"line_number":51,"context_line":"        meta \u003d self.get_metadata()"},{"line_number":52,"context_line":"        meta.reflect()"},{"line_number":53,"context_line":"        meta.drop_all()"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def _load_models(self, loaders\u003dNone):"},{"line_number":56,"context_line":"        \"\"\"Sqlalchemy models initializing to a metadata instance"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FGQ4%3D","line":53,"updated":"2014-03-20 10:12:45.000000000","message":"nit: this is done in ModelsMigrationsSync","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"77a152d4e35bc7063b1720232d8588712a7734c0","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    def _clean_db(self):"},{"line_number":51,"context_line":"        meta \u003d self.get_metadata()"},{"line_number":52,"context_line":"        meta.reflect()"},{"line_number":53,"context_line":"        meta.drop_all()"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def _load_models(self, loaders\u003dNone):"},{"line_number":56,"context_line":"        \"\"\"Sqlalchemy models initializing to a metadata instance"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FEaE%3D","line":53,"in_reply_to":"AAAAWH%2F%2FGQ4%3D","updated":"2014-03-20 14:27:55.000000000","message":"Yep, I forgot it and found it today. Fixed.","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"2c33cafd26cb762e8a6d84367318b2a7f86c32da","unresolved":false,"context_lines":[{"line_number":57,"context_line":""},{"line_number":58,"context_line":"        All the models should be initialized. Therefore all the modules"},{"line_number":59,"context_line":"        which contains sqlalchemy declarative models must be imported before"},{"line_number":60,"context_line":"        the test will be runed. Models loaded in regard of name convention:"},{"line_number":61,"context_line":"        modiles contain models are named `sql.py`."},{"line_number":62,"context_line":"        \"\"\""},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FGQA%3D","line":60,"updated":"2014-03-20 10:12:45.000000000","message":"do all modules in keystone follow this naming convention?\n\nI\u0027d rather we load modules explicitly by name here instead of relying on any naming convention (this would actually allow to make this code much easier)","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"77a152d4e35bc7063b1720232d8588712a7734c0","unresolved":false,"context_lines":[{"line_number":57,"context_line":""},{"line_number":58,"context_line":"        All the models should be initialized. Therefore all the modules"},{"line_number":59,"context_line":"        which contains sqlalchemy declarative models must be imported before"},{"line_number":60,"context_line":"        the test will be runed. Models loaded in regard of name convention:"},{"line_number":61,"context_line":"        modiles contain models are named `sql.py`."},{"line_number":62,"context_line":"        \"\"\""},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FEX8%3D","line":60,"in_reply_to":"AAAAWH%2F%2FGQA%3D","updated":"2014-03-20 14:27:55.000000000","message":"Yes all the modules follow this convention. Hmmm... if we will have hardcoded  imports we are risking to loose models which can be added during further project development. So I\u0027m sure we should search and load modules accordingly to the naming convention to avoid difficult detecting bugs.","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"2c33cafd26cb762e8a6d84367318b2a7f86c32da","unresolved":false,"context_lines":[{"line_number":65,"context_line":"        level_next \u003d list(itertools.chain("},{"line_number":66,"context_line":"            *[i.iter_modules(prefix\u003di.path + \u0027/\u0027) for i in loaders]))"},{"line_number":67,"context_line":"        self._models_modules_paths |\u003d set("},{"line_number":68,"context_line":"            map(lambda i: i[0].replace(\u0027/\u0027, \u0027.\u0027),"},{"line_number":69,"context_line":"                filter(lambda x: x[0].endswith(\u0027/sql\u0027), level_next))"},{"line_number":70,"context_line":"        )"},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FGEI%3D","line":68,"updated":"2014-03-20 10:12:45.000000000","message":"(unrelated) filter + map in 99% of times look better when replaced with a list comprehension","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"77a152d4e35bc7063b1720232d8588712a7734c0","unresolved":false,"context_lines":[{"line_number":65,"context_line":"        level_next \u003d list(itertools.chain("},{"line_number":66,"context_line":"            *[i.iter_modules(prefix\u003di.path + \u0027/\u0027) for i in loaders]))"},{"line_number":67,"context_line":"        self._models_modules_paths |\u003d set("},{"line_number":68,"context_line":"            map(lambda i: i[0].replace(\u0027/\u0027, \u0027.\u0027),"},{"line_number":69,"context_line":"                filter(lambda x: x[0].endswith(\u0027/sql\u0027), level_next))"},{"line_number":70,"context_line":"        )"},{"line_number":71,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FEXg%3D","line":68,"in_reply_to":"AAAAWH%2F%2FGEI%3D","updated":"2014-03-20 14:27:55.000000000","message":"No prob.","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"2c33cafd26cb762e8a6d84367318b2a7f86c32da","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            except exception.MigrationNotProvided:"},{"line_number":88,"context_line":"                pass"},{"line_number":89,"context_line":"        else:"},{"line_number":90,"context_line":"            self.skip(\u0027There is not assigned any module to sync with.\u0027)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":93,"context_line":"        module_name \u003d \u0027.\u0027.join((self.module, self.models_path))"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FGHc%3D","line":90,"updated":"2014-03-20 10:12:45.000000000","message":"not sure why this skip is needed and module can be None","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"77a152d4e35bc7063b1720232d8588712a7734c0","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            except exception.MigrationNotProvided:"},{"line_number":88,"context_line":"                pass"},{"line_number":89,"context_line":"        else:"},{"line_number":90,"context_line":"            self.skip(\u0027There is not assigned any module to sync with.\u0027)"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":93,"context_line":"        module_name \u003d \u0027.\u0027.join((self.module, self.models_path))"}],"source_content_type":"text/x-python","patch_set":5,"id":"AAAAWH%2F%2FEUg%3D","line":90,"in_reply_to":"AAAAWH%2F%2FGHc%3D","updated":"2014-03-20 14:27:55.000000000","message":"Module can be None in the basic (particular) test case. Maybe I should make it with default value, it will rid from skipping.","commit_id":"718a9e2846d9736c8540aed837046f905e1fadec"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"cbfce484f0b577504367b4eeb82e902baf3b1c77","unresolved":false,"context_lines":[{"line_number":35,"context_line":"            \u0027.\u0027.join((self.module, self.models_path)))"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    @property"},{"line_number":38,"context_line":"    def module(self):"},{"line_number":39,"context_line":"        self.skip(\u0027There is not assigned any module to sync with.\u0027)"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def db_sync(self, engine):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2B9mo%3D","line":38,"updated":"2014-03-21 11:01:31.000000000","message":"Do we really need this property declared here?\n\nWhy not to remove \u0027Test\u0027 prefix from the name and allow subclasses to provide module attribute?","commit_id":"2cc2e6d619be78eb3b39f8622c206e1e7a350703"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"24f965044f0524029c40c1c4b34fe1801b54e912","unresolved":false,"context_lines":[{"line_number":35,"context_line":"            \u0027.\u0027.join((self.module, self.models_path)))"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    @property"},{"line_number":38,"context_line":"    def module(self):"},{"line_number":39,"context_line":"        self.skip(\u0027There is not assigned any module to sync with.\u0027)"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    def db_sync(self, engine):"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2B7ho%3D","line":38,"in_reply_to":"AAAAWH%2F%2B9mo%3D","updated":"2014-03-21 15:56:59.000000000","message":"Done","commit_id":"2cc2e6d619be78eb3b39f8622c206e1e7a350703"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"cbfce484f0b577504367b4eeb82e902baf3b1c77","unresolved":false,"context_lines":[{"line_number":49,"context_line":"            pass"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":52,"context_line":"        def filter_func(attr):"},{"line_number":53,"context_line":"            return isinstance(attr, type) and issubclass(attr, sql.ModelBase)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        tables \u003d map(lambda model: model.__table__.name, filter("}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2B9mc%3D","line":52,"updated":"2014-03-21 11:01:31.000000000","message":"IMO, you could replace this with a nice list comprehension.","commit_id":"2cc2e6d619be78eb3b39f8622c206e1e7a350703"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"cbfce484f0b577504367b4eeb82e902baf3b1c77","unresolved":false,"context_lines":[{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        tables \u003d map(lambda model: model.__table__.name, filter("},{"line_number":56,"context_line":"            filter_func, self.models_module.__dict__.itervalues()))"},{"line_number":57,"context_line":"        return name not in self.ignore_list and name in tables"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def get_engine(self):"},{"line_number":60,"context_line":"        return self.engine"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2B9mA%3D","line":57,"updated":"2014-03-21 11:01:31.000000000","message":"The caveat here is that include_object is called not only for tables, but also for columns. \n\nI.e., you silently ignore all the columns here when telling alembic, what it should compare.","commit_id":"2cc2e6d619be78eb3b39f8622c206e1e7a350703"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"24f965044f0524029c40c1c4b34fe1801b54e912","unresolved":false,"context_lines":[{"line_number":54,"context_line":""},{"line_number":55,"context_line":"        tables \u003d map(lambda model: model.__table__.name, filter("},{"line_number":56,"context_line":"            filter_func, self.models_module.__dict__.itervalues()))"},{"line_number":57,"context_line":"        return name not in self.ignore_list and name in tables"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def get_engine(self):"},{"line_number":60,"context_line":"        return self.engine"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2B9kk%3D","line":57,"in_reply_to":"AAAAWH%2F%2B9mA%3D","updated":"2014-03-21 15:56:59.000000000","message":"This is it, I think so!","commit_id":"2cc2e6d619be78eb3b39f8622c206e1e7a350703"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"cbfce484f0b577504367b4eeb82e902baf3b1c77","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def get_metadata(self):"},{"line_number":63,"context_line":"        return sql.ModelBase.metadata"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"class TestSyncTrust(TestSyncModelsWithMigrations):"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    module \u003d \u0027keystone.trust\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2B9ls%3D","line":65,"updated":"2014-03-21 11:01:31.000000000","message":"Shouldn\u0027t we also have a test case for core models?","commit_id":"2cc2e6d619be78eb3b39f8622c206e1e7a350703"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"24f965044f0524029c40c1c4b34fe1801b54e912","unresolved":false,"context_lines":[{"line_number":62,"context_line":"    def get_metadata(self):"},{"line_number":63,"context_line":"        return sql.ModelBase.metadata"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"class TestSyncTrust(TestSyncModelsWithMigrations):"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    module \u003d \u0027keystone.trust\u0027"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAAWH%2F%2B9j8%3D","line":65,"in_reply_to":"AAAAWH%2F%2B9ls%3D","updated":"2014-03-21 15:56:59.000000000","message":"Unfortunately, there is no core models.","commit_id":"2cc2e6d619be78eb3b39f8622c206e1e7a350703"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"1c12efde860ca5378734333ce1c9e05f52a14a3b","unresolved":false,"context_lines":[{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    def setUp(self):"},{"line_number":37,"context_line":"        super(SyncModelsWithMigrations, self).setUp()"},{"line_number":38,"context_line":"        if not self.module:"},{"line_number":39,"context_line":"            self.skip(\u0027There is not assigned any module to sync with.\u0027)"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"        self.models_module \u003d importlib.import_module("}],"source_content_type":"text/x-python","patch_set":8,"id":"AAAAWH%2F%2B7Kg%3D","line":38,"updated":"2014-03-21 16:44:33.000000000","message":"It seems to be impossible to rid test skipping in the base test case. The test which is declared in the parent test case, named `test_models_sync`, so it is still appropriate to naming convention of test runners. I cant set default module because there is no core module with models in Keystone. If I will choose random module as default it will be weird.","commit_id":"2ba74840edf1fbb5279e89229d7e818d1c2b13a9"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"720025d8198021931623237854bc051c027be798","unresolved":false,"context_lines":[{"line_number":55,"context_line":"                  if inspect.isclass(m) and issubclass(m, sql.ModelBase)]"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"},{"line_number":58,"context_line":"            return name not in self.ignore_list and name in models"},{"line_number":59,"context_line":"        elif type_ \u003d\u003d \u0027column\u0027:"},{"line_number":60,"context_line":"            return True"},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"AAAAWH%2F%2B7Cw%3D","line":58,"updated":"2014-03-21 17:00:13.000000000","message":"I doubt that this is really correct. If some table existing in DB is absent in the model we will ignore it.","commit_id":"de9dc78486f5e0a9fd2097d647ce02fcef95f13e"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"d548d83c4eca63c8d104e679a914317eb84b5d81","unresolved":false,"context_lines":[{"line_number":51,"context_line":"               \u0027assignment\u0027,"},{"line_number":52,"context_line":"               \u0027credential\u0027,"},{"line_number":53,"context_line":"               \u0027policy\u0027,"},{"line_number":54,"context_line":"               \u0027catalog\u0027,"},{"line_number":55,"context_line":"               \u0027catalog\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BmGs%3D","line":54,"updated":"2014-03-25 17:13:03.000000000","message":"typo?","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c14649d2a1ca0e0e8b450ac609f2dd447080e0a","unresolved":false,"context_lines":[{"line_number":51,"context_line":"               \u0027assignment\u0027,"},{"line_number":52,"context_line":"               \u0027credential\u0027,"},{"line_number":53,"context_line":"               \u0027policy\u0027,"},{"line_number":54,"context_line":"               \u0027catalog\u0027,"},{"line_number":55,"context_line":"               \u0027catalog\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BhM8%3D","line":54,"in_reply_to":"AAAAWH%2F%2BmGs%3D","updated":"2014-06-17 16:20:06.000000000","message":"Yes...","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"d548d83c4eca63c8d104e679a914317eb84b5d81","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        \"\"\""},{"line_number":61,"context_line":"        for bc in cls.backends:"},{"line_number":62,"context_line":"            bc_name \u003d bc.__name__.replace(\u0027OpportunisticTestCase\u0027, \u0027\u0027)"},{"line_number":63,"context_line":"            nc_bases \u003d list(bases)"},{"line_number":64,"context_line":"            nc_bases.insert(0, bc)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"            for module in cls.modules:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BmBc%3D","line":63,"updated":"2014-03-25 17:13:03.000000000","message":"nc_bases \u003d (bc, ) + bases ?","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c14649d2a1ca0e0e8b450ac609f2dd447080e0a","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        \"\"\""},{"line_number":61,"context_line":"        for bc in cls.backends:"},{"line_number":62,"context_line":"            bc_name \u003d bc.__name__.replace(\u0027OpportunisticTestCase\u0027, \u0027\u0027)"},{"line_number":63,"context_line":"            nc_bases \u003d list(bases)"},{"line_number":64,"context_line":"            nc_bases.insert(0, bc)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"            for module in cls.modules:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2Bgv8%3D","line":63,"in_reply_to":"AAAAWH%2F%2BmBc%3D","updated":"2014-06-17 16:20:06.000000000","message":"Done","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"d548d83c4eca63c8d104e679a914317eb84b5d81","unresolved":false,"context_lines":[{"line_number":66,"context_line":"            for module in cls.modules:"},{"line_number":67,"context_line":"                md_name \u003d module.split(\u0027.\u0027)[-1].capitalize()"},{"line_number":68,"context_line":"                name \u003d \u0027\u0027.join((\u0027Test\u0027, bc_name, md_name))"},{"line_number":69,"context_line":"                nc_attrs \u003d copy.copy(attrs)"},{"line_number":70,"context_line":"                nc_attrs[\u0027module\u0027] \u003d \u0027.\u0027.join((\u0027keystone\u0027, module))"},{"line_number":71,"context_line":"                yield (name, type(name, tuple(nc_bases), attrs))"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BmBk%3D","line":69,"updated":"2014-03-25 17:13:03.000000000","message":"a shallow copy of a dict can be created by the means of dict.copy() method","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"d548d83c4eca63c8d104e679a914317eb84b5d81","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                name \u003d \u0027\u0027.join((\u0027Test\u0027, bc_name, md_name))"},{"line_number":69,"context_line":"                nc_attrs \u003d copy.copy(attrs)"},{"line_number":70,"context_line":"                nc_attrs[\u0027module\u0027] \u003d \u0027.\u0027.join((\u0027keystone\u0027, module))"},{"line_number":71,"context_line":"                yield (name, type(name, tuple(nc_bases), attrs))"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def __new__(cls, name, bases, attrs):"},{"line_number":74,"context_line":"        \"\"\"Push all created modules to a global modules namespace"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BmGo%3D","line":71,"updated":"2014-03-25 17:13:03.000000000","message":"you must have meant nc_attrs here","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c14649d2a1ca0e0e8b450ac609f2dd447080e0a","unresolved":false,"context_lines":[{"line_number":68,"context_line":"                name \u003d \u0027\u0027.join((\u0027Test\u0027, bc_name, md_name))"},{"line_number":69,"context_line":"                nc_attrs \u003d copy.copy(attrs)"},{"line_number":70,"context_line":"                nc_attrs[\u0027module\u0027] \u003d \u0027.\u0027.join((\u0027keystone\u0027, module))"},{"line_number":71,"context_line":"                yield (name, type(name, tuple(nc_bases), attrs))"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    def __new__(cls, name, bases, attrs):"},{"line_number":74,"context_line":"        \"\"\"Push all created modules to a global modules namespace"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BhMs%3D","line":71,"in_reply_to":"AAAAWH%2F%2BmGo%3D","updated":"2014-06-17 16:20:06.000000000","message":"Sure.","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"d548d83c4eca63c8d104e679a914317eb84b5d81","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        The class itself does not contain any tests."},{"line_number":77,"context_line":"        \"\"\""},{"line_number":78,"context_line":"        globals().update(dict(cls._produce(bases, attrs)))"},{"line_number":79,"context_line":"        return type(name, tuple(), {})"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BmDY%3D","line":78,"updated":"2014-03-25 17:13:03.000000000","message":"explicit for loop would be more readable, IMO","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c14649d2a1ca0e0e8b450ac609f2dd447080e0a","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        The class itself does not contain any tests."},{"line_number":77,"context_line":"        \"\"\""},{"line_number":78,"context_line":"        globals().update(dict(cls._produce(bases, attrs)))"},{"line_number":79,"context_line":"        return type(name, tuple(), {})"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BhH0%3D","line":78,"in_reply_to":"AAAAWH%2F%2BmDY%3D","updated":"2014-06-17 16:20:06.000000000","message":"I have two motivations to leave it as is. I have started from explicit for loop, and decomposed design looks better to me. And if we implement an explicit loop here, we need to call `globals()` every single iteration, I don\u0027t like it too. But if you insist, I\u0027m ok with explicit loop here.","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"d548d83c4eca63c8d104e679a914317eb84b5d81","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        return type(name, tuple(), {})"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"class LoaderSynchronizer(test_base.DbTestCase):"},{"line_number":83,"context_line":"    \"\"\"Mixin intended to override ModelsMigrationsSync methods.\"\"\""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    module \u003d None"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BmFs%3D","line":82,"updated":"2014-03-25 17:13:03.000000000","message":"we could use metaclass for this class instead","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c14649d2a1ca0e0e8b450ac609f2dd447080e0a","unresolved":false,"context_lines":[{"line_number":79,"context_line":"        return type(name, tuple(), {})"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"class LoaderSynchronizer(test_base.DbTestCase):"},{"line_number":83,"context_line":"    \"\"\"Mixin intended to override ModelsMigrationsSync methods.\"\"\""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    module \u003d None"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BhKs%3D","line":82,"in_reply_to":"AAAAWH%2F%2BmFs%3D","updated":"2014-06-17 16:20:06.000000000","message":"There is a problem with test runner. I haven\u0027t found how is it happening yet, but if metaclass used directly for this class, generated classes have wrong `self` argument in methods. I will debug this behavior and fix it or prove that the approach is the only possible.","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"d548d83c4eca63c8d104e679a914317eb84b5d81","unresolved":false,"context_lines":[{"line_number":119,"context_line":""},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"@six.add_metaclass(RealBackends)"},{"line_number":122,"context_line":"class TestSyncModelsMigrations(LoaderSynchronizer,"},{"line_number":123,"context_line":"                               test_migrations.ModelsMigrationsSync):"},{"line_number":124,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BmGM%3D","line":122,"updated":"2014-03-25 17:13:03.000000000","message":"Do we need this class at all?","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c14649d2a1ca0e0e8b450ac609f2dd447080e0a","unresolved":false,"context_lines":[{"line_number":119,"context_line":""},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"@six.add_metaclass(RealBackends)"},{"line_number":122,"context_line":"class TestSyncModelsMigrations(LoaderSynchronizer,"},{"line_number":123,"context_line":"                               test_migrations.ModelsMigrationsSync):"},{"line_number":124,"context_line":"    pass"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAAWH%2F%2BhFk%3D","line":122,"in_reply_to":"AAAAWH%2F%2BmGM%3D","updated":"2014-06-17 16:20:06.000000000","message":"Please see previous comment. I hope we don\u0027t. I\u0027ll try to fix it today.","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"a0bfade47e24036dc84da9ddc66b245eef82fa75","unresolved":false,"context_lines":[{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"},{"line_number":110,"context_line":"            return name not in self.ignore_list and name in models"},{"line_number":111,"context_line":"        elif type_ \u003d\u003d \u0027column\u0027:"},{"line_number":112,"context_line":"            return True"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    def get_engine(self):"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAAWH%2F%2BAyU%3D","line":111,"updated":"2014-03-31 15:04:09.000000000","message":"include_object() should return True by default","commit_id":"68bba6186bf163ae524bf14d669d57defd9c0510"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ba67960ba4963f90500e1d6d512468bd95ea718e","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    Attributes"},{"line_number":34,"context_line":"    ::backends: basic test cases to use real backends for testing."},{"line_number":35,"context_line":"    ::modules: relative paths to modules containing sqlalchemy models."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    To test all the modules with all the backends necessary to implement amount"},{"line_number":38,"context_line":"    of almost identical test cases. The meta calss produces all neccessary"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9xTA%3D","line":35,"updated":"2014-04-02 08:56:05.000000000","message":"Maybe it makes sense to make those absolute? (e.g. if for some reason models won\u0027t be stored under backends/sql dir)","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"f8b36103d8a76e69d7bea73101041cf4f1df131b","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":"    Attributes"},{"line_number":34,"context_line":"    ::backends: basic test cases to use real backends for testing."},{"line_number":35,"context_line":"    ::modules: relative paths to modules containing sqlalchemy models."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    To test all the modules with all the backends necessary to implement amount"},{"line_number":38,"context_line":"    of almost identical test cases. The meta calss produces all neccessary"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9xDo%3D","line":35,"in_reply_to":"AAAAWH%2F9xTA%3D","updated":"2014-04-02 10:25:25.000000000","message":"It could be. But the problem with a path different from backends/sql is stipulated in LoaderSynchronizer class with attribute models_path, which can be easily overrided in subclasses. So casting to an absolute path could be done at any step, if it really necessary.","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ba67960ba4963f90500e1d6d512468bd95ea718e","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    ::backends: basic test cases to use real backends for testing."},{"line_number":35,"context_line":"    ::modules: relative paths to modules containing sqlalchemy models."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    To test all the modules with all the backends necessary to implement amount"},{"line_number":38,"context_line":"    of almost identical test cases. The meta calss produces all neccessary"},{"line_number":39,"context_line":"    test cases and puts it to a global module namespace. This approach helps"},{"line_number":40,"context_line":"    to keep the module DRY."}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9xSM%3D","line":37,"updated":"2014-04-02 08:56:05.000000000","message":"nit: it is necessary\n\ns/amount/a number/","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"f8b36103d8a76e69d7bea73101041cf4f1df131b","unresolved":false,"context_lines":[{"line_number":34,"context_line":"    ::backends: basic test cases to use real backends for testing."},{"line_number":35,"context_line":"    ::modules: relative paths to modules containing sqlalchemy models."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    To test all the modules with all the backends necessary to implement amount"},{"line_number":38,"context_line":"    of almost identical test cases. The meta calss produces all neccessary"},{"line_number":39,"context_line":"    test cases and puts it to a global module namespace. This approach helps"},{"line_number":40,"context_line":"    to keep the module DRY."}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9wms%3D","line":37,"in_reply_to":"AAAAWH%2F9xSM%3D","updated":"2014-04-02 10:25:25.000000000","message":"Done","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ba67960ba4963f90500e1d6d512468bd95ea718e","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    ::modules: relative paths to modules containing sqlalchemy models."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    To test all the modules with all the backends necessary to implement amount"},{"line_number":38,"context_line":"    of almost identical test cases. The meta calss produces all neccessary"},{"line_number":39,"context_line":"    test cases and puts it to a global module namespace. This approach helps"},{"line_number":40,"context_line":"    to keep the module DRY."},{"line_number":41,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9xSQ%3D","line":38,"updated":"2014-04-02 08:56:05.000000000","message":"nit: class","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"f8b36103d8a76e69d7bea73101041cf4f1df131b","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    ::modules: relative paths to modules containing sqlalchemy models."},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    To test all the modules with all the backends necessary to implement amount"},{"line_number":38,"context_line":"    of almost identical test cases. The meta calss produces all neccessary"},{"line_number":39,"context_line":"    test cases and puts it to a global module namespace. This approach helps"},{"line_number":40,"context_line":"    to keep the module DRY."},{"line_number":41,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9wmk%3D","line":38,"in_reply_to":"AAAAWH%2F9xSQ%3D","updated":"2014-04-02 10:25:25.000000000","message":"Done","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ba67960ba4963f90500e1d6d512468bd95ea718e","unresolved":false,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        The class itself does not contain any tests."},{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        globals().update(dict(cls._produce(bases, attrs)))"},{"line_number":78,"context_line":"        return type(name, tuple(), {})"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9xfY%3D","line":77,"updated":"2014-04-02 08:56:05.000000000","message":"I\u0027m not sure, if there is a profit in yielding values from _produce() method, if you still need to create a dictionary instance here. I\u0027d rather see this implemented as simply as possible: no _produce() method, but a plain for loop in __new__() instead, adding classes to the global scope","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"f8b36103d8a76e69d7bea73101041cf4f1df131b","unresolved":false,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        The class itself does not contain any tests."},{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        globals().update(dict(cls._produce(bases, attrs)))"},{"line_number":78,"context_line":"        return type(name, tuple(), {})"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9wjM%3D","line":77,"in_reply_to":"AAAAWH%2F9xfY%3D","updated":"2014-04-02 10:25:25.000000000","message":"No problem to squash it into the one method. It looks ugly to me, but it is my own opinion. I\u0027m not sure is it possible to make workable produced classes without patching the global scope. I\u0027ll try it.","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ba67960ba4963f90500e1d6d512468bd95ea718e","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        return type(name, tuple(), {})"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"class LoaderSynchronizer(test_base.DbTestCase):"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    \"\"\"Mixin intended to override ModelsMigrationsSync methods.\"\"\""},{"line_number":84,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9xYU%3D","line":81,"updated":"2014-04-02 08:56:05.000000000","message":"I\u0027m not sure why this class is called LoaderSynchronizer :)","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"f8b36103d8a76e69d7bea73101041cf4f1df131b","unresolved":false,"context_lines":[{"line_number":78,"context_line":"        return type(name, tuple(), {})"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"class LoaderSynchronizer(test_base.DbTestCase):"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    \"\"\"Mixin intended to override ModelsMigrationsSync methods.\"\"\""},{"line_number":84,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9wf0%3D","line":81,"in_reply_to":"AAAAWH%2F9xYU%3D","updated":"2014-04-02 10:25:25.000000000","message":"I figured that the class loads module (in setUp) and syncs migrations. But I mess that the class overrides several other methods. I\u0027ll thinking about more common name.","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ba67960ba4963f90500e1d6d512468bd95ea718e","unresolved":false,"context_lines":[{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    module \u003d None"},{"line_number":86,"context_line":"    models_path \u003d \u0027backends.sql\u0027"},{"line_number":87,"context_line":"    ignore_list \u003d [\u0027migrate_version\u0027, ]"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def setUp(self):"},{"line_number":90,"context_line":"        super(LoaderSynchronizer, self).setUp()"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9xiQ%3D","line":87,"updated":"2014-04-02 08:56:05.000000000","message":"nit: for lists with one element you can safely omit the comma","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"f8b36103d8a76e69d7bea73101041cf4f1df131b","unresolved":false,"context_lines":[{"line_number":84,"context_line":""},{"line_number":85,"context_line":"    module \u003d None"},{"line_number":86,"context_line":"    models_path \u003d \u0027backends.sql\u0027"},{"line_number":87,"context_line":"    ignore_list \u003d [\u0027migrate_version\u0027, ]"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def setUp(self):"},{"line_number":90,"context_line":"        super(LoaderSynchronizer, self).setUp()"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9wfw%3D","line":87,"in_reply_to":"AAAAWH%2F9xiQ%3D","updated":"2014-04-02 10:25:25.000000000","message":"Done","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"ba67960ba4963f90500e1d6d512468bd95ea718e","unresolved":false,"context_lines":[{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":105,"context_line":"        models \u003d [m.__tablename__"},{"line_number":106,"context_line":"                  for m in self.models_module.__dict__.itervalues()"},{"line_number":107,"context_line":"                  if inspect.isclass(m) and issubclass(m, sql.ModelBase)]"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9xhw%3D","line":106,"updated":"2014-04-02 08:56:05.000000000","message":"nit: for the sake of Python 3 compatibility, please use values() instead of itervalues()","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"f8b36103d8a76e69d7bea73101041cf4f1df131b","unresolved":false,"context_lines":[{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":105,"context_line":"        models \u003d [m.__tablename__"},{"line_number":106,"context_line":"                  for m in self.models_module.__dict__.itervalues()"},{"line_number":107,"context_line":"                  if inspect.isclass(m) and issubclass(m, sql.ModelBase)]"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAAWH%2F9wfs%3D","line":106,"in_reply_to":"AAAAWH%2F9xhw%3D","updated":"2014-04-02 10:25:25.000000000","message":"Done","commit_id":"92d7eedbc830a3e3dbc5dae02c47acdfa1c1d332"},{"author":{"_account_id":11717,"name":"Ryan Oshima","email":"ryan.oshima@hp.com","username":"RyanOshima"},"change_message_id":"a01ef0a6ba89b05e2774175405021d7467772818","unresolved":false,"context_lines":[{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    To test all the modules with all the backends necessary to implement a"},{"line_number":38,"context_line":"    number of almost identical test cases. The meta class produces all"},{"line_number":39,"context_line":"    neccessary test cases and puts it to a global module namespace. This"},{"line_number":40,"context_line":"    approach helps to keep the module DRY."},{"line_number":41,"context_line":"    \"\"\""},{"line_number":42,"context_line":""}],"source_content_type":"text/x-python","patch_set":55,"id":"1ae5cdf2_1e51eed8","line":39,"updated":"2014-06-19 16:13:32.000000000","message":"necessary*","commit_id":"fb09f87f69d31c30ffc35caa4229a1bdf98d1fe4"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"307212593cef40bed4840b14e19fdca455d73c6f","unresolved":false,"context_lines":[{"line_number":36,"context_line":""},{"line_number":37,"context_line":"    To test all the modules with all the backends necessary to implement a"},{"line_number":38,"context_line":"    number of almost identical test cases. The meta class produces all"},{"line_number":39,"context_line":"    neccessary test cases and puts it to a global module namespace. This"},{"line_number":40,"context_line":"    approach helps to keep the module DRY."},{"line_number":41,"context_line":"    \"\"\""},{"line_number":42,"context_line":""}],"source_content_type":"text/x-python","patch_set":55,"id":"1ae5cdf2_74f3f372","line":39,"in_reply_to":"1ae5cdf2_1e51eed8","updated":"2014-06-19 17:15:06.000000000","message":"Thanks! I\u0027m sorry, I saw your comment after I uploaded patch set #56.","commit_id":"fb09f87f69d31c30ffc35caa4229a1bdf98d1fe4"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"5fa0ee7f887eef3ba1e7c21b5a1f19a2e0f9b3c6","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        \u0027identity\u0027,"},{"line_number":48,"context_line":"        \u0027contrib.oauth1\u0027,"},{"line_number":49,"context_line":"        \u0027contrib.federation\u0027,"},{"line_number":50,"context_line":"        \u0027contrib.endpoint_filter\u0027,"},{"line_number":51,"context_line":"        \u0027token\u0027,"},{"line_number":52,"context_line":"        \u0027assignment\u0027,"},{"line_number":53,"context_line":"        \u0027credential\u0027,"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_e5b904ed","line":50,"updated":"2014-08-03 23:31:17.000000000","message":"shouldn\u0027t this list also contain contrib.revoke?","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"36212b40eb561c9a285f550e42bc857e0820bc3b","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        \u0027identity\u0027,"},{"line_number":48,"context_line":"        \u0027contrib.oauth1\u0027,"},{"line_number":49,"context_line":"        \u0027contrib.federation\u0027,"},{"line_number":50,"context_line":"        \u0027contrib.endpoint_filter\u0027,"},{"line_number":51,"context_line":"        \u0027token\u0027,"},{"line_number":52,"context_line":"        \u0027assignment\u0027,"},{"line_number":53,"context_line":"        \u0027credential\u0027,"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_68722113","line":50,"in_reply_to":"baada198_e5b904ed","updated":"2014-08-04 10:00:35.000000000","message":"Done","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"5fa0ee7f887eef3ba1e7c21b5a1f19a2e0f9b3c6","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        \u0027assignment\u0027,"},{"line_number":53,"context_line":"        \u0027credential\u0027,"},{"line_number":54,"context_line":"        \u0027policy\u0027,"},{"line_number":55,"context_line":"        \u0027catalog\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def __new__(cls, name, bases, attrs):"},{"line_number":58,"context_line":"        \"\"\"Push all created modules to a global modules namespace"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_a5ec6cf5","line":55,"updated":"2014-08-03 23:31:17.000000000","message":"might as well put these in alphabetical order.","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"36212b40eb561c9a285f550e42bc857e0820bc3b","unresolved":false,"context_lines":[{"line_number":52,"context_line":"        \u0027assignment\u0027,"},{"line_number":53,"context_line":"        \u0027credential\u0027,"},{"line_number":54,"context_line":"        \u0027policy\u0027,"},{"line_number":55,"context_line":"        \u0027catalog\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def __new__(cls, name, bases, attrs):"},{"line_number":58,"context_line":"        \"\"\"Push all created modules to a global modules namespace"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_688ea1d2","line":55,"in_reply_to":"baada198_a5ec6cf5","updated":"2014-08-04 10:00:35.000000000","message":"Done","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"5fa0ee7f887eef3ba1e7c21b5a1f19a2e0f9b3c6","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    def __new__(cls, name, bases, attrs):"},{"line_number":58,"context_line":"        \"\"\"Push all created modules to a global modules namespace"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        Uses all real backends for all modules containing sqlalchemy models."},{"line_number":61,"context_line":"        The class itself does not contain any tests."},{"line_number":62,"context_line":"        \"\"\""},{"line_number":63,"context_line":"        for bc in cls.backends:"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_45b39008","line":60,"updated":"2014-08-03 23:31:17.000000000","message":"what\u0027s a real backend?","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"36212b40eb561c9a285f550e42bc857e0820bc3b","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    def __new__(cls, name, bases, attrs):"},{"line_number":58,"context_line":"        \"\"\"Push all created modules to a global modules namespace"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        Uses all real backends for all modules containing sqlalchemy models."},{"line_number":61,"context_line":"        The class itself does not contain any tests."},{"line_number":62,"context_line":"        \"\"\""},{"line_number":63,"context_line":"        for bc in cls.backends:"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_48aabd1a","line":60,"in_reply_to":"baada198_45b39008","updated":"2014-08-04 10:00:35.000000000","message":"Done","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"5fa0ee7f887eef3ba1e7c21b5a1f19a2e0f9b3c6","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"class ModelsMigrationsComparer(test_base.DbTestCase):"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    \"\"\"Mixin intended to override ModelsMigrationsSync methods.\"\"\""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    module \u003d None"},{"line_number":81,"context_line":"    models_path \u003d \u0027backends.sql\u0027"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_85c84876","line":78,"updated":"2014-08-03 23:31:17.000000000","message":"replace \"ModelsMigrationsSync\" with \"test_migrations.ModelsMigrationsSync\" so we know what it is.","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"36212b40eb561c9a285f550e42bc857e0820bc3b","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"class ModelsMigrationsComparer(test_base.DbTestCase):"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    \"\"\"Mixin intended to override ModelsMigrationsSync methods.\"\"\""},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    module \u003d None"},{"line_number":81,"context_line":"    models_path \u003d \u0027backends.sql\u0027"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_887775d0","line":78,"in_reply_to":"baada198_85c84876","updated":"2014-08-04 10:00:35.000000000","message":"Done","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"5fa0ee7f887eef3ba1e7c21b5a1f19a2e0f9b3c6","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            \u0027.\u0027.join((self.module, self.models_path)))"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def db_sync(self, engine):"},{"line_number":90,"context_line":"        migration.db_sync(engine\u003dengine,"},{"line_number":91,"context_line":"                          abs_path\u003dmigration_helpers.find_migrate_repo(),"},{"line_number":92,"context_line":"                          init_version\u003dsql.migrate_repo.DB_INIT_VERSION)"},{"line_number":93,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_65941444","line":90,"updated":"2014-08-03 23:31:17.000000000","message":"why is this db_sync done? Add a comment.","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"36212b40eb561c9a285f550e42bc857e0820bc3b","unresolved":false,"context_lines":[{"line_number":87,"context_line":"            \u0027.\u0027.join((self.module, self.models_path)))"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def db_sync(self, engine):"},{"line_number":90,"context_line":"        migration.db_sync(engine\u003dengine,"},{"line_number":91,"context_line":"                          abs_path\u003dmigration_helpers.find_migrate_repo(),"},{"line_number":92,"context_line":"                          init_version\u003dsql.migrate_repo.DB_INIT_VERSION)"},{"line_number":93,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_962b1232","line":90,"in_reply_to":"baada198_65941444","updated":"2014-08-04 10:00:35.000000000","message":"Done","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"5fa0ee7f887eef3ba1e7c21b5a1f19a2e0f9b3c6","unresolved":false,"context_lines":[{"line_number":96,"context_line":"            migration.db_version_control(engine, abs_path)"},{"line_number":97,"context_line":"            migration.db_sync(engine, abs_path)"},{"line_number":98,"context_line":"        except exception.MigrationNotProvided:"},{"line_number":99,"context_line":"            pass"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":102,"context_line":"        models \u003d [m.__tablename__"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_e5d2e432","line":99,"updated":"2014-08-03 23:31:17.000000000","message":"for a test, I\u0027d rather the test failed if an exception happens rather than passing. This should hard-code those modules that are known to not have migrations and if it\u0027s not in the list then reraise and fail.","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"36212b40eb561c9a285f550e42bc857e0820bc3b","unresolved":false,"context_lines":[{"line_number":96,"context_line":"            migration.db_version_control(engine, abs_path)"},{"line_number":97,"context_line":"            migration.db_sync(engine, abs_path)"},{"line_number":98,"context_line":"        except exception.MigrationNotProvided:"},{"line_number":99,"context_line":"            pass"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":102,"context_line":"        models \u003d [m.__tablename__"}],"source_content_type":"text/x-python","patch_set":61,"id":"baada198_88fcd50e","line":99,"in_reply_to":"baada198_e5d2e432","updated":"2014-08-04 10:00:35.000000000","message":"Done","commit_id":"f21411d4732e030826d7618855416323d3402bd6"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"4fdd11bbbc890b5fa872f1d44166fab4c3df2116","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            \u0027.\u0027.join((self.module, self.models_path)))"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def db_sync(self, engine):"},{"line_number":91,"context_line":"        # NOTE (I159): the migrations are applied for further comparaison with"},{"line_number":92,"context_line":"        # the models."},{"line_number":93,"context_line":"        migration.db_sync(engine\u003dengine,"},{"line_number":94,"context_line":"                          abs_path\u003dmigration_helpers.find_migrate_repo(),"}],"source_content_type":"text/x-python","patch_set":64,"id":"7ac7a964_e84a4282","line":91,"updated":"2014-08-15 01:11:57.000000000","message":"(nit) change \"comparaison\" to \"comparison\"","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c13930943fde05a3515ab53174cd12d2fc04775","unresolved":false,"context_lines":[{"line_number":88,"context_line":"            \u0027.\u0027.join((self.module, self.models_path)))"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    def db_sync(self, engine):"},{"line_number":91,"context_line":"        # NOTE (I159): the migrations are applied for further comparaison with"},{"line_number":92,"context_line":"        # the models."},{"line_number":93,"context_line":"        migration.db_sync(engine\u003dengine,"},{"line_number":94,"context_line":"                          abs_path\u003dmigration_helpers.find_migrate_repo(),"}],"source_content_type":"text/x-python","patch_set":64,"id":"1abeadc6_a18f8774","line":91,"in_reply_to":"7ac7a964_e84a4282","updated":"2014-08-26 11:41:38.000000000","message":"Done","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"4fdd11bbbc890b5fa872f1d44166fab4c3df2116","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        migration.db_version_control(engine, abs_path)"},{"line_number":99,"context_line":"        migration.db_sync(engine, abs_path)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":102,"context_line":"        models \u003d [m.__tablename__"},{"line_number":103,"context_line":"                  for m in self.models_module.__dict__.values()"},{"line_number":104,"context_line":"                  if inspect.isclass(m) and issubclass(m, sql.ModelBase)]"}],"source_content_type":"text/x-python","patch_set":64,"id":"7ac7a964_a334ebde","line":101,"updated":"2014-08-15 01:11:57.000000000","message":"I don\u0027t see this used anywhere. What\u0027s it supposed to do? Add a docstring.","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c13930943fde05a3515ab53174cd12d2fc04775","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        migration.db_version_control(engine, abs_path)"},{"line_number":99,"context_line":"        migration.db_sync(engine, abs_path)"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":102,"context_line":"        models \u003d [m.__tablename__"},{"line_number":103,"context_line":"                  for m in self.models_module.__dict__.values()"},{"line_number":104,"context_line":"                  if inspect.isclass(m) and issubclass(m, sql.ModelBase)]"}],"source_content_type":"text/x-python","patch_set":64,"id":"1abeadc6_dced4690","line":101,"in_reply_to":"7ac7a964_a334ebde","updated":"2014-08-26 11:41:38.000000000","message":"This method is overrided method from oslo.db.sqlalchemy.test_migrations.ModelsMigrationsSync, as described in the docstring of this mixin. https://github.com/openstack/oslo.db/blob/master/oslo/db/sqlalchemy/test_migrations.py#L296\n\n\nhttps://github.com/openstack/oslo.db/blob/master/oslo/db/sqlalchemy/test_migrations.py#L406","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"4fdd11bbbc890b5fa872f1d44166fab4c3df2116","unresolved":false,"context_lines":[{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"},{"line_number":107,"context_line":"            return name not in self.ignore_list and name in models"},{"line_number":108,"context_line":"        return True"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def get_engine(self):"},{"line_number":111,"context_line":"        return self.engine"}],"source_content_type":"text/x-python","patch_set":64,"id":"7ac7a964_23a61b11","line":108,"updated":"2014-08-15 01:11:57.000000000","message":"should just `return True if type_ !\u003d \u0027table\u0027` at the beginning of the function then don\u0027t have to create the models list unnecessarily.","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c13930943fde05a3515ab53174cd12d2fc04775","unresolved":false,"context_lines":[{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"},{"line_number":107,"context_line":"            return name not in self.ignore_list and name in models"},{"line_number":108,"context_line":"        return True"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def get_engine(self):"},{"line_number":111,"context_line":"        return self.engine"}],"source_content_type":"text/x-python","patch_set":64,"id":"1abeadc6_bc7deab3","line":108,"in_reply_to":"7ac7a964_23a61b11","updated":"2014-08-26 11:41:38.000000000","message":"It is not so easy, sometimes we need to ignore some tables. \n\n\"Return True for objects that should be compared.\" as described in the original method docstring, not all tables in a database.","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"4fdd11bbbc890b5fa872f1d44166fab4c3df2116","unresolved":false,"context_lines":[{"line_number":107,"context_line":"            return name not in self.ignore_list and name in models"},{"line_number":108,"context_line":"        return True"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def get_engine(self):"},{"line_number":111,"context_line":"        return self.engine"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def get_metadata(self):"}],"source_content_type":"text/x-python","patch_set":64,"id":"7ac7a964_63af33e4","line":110,"updated":"2014-08-15 01:11:57.000000000","message":"This doesn\u0027t seem useful. Why don\u0027t I just use self.engine?","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c13930943fde05a3515ab53174cd12d2fc04775","unresolved":false,"context_lines":[{"line_number":107,"context_line":"            return name not in self.ignore_list and name in models"},{"line_number":108,"context_line":"        return True"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"    def get_engine(self):"},{"line_number":111,"context_line":"        return self.engine"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def get_metadata(self):"}],"source_content_type":"text/x-python","patch_set":64,"id":"1abeadc6_d7cfe1b1","line":110,"in_reply_to":"7ac7a964_63af33e4","updated":"2014-08-26 11:41:38.000000000","message":"This is an overrided abstract method https://github.com/openstack/oslo.db/blob/master/oslo/db/sqlalchemy/test_migrations.py#L279\n\nWe need it because the base mixin doesn\u0027t know what the engine needs every particular test case in a projects. So to avoid congestion of the __init__ method, we prepared interface to provide an engine. Keystone is pretty plain case, so it looks strange, but in common case we need it.","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"4fdd11bbbc890b5fa872f1d44166fab4c3df2116","unresolved":false,"context_lines":[{"line_number":110,"context_line":"    def get_engine(self):"},{"line_number":111,"context_line":"        return self.engine"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def get_metadata(self):"},{"line_number":114,"context_line":"        return sql.ModelBase.metadata"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":""}],"source_content_type":"text/x-python","patch_set":64,"id":"7ac7a964_83ac4fef","line":113,"updated":"2014-08-15 01:11:57.000000000","message":"This doesn\u0027t seem useful. Why don\u0027t I just use sql.ModelBase.metadata?","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"3c13930943fde05a3515ab53174cd12d2fc04775","unresolved":false,"context_lines":[{"line_number":110,"context_line":"    def get_engine(self):"},{"line_number":111,"context_line":"        return self.engine"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    def get_metadata(self):"},{"line_number":114,"context_line":"        return sql.ModelBase.metadata"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":""}],"source_content_type":"text/x-python","patch_set":64,"id":"1abeadc6_77c0cd7c","line":113,"in_reply_to":"7ac7a964_83ac4fef","updated":"2014-08-26 11:41:38.000000000","message":"Same description as previous one.","commit_id":"1f187327ec8bf644ca03a77df34c9096ec4406c3"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"591aa7c57f94ff1642af55b3f2231c8edf7593b0","unresolved":false,"context_lines":[{"line_number":25,"context_line":"from keystone.common.sql import migration_helpers"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class RealBackends(object):"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    \"\"\"Meta class produces test cases for all required modules and backends"},{"line_number":31,"context_line":""}],"source_content_type":"text/x-python","patch_set":66,"id":"da9df570_077021a4","line":28,"updated":"2014-09-24 16:00:27.000000000","message":"As I recall, metaclasses should be \u0027type\u0027 not \u0027object\u0027","commit_id":"5ab6ed339f0608d5366d863fcde32c9a475702aa"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"49216081e0b401df8b7f7ae9c563b1787f8ea111","unresolved":false,"context_lines":[{"line_number":25,"context_line":"from keystone.common.sql import migration_helpers"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class RealBackends(object):"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    \"\"\"Meta class produces test cases for all required modules and backends"},{"line_number":31,"context_line":""}],"source_content_type":"text/x-python","patch_set":66,"id":"da9df570_91cfb828","line":28,"in_reply_to":"da9df570_077021a4","updated":"2014-09-26 12:58:37.000000000","message":"Done","commit_id":"5ab6ed339f0608d5366d863fcde32c9a475702aa"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"bb1a046bc52347a7bcf75cf248c078c04ed6b5f0","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        \u0027token\u0027,"},{"line_number":55,"context_line":"        \u0027trust\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def __new__(cls, name, bases, attrs):"},{"line_number":58,"context_line":"        \"\"\"Push all created modules to a global modules namespace"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        Uses MySQL and Postgresql for testing of all modules containing"}],"source_content_type":"text/x-python","patch_set":66,"id":"da9df570_24ec43c7","line":57,"updated":"2014-09-24 15:46:01.000000000","message":"I fear that this is overly complicated and will not be easy to understand by those not familiar with dynamically creating classes. Is this just to same lines of code?","commit_id":"5ab6ed339f0608d5366d863fcde32c9a475702aa"},{"author":{"_account_id":2903,"name":"Morgan Fainberg","email":"morgan.fainberg@gmail.com","username":"mdrnstm"},"change_message_id":"591aa7c57f94ff1642af55b3f2231c8edf7593b0","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        \u0027token\u0027,"},{"line_number":55,"context_line":"        \u0027trust\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def __new__(cls, name, bases, attrs):"},{"line_number":58,"context_line":"        \"\"\"Push all created modules to a global modules namespace"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        Uses MySQL and Postgresql for testing of all modules containing"}],"source_content_type":"text/x-python","patch_set":66,"id":"da9df570_67364de9","line":57,"in_reply_to":"da9df570_24ec43c7","updated":"2014-09-24 16:00:27.000000000","message":"Good question, I am also concerned about metaclass use and it\u0027s complexity. \n\nWhile there are exceptions, typically metaclasses in python bring complexity and everything can be done in a more readable way without them. Is this a case that really justifies the metaclass use?","commit_id":"5ab6ed339f0608d5366d863fcde32c9a475702aa"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"49216081e0b401df8b7f7ae9c563b1787f8ea111","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        \u0027token\u0027,"},{"line_number":55,"context_line":"        \u0027trust\u0027)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"    def __new__(cls, name, bases, attrs):"},{"line_number":58,"context_line":"        \"\"\"Push all created modules to a global modules namespace"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        Uses MySQL and Postgresql for testing of all modules containing"}],"source_content_type":"text/x-python","patch_set":66,"id":"da9df570_d10dc03f","line":57,"in_reply_to":"da9df570_67364de9","updated":"2014-09-26 12:58:37.000000000","message":"This is production class, it produces separated classes for each backend and each module contained migrations. Yes it is possible to write the tests without metaclass. But the module will be huge ugly and unDRY. Without metaclass there will be test classes as much as /backends X modules/.","commit_id":"5ab6ed339f0608d5366d863fcde32c9a475702aa"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"ff9fb14c57857807bc26b07753e8dcd6fafebb1f","unresolved":false,"context_lines":[{"line_number":101,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":102,"context_line":"        models \u003d [m.__tablename__"},{"line_number":103,"context_line":"                  for m in self.models_module.__dict__.values()"},{"line_number":104,"context_line":"                  if inspect.isclass(m) and issubclass(m, sql.ModelBase)]"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"},{"line_number":107,"context_line":"            return name not in self.ignore_list and name in models"}],"source_content_type":"text/x-python","patch_set":66,"id":"da9df570_ee8cda37","line":104,"updated":"2014-09-24 14:49:16.000000000","message":"Could this be broken out into something that\u0027s a little more readable?","commit_id":"5ab6ed339f0608d5366d863fcde32c9a475702aa"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"49216081e0b401df8b7f7ae9c563b1787f8ea111","unresolved":false,"context_lines":[{"line_number":101,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":102,"context_line":"        models \u003d [m.__tablename__"},{"line_number":103,"context_line":"                  for m in self.models_module.__dict__.values()"},{"line_number":104,"context_line":"                  if inspect.isclass(m) and issubclass(m, sql.ModelBase)]"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"},{"line_number":107,"context_line":"            return name not in self.ignore_list and name in models"}],"source_content_type":"text/x-python","patch_set":66,"id":"da9df570_ecae672d","line":104,"in_reply_to":"da9df570_ee8cda37","updated":"2014-09-26 12:58:37.000000000","message":"Done","commit_id":"5ab6ed339f0608d5366d863fcde32c9a475702aa"},{"author":{"_account_id":6486,"name":"Brant Knudson","email":"blk@acm.org","username":"blk-u"},"change_message_id":"bcc573a9837980fc690dc0087e5aafd9d916fb09","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        \u0027catalog\u0027,"},{"line_number":47,"context_line":"        \u0027contrib.oauth1\u0027,"},{"line_number":48,"context_line":"        \u0027contrib.federation\u0027,"},{"line_number":49,"context_line":"        \u0027contrib.endpoint_filter\u0027,"},{"line_number":50,"context_line":"        \u0027contrib.revoke\u0027,"},{"line_number":51,"context_line":"        \u0027credential\u0027,"},{"line_number":52,"context_line":"        \u0027identity\u0027,"}],"source_content_type":"text/x-python","patch_set":68,"id":"baa201ad_0e4b075a","line":49,"updated":"2014-10-12 21:04:09.000000000","message":"endpoint_policy is missing now. \n\nAlso, token.persistence.\n\nHow is this list going to be kept in sync?","commit_id":"b78d008ef849f8d9c0d03494206c81f1a620d5e9"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"7ddf56f5903af307a4b0f534e4f1c38482af5180","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        \u0027catalog\u0027,"},{"line_number":47,"context_line":"        \u0027contrib.oauth1\u0027,"},{"line_number":48,"context_line":"        \u0027contrib.federation\u0027,"},{"line_number":49,"context_line":"        \u0027contrib.endpoint_filter\u0027,"},{"line_number":50,"context_line":"        \u0027contrib.revoke\u0027,"},{"line_number":51,"context_line":"        \u0027credential\u0027,"},{"line_number":52,"context_line":"        \u0027identity\u0027,"}],"source_content_type":"text/x-python","patch_set":68,"id":"baa201ad_22f1bacd","line":49,"in_reply_to":"baa201ad_0e4b075a","updated":"2014-10-13 07:47:27.000000000","message":"Yes, you are right, we need to test the list. I\u0027ll make a test for it.","commit_id":"b78d008ef849f8d9c0d03494206c81f1a620d5e9"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"dcb003d40f0e9d7db1ba83e492f5edc12453e923","unresolved":false,"context_lines":[{"line_number":46,"context_line":"        \u0027catalog\u0027,"},{"line_number":47,"context_line":"        \u0027contrib.oauth1\u0027,"},{"line_number":48,"context_line":"        \u0027contrib.federation\u0027,"},{"line_number":49,"context_line":"        \u0027contrib.endpoint_filter\u0027,"},{"line_number":50,"context_line":"        \u0027contrib.revoke\u0027,"},{"line_number":51,"context_line":"        \u0027credential\u0027,"},{"line_number":52,"context_line":"        \u0027identity\u0027,"}],"source_content_type":"text/x-python","patch_set":68,"id":"baa201ad_dc08a7db","line":49,"in_reply_to":"baa201ad_22f1bacd","updated":"2014-10-14 12:57:57.000000000","message":"I have no better idea than automate the list collecting.","commit_id":"b78d008ef849f8d9c0d03494206c81f1a620d5e9"},{"author":{"_account_id":7725,"name":"David Stanek","email":"dstanek@dstanek.com","username":"dstanek"},"change_message_id":"d295f1fa701e26efb90f32b59fc9b85958da0274","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"class RealBackends(type):"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    \"\"\"Meta class produces test cases for all required modules and backends"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    Attributes"}],"source_content_type":"text/x-python","patch_set":69,"id":"9aa7fdbe_fdd04955","line":33,"updated":"2014-11-21 13:59:35.000000000","message":"Any reason for this newline?","commit_id":"a4d469869d4b5b3cb1f497dbc629faabe9b6067e"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"180ffa5ee40f386133139d75b384fe6d638d74b3","unresolved":false,"context_lines":[{"line_number":30,"context_line":""},{"line_number":31,"context_line":""},{"line_number":32,"context_line":"class RealBackends(type):"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    \"\"\"Meta class produces test cases for all required modules and backends"},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"    Attributes"}],"source_content_type":"text/x-python","patch_set":69,"id":"5a890539_2546e721","line":33,"in_reply_to":"9aa7fdbe_fdd04955","updated":"2014-11-27 14:05:04.000000000","message":"Nope","commit_id":"a4d469869d4b5b3cb1f497dbc629faabe9b6067e"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"26f27ac6b597d55a12381b7b69c5ec03139b345b","unresolved":false,"context_lines":[{"line_number":45,"context_line":"from keystone.openstack.common import log"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"MODULES \u003d []"}],"source_content_type":"text/x-python","patch_set":72,"id":"5a890539_591089a8","line":48,"updated":"2014-11-28 13:25:22.000000000","message":"this seems to be unused","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"a00748738799e9826799e194d1aa9af413c7466a","unresolved":false,"context_lines":[{"line_number":45,"context_line":"from keystone.openstack.common import log"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"LOG \u003d log.getLogger(__name__)"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"MODULES \u003d []"}],"source_content_type":"text/x-python","patch_set":72,"id":"5a890539_f4485c8c","line":48,"in_reply_to":"5a890539_591089a8","updated":"2014-11-28 16:37:08.000000000","message":"Done","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"26f27ac6b597d55a12381b7b69c5ec03139b345b","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    convention: all sql models contained in a modules named `sql`."},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    for mod in modules_list:"},{"line_number":97,"context_line":"        if mod[1] \u003d\u003d \u0027sql\u0027:"},{"line_number":98,"context_line":"            module \u003d os.path.relpath(mod[0].path).split(\u0027/\u0027)"},{"line_number":99,"context_line":"            sql_module \u003d \u0027.\u0027.join(module + [mod[1], ])"}],"source_content_type":"text/x-python","patch_set":72,"id":"5a890539_3911fd5d","line":96,"updated":"2014-11-28 13:25:22.000000000","message":"nit: can you please use names instead of indexes for readability? For example:\n\n for some, thing in modules_list:\n     module \u003d os.path.relpath(some.path).split(\u0027/\u0027)\n     ...","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"a00748738799e9826799e194d1aa9af413c7466a","unresolved":false,"context_lines":[{"line_number":93,"context_line":"    convention: all sql models contained in a modules named `sql`."},{"line_number":94,"context_line":"    \"\"\""},{"line_number":95,"context_line":""},{"line_number":96,"context_line":"    for mod in modules_list:"},{"line_number":97,"context_line":"        if mod[1] \u003d\u003d \u0027sql\u0027:"},{"line_number":98,"context_line":"            module \u003d os.path.relpath(mod[0].path).split(\u0027/\u0027)"},{"line_number":99,"context_line":"            sql_module \u003d \u0027.\u0027.join(module + [mod[1], ])"}],"source_content_type":"text/x-python","patch_set":72,"id":"5a890539_4b0d0a37","line":96,"in_reply_to":"5a890539_3911fd5d","updated":"2014-11-28 16:37:08.000000000","message":"Done","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"26f27ac6b597d55a12381b7b69c5ec03139b345b","unresolved":false,"context_lines":[{"line_number":103,"context_line":""},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"def _separate_packages_modules(modules):"},{"line_number":106,"context_line":"    return (filter(lambda m: m[2], modules),"},{"line_number":107,"context_line":"            filter(lambda m: not m[2], modules))"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":""}],"source_content_type":"text/x-python","patch_set":72,"id":"5a890539_79a1c594","line":106,"updated":"2014-11-28 13:25:22.000000000","message":"filter() behavior is different in py2 and py3 but it looks safe here","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"a00748738799e9826799e194d1aa9af413c7466a","unresolved":false,"context_lines":[{"line_number":103,"context_line":""},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"def _separate_packages_modules(modules):"},{"line_number":106,"context_line":"    return (filter(lambda m: m[2], modules),"},{"line_number":107,"context_line":"            filter(lambda m: not m[2], modules))"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":""}],"source_content_type":"text/x-python","patch_set":72,"id":"5a890539_c846604f","line":106,"in_reply_to":"5a890539_79a1c594","updated":"2014-11-28 16:37:08.000000000","message":"Do we leave it as is?","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"26f27ac6b597d55a12381b7b69c5ec03139b345b","unresolved":false,"context_lines":[{"line_number":110,"context_line":"def _get_sql_modules(paths\u003dNone):"},{"line_number":111,"context_line":"    \"\"\"Recursive get all modules and packages."},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    :keyword list paths: list of paths of packages for further submodules"},{"line_number":114,"context_line":"                         search"},{"line_number":115,"context_line":"    :returns: list of Python paths of `sql` modules which contain sql"},{"line_number":116,"context_line":"              models."}],"source_content_type":"text/x-python","patch_set":72,"id":"5a890539_943c78c1","line":113,"updated":"2014-11-28 13:25:22.000000000","message":"should this be a just \n\n :keyword paths:\n\n?","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"a00748738799e9826799e194d1aa9af413c7466a","unresolved":false,"context_lines":[{"line_number":110,"context_line":"def _get_sql_modules(paths\u003dNone):"},{"line_number":111,"context_line":"    \"\"\"Recursive get all modules and packages."},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"    :keyword list paths: list of paths of packages for further submodules"},{"line_number":114,"context_line":"                         search"},{"line_number":115,"context_line":"    :returns: list of Python paths of `sql` modules which contain sql"},{"line_number":116,"context_line":"              models."}],"source_content_type":"text/x-python","patch_set":72,"id":"5a890539_2b08be27","line":113,"in_reply_to":"5a890539_943c78c1","updated":"2014-11-28 16:37:08.000000000","message":"Done","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"ba869cd3cbc1b038844f656a654c59765983b75f","unresolved":false,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"MODULES \u003d []"},{"line_number":50,"context_line":"BACKENDS \u003d (test_base.PostgreSQLOpportunisticTestCase,"},{"line_number":51,"context_line":"            test_base.MySQLOpportunisticTestCase)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"class ModelsMigrationsComparer(test_base.DbTestCase):"}],"source_content_type":"text/x-python","patch_set":78,"id":"5a890539_873571f8","line":51,"updated":"2014-12-04 17:32:39.000000000","message":"Hm... Keystone still supports SQLite in their migrations. What do you think, if we also add test_base.DbTestCase to BACKENDS as an SQLite backend?","commit_id":"7ef95b38098016f81cae653f8d84f432069e8501"}],"keystone/tests/unit/ksfixtures/database.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"443f1f508b21bf588220ead69c411a42322ea716","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"@run_once"},{"line_number":95,"context_line":"def load_sqlalchemy_models():"},{"line_number":96,"context_line":"    \"\"\"Find all modules containing SQLAlchemy models and import them."},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    This creates more consistent, deterministic test runs because tables"},{"line_number":99,"context_line":"    for all core and extension models are always created in the test"}],"source_content_type":"text/x-python","patch_set":90,"id":"3afb71cf_bfeb2078","line":96,"updated":"2015-06-11 17:56:27.000000000","message":"This comment kinda belong with the get_sql_modules method now.","commit_id":"5a0cb4c773fcb5e0f848b8df094849d6b5adda42"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"a6e082995a53e99325cb224fa5d16598da5d1965","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":"@run_once"},{"line_number":95,"context_line":"def load_sqlalchemy_models():"},{"line_number":96,"context_line":"    \"\"\"Find all modules containing SQLAlchemy models and import them."},{"line_number":97,"context_line":""},{"line_number":98,"context_line":"    This creates more consistent, deterministic test runs because tables"},{"line_number":99,"context_line":"    for all core and extension models are always created in the test"}],"source_content_type":"text/x-python","patch_set":90,"id":"1af86dd1_fe1f5359","line":96,"in_reply_to":"3afb71cf_bfeb2078","updated":"2015-06-12 19:32:55.000000000","message":"Fixed.","commit_id":"5a0cb4c773fcb5e0f848b8df094849d6b5adda42"}],"keystone/tests/unit/test_sync_migrations.py":[{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"b30d225b88e25f07162d6c6f9b4f5d3954b976bd","unresolved":false,"context_lines":[{"line_number":37,"context_line":"def _get_sql_modules(paths\u003dNone):"},{"line_number":38,"context_line":"    \"\"\"Recursive get all modules and packages."},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    This method works accordingly to an existing in Keystone naming"},{"line_number":41,"context_line":"    convention: all sql models contained in a modules named `sql`."},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    :keyword paths: list of paths of packages for further submodules search."}],"source_content_type":"text/x-python","patch_set":87,"id":"baa041b7_66425c12","line":40,"updated":"2015-04-05 15:55:53.000000000","message":"nit: s/works accordingly to an existing in Keystone/assumes the existing Keystone/","commit_id":"454840e2a100a374ef8dc4ea5cef327a66ebfcee"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"db4e159e42a11a9b2cdd885a358257359c971e43","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"class ModelsMigrationsComparer(object):"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    \"\"\"Mixin intended to override test_migrations.ModelsMigrationsSync methods."},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_1683ce99","line":37,"updated":"2015-04-08 12:32:15.000000000","message":"remove this line","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"944b8cbe1c5f7036583ad30ba211e38d2a3d1c3d","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"class ModelsMigrationsComparer(object):"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    \"\"\"Mixin intended to override test_migrations.ModelsMigrationsSync methods."},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_dcb58031","line":37,"in_reply_to":"9aa53dc9_1683ce99","updated":"2015-04-08 14:31:41.000000000","message":"will do","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"02f9c22c348398424c452fe4b5ea8cd78ae315be","unresolved":false,"context_lines":[{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"class ModelsMigrationsComparer(object):"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    \"\"\"Mixin intended to override test_migrations.ModelsMigrationsSync methods."},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"5aa745d1_bf3fa124","line":37,"in_reply_to":"9aa53dc9_dcb58031","updated":"2015-04-16 11:25:25.000000000","message":"Done","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"db4e159e42a11a9b2cdd885a358257359c971e43","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    \"\"\"Mixin intended to override test_migrations.ModelsMigrationsSync methods."},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    scenarios \u003d [(m, {\u0027sql_module\u0027: m}) for m in database.get_sql_modules()]"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    ignore_list \u003d [\u0027migrate_version\u0027]"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_593ce7c7","line":41,"updated":"2015-04-08 12:32:15.000000000","message":"Is this variable needed? Does it override something from test_migrations.ModelsMigrationsSync? If yes, why is it done as a variable and not as a method?","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"944b8cbe1c5f7036583ad30ba211e38d2a3d1c3d","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    \"\"\"Mixin intended to override test_migrations.ModelsMigrationsSync methods."},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    scenarios \u003d [(m, {\u0027sql_module\u0027: m}) for m in database.get_sql_modules()]"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    ignore_list \u003d [\u0027migrate_version\u0027]"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_dc8c6081","line":41,"in_reply_to":"9aa53dc9_593ce7c7","updated":"2015-04-08 14:31:41.000000000","message":"This required for testscenarios, see https://pypi.python.org/pypi/testscenarios/","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"0909ceb56cd7cccdd1cf6ee0b7afc9ee07d74086","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    \"\"\"Mixin intended to override test_migrations.ModelsMigrationsSync methods."},{"line_number":39,"context_line":"    \"\"\""},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    scenarios \u003d [(m, {\u0027sql_module\u0027: m}) for m in database.get_sql_modules()]"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    ignore_list \u003d [\u0027migrate_version\u0027]"},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_9ccb781e","line":41,"in_reply_to":"9aa53dc9_dc8c6081","updated":"2015-04-08 14:47:01.000000000","message":"please, add a comment","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"db4e159e42a11a9b2cdd885a358257359c971e43","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    ignore_list \u003d [\u0027migrate_version\u0027]"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def get_engine(self):"},{"line_number":46,"context_line":"        return self.engine"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def get_metadata(self):"},{"line_number":49,"context_line":"        return sql.ModelBase.metadata"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_795b2b2f","line":46,"updated":"2015-04-08 12:32:15.000000000","message":"what\u0027s the purpose of this override and why can\u0027t we move this function to test_migrations.ModelsMigrationsSync? We don\u0027t set self.engine in this mixin.","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"fd4f1ad4a822350c541c996eb94c4d4e02ec99a1","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    ignore_list \u003d [\u0027migrate_version\u0027]"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def get_engine(self):"},{"line_number":46,"context_line":"        return self.engine"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def get_metadata(self):"},{"line_number":49,"context_line":"        return sql.ModelBase.metadata"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_7fb78686","line":46,"in_reply_to":"9aa53dc9_5f24c2ad","updated":"2015-04-08 14:51:35.000000000","message":"self.engine provided by `test_base.*SQLOpportunisticTestCase` class","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"944b8cbe1c5f7036583ad30ba211e38d2a3d1c3d","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    ignore_list \u003d [\u0027migrate_version\u0027]"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def get_engine(self):"},{"line_number":46,"context_line":"        return self.engine"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def get_metadata(self):"},{"line_number":49,"context_line":"        return sql.ModelBase.metadata"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_7c59d4fd","line":46,"in_reply_to":"9aa53dc9_795b2b2f","updated":"2015-04-08 14:31:41.000000000","message":"this method was implemented as abstract method in test_migrations.ModelsMigrationsSync. See [1]\n\n[1] http://docs.openstack.org/developer/oslo.db/api/sqlalchemy/test_migrations.html#oslo_db.sqlalchemy.test_migrations.ModelsMigrationsSync.get_engine","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"0909ceb56cd7cccdd1cf6ee0b7afc9ee07d74086","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    ignore_list \u003d [\u0027migrate_version\u0027]"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    def get_engine(self):"},{"line_number":46,"context_line":"        return self.engine"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"    def get_metadata(self):"},{"line_number":49,"context_line":"        return sql.ModelBase.metadata"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_5f24c2ad","line":46,"in_reply_to":"9aa53dc9_7c59d4fd","updated":"2015-04-08 14:47:01.000000000","message":"where do we assign self.engine to something? The method should be there","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"db4e159e42a11a9b2cdd885a358257359c971e43","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        return sql.ModelBase.metadata"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def db_sync(self, engine):"},{"line_number":52,"context_line":"        if \u0027contrib\u0027 in self.sql_module:"},{"line_number":53,"context_line":"            # \u0027keystone.contrib.oauth1.backends.sql\u0027 -\u003e \u0027oauth1\u0027"},{"line_number":54,"context_line":"            extension \u003d self.sql_module.split(\u0027.\u0027)[-3]"},{"line_number":55,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_366a521b","line":52,"updated":"2015-04-08 12:32:15.000000000","message":"where does self.sql_module come from? It should be explained in the comments or somewhere else.","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"944b8cbe1c5f7036583ad30ba211e38d2a3d1c3d","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        return sql.ModelBase.metadata"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def db_sync(self, engine):"},{"line_number":52,"context_line":"        if \u0027contrib\u0027 in self.sql_module:"},{"line_number":53,"context_line":"            # \u0027keystone.contrib.oauth1.backends.sql\u0027 -\u003e \u0027oauth1\u0027"},{"line_number":54,"context_line":"            extension \u003d self.sql_module.split(\u0027.\u0027)[-3]"},{"line_number":55,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_dcffc0a8","line":52,"in_reply_to":"9aa53dc9_366a521b","updated":"2015-04-08 14:31:41.000000000","message":"well, I\u0027m not very familiar with keystone code base. Can you suggest, how should I determine, is this sql module related to extension or not?","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"fd4f1ad4a822350c541c996eb94c4d4e02ec99a1","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        return sql.ModelBase.metadata"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def db_sync(self, engine):"},{"line_number":52,"context_line":"        if \u0027contrib\u0027 in self.sql_module:"},{"line_number":53,"context_line":"            # \u0027keystone.contrib.oauth1.backends.sql\u0027 -\u003e \u0027oauth1\u0027"},{"line_number":54,"context_line":"            extension \u003d self.sql_module.split(\u0027.\u0027)[-3]"},{"line_number":55,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_7f8426d3","line":52,"in_reply_to":"9aa53dc9_bf83ce55","updated":"2015-04-08 14:51:35.000000000","message":"this was made by testscenarios magic","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"0909ceb56cd7cccdd1cf6ee0b7afc9ee07d74086","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        return sql.ModelBase.metadata"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    def db_sync(self, engine):"},{"line_number":52,"context_line":"        if \u0027contrib\u0027 in self.sql_module:"},{"line_number":53,"context_line":"            # \u0027keystone.contrib.oauth1.backends.sql\u0027 -\u003e \u0027oauth1\u0027"},{"line_number":54,"context_line":"            extension \u003d self.sql_module.split(\u0027.\u0027)[-3]"},{"line_number":55,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_bf83ce55","line":52,"in_reply_to":"9aa53dc9_dcffc0a8","updated":"2015-04-08 14:47:01.000000000","message":"No, wait, my question was not about it. Here we use self.sql_module but don\u0027t initialize it anywhere in this class. Where does it happen?","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"db4e159e42a11a9b2cdd885a358257359c971e43","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    def _is_model(self, model):"},{"line_number":62,"context_line":"        return inspect.isclass(model) and issubclass(model, sql.ModelBase)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":65,"context_line":"        models_module \u003d importlib.import_module(self.sql_module)"},{"line_number":66,"context_line":"        module_items \u003d models_module.__dict__.values()"},{"line_number":67,"context_line":"        models \u003d [i.__tablename__ for i in module_items if self._is_model(i)]"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_363c922e","line":64,"updated":"2015-04-08 12:32:15.000000000","message":"needs docstring with explanation of every parameter","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"02f9c22c348398424c452fe4b5ea8cd78ae315be","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    def _is_model(self, model):"},{"line_number":62,"context_line":"        return inspect.isclass(model) and issubclass(model, sql.ModelBase)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":65,"context_line":"        models_module \u003d importlib.import_module(self.sql_module)"},{"line_number":66,"context_line":"        module_items \u003d models_module.__dict__.values()"},{"line_number":67,"context_line":"        models \u003d [i.__tablename__ for i in module_items if self._is_model(i)]"}],"source_content_type":"text/x-python","patch_set":88,"id":"5aa745d1_852ff4a0","line":64,"in_reply_to":"9aa53dc9_1fc75a46","updated":"2015-04-16 11:25:25.000000000","message":"Done","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"944b8cbe1c5f7036583ad30ba211e38d2a3d1c3d","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    def _is_model(self, model):"},{"line_number":62,"context_line":"        return inspect.isclass(model) and issubclass(model, sql.ModelBase)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":65,"context_line":"        models_module \u003d importlib.import_module(self.sql_module)"},{"line_number":66,"context_line":"        module_items \u003d models_module.__dict__.values()"},{"line_number":67,"context_line":"        models \u003d [i.__tablename__ for i in module_items if self._is_model(i)]"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_7cb554ec","line":64,"in_reply_to":"9aa53dc9_363c922e","updated":"2015-04-08 14:31:41.000000000","message":"I see no big sense in it, because this is mixin and this method was documented in test_migrations.ModelsMigrationsSync. See [1]. But I can add documentation, if you insist.\n\n[1] http://docs.openstack.org/developer/oslo.db/api/sqlalchemy/test_migrations.html#oslo_db.sqlalchemy.test_migrations.ModelsMigrationsSync.include_object","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"0909ceb56cd7cccdd1cf6ee0b7afc9ee07d74086","unresolved":false,"context_lines":[{"line_number":61,"context_line":"    def _is_model(self, model):"},{"line_number":62,"context_line":"        return inspect.isclass(model) and issubclass(model, sql.ModelBase)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    def include_object(self, object_, name, type_, reflected, compare_to):"},{"line_number":65,"context_line":"        models_module \u003d importlib.import_module(self.sql_module)"},{"line_number":66,"context_line":"        module_items \u003d models_module.__dict__.values()"},{"line_number":67,"context_line":"        models \u003d [i.__tablename__ for i in module_items if self._is_model(i)]"}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_1fc75a46","line":64,"in_reply_to":"9aa53dc9_7cb554ec","updated":"2015-04-08 14:47:01.000000000","message":"hm, ok. Anyway, a comment about what the code does should be there. I don\u0027t understand what the code does on the first sight.","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":13478,"name":"Boris Bobrov","email":"b.bobrov@sap.com","username":"bbobrov"},"change_message_id":"db4e159e42a11a9b2cdd885a358257359c971e43","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        module_items \u003d models_module.__dict__.values()"},{"line_number":67,"context_line":"        models \u003d [i.__tablename__ for i in module_items if self._is_model(i)]"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"},{"line_number":70,"context_line":"            return name not in self.ignore_list and name in models"},{"line_number":71,"context_line":"        return True"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_769d7a58","line":69,"updated":"2015-04-08 12:32:15.000000000","message":"this check should be moved above \u0027models_module \u003d ...\u0027","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"944b8cbe1c5f7036583ad30ba211e38d2a3d1c3d","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        module_items \u003d models_module.__dict__.values()"},{"line_number":67,"context_line":"        models \u003d [i.__tablename__ for i in module_items if self._is_model(i)]"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"},{"line_number":70,"context_line":"            return name not in self.ignore_list and name in models"},{"line_number":71,"context_line":"        return True"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"9aa53dc9_7cac34a0","line":69,"in_reply_to":"9aa53dc9_769d7a58","updated":"2015-04-08 14:31:41.000000000","message":"thanks, will do","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"02f9c22c348398424c452fe4b5ea8cd78ae315be","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        module_items \u003d models_module.__dict__.values()"},{"line_number":67,"context_line":"        models \u003d [i.__tablename__ for i in module_items if self._is_model(i)]"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"        if type_ \u003d\u003d \u0027table\u0027:"},{"line_number":70,"context_line":"            return name not in self.ignore_list and name in models"},{"line_number":71,"context_line":"        return True"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":88,"id":"5aa745d1_c525fcc2","line":69,"in_reply_to":"9aa53dc9_7cac34a0","updated":"2015-04-16 11:25:25.000000000","message":"Done","commit_id":"b3c8964169c083b3ee92172c0c5e19c308a4896a"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"062644fa9eabc8627c9e16d8788aa2f1e66206db","unresolved":false,"context_lines":[{"line_number":31,"context_line":"database.load_sqlalchemy_models()"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"IGNORED_SCENARIOS \u003d ["},{"line_number":34,"context_line":"    \u0027keystone.contrib.endpoint_filter.backends.sql\u0027,"},{"line_number":35,"context_line":"    \u0027keystone.contrib.oauth1.backends.sql\u0027,"},{"line_number":36,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/168947"},{"line_number":37,"context_line":"    \u0027keystone.contrib.federation.backends.sql\u0027,"}],"source_content_type":"text/x-python","patch_set":89,"id":"5aa745d1_81d59e44","line":34,"updated":"2015-04-16 13:45:06.000000000","message":"Addressed by https://review.openstack.org/174388","commit_id":"205a3356746d8b4850ec4405474a0edb111683f1"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"443f1f508b21bf588220ead69c411a42322ea716","unresolved":false,"context_lines":[{"line_number":31,"context_line":"database.load_sqlalchemy_models()"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"IGNORED_SCENARIOS \u003d ["},{"line_number":34,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174388/"},{"line_number":35,"context_line":"    \u0027keystone.contrib.endpoint_filter.backends.sql\u0027,"},{"line_number":36,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174871/"},{"line_number":37,"context_line":"    \u0027keystone.contrib.oauth1.backends.sql\u0027,"}],"source_content_type":"text/x-python","patch_set":90,"id":"3afb71cf_df6b7cf0","line":34,"updated":"2015-06-11 17:56:27.000000000","message":"Add a FIXME here with a name, so that we can track it a little easier.","commit_id":"5a0cb4c773fcb5e0f848b8df094849d6b5adda42"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"a6e082995a53e99325cb224fa5d16598da5d1965","unresolved":false,"context_lines":[{"line_number":31,"context_line":"database.load_sqlalchemy_models()"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"IGNORED_SCENARIOS \u003d ["},{"line_number":34,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174388/"},{"line_number":35,"context_line":"    \u0027keystone.contrib.endpoint_filter.backends.sql\u0027,"},{"line_number":36,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174871/"},{"line_number":37,"context_line":"    \u0027keystone.contrib.oauth1.backends.sql\u0027,"}],"source_content_type":"text/x-python","patch_set":90,"id":"1af86dd1_492b3c83","line":34,"in_reply_to":"3afb71cf_df6b7cf0","updated":"2015-06-12 19:32:55.000000000","message":"Done","commit_id":"5a0cb4c773fcb5e0f848b8df094849d6b5adda42"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"443f1f508b21bf588220ead69c411a42322ea716","unresolved":false,"context_lines":[{"line_number":33,"context_line":"IGNORED_SCENARIOS \u003d ["},{"line_number":34,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174388/"},{"line_number":35,"context_line":"    \u0027keystone.contrib.endpoint_filter.backends.sql\u0027,"},{"line_number":36,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174871/"},{"line_number":37,"context_line":"    \u0027keystone.contrib.oauth1.backends.sql\u0027,"},{"line_number":38,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/168947"},{"line_number":39,"context_line":"    \u0027keystone.contrib.federation.backends.sql\u0027,"}],"source_content_type":"text/x-python","patch_set":90,"id":"3afb71cf_9f7624d7","line":36,"updated":"2015-06-11 17:56:27.000000000","message":"same comment applies here","commit_id":"5a0cb4c773fcb5e0f848b8df094849d6b5adda42"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"a6e082995a53e99325cb224fa5d16598da5d1965","unresolved":false,"context_lines":[{"line_number":33,"context_line":"IGNORED_SCENARIOS \u003d ["},{"line_number":34,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174388/"},{"line_number":35,"context_line":"    \u0027keystone.contrib.endpoint_filter.backends.sql\u0027,"},{"line_number":36,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174871/"},{"line_number":37,"context_line":"    \u0027keystone.contrib.oauth1.backends.sql\u0027,"},{"line_number":38,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/168947"},{"line_number":39,"context_line":"    \u0027keystone.contrib.federation.backends.sql\u0027,"}],"source_content_type":"text/x-python","patch_set":90,"id":"1af86dd1_891a546d","line":36,"in_reply_to":"3afb71cf_9f7624d7","updated":"2015-06-12 19:32:55.000000000","message":"Done","commit_id":"5a0cb4c773fcb5e0f848b8df094849d6b5adda42"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"443f1f508b21bf588220ead69c411a42322ea716","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    \u0027keystone.contrib.endpoint_filter.backends.sql\u0027,"},{"line_number":36,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174871/"},{"line_number":37,"context_line":"    \u0027keystone.contrib.oauth1.backends.sql\u0027,"},{"line_number":38,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/168947"},{"line_number":39,"context_line":"    \u0027keystone.contrib.federation.backends.sql\u0027,"},{"line_number":40,"context_line":"]"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-python","patch_set":90,"id":"3afb71cf_7f7368e8","line":38,"updated":"2015-06-11 17:56:27.000000000","message":"and here.","commit_id":"5a0cb4c773fcb5e0f848b8df094849d6b5adda42"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"a6e082995a53e99325cb224fa5d16598da5d1965","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    \u0027keystone.contrib.endpoint_filter.backends.sql\u0027,"},{"line_number":36,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/174871/"},{"line_number":37,"context_line":"    \u0027keystone.contrib.oauth1.backends.sql\u0027,"},{"line_number":38,"context_line":"    # Will be fixed in https://review.openstack.org/#/c/168947"},{"line_number":39,"context_line":"    \u0027keystone.contrib.federation.backends.sql\u0027,"},{"line_number":40,"context_line":"]"},{"line_number":41,"context_line":""}],"source_content_type":"text/x-python","patch_set":90,"id":"1af86dd1_a91d1068","line":38,"in_reply_to":"3afb71cf_7f7368e8","updated":"2015-06-12 19:32:55.000000000","message":"Done","commit_id":"5a0cb4c773fcb5e0f848b8df094849d6b5adda42"}],"test-requirements-py3.txt":[{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"26f27ac6b597d55a12381b7b69c5ec03139b345b","unresolved":false,"context_lines":[{"line_number":63,"context_line":"stevedore\u003e\u003d1.1.0  # Apache-2.0"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"# Testing on real sql backends"},{"line_number":66,"context_line":"MySQL-python"},{"line_number":67,"context_line":"psycopg2"}],"source_content_type":"text/plain","patch_set":72,"id":"5a890539_d9fe39ae","line":66,"updated":"2014-11-28 13:25:22.000000000","message":"MySQL-python is not py3 compatible, you can try to use PyMySQL instead","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"},{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"a00748738799e9826799e194d1aa9af413c7466a","unresolved":false,"context_lines":[{"line_number":63,"context_line":"stevedore\u003e\u003d1.1.0  # Apache-2.0"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"# Testing on real sql backends"},{"line_number":66,"context_line":"MySQL-python"},{"line_number":67,"context_line":"psycopg2"}],"source_content_type":"text/plain","patch_set":72,"id":"5a890539_213a9fe7","line":66,"in_reply_to":"5a890539_d9fe39ae","updated":"2014-11-28 16:37:08.000000000","message":"Done","commit_id":"0607f27739aaa398c493d1bd76c686509f0d0265"}],"test-requirements.txt":[{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"a0bfade47e24036dc84da9ddc66b245eef82fa75","unresolved":false,"context_lines":[{"line_number":28,"context_line":"WebTest\u003e\u003d2.0"},{"line_number":29,"context_line":"# Sync models with migrations"},{"line_number":30,"context_line":"alembic\u003e\u003d0.4.1"},{"line_number":31,"context_line":"psycopg2\u003e\u003d2.5.2"},{"line_number":32,"context_line":"MySQL-python\u003e\u003d1.2.5"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"discover"}],"source_content_type":"text/plain","patch_set":12,"id":"AAAAWH%2F%2BA3M%3D","line":31,"updated":"2014-03-31 15:04:09.000000000","message":"this must be:\n\npsycopg2\nMySQL-python\n\n(to be compatible with global requirements)","commit_id":"68bba6186bf163ae524bf14d669d57defd9c0510"},{"author":{"_account_id":7491,"name":"Viktor Serhieiev","email":"viktor.sergeyev@gmail.com","username":"vsergeyev"},"change_message_id":"97d0874e788fe1eaa4b03880d0307e474bd78793","unresolved":false,"context_lines":[{"line_number":25,"context_line":"sphinx\u003e\u003d1.1.2,\u003c1.2"},{"line_number":26,"context_line":"# test wsgi apps without starting an http server"},{"line_number":27,"context_line":"WebTest\u003e\u003d2.0"},{"line_number":28,"context_line":"# Sync models with migrations"},{"line_number":29,"context_line":"alembic\u003e\u003d0.4.1"},{"line_number":30,"context_line":"psycopg2"},{"line_number":31,"context_line":"MySQL-python"}],"source_content_type":"text/plain","patch_set":46,"id":"7adec928_771b32ca","line":28,"updated":"2014-05-15 08:46:56.000000000","message":"we already have these dependencies in the oslo.db so I see no big sense to keep them here also","commit_id":"a60c93ea5fbd61d502a7385678a66f36f91f7f18"}],"tox.ini":[{"author":{"_account_id":7536,"name":"Ilya Pekelny","email":"ipekelny@mirantis.com","username":"I159"},"change_message_id":"b74ba7733679f3a16783a547094176e5c6d48c6c","unresolved":false,"context_lines":[{"line_number":9,"context_line":"setenv \u003d VIRTUAL_ENV\u003d{envdir}"},{"line_number":10,"context_line":"deps \u003d -r{toxinidir}/requirements.txt"},{"line_number":11,"context_line":"       -r{toxinidir}/test-requirements.txt"},{"line_number":12,"context_line":"commands \u003d python -m keystone.openstack.common.lockutils python setup.py testr --testr-args\u003d\u0027{posargs}\u0027"},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"[testenv:pep8]"},{"line_number":15,"context_line":"envdir \u003d {toxworkdir}/venv"}],"source_content_type":"text/x-properties","patch_set":10,"id":"AAAAWH%2F%2Bmiw%3D","line":12,"updated":"2014-03-25 16:20:11.000000000","message":"Forgot about it. I think it should be separated patch.","commit_id":"578078eaeeb181bd8b452e61a2fbb1ee9ff1deca"},{"author":{"_account_id":6849,"name":"Roman Podoliaka","email":"roman.podoliaka@gmail.com","username":"rpodolyaka"},"change_message_id":"a0bfade47e24036dc84da9ddc66b245eef82fa75","unresolved":false,"context_lines":[{"line_number":9,"context_line":"setenv \u003d VIRTUAL_ENV\u003d{envdir}"},{"line_number":10,"context_line":"deps \u003d -r{toxinidir}/requirements.txt"},{"line_number":11,"context_line":"       -r{toxinidir}/test-requirements.txt"},{"line_number":12,"context_line":"commands \u003d python -m keystone.openstack.common.lockutils python setup.py testr --testr-args\u003d\u0027{posargs}\u0027"},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"[testenv:pep8]"},{"line_number":15,"context_line":"envdir \u003d {toxworkdir}/venv"}],"source_content_type":"text/x-properties","patch_set":12,"id":"AAAAWH%2F%2BA2o%3D","line":12,"updated":"2014-03-31 15:04:09.000000000","message":"This should be put into a separate patch.","commit_id":"68bba6186bf163ae524bf14d669d57defd9c0510"}]}
