URL: https://github.com/freeipa/freeipa/pull/169
Author: tiran
 Title: #169: Replace ipaplatform's symlinks with a meta importer
Action: opened

PR body:
"""
Signed-off-by: Christian Heimes <chei...@redhat.com>
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/169/head:pr169
git checkout pr169
From 912fbed861ffd15f60f64a0d603ed190903ed3eb Mon Sep 17 00:00:00 2001
From: Christian Heimes <chei...@redhat.com>
Date: Tue, 18 Oct 2016 09:14:31 +0200
Subject: [PATCH] Replace ipaplatform's symlinks with a meta importer

Signed-off-by: Christian Heimes <chei...@redhat.com>
---
 .gitignore                 |  4 ----
 Makefile                   |  5 -----
 ipaplatform/__init__.py.in | 54 ++++++++++++++++++++++++++++++++++++++++++++--
 ipaserver/dcerpc.py        |  2 +-
 pylint_plugins.py          | 20 ++++++++++++++++-
 5 files changed, 72 insertions(+), 13 deletions(-)

diff --git a/.gitignore b/.gitignore
index 61054de..9b15475 100644
--- a/.gitignore
+++ b/.gitignore
@@ -77,7 +77,3 @@ freeipa2-dev-doc
 
 /ipaplatform/__init__.py
 /ipaplatform/setup.py
-/ipaplatform/tasks.py
-/ipaplatform/services.py
-/ipaplatform/paths.py
-/ipaplatform/constants.py
diff --git a/Makefile b/Makefile
index 6324308..0435fe9 100644
--- a/Makefile
+++ b/Makefile
@@ -197,11 +197,6 @@ version-update: release-update
 	if [ "$(SUPPORTED_PLATFORM)" != "" ]; then \
 		sed -e s/__PLATFORM__/$(SUPPORTED_PLATFORM)/ \
 			ipaplatform/__init__.py.in > ipaplatform/__init__.py; \
-		rm -f ipaplatform/paths.py ipaplatform/services.py ipaplatform/tasks.py ipaplatform/constants.py; \
-		ln -s $(SUPPORTED_PLATFORM)/paths.py ipaplatform/paths.py; \
-		ln -s $(SUPPORTED_PLATFORM)/services.py ipaplatform/services.py; \
-		ln -s $(SUPPORTED_PLATFORM)/tasks.py ipaplatform/tasks.py; \
-		ln -s $(SUPPORTED_PLATFORM)/constants.py ipaplatform/constants.py; \
 	fi
 
 	if [ "$(SKIP_API_VERSION_CHECK)" != "yes" ]; then \
diff --git a/ipaplatform/__init__.py.in b/ipaplatform/__init__.py.in
index 61f6f3c..f815118 100644
--- a/ipaplatform/__init__.py.in
+++ b/ipaplatform/__init__.py.in
@@ -5,8 +5,58 @@
 '''
 Module containing platform-specific functionality for every platform.
 '''
+import sys
 
 NAME = "__PLATFORM__"
 
-# FIXME: too much cyclic dependencies
-# from __PLATFORM__ import paths, tasks, services
+_new_module = type(sys)
+
+
+class IpaPlatformImporter(object):
+    mod_aliases = ['constants', 'paths', 'services', 'tasks']
+
+    def __init__(self, platform=NAME):
+        self.aliases = {}
+        for alias in self.mod_aliases:
+            destmodname = 'ipaplatform.{}.{}'.format(platform, alias)
+            aliasmodname = 'ipaplatform.{}'.format(alias)
+            self.aliases[aliasmodname] = destmodname
+
+    def find_module(self, fullname, path=None):
+        if fullname in self.aliases:
+            return self
+        return None
+
+    def load_module(self, fullname):
+        try:
+            return sys.modules[fullname]
+        except KeyError:
+            pass
+        try:
+            dest = self.aliases[fullname]
+        except KeyError:
+            raise ImportError(fullname)
+        # load destination
+        __import__(dest)
+        mod = sys.modules[dest]
+        # create a new module and copy module content
+        newmod = _new_module(fullname)
+        newmod.__dict__.update(mod.__dict__)
+        newmod.__loader__ = self
+        # register module
+        sys.modules[fullname] = newmod
+        return newmod
+
+    def is_package(self, fullname):
+        mod = self.load_module(fullname)
+        return hasattr(mod, '__path__')
+
+    def get_code(self, fullname):
+        self.load_module(fullname)
+        return None
+
+    def get_source(self, fullname):
+        self.load_module(fullname)
+        return None
+
+sys.meta_path.append(IpaPlatformImporter())
diff --git a/ipaserver/dcerpc.py b/ipaserver/dcerpc.py
index bd1d8c1..86fe5a0 100644
--- a/ipaserver/dcerpc.py
+++ b/ipaserver/dcerpc.py
@@ -58,7 +58,7 @@
 import pysss_nss_idmap
 import pysss
 import six
-from ipaplatform.paths import paths
+from ipaplatform.paths import paths  # pylint: disable=E0401
 
 from ldap.filter import escape_filter_chars
 from time import sleep
diff --git a/pylint_plugins.py b/pylint_plugins.py
index bf35773..be6944a 100644
--- a/pylint_plugins.py
+++ b/pylint_plugins.py
@@ -6,9 +6,11 @@
 
 import copy
 import sys
+import textwrap
 
-from astroid import MANAGER
+from astroid import MANAGER, register_module_extender
 from astroid import scoped_nodes
+from astroid.builder import AstroidBuilder
 
 
 def register(linter):
@@ -255,3 +257,19 @@ def fix_ipa_classes(cls):
         fake_class(cls, ipa_class_members[class_name_with_module])
 
 MANAGER.register_transform(scoped_nodes.Class, fix_ipa_classes)
+
+
+def ipaplatform_transform():
+    """Module aliases for IpaPlatformImporter
+    """
+    return AstroidBuilder(MANAGER).string_build(textwrap.dedent(
+        """
+        from ipaplatform.fedora import constants
+        from ipaplatform.fedora import paths
+        from ipaplatform.fedora import services
+        from ipaplatform.fedora import tasks
+        """
+    ))
+
+
+register_module_extender(MANAGER, 'ipaplatform', ipaplatform_transform)
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to