changeset 8727:c98c7d4c9ec3

model: changes toward import whole modules *If* there should be circular dependencies, importing 'from' another module could fail because the module at that time only was partially imported. That had to be worked around by importing at runtime instead of globally. Instead, try to always import whole modules. (But we should still try to avoid cycles.)
author Mads Kiilerich <mads@kiilerich.com>
date Fri, 30 Oct 2020 14:54:42 +0100
parents 905cab5f971d
children f3fab7b124f2
files kallithea/model/comment.py kallithea/model/gist.py kallithea/model/pull_request.py kallithea/model/repo.py kallithea/model/repo_group.py kallithea/model/user.py
diffstat 6 files changed, 43 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/model/comment.py	Fri Oct 30 02:14:04 2020 +0100
+++ b/kallithea/model/comment.py	Fri Oct 30 14:54:42 2020 +0100
@@ -33,8 +33,7 @@
 from kallithea.lib import webutils
 from kallithea.lib.utils import extract_mentioned_users
 from kallithea.lib.utils2 import shorter
-from kallithea.model import db, meta
-from kallithea.model.notification import NotificationModel
+from kallithea.model import db, meta, notification
 
 
 log = logging.getLogger(__name__)
@@ -69,7 +68,7 @@
 
         # changeset
         if revision:
-            notification_type = NotificationModel.TYPE_CHANGESET_COMMENT
+            notification_type = notification.NotificationModel.TYPE_CHANGESET_COMMENT
             cs = repo.scm_instance.get_changeset(revision)
             desc = cs.short_id
 
@@ -114,7 +113,7 @@
             }
         # pull request
         elif pull_request:
-            notification_type = NotificationModel.TYPE_PULL_REQUEST_COMMENT
+            notification_type = notification.NotificationModel.TYPE_PULL_REQUEST_COMMENT
             desc = comment.pull_request.title
             _org_ref_type, org_ref_name, _org_rev = comment.pull_request.org_ref.split(':')
             _other_ref_type, other_ref_name, _other_rev = comment.pull_request.other_ref.split(':')
@@ -208,7 +207,7 @@
                                 closing_pr=closing_pr)
             email_kwargs['is_mention'] = False
             # create notification objects, and emails
