1.1 --- a/classhook.py Thu Dec 09 20:51:18 2004 +0100
1.2 +++ b/classhook.py Fri Dec 10 01:04:59 2004 +0100
1.3 @@ -260,11 +260,6 @@
1.4 global_names = module.__dict__
1.5 global_names["__builtins__"] = __builtins__
1.6
1.7 - # Process each class file, producing a genuine Python class.
1.8 -
1.9 - class_files = []
1.10 - classes = []
1.11 -
1.12 # Get the real filename.
1.13
1.14 filename = self._get_path_in_archive(filename)
1.15 @@ -312,27 +307,69 @@
1.16
1.17 position += 1
1.18
1.19 - class_files = [class_files[class_name] for class_name in class_file_index]
1.20 + # Process each class file, producing a genuine Python class.
1.21 + # Create the classes, but establish a proper initialisation order.
1.22
1.23 - for class_file in class_files:
1.24 + class_file_init_index = []
1.25 + class_file_init = {}
1.26 +
1.27 + for class_name in class_file_index:
1.28 + print "* Class", class_name
1.29 + class_file = class_files[class_name]
1.30 translator = bytecode.ClassTranslator(class_file)
1.31 cls, external_names = translator.process(global_names)
1.32 module.__dict__[cls.__name__] = cls
1.33 - classes.append((cls, class_file))
1.34 +
1.35 + # Process external names.
1.36
1.37 - # Import the local names.
1.38 + this_class_name_parts = class_file.this_class.get_python_name().split(".")
1.39 + this_class_module, this_class_name = this_class_name_parts[:-1], this_class_name_parts[-1]
1.40
1.41 for external_name in external_names:
1.42 + print "* Name", external_name
1.43 external_name_parts = external_name.split(".")
1.44 - if len(external_name_parts) > 1:
1.45 - external_module_name = ".".join(external_name_parts[:-1])
1.46 + external_class_module, external_class_name = external_name_parts[:-1], external_name_parts[-1]
1.47 +
1.48 + # Names not local to this package need importing.
1.49 +
1.50 + if len(external_name_parts) > 1 and this_class_module != external_class_module:
1.51 +
1.52 + external_module_name = ".".join(external_class_module)
1.53 print "* Importing", external_module_name
1.54 obj = __import__(external_module_name, global_names, {}, [])
1.55 global_names[external_name_parts[0]] = obj
1.56
1.57 + # Names local to this package may affect initialisation order.
1.58 +
1.59 + elif external_class_name not in class_file_init_index:
1.60 + try:
1.61 + this_class_name_index = class_file_init_index.index(this_class_name)
1.62 +
1.63 + # Either insert this name before the current class's
1.64 + # name.
1.65 +
1.66 + print "* Inserting", external_class_name
1.67 + class_file_init_index.insert(this_class_name_index, external_class_name)
1.68 +
1.69 + except ValueError:
1.70 +
1.71 + # Or add this name in anticipation of the current
1.72 + # class's name appearing.
1.73 +
1.74 + print "* Including", external_class_name
1.75 + class_file_init_index.append(external_class_name)
1.76 +
1.77 + # Add this class name to the initialisation index.
1.78 +
1.79 + if class_name not in class_file_init_index:
1.80 + class_file_init_index.append(this_class_name)
1.81 + class_file_init[this_class_name] = (cls, class_file)
1.82 +
1.83 # Finally, call __clinit__ methods for all relevant classes.
1.84
1.85 - for cls, class_file in classes:
1.86 + print "** Initialisation order", class_file_init_index
1.87 + for class_name in class_file_init_index:
1.88 + cls, class_file = class_file_init[class_name]
1.89 print "**", cls, class_file
1.90 if hasattr(cls, "__clinit__"):
1.91 eval(cls.__clinit__.func_code, global_names)