The make_eiffel_module Python script

As with Python classes (or almost all Python objects), Python modules have an attribute __dict__ which contains a basic "symbol table" for that object. In the case of a class, the class object has a symbol table containing references to each function and attribute of the class. In the case of a module, the symbol table contains those as well as class definitions.

When exporting a module into an Eiffel-compatible class, we're really concerned mostly with the functions in question (the attributes are handled by the set_attr* series of functions and generated getters, as noted earlier, and the classes can be handled by our earlier Python script as necessary). Focusing on the module itself, export and code generation can be accomplished in much the same way as it was with the user class: import the module and iterate through the __dict__ symbol table--for every item there that appears to be a function, create an analogous feature in the generated Eiffel class. This indeed can generate a single Eiffel class from a single Python module; shown below are the exported "error" attribute and the "compile" feature from the re module:

Example 10-4. Portions of the generated RE Eiffel class

class RE


   module_name : STRING is "re";
   error: PYTHON_OBJECT is
         has_attr_string( "error" )
         Result := get_attr_string( "error" )
   compile( args : ARRAY[ ANY ] ) : PYTHON_OBJECT is
         Result := call_function( "compile", python_object_factory.new_python_tuple( args ) )
   compile_python( args : PYTHON_TUPLE ) : PYTHON_OBJECT is
         Result := call_function( "compile", args )

As it happens, this does our work for us. However, we can make it do even more. Typically, users of a module are interested not just in the functions and data attributes of the module but also in all the classes it exports.