-            NotificationModel().create(
+            notification.NotificationModel().create(
                 created_by=author, subject=subj, body=body,
                 recipients=recipients, type_=notification_type,
                 email_kwargs=email_kwargs,
@@ -219,7 +218,7 @@
                 email_kwargs['is_mention'] = True
                 subj = _('[Mention]') + ' ' + subj
                 # FIXME: this subject is wrong and unused!
-                NotificationModel().create(
+                notification.NotificationModel().create(
                     created_by=author, subject=subj, body=body,
                     recipients=mention_recipients,
                     type_=notification_type,
--- a/kallithea/model/gist.py	Fri Oct 30 02:14:04 2020 +0100
+++ b/kallithea/model/gist.py	Fri Oct 30 14:54:42 2020 +0100
@@ -34,9 +34,7 @@
 
 from kallithea.lib import ext_json
 from kallithea.lib.utils2 import AttributeDict, ascii_bytes, safe_int, time_to_datetime
-from kallithea.model import db, meta
-from kallithea.model.repo import RepoModel
-from kallithea.model.scm import ScmModel
+from kallithea.model import db, meta, repo, scm
 
 
 log = logging.getLogger(__name__)
@@ -58,12 +56,12 @@
 
         :param gist: gist object
         """
-        root_path = RepoModel().repos_path
+        root_path = repo.RepoModel().repos_path
         rm_path = os.path.join(root_path, db.Gist.GIST_STORE_LOC, gist.gist_access_id)
         log.info("Removing %s", rm_path)
         shutil.rmtree(rm_path)
 
-    def _store_metadata(self, repo, gist_id, gist_access_id, user_id, gist_type,
+    def _store_metadata(self, fs_repo, gist_id, gist_access_id, user_id, gist_type,
                         gist_expires):
         """
         store metadata inside the gist, this can be later used for imports
@@ -78,7 +76,7 @@
             'gist_expires': gist_expires,
             'gist_updated': time.time(),
         }
-        with open(os.path.join(repo.path, '.hg', db.Gist.GIST_METADATA_FILE), 'wb') as f:
+        with open(os.path.join(fs_repo.path, '.hg', db.Gist.GIST_METADATA_FILE), 'wb') as f:
             f.write(ascii_bytes(ext_json.dumps(metadata)))
 
     def get_gist(self, gist):
@@ -90,8 +88,8 @@
 
         :param gist_access_id:
         """
-        repo = db.Gist.get_by_access_id(gist_access_id)
-        cs = repo.scm_instance.get_changeset(revision)
+        gist_repo = db.Gist.get_by_access_id(gist_access_id)
+        cs = gist_repo.scm_instance.get_changeset(revision)
         return cs, [n for n in cs.get_node('/')]
 
     def create(self, description, owner, ip_addr, gist_mapping,
@@ -125,7 +123,7 @@
             gist.gist_access_id = str(gist.gist_id)
 
         log.debug('Creating new %s GIST repo %s', gist_type, gist.gist_access_id)
-        repo = RepoModel()._create_filesystem_repo(
+        fs_repo = repo.RepoModel()._create_filesystem_repo(
             repo_name=gist.gist_access_id, repo_type='hg', repo_group=db.Gist.GIST_STORE_LOC)
 
         processed_mapping = {}
@@ -151,9 +149,9 @@
         # fake Kallithea Repository object
         fake_repo = AttributeDict(dict(
             repo_name=os.path.join(db.Gist.GIST_STORE_LOC, gist.gist_access_id),
-            scm_instance_no_cache=lambda: repo,
+            scm_instance_no_cache=lambda: fs_repo,
         ))
-        ScmModel().create_nodes(
+        scm.ScmModel().create_nodes(
             user=owner.user_id,
             ip_addr=ip_addr,
             repo=fake_repo,
@@ -162,7 +160,7 @@
             trigger_push_hook=False
         )
 
-        self._store_metadata(repo, gist.gist_id, gist.gist_access_id,
+        self._store_metadata(fs_repo, gist.gist_id, gist.gist_access_id,
                              owner.user_id, gist.gist_type, gist.gist_expires)
         return gist
 
@@ -221,7 +219,7 @@
         self._store_metadata(gist_repo, gist.gist_id, gist.gist_access_id,
                              owner.user_id, gist.gist_type, gist.gist_expires)
 
-        ScmModel().update_nodes(
+        scm.ScmModel().update_nodes(
             user=owner.user_id,
             ip_addr=ip_addr,
             repo=fake_repo,
--- a/kallithea/model/pull_request.py	Fri Oct 30 02:14:04 2020 +0100
+++ b/kallithea/model/pull_request.py	Fri Oct 30 14:54:42 2020 +0100
@@ -36,8 +36,7 @@
 from kallithea.lib.hooks import log_create_pullrequest
 from kallithea.lib.utils import extract_mentioned_users
 from kallithea.lib.utils2 import ascii_bytes, short_ref_name, shorter
-from kallithea.model import db, meta
-from kallithea.model.notification import NotificationModel
+from kallithea.model import changeset_status, comment, db, meta, notification
 
 
 log = logging.getLogger(__name__)
@@ -114,18 +113,18 @@
             'is_mention': False,
             }
         if reviewers:
-            NotificationModel().create(created_by=user, subject=subject, body=body,
+            notification.NotificationModel().create(created_by=user, subject=subject, body=body,
                                        recipients=reviewers,
-                                       type_=NotificationModel.TYPE_PULL_REQUEST,
+                                       type_=notification.NotificationModel.TYPE_PULL_REQUEST,
                                        email_kwargs=email_kwargs)
 
         if mention_recipients:
             email_kwargs['is_mention'] = True
             subject = _('[Mention]') + ' ' + subject
             # FIXME: this subject is wrong and unused!
-            NotificationModel().create(created_by=user, subject=subject, body=body,
+            notification.NotificationModel().create(created_by=user, subject=subject, body=body,
                                        recipients=mention_recipients,
-                                       type_=NotificationModel.TYPE_PULL_REQUEST,
+                                       type_=notification.NotificationModel.TYPE_PULL_REQUEST,
                                        email_kwargs=email_kwargs)
 
         return reviewers, redundant_reviewers
@@ -272,9 +271,7 @@
             self.org_repo.scm_instance._repo[b"refs/pull/%d/head" % pr.pull_request_id] = ascii_bytes(self.org_rev)
 
         # reset state to under-review
-        from kallithea.model.changeset_status import ChangesetStatusModel
-        from kallithea.model.comment import ChangesetCommentsModel
-        comment = ChangesetCommentsModel().create(
+        new_comment = comment.ChangesetCommentsModel().create(
             text='',
             repo=self.org_repo,
             author=created_by,
@@ -282,11 +279,11 @@
             send_email=False,
             status_change=db.ChangesetStatus.STATUS_UNDER_REVIEW,
         )
-        ChangesetStatusModel().set_status(
+        changeset_status.ChangesetStatusModel().set_status(
             self.org_repo,
             db.ChangesetStatus.STATUS_UNDER_REVIEW,
             created_by,
-            comment,
+            new_comment,
             pull_request=pr,
         )
 
@@ -393,8 +390,7 @@
         pull_request = self.create_action.execute()
 
         # Close old iteration
-        from kallithea.model.comment import ChangesetCommentsModel
-        ChangesetCommentsModel().create(
+        comment.ChangesetCommentsModel().create(
             text=_('Closed, next iteration: %s .') % pull_request.url(canonical=True),
             repo=self.old_pull_request.other_repo_id,
             author=request.authuser.user_id,
--- a/kallithea/model/repo.py	Fri Oct 30 02:14:04 2020 +0100
+++ b/kallithea/model/repo.py	Fri Oct 30 14:54:42 2020 +0100
@@ -39,7 +39,7 @@
 from kallithea.lib.utils import is_valid_repo_uri, make_ui
 from kallithea.lib.utils2 import LazyProperty, get_current_authuser, obfuscate_url_pw, remove_prefix
 from kallithea.lib.vcs.backends import get_backend
-from kallithea.model import db, meta
+from kallithea.model import db, meta, scm
 
 
 log = logging.getLogger(__name__)
@@ -131,7 +131,6 @@
         from tg import tmpl_context as c
 
         import kallithea.lib.helpers as h
-        from kallithea.model.scm import ScmModel
 
         def repo_lnk(name, rtype, rstate, private, fork_of):
             return _render('repo_name', name, rtype, rstate, private, fork_of,
@@ -187,7 +186,7 @@
                                  repo.repo_state, repo.private, repo.fork),
                 "following": following(
                     repo.repo_id,
-                    ScmModel().is_following_repo(repo.repo_name, request.authuser.user_id),
+                    scm.ScmModel().is_following_repo(repo.repo_name, request.authuser.user_id),
                 ),
                 "last_change_iso": repo.last_db_change.isoformat(),
                 "last_change": last_change(repo.last_db_change),
@@ -332,8 +331,6 @@
         executed by create() repo, with exception of importing existing repos.
 
         """
-        from kallithea.model.scm import ScmModel
-
         owner = db.User.guess_instance(owner)
         fork_of = db.Repository.guess_instance(fork_of)
         repo_group = db.RepoGroup.guess_instance(repo_group)
@@ -408,7 +405,7 @@
                 self._create_default_perms(new_repo, private)
 
             # now automatically start following this repository as owner
-            ScmModel().toggle_following_repo(new_repo.repo_id, owner.user_id)
+            scm.ScmModel().toggle_following_repo(new_repo.repo_id, owner.user_id)
             # we need to flush here, in order to check if database won't
             # throw any exceptions, create filesystem dirs at the very end
             meta.Session().flush()
@@ -628,7 +625,6 @@
         Note: clone_uri is low level and not validated - it might be a file system path used for validated cloning
         """
         from kallithea.lib.utils import is_valid_repo, is_valid_repo_group
-        from kallithea.model.scm import ScmModel
 
         if '/' in repo_name:
             raise ValueError('repo_name must not contain groups got `%s`' % repo_name)
@@ -669,7 +665,7 @@
         elif repo_type == 'git':
             repo = backend(repo_path, create=True, src_url=clone_uri, bare=True)
             # add kallithea hook into this repo
-            ScmModel().install_git_hooks(repo)
+            scm.ScmModel().install_git_hooks(repo)
         else:
             raise Exception('Not supported repo_type %s expected hg/git' % repo_type)
 
--- a/kallithea/model/repo_group.py	Fri Oct 30 02:14:04 2020 +0100
+++ b/kallithea/model/repo_group.py	Fri Oct 30 14:54:42 2020 +0100
@@ -34,7 +34,7 @@
 
 import kallithea.lib.utils2
 from kallithea.lib.utils2 import LazyProperty
-from kallithea.model import db, meta
+from kallithea.model import db, meta, repo
 
 
 log = logging.getLogger(__name__)
@@ -189,7 +189,6 @@
                             perms_updates=None, recursive=None,
                             check_perms=True):
         from kallithea.lib.auth import HasUserGroupPermissionLevel
-        from kallithea.model.repo import RepoModel
 
         if not perms_new:
             perms_new = []
@@ -210,7 +209,7 @@
                 # we set group permission but we have to switch to repo
                 # permission
                 perm = perm.replace('group.', 'repository.')
-                RepoModel().grant_user_permission(
+                repo.RepoModel().grant_user_permission(
                     repo=obj, user=user, perm=perm
                 )
 
@@ -223,7 +222,7 @@
                 # we set group permission but we have to switch to repo
                 # permission
                 perm = perm.replace('group.', 'repository.')
-                RepoModel().grant_user_group_permission(
+                repo.RepoModel().grant_user_group_permission(
                     repo=obj, group_name=users_group, perm=perm
                 )
 
@@ -335,7 +334,6 @@
             raise
 
     def add_permission(self, repo_group, obj, obj_type, perm, recursive):
-        from kallithea.model.repo import RepoModel
         repo_group = db.RepoGroup.guess_instance(repo_group)
         perm = db.Permission.guess_instance(perm)
 
@@ -367,9 +365,9 @@
                 # for repos we need to hotfix the name of permission
                 _perm = perm.permission_name.replace('group.', 'repository.')
                 if obj_type == 'user':
-                    RepoModel().grant_user_permission(el, user=obj, perm=_perm)
+                    repo.RepoModel().grant_user_permission(el, user=obj, perm=_perm)
                 elif obj_type == 'user_group':
-                    RepoModel().grant_user_group_permission(el, group_name=obj, perm=_perm)
+                    repo.RepoModel().grant_user_group_permission(el, group_name=obj, perm=_perm)
                 else:
                     raise Exception('undefined object type %s' % obj_type)
             else:
@@ -391,7 +389,6 @@
         :param obj_type: user or user group type
         :param recursive: recurse to all children of group
         """
-        from kallithea.model.repo import RepoModel
         repo_group = db.RepoGroup.guess_instance(repo_group)
 
         for el in repo_group.recursive_groups_and_repos():
@@ -420,9 +417,9 @@
                     raise Exception('undefined object type %s' % obj_type)
             elif isinstance(el, db.Repository):
                 if obj_type == 'user':
-                    RepoModel().revoke_user_permission(el, user=obj)
+                    repo.RepoModel().revoke_user_permission(el, user=obj)
                 elif obj_type == 'user_group':
-                    RepoModel().revoke_user_group_permission(el, group_name=obj)
+                    repo.RepoModel().revoke_user_group_permission(el, group_name=obj)
                 else:
                     raise Exception('undefined object type %s' % obj_type)
             else:
--- a/kallithea/model/user.py	Fri Oct 30 02:14:04 2020 +0100
+++ b/kallithea/model/user.py	Fri Oct 30 14:54:42 2020 +0100
@@ -166,7 +166,7 @@
             raise
 
     def create_registration(self, form_data):
-        from kallithea.model.notification import NotificationModel
+        from kallithea.model import notification
 
         form_data['admin'] = False
         form_data['extern_type'] = db.User.DEFAULT_AUTH_TYPE
@@ -188,9 +188,9 @@
             'new_username': new_user.username,
             'new_email': new_user.email,
             'new_full_name': new_user.full_name}
-        NotificationModel().create(created_by=new_user, subject=subject,
+        notification.NotificationModel().create(created_by=new_user, subject=subject,
                                    body=body, recipients=None,
-                                   type_=NotificationModel.TYPE_REGISTRATION,
+                                   type_=notification.NotificationModel.TYPE_REGISTRATION,
                                    email_kwargs=email_kwargs)
 
     def update(self, user_id, form_data, skip_attrs=None):
@@ -315,7 +315,7 @@
         email.
         """
         from kallithea.lib.celerylib import tasks
-        from kallithea.model.notification import EmailNotificationModel
+        from kallithea.model import notification
 
         user_email = data['email']
         user = db.User.get_by_email(user_email)
@@ -336,13 +336,13 @@
             else:
                 log.debug('password reset user %s found but was managed', user)
                 token = link = None
-            reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET
-            body = EmailNotificationModel().get_email_tmpl(
+            reg_type = notification.EmailNotificationModel.TYPE_PASSWORD_RESET
+            body = notification.EmailNotificationModel().get_email_tmpl(
                 reg_type, 'txt',
                 user=user.short_contact,
                 reset_token=token,
                 reset_url=link)
-            html_body = EmailNotificationModel().get_email_tmpl(
+            html_body = notification.EmailNotificationModel().get_email_tmpl(
                 reg_type, 'html',
                 user=user.short_contact,
                 reset_token=token,