7147577 pkgdepend should no longer analyze python 2.4 modules s11u1b14
authorBrock Pytlik <brock.pytlik@oracle.com>
Fri, 13 Apr 2012 16:29:31 -0700
changeset 2655 4b375e80ded1
parent 2654 e47181db432e
child 2656 c51505c00dab
7147577 pkgdepend should no longer analyze python 2.4 modules
src/modules/flavor/depthlimitedmf24.py
src/pkg/manifests/package:pkg.p5m
src/tests/api/t_dependencies.py
src/tests/cli/t_pkgsign.py
--- a/src/modules/flavor/depthlimitedmf24.py	Fri Apr 13 15:07:56 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,371 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Python
-# Software Foundation; All Rights Reserved
-#
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-
-
-"""A standalone version of ModuleFinder which limits the depth of exploration
-for loaded modules and discovers where a module might be loaded instead of
-determining which path contains a module to be loaded.  It is designed to be run
-by python2.4 against 2.4 modules.  To communicate its results to the process
-which ran it, it prints output to stdout.  The format is to start a line with
-'DEP ' if it contains information about a dependency, and 'ERR ' if it contains
-information about a module it couldn't analyze."""
-
-# This module cannot import other pkg modules because running the 2.4
-# interpreter will overwrite the pyc files for some of the other flavor modules.
-# With 2.6, the -B option can be added to the command line invocation for the
-# subprocess and the interpreter won't overwrite pyc files.
-
-import dis
-import modulefinder
-import os
-import sys
-
-from modulefinder import LOAD_CONST, IMPORT_NAME, STORE_NAME, STORE_GLOBAL, \
-    STORE_OPS
-
-# A string used as a component of the pkg.depend.runpath value as a special
-# token to determine where to insert the runpath that pkgdepend generates itself
-# (duplicated from pkg.portable.__init__ for reasons above)
-PD_DEFAULT_RUNPATH = "$PKGDEPEND_RUNPATH"
-
-python_path = "PYTHONPATH"
-
-class ModuleInfo(object):
-        """This class contains information about from where a python module
-        might be loaded."""
-
-        def __init__(self, name, dirs, builtin=False):
-                """Build a ModuleInfo object.
-
-                The 'name' parameter is the name of the module.
-
-                The 'dirs' parameter is the list of directories where the module
-                might be found.
-
-                The 'builtin' parameter sets whether the module is a python
-                builtin (like sys)."""
-
-                self.name = name
-                self.builtin = builtin
-                self.suffixes = [".py", ".pyc", ".pyo", "/__init__.py", ".so",
-                    "module.so"]
-                self.dirs = sorted(dirs)
-
-        def make_package(self):
-                """Declare that this module is a package."""
-
-                if self.dirs:
-                        self.suffixes = ["/__init__.py"]
-                else:
-                        self.suffixes = []
-
-        def get_package_dirs(self):
-                """Get the directories where this package might be defined."""
-
-                return [os.path.join(p, self.name) for p in self.dirs]
-
-        def get_file_names(self):
-                """Return all the file names under which this module might be
-                found."""
-
-                return ["%s%s" % (self.name, suf) for suf in self.suffixes]
-
-        def __str__(self):
-                return "name:%s suffixes:%s dirs:%s" % (self.name,
-                    " ".join(self.suffixes), len(self.dirs))
-
-class MultipleDefaultRunPaths(Exception):
-
-        def __unicode__(self):
-                # To workaround python issues 6108 and 2517, this provides a
-                # a standard wrapper for this class' exceptions so that they
-                # have a chance of being stringified correctly.
-                return str(self)
-
-        def __str__(self):
-                return _(
-                    "More than one $PKGDEPEND_RUNPATH token was set on the "
-                    "same action in this manifest.")
-
-class DepthLimitedModuleFinder(modulefinder.ModuleFinder):
-
-        def __init__(self, install_dir, *args, **kwargs):
-                """Produce a module finder that ignores PYTHONPATH and only
-                reports the direct imports of a module.
-
-                run_paths as a keyword argument specifies a list of additional
-                paths to use when searching for modules."""
-
-                # ModuleFinder.__init__ doesn't expect run_paths
-                run_paths = kwargs.pop("run_paths", [])
-
-                # Check to see whether a python path has been set.
-                if python_path in os.environ:
-                        py_path = [
-                            os.path.normpath(fp)
-                            for fp in os.environ[python_path].split(os.pathsep)
-                        ]
-                else:
-                        py_path = []
-
-                # Remove any paths that start with the defined python paths.
-                new_path = [
-                    fp
-                    for fp in sys.path[1:]
-                    if not self.startswith_path(fp, py_path)
-                ]
-                new_path.append(install_dir)
-
-                if run_paths:
-                        # insert our default search path where the
-                        # PD_DEFAULT_RUNPATH token was found
-                        try:
-                                index = run_paths.index(PD_DEFAULT_RUNPATH)
-                                if index >= 0:
-                                        run_paths = run_paths[:index] + \
-                                            new_path + run_paths[index + 1:]
-                                if PD_DEFAULT_RUNPATH in run_paths:
-                                        raise MultipleDefaultRunPaths()
-                        except ValueError:
-                                # no PD_DEFAULT_PATH token, so we override the
-                                # whole default search path
-                                pass
-                        new_path = run_paths
-
-                modulefinder.ModuleFinder.__init__(self, path=new_path,
-                    *args, **kwargs)
-
-        @staticmethod
-        def startswith_path(path, lst):
-                for l in lst:
-                        if path.startswith(l):
-                                return True
-                return False
-
-        def run_script(self, pathname):
-                """Find all the modules the module at pathname directly
-                imports."""
-
-                fp = open(pathname, "r")
-                return self.load_module('__main__', fp, pathname)
-
-        def load_module(self, fqname, fp, pathname):
-                """This code has been slightly modified from the function of
-                the parent class. Specifically, it checks the current depth
-                of the loading and halts if it exceeds the depth that was given
-                to run_script."""
-
-                self.msgin(2, "load_module", fqname, fp and "fp", pathname)
-                co = compile(fp.read()+'\n', pathname, 'exec')
-                m = self.add_module(fqname)
-                m.__file__ = pathname
-                res = []
-                if co:
-                        if self.replace_paths:
-                                co = self.replace_paths_in_code(co)
-                        m.__code__ = co
-                        try:
-                                res.extend(self.scan_code(co, m))
-                        except ImportError, msg:
-                                self.msg(2, "ImportError:", str(msg), fqname,
-                                    pathname)
-                                self._add_badmodule(fqname, m)
-                self.msgout(2, "load_module ->", m)
-                return res
-
-        def scan_code(self, co, m):
-                res = []
-                code = co.co_code
-                n = len(code)
-                i = 0
-                fromlist = None
-                while i < n:
-                        c = code[i]
-                        i = i+1
-                        op = ord(c)
-                        if op >= dis.HAVE_ARGUMENT:
-                                oparg = ord(code[i]) + ord(code[i+1])*256
-                                i = i+2
-                        if op == LOAD_CONST:
-                                # An IMPORT_NAME is always preceded by a
-                                # LOAD_CONST, it's a tuple of "from" names, or
-                                # None for a regular import.  The tuple may
-                                # contain "*" for "from <mod> import *"
-                                fromlist = co.co_consts[oparg]
-                        elif op == IMPORT_NAME:
-                                assert fromlist is None or \
-                                    type(fromlist) is tuple
-                                name = co.co_names[oparg]
-                                have_star = 0
-                                if fromlist is not None:
-                                        if "*" in fromlist:
-                                                have_star = 1
-                                        fromlist = [
-                                            f for f in fromlist if f != "*"
-                                        ]
-                                res.extend(self._safe_import_hook(name, m,
-                                    fromlist))
-                        elif op in STORE_OPS:
-                                # keep track of all global names that are
-                                # assigned to
-                                name = co.co_names[oparg]
-                                m.globalnames[name] = 1
-                for c in co.co_consts:
-                    if isinstance(c, type(co)):
-                        res.extend(self.scan_code(c, m))
-                return res
-
-
-        def _safe_import_hook(self, name, caller, fromlist, level=-1):
-                """Wrapper for self.import_hook() that won't raise ImportError.
-                """
-
-                res = []
-                if name in self.badmodules:
-                        self._add_badmodule(name, caller)
-                        return []
-                try:
-                        res.extend(self.import_hook(name, caller, level=level))
-                except ImportError, msg:
-                        self.msg(2, "ImportError:", str(msg))
-                        self._add_badmodule(name, caller)
-                else:
-                        if fromlist:
-                                for sub in fromlist:
-                                        if sub in self.badmodules:
-                                                self._add_badmodule(sub, caller)
-                                                continue
-                                        res.extend(self.import_hook(name,
-                                            caller, [sub], level=level))
-                return res
-
-        def import_hook(self, name, caller=None, fromlist=None, level=-1):
-                """Find all the modules that importing name will import."""
-
-                # Special handling for os.path is needed because the os module
-                # manipulates sys.modules directly to provide both os and
-                # os.path.
-                if name == "os.path":
-                        self.msg(2, "bypassing os.path import - importing os "
-                            "instead", name, caller, fromlist, level)
-                        name = "os"
-
-                self.msg(3, "import_hook", name, caller, fromlist, level)
-                parent = self.determine_parent(caller)
-                q, tail = self.find_head_package(parent, name)
-                if not tail:
-                        # If q is a builtin module, don't report it because it
-                        # doesn't live in the normal module space and it's part
-                        # of python itself, which is handled by a different
-                        # kind of dependency.
-                        if isinstance(q, ModuleInfo) and q.builtin:
-                                return []
-                        elif isinstance(q, modulefinder.Module):
-                                name = q.__name__
-                                path = q.__path__
-                                # some Module objects don't get a path, this
-                                # isn't optimal, but it's the best we can do
-                                if not path:
-                                        if name in sys.builtin_module_names or \
-                                            name == "__future__":
-                                                return [ModuleInfo(name, [],
-                                                    builtin=True)]
-                                        else:
-                                                return [ModuleInfo(name, [])]
-                                return [ModuleInfo(name, path)]
-                        else:
-                                return [q]
-                res = self.load_tail(q, tail)
-                q.make_package()
-                res.append(q)
-                return res
-
-        def import_module(self, partname, fqname, parent):
-                """Find where this module lives relative to its parent."""
-
-                parent_dirs = None
-                self.msgin(3, "import_module", partname, fqname, parent)
-                try:
-                        m = self.modules[fqname]
-                except KeyError:
-                        pass
-                else:
-                        self.msgout(3, "import_module ->", m)
-                        return m
-                if fqname in self.badmodules:
-                        self.msgout(3, "import_module -> None")
-                        return None
-                if parent:
-                        if not parent.dirs:
-                                self.msgout(3, "import_module -> None")
-                                return None
-                        else:
-                                parent_dirs = parent.get_package_dirs()
-                try:
-                        mod = self.find_module(partname, parent_dirs, parent)
-                except ImportError:
-                        self.msgout(3, "import_module ->", None)
-                        return None
-                return mod
-
-        def find_module(self, name, path, parent=None):
-                """Calculate the potential paths on the file system where the
-                module could be found."""
-
-                if path is None:
-                    if name in sys.builtin_module_names or name == "__future__":
-                            return ModuleInfo(name, [], builtin=True)
-                    path = self.path
-                return ModuleInfo(name, path)
-
-        def load_tail(self, q, tail):
-                """Determine where each component of a multilevel import would
-                be found on the file system."""
-
-                self.msgin(4, "load_tail", q, tail)
-                res = []
-                name = q.name
-                cur_parent = q
-                while tail:
-                        i = tail.find('.')
-                        if i < 0: i = len(tail)
-                        head, tail = tail[:i], tail[i+1:]
-                        new_name = "%s.%s" % (name, head)
-                        r = self.import_module(head, new_name, cur_parent)
-                        res.append(r)
-                        name = new_name
-                        cur_parent = r
-
-                # All but the last module found must be packages because they
-                # contained other packages.
-                for i in range(0, len(res) - 1):
-                        res[i].make_package()
-
-                self.msgout(4, "load_tail ->", q)
-                return res
-
-
-if __name__ == "__main__":
-        """Usage:
-              depthlimitedmf24.py <install_path> <script>
-                  [ run_path run_path ... ]
-        """
-        run_paths = sys.argv[3:]
-        try:
-                mf = DepthLimitedModuleFinder(sys.argv[1], run_paths=run_paths)
-                loaded_modules = mf.run_script(sys.argv[2])
-                for res in set([
-                    (tuple(m.get_file_names()), tuple(m.dirs))
-                    for m in loaded_modules
-                ]):
-                        print "DEP %s" % (res,)
-                missing, maybe =  mf.any_missing_maybe()
-                for name in missing:
-                        print "ERR %s" % name,
-        except ValueError, e:
-                print "ERR %s" % e
-        except MultipleDefaultRunPaths, e:
-                print e
--- a/src/pkg/manifests/package:pkg.p5m	Fri Apr 13 15:07:56 2012 -0700
+++ b/src/pkg/manifests/package:pkg.p5m	Fri Apr 13 16:29:31 2012 -0700
@@ -117,7 +117,6 @@
 file path=$(PYDIRVP)/pkg/flavor/__init__.py
 file path=$(PYDIRVP)/pkg/flavor/base.py
 file path=$(PYDIRVP)/pkg/flavor/depthlimitedmf.py
