Richard Jones wrote:

The import trickery is to allow users to "import pyglet" and then
refer to any sub-module with no further imports; but without requiring
that the "pyglet" module actually import all those sub-modules until
they're needed.

I've developed a scheme for doing this in PyGUI that you
might like to take a look at. It involves replacing the
top-level module with a subclass that does the importing
the first time something from a submodule is referenced.

No proxy objects are used anywhere -- when you ask for
something, you get exactly what you expected.

The relevant code is in the attachment starting with
class AutoloadingModule.

--
Greg
#--------------------------------------------------------------------
#
#   PyGUI - Top level package initialisation
#
#--------------------------------------------------------------------

import sys, types

#  The first item of each of the following pairs is the name of a module
#  to try to import. If the import is successful, the platform-dependent
#  directory named by the second item is used.

_versions = [
        ("objc", "Cocoa"),
        ("nt", "Win32"),
        ("gtk", "Gtk"),
]

#
#  The environment variable PYGUI_IMPLEMENTATION may be set to the
#  name of one of the platform-dependent directories to force that
#  implementation to be used. This can be useful if more than one
#  PyGUI implementation is usable on your setup.
#

from os import environ as _env
_platdir = _env.get("PYGUI_IMPLEMENTATION")
if not _platdir:
        for _testmod, _platdir in _versions:
                try:
                        __import__(_testmod)
                        break
                except ImportError:
                        continue
        else:
                raise ImportError("Unable to find an implementation of PyGUI 
for this installation")

if _env.get("PYGUI_IMPLEMENTATION_DEBUG"):
        print "PyGUI: Using implementation:", _platdir

#
#  Append the chosen platform-dependent directory to the search
#  path for submodules of this package.
#

from os.path import join as _join
_here = __path__[0]
__path__.append(_join(_here, _platdir))
__path__.append(_join(_here, "Generic"))

#
#  Autoloading machinery. Arranges things so that referring to
#  an undefined name in the GUI module causes an attempt to
#  import it from the appropriate submodule.
#

class AutoloadingModule(types.ModuleType):
        
        def __getattr__(self, name):
                #print "AutoloadingModule.__getattr__", repr(name)
                modname = __automap__.get(name)
                if modname == "*": # is a submodule
                        raise AttributeError
                try:
                        if not modname:
                                raise ImportError("No autoload mapping for name 
%s in module %s" %
                                        (name, self.__name__))
                        #print "AutoloadingModule: Attempting to import", 
repr(modname)
                        module = __import__(modname, self.__dict__, locals(), 
[name])
                        #print "AutoloadingModule: Imported", module
                        attr = getattr(module, name)
                        setattr(self, name, attr)
                        return attr
                except:
                        import os, sys, traceback
                        #  Exception sometimes gets swallowed here, so report 
it ourselves.
                        #print "AutoloadingModule.__getattr__:", sys.exc_info() 
###
                        traceback.print_stack()
                        print >>sys.stderr, "Failed to import %r from %s" % 
(name, modname)
                        traceback.print_exc()
                        os._exit(1)

__automap__ = {}

#
#  The following function declares a list of names to be autoloaded
#  from a specified module.
#

def autoload(modname, *args):
        for namestr in args:
                names = namestr.split(",")
                for name in names:
                        __automap__[name.strip()] = modname

def submodule(modname):
        __automap__[modname] = "*"

#
#  Now import or autoload all the stuff to be made public.
#

from Version import version

autoload("Actions", "Action")
autoload("AlertFunctions",
        "alert, alert2, alert3, stop_alert, note_alert, confirm, ask",
        "confirm_or_cancel, ask_or_cancel")
autoload("Applications", "Application")
autoload("Buttons", "Button")
autoload("Canvases", "Canvas")
autoload("CheckBoxes", "CheckBox")
autoload("Colors", "Color, rgb")
autoload("Components", "Component")
autoload("Cursors", "Cursor")
autoload("Dialogs", "Dialog")
autoload("Documents", "Document")
autoload("DrawableContainers", "DrawableContainer")
autoload("Events", "Event")
autoload("Exceptions", "Cancel, ResourceNotFoundError, ApplicationError")
autoload("FileDialogs",
        "request_old_file, request_new_file",
        "request_old_files, request_old_directory",
        "request_old_directories, request_new_directory")
autoload("Files", "FileRef, DirRef, FileType")
autoload("Fonts", "Font")
autoload("Frames", "Frame")
autoload("Globals", "application, run")
autoload("ImageBases", "ImageBase")
autoload("Images", "Image")
autoload("Labels", "Label")
autoload("Menus", "Menu, MenuItem")
autoload("MenuLists", "MenuList")
autoload("MessageHandlers", "MessageHandler")
autoload("ModalDialogs", "ModalDialog")
autoload("Models", "Model")
autoload("Printing", "PageSetup, present_page_setup_dialog")
# from Pictures import Picture
autoload("Pixmaps", "Pixmap")
autoload("Properties import Properties, overridable_property")
autoload("RadioButtons", "RadioButton")
autoload("RadioGroups", "RadioGroup")
autoload("Resources", "resource_path, find_resource")
autoload("Layout", "Row,Column,Grid")
autoload("ScrollableViews", "ScrollableView")
autoload("Sliders", "Slider")
autoload("StdButtons", "DefaultButton, CancelButton")
submodule("StdColors")
submodule("StdCursors")
submodule("StdFonts")
submodule("StdMenus")
autoload("Tasks", "Task")
autoload("TextFields", "TextField")
autoload("TextEditors", "TextEditor")
# ##from TextModels import TextModel
# ##from TextViews import TextView
autoload("ViewBases", "ViewBase")
autoload("Views", "View")
autoload("Windows", "Window")

from Resources import _add_file_path, _add_module_path
import __main__
_add_file_path(__file__)
_add_module_path(__main__)
_add_module_path(__main__, 1)
#print "GUI: resource_path =", resource_path ###

import GUI
module = AutoloadingModule(GUI.__name__)
module.__dict__.update(GUI.__dict__)
sys.modules["GUI"] = module

-- 
You received this message because you are subscribed to the Google Groups 
"pyglet-users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/pyglet-users?hl=en.

Reply via email to