ANN: experimental patch to allow importing from file-like objects

Gerson Kurz gerson.kurz at t-online.de
Fri Mar 1 13:50:34 EST 2002


Motivation: Write a customized import that reads data from encrypted
files. Both execfile() and exec() are limited, if only that that they
don't mimic the import syntax. 

Problem: imp.load_module does expect a file object, but you can only
pass "real" files, not file-like objects. The internal C-code expects
native FILE* stuff.

Solution: An experimental patch to the python22.dll that makes this
possible. Using file-like objects for import opens up a whole new set
of possibilities, for example you could fetch the code at runtime from
a database or a socket. 

Limitations: 
- Currently, Win32 only. 
- Currently, you can only import source from file-like objects, not
precompiled binaries. 
- Currently, error handling is completely undefined.

Sample Code:

import imp, os, rotor

# sample code ***************************************
source = """
print 'Inside encrypted code'
variable = 123
"""
# generate encrypted file ***************************
file = open("test.raw","wb")
rt = rotor.newrotor('key', 12)
file.write( rt.encrypt(source) )
file.close()

# sample file class, that reads data from encrypted file
class my_file_class:
    def __init__(self,filename):
        rt = rotor.newrotor('key', 12)
        self.lines = rt.decrypt(open(filename).read()).split('\n')
        print "read", len(self.lines), "lines from encrypted file"


    def read(self,size):
        if self.lines:
            line = self.lines[0]
            # must make sure line ends with \n
            if not line:
                line = '\n'
            elif not (line[-1] == '\n'):
                line += '\n'
            self.lines = self.lines[1:]
            return line

# redirect import hook ******************************
old_import_func = __import__

def my_import_func(name, globals=None, locals=None, fromlist=None):
    global old_import_func
    
    if name == "encrypted_test":
        return imp.load_module(name,
                               my_file_class("test.raw"),
                               "test.raw",
                               ('.raw','rb',imp.PY_FILEOBJECT_SOURCE))


    # use original code    
    return old_import_func( name, globals, locals, fromlist )

__builtins__.__import__ = my_import_func

# test code
import encrypted_test
print encrypted_test.variable

Download:
http://p-nand-q.com/python/pyimport.zip

More technical details:
http://p-nand-q.com/pyimport.htm (at the bottom)

Now what? PEP-stuff? Or completely uninteresting? 




More information about the Python-list mailing list