javaclass

Change of classhook.py

84:eb71e53b14ce
classhook.py
     1.1 --- a/classhook.py	Thu Dec 09 20:50:19 2004 +0100
     1.2 +++ b/classhook.py	Thu Dec 09 20:51:18 2004 +0100
     1.3 @@ -105,6 +105,31 @@
     1.4  
     1.5      "A class providing support for searching directories for supported files."
     1.6  
     1.7 +    def find_module(self, name, path=None):
     1.8 +
     1.9 +        """
    1.10 +        Find the module with the given 'name', using the given 'path' to locate
    1.11 +        it. Note that ModuleLoader.find_module is almost sufficient, but does
    1.12 +        not provide enough support for "package unions" where the root of a
    1.13 +        package hierarchy may appear in several places.
    1.14 +
    1.15 +        Return a list of locations (each being the "stuff" data structure used
    1.16 +        by load_module); this replaces the single "stuff" value or None returned
    1.17 +        by ModuleLoader.find_module.
    1.18 +        """
    1.19 +
    1.20 +        if path is None:
    1.21 +            path = [None] + self.default_path()
    1.22 +
    1.23 +        found_locations = []
    1.24 +
    1.25 +        for dir in path:
    1.26 +            stuff = self.find_module_in_dir(name, dir)
    1.27 +            if stuff:
    1.28 +                found_locations.append(stuff)
    1.29 +
    1.30 +        return found_locations
    1.31 +
    1.32      def find_module_in_dir(self, name, dir, allow_packages=1):
    1.33  
    1.34          """
    1.35 @@ -196,107 +221,121 @@
    1.36      def load_module(self, name, stuff):
    1.37  
    1.38          """
    1.39 -        Load the module with the given 'name', whose 'stuff' which describes the
    1.40 -        location of the module is a tuple of the form (file, filename, (suffix,
    1.41 -        mode, data type)). Return a module object or raise an ImportError if a
    1.42 -        problem occurred in the import operation.
    1.43 +        Load the module with the given 'name', with a list of 'stuff' items,
    1.44 +        each of which describes the location of the module and is a tuple of the
    1.45 +        form (file, filename, (suffix, mode, data type)).
    1.46 +
    1.47 +        Return a module object or raise an ImportError if a problem occurred in
    1.48 +        the import operation.
    1.49 +
    1.50 +        Note that the 'stuff' parameter is a list and not a single item as in
    1.51 +        ModuleLoader.load_module. This should still work, however, since the
    1.52 +        find_module method produces such a list.
    1.53          """
    1.54  
    1.55 -        # Just go into the directory and find the class files.
    1.56 -
    1.57 -        archive, filename, info = stuff
    1.58 -        suffix, mode, datatype = info
    1.59 -        if datatype not in (JAVA_PACKAGE, JAVA_ARCHIVE):
    1.60 -            return ihooks.ModuleLoader.load_module(self, name, stuff)
    1.61 -
    1.62 -        #print "Loading", archive, filename, info
    1.63 -
    1.64          # Set up the module.
    1.65 +        # A union of all locations is placed in the module's path.
    1.66  
    1.67          module = self.hooks.add_module(name)
    1.68 -        module.__path__ = [filename]
    1.69 +        module.__path__ = [item_filename for (item_archive, item_filename, item_info) in stuff]
    1.70  
    1.71 -        # Prepare a dictionary of globals.
    1.72 +        # Just go into each package and find the class files.
    1.73  
    1.74 -        global_names = module.__dict__
    1.75 -        global_names["__builtins__"] = __builtins__
    1.76 +        for stuff_item in stuff:
    1.77  
    1.78 -        # Process each class file, producing a genuine Python class.
    1.79 +            # Extract the details, delegating loading responsibility to the
    1.80 +            # default loader where appropriate.
    1.81 +            # NOTE: Should we not be using some saved loader remembered upon
    1.82 +            # NOTE: installation?
    1.83  
    1.84 -        class_files = []
    1.85 -        classes = []
    1.86 +            archive, filename, info = stuff_item
    1.87 +            suffix, mode, datatype = info
    1.88 +            if datatype not in (JAVA_PACKAGE, JAVA_ARCHIVE):
    1.89 +                return ihooks.ModuleLoader.load_module(self, name, stuff_item)
    1.90  
    1.91 -        # Get the real filename.
    1.92 +            #print "Loading", archive, filename, info
    1.93  
    1.94 -        filename = self._get_path_in_archive(filename)
    1.95 -        #print "Real filename", filename
    1.96 +            # Prepare a dictionary of globals.
    1.97  
    1.98 -        # Load the class files.
    1.99 +            global_names = module.__dict__
   1.100 +            global_names["__builtins__"] = __builtins__
   1.101 +
   1.102 +            # Process each class file, producing a genuine Python class.
   1.103  
   1.104 -        class_files = {}
   1.105 -        for class_filename in self.hooks.matching(filename, os.extsep + "class", archive):
   1.106 -            #print "Loading class", class_filename
   1.107 -            s = self.hooks.read(class_filename, archive)
   1.108 -            class_file = classfile.ClassFile(s)
   1.109 -            class_files[str(class_file.this_class.get_name())] = class_file
   1.110 +            class_files = []
   1.111 +            classes = []
   1.112 +
   1.113 +            # Get the real filename.
   1.114  
   1.115 -        # Get an index of the class files.
   1.116 +            filename = self._get_path_in_archive(filename)
   1.117 +            #print "Real filename", filename
   1.118  
   1.119 -        class_file_index = class_files.keys()
   1.120 +            # Load the class files.
   1.121  
   1.122 -        # NOTE: Unnecessary sorting for test purposes.
   1.123 -
   1.124 -        class_file_index.sort()
   1.125 +            class_files = {}
   1.126 +            for class_filename in self.hooks.matching(filename, os.extsep + "class", archive):
   1.127 +                #print "Loading class", class_filename
   1.128 +                s = self.hooks.read(class_filename, archive)
   1.129 +                class_file = classfile.ClassFile(s)
   1.130 +                class_files[str(class_file.this_class.get_name())] = class_file
   1.131  
   1.132 -        # Now go through the classes arranging them in a safe loading order.
   1.133 +            # Get an index of the class files.
   1.134 +
   1.135 +            class_file_index = class_files.keys()
   1.136  
   1.137 -        position = 0
   1.138 -        while position < len(class_file_index):
   1.139 -            class_name = class_file_index[position]
   1.140 -            super_class_name = str(class_files[class_name].super_class.get_name())
   1.141 +            # NOTE: Unnecessary sorting for test purposes.
   1.142 +
   1.143 +            class_file_index.sort()
   1.144  
   1.145 -            # Discover whether the superclass appears later.
   1.146 +            # Now go through the classes arranging them in a safe loading order.
   1.147  
   1.148 -            try:
   1.149 -                super_class_position = class_file_index.index(super_class_name)
   1.150 -                if super_class_position > position:
   1.151 +            position = 0
   1.152 +            while position < len(class_file_index):
   1.153 +                class_name = class_file_index[position]
   1.154 +                super_class_name = str(class_files[class_name].super_class.get_name())
   1.155  
   1.156 -                    # If the superclass appears later, swap this class and the
   1.157 -                    # superclass, then process the superclass.
   1.158 +                # Discover whether the superclass appears later.
   1.159  
   1.160 -                    class_file_index[position] = super_class_name
   1.161 -                    class_file_index[super_class_position] = class_name
   1.162 -                    continue
   1.163 +                try:
   1.164 +                    super_class_position = class_file_index.index(super_class_name)
   1.165 +                    if super_class_position > position:
   1.166 +
   1.167 +                        # If the superclass appears later, swap this class and the
   1.168 +                        # superclass, then process the superclass.
   1.169  
   1.170 -            except ValueError:
   1.171 -                pass
   1.172 +                        class_file_index[position] = super_class_name
   1.173 +                        class_file_index[super_class_position] = class_name
   1.174 +                        continue
   1.175  
   1.176 -            position += 1
   1.177 +                except ValueError:
   1.178 +                    pass
   1.179  
   1.180 -        class_files = [class_files[class_name] for class_name in class_file_index]
   1.181 +                position += 1
   1.182  
   1.183 -        for class_file in class_files:
   1.184 -            translator = bytecode.ClassTranslator(class_file)
   1.185 -            cls, external_names = translator.process(global_names)
   1.186 -            module.__dict__[cls.__name__] = cls
   1.187 -            classes.append((cls, class_file))
   1.188 +            class_files = [class_files[class_name] for class_name in class_file_index]
   1.189  
   1.190 -            # Import the local names.
   1.191 +            for class_file in class_files:
   1.192 +                translator = bytecode.ClassTranslator(class_file)
   1.193 +                cls, external_names = translator.process(global_names)
   1.194 +                module.__dict__[cls.__name__] = cls
   1.195 +                classes.append((cls, class_file))
   1.196 +
   1.197 +                # Import the local names.
   1.198  
   1.199 -            for external_name in external_names:
   1.200 -                external_name_parts = external_name.split(".")
   1.201 -                if len(external_name_parts) > 1:
   1.202 -                    external_module_name = ".".join(external_name_parts[:-1])
   1.203 -                    print "* Importing", external_module_name
   1.204 -                    obj = __import__(external_module_name, global_names, {}, [])
   1.205 -                    global_names[external_name_parts[0]] = obj
   1.206 +                for external_name in external_names:
   1.207 +                    external_name_parts = external_name.split(".")
   1.208 +                    if len(external_name_parts) > 1:
   1.209 +                        external_module_name = ".".join(external_name_parts[:-1])
   1.210 +                        print "* Importing", external_module_name
   1.211 +                        obj = __import__(external_module_name, global_names, {}, [])
   1.212 +                        global_names[external_name_parts[0]] = obj
   1.213  
   1.214 -        # Finally, call __clinit__ methods for all relevant classes.
   1.215 +            # Finally, call __clinit__ methods for all relevant classes.
   1.216  
   1.217 -        for cls, class_file in classes:
   1.218 -            print "**", cls, class_file
   1.219 -            if hasattr(cls, "__clinit__"):
   1.220 -                eval(cls.__clinit__.func_code, global_names)
   1.221 +            for cls, class_file in classes:
   1.222 +                print "**", cls, class_file
   1.223 +                if hasattr(cls, "__clinit__"):
   1.224 +                    eval(cls.__clinit__.func_code, global_names)
   1.225  
   1.226          return module
   1.227