-file path=$(PYDIRVP)/pkg/flavor/depthlimitedmf24.py
 file path=$(PYDIRVP)/pkg/flavor/depthlimitedmf27.py
 file path=$(PYDIRVP)/pkg/flavor/elf.py
 file path=$(PYDIRVP)/pkg/flavor/hardlink.py
--- a/src/tests/api/t_dependencies.py	Fri Apr 13 15:07:56 2012 -0700
+++ b/src/tests/api/t_dependencies.py	Fri Apr 13 16:29:31 2012 -0700
@@ -20,7 +20,7 @@
 # CDDL HEADER END
 #
 
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
 
 import testutils
 if __name__ == "__main__":
@@ -68,7 +68,7 @@
             "script_path": "lib/svc/method/svc-pkg-depot",
             "syslog_path": "var/log/syslog",
             "py_mod_path": "usr/lib/python2.6/vendor-packages/cProfile.py",
-            "py_mod_path24": "usr/lib/python2.4/vendor-packages/cProfile.py"
+            "py_mod_path27": "usr/lib/python2.7/vendor-packages/cProfile.py"
         }
 
         smf_paths = {
@@ -132,7 +132,7 @@
 
         python_mod_manf = """ \
 file NOHASH group=bin mode=0755 owner=root path=%(py_mod_path)s
-file NOHASH group=bin mode=0755 owner=root path=%(py_mod_path24)s
+file NOHASH group=bin mode=0755 owner=root path=%(py_mod_path27)s
 """ % paths
 
         relative_ext_depender_manf = """ \
@@ -1334,7 +1334,7 @@
                 we try to import __main__"""
 
                 t_path = self.make_manifest(self.python_mod_manf)
-                self.make_python_test_files(2.4)
+                self.make_python_test_files(2.7)
                 self.make_python_test_files(2.6)
 
                 ds, es, ms, pkg_attrs = dependencies.list_implicit_deps(t_path,
@@ -1423,7 +1423,7 @@
                 syntax error doesn't cause a traceback."""
 
                 t_path = self.make_manifest(self.python_mod_manf)
-                self.make_broken_python_test_file(2.4)
+                self.make_broken_python_test_file(2.7)
                 self.make_broken_python_test_file(2.6)
                 ds, es, ms, pkg_attrs = dependencies.list_implicit_deps(t_path,
                     [self.proto_dir], {}, [], convert=False)
@@ -1681,7 +1681,7 @@
                 str(elf.UnsupportedDynamicToken("/proto_path", "/install",
                     "run_path", "tok"))
                 str(py.PythonModuleMissingPath("foo", "bar"))
-                str(py.PythonMismatchedVersion("2.4", "2.6", "foo", "bar"))
+                str(py.PythonMismatchedVersion("2.7", "2.6", "foo", "bar"))
                 str(py.PythonSubprocessError(2, "foo", "bar"))
                 str(py.PythonSubprocessBadLine("cmd", ["l1", "l2"]))
                 mi = dlmf.ModuleInfo("name", ["/d1", "/d2"])
--- a/src/tests/cli/t_pkgsign.py	Fri Apr 13 15:07:56 2012 -0700
+++ b/src/tests/cli/t_pkgsign.py	Fri Apr 13 16:29:31 2012 -0700
@@ -65,7 +65,7 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/bin
             add dir mode=0755 owner=root group=bin path=/bin/example_dir
-            add dir mode=0755 owner=root group=bin path=/usr/lib/python2.4/vendor-packages/OpenSSL
+            add dir mode=0755 owner=root group=bin path=/usr/lib/python2.7/vendor-packages/OpenSSL
             add file tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path
             add set name=com.sun.service.incorporated_changes value="6556919 6627937"
             add set name=com.sun.service.random_test value=42 value=79
@@ -2844,7 +2844,7 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/bin
             add dir mode=0755 owner=root group=bin path=/bin/example_dir
-            add dir mode=0755 owner=root group=bin path=/usr/lib/python2.4/vendor-packages/OpenSSL
+            add dir mode=0755 owner=root group=bin path=/usr/lib/python2.7/vendor-packages/OpenSSL
             add file tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path
             add set name=com.sun.service.incorporated_changes value="6556919 6627937"
             add set name=com.sun.service.random_test value=42 value=79