[Python-checkins] r52288 - sandbox/trunk/import_in_py/importer.py

brett.cannon python-checkins at python.org
Thu Oct 12 00:39:16 CEST 2006


Author: brett.cannon
Date: Thu Oct 12 00:39:15 2006
New Revision: 52288

Modified:
   sandbox/trunk/import_in_py/importer.py
Log:
Flesh out PTL example and make bytecode handler abstract out more of handling
source code.


Modified: sandbox/trunk/import_in_py/importer.py
==============================================================================
--- sandbox/trunk/import_in_py/importer.py	(original)
+++ sandbox/trunk/import_in_py/importer.py	Thu Oct 12 00:39:15 2006
@@ -41,14 +41,22 @@
       not have an importer that can handle them so they can be retried at the
       next needed import (that was not found in sys.modules).
       
-XXX Use cases to consider:
-    * PTL files (from Quixote)
-        + Tweaked source files that need to be pre-processed before they are imported.
-        + Should be able to write out bytecode files.
-            - Need to make it easy for .pyc file output, or should just have them use their
-              own file extension?
-        + Should let them use as much base infrastructure from the source and bytecode
-          handlers as possible along with the filesystem importer/loader.
+XXX PTL use-case:
+    * Tweaked source files that need to be pre-processed before they are imported.
+    * Should be able to write out bytecode files easily.
+    * Should let them use as much base infrastructure from the source and bytecode
+      handlers as possible along with the filesystem importer/loader.
+    * Expected implementaiton
+        + Source handler
+            - Set 'handles' to source extension
+                * 'ptl'
+            - Override get_code()
+                * Read PTL source.
+                * Translate as needed.
+                * Generate code object.
+        + Bytecode handler
+            - Set 'handles' to bytecode extension
+                * 'ptlc'
 
 """
 from __future__ import with_statement
@@ -192,15 +200,19 @@
     """Handler for importing Python source modules."""
 
     handles = 'py'
+    
+    def get_code(self, file_path):
+        """Return the code object as stored at file_path."""
+        with open(file_path, 'rU') as source_file:
+            source_code = source_file.read()
+        return compile(source_code, file_path, 'exec')      
 
     def handle_file(self, module, fullname, path, file_path):
         """Import the Python source file at 'path' and use it to initialize
         'module'."""
         module.__file__ = file_path
         module.__name__ = fullname
-        with open(file_path, 'rU') as source_file:
-            source_code = source_file.read()
-        compiled_code = compile(source_code, file_path, 'exec')
+        compiled_code =  self.get_code(file_path)
         exec compiled_code in module.__dict__
         return module
 
@@ -213,6 +225,10 @@
     # that if the .pyc is outdated it can easily use PySourceHandler to do the
     # import for it and then write out the new .pyc .
     # XXX Writing out a new .pyc should be made optional.
+    
+    def __init__(self, source=None):
+        """Store a source handler in case bytecode is invalid."""
+        self.source_handler = source
 
     def _handles(self):
         """Return either 'pyc' or 'pyo' based on __debug__."""
@@ -223,8 +239,11 @@
     def find_source(self, bytecode_path):
         """Return the path to the source file for the bytecode or None if it
         was not found."""
-        # XXX Might be nicer to not hard-code this and instead work off of a handler.
-        source_path = bytecode_path[:-1]
+        if self.source_handler is None:
+            return None
+        source_ext = self.source_handler.handles
+        bytecode_base, bytecode_ext = os.path.splitext(bytecode_path)
+        source_path = bytecode_base + '.' + source_ext
         return source_path if os.path.exists(source_path) else None
     
     def validate_magic(self, marshalled_magic):
@@ -251,19 +270,13 @@
         code object created."""
         raise NotImplementedError("need to be able to marshal longs directly")
         # XXX Need to be expose Python/marshal.c:w_long()
-        marshalled_magic = marshal.loads(imp.get_magic())
         timestamp = os.stat(source_path).st_mtime
-        marshalled_timestamp = marshal.loads(timestamp)
-        with open(source_path, 'rU') as source_file:
-            source_code = source_file.read()
-        code_object = compile(source_code, source_path, 'exec')
+        code_object = self.source_handler.get_code(source_path)
         with open(bytecode_path, 'wb') as bytecode_file:
-            bytecode_file.write(marshalled_magic)
-            bytecode_file.write(marshalled_timestamp)
+            marshal.dump(imp.get_magic(), bytecode_file)
+            marshal.dump(timestamp, bytecode_file)
             marshal.dump(code_object, bytecode_file)
         return code_object
-        
-        
 
     def handle_file(self, module, fullname, path, file_path):
         """Import the Python bytecode file at 'path' and use it to initialize
@@ -284,4 +297,4 @@
         exec compiled_code in module.__dict__
         module.__file__ = file_path
         module.__name__ = fullname
-        return module
+        return module
\ No newline at end of file


More information about the Python-checkins mailing list