summaryrefslogtreecommitdiff
path: root/cad/src/exprs/__Symbols__.py
blob: 3a6fabf11a1cb80dfd57c694462318d4a1aed0bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# Copyright 2006-2007 Nanorex, Inc.  See LICENSE file for details.
"""
__Symbols__.py -- support for "from __Symbols__ import xxx",
to make a shared Symbol object within the exprs module.

$Id$

NOTE: This module replaces its entry in sys.modules with a
_FakeModule_for_Symbols object. That object probably doesn't support reload.
So this module is effectively not reloadable.

TODO: it might be possible to make this reloadable
by passing in a new version of getattr_func,
or if the reload would occur in here, passing in a
source for new getattr_funcs. The Python 2.3 new import hooks
might also help with this. Details not yet analyzed.
"""
__author__ = "bruce" # (but I took the idea of _FakeModule_for_Symbols
    # from Pmw == Python Megawidgets)

from exprs.Exprs import Symbol
    ### TODO: remove this import cycle, here or (preferably?) in Exprs

class _FakeModule_for_Symbols:
    """
    An object which can take the place of a real module
    in sys.modules, for some purposes. Used as a singleton.
    Comments and messages assume it's used to create "Symbols".
    """
    # make sure all of our private attrs or methods start with '__'
    __getattr_func = None # initial value of instance variable
    def __init__(self, name, getattr_func = None):
        self.__name__ = name
        # note: self.__file__ can be assigned by caller, if it wants
        self.__path__ = "fakepath/" + name
            #k ok? maybe not, it might be some sort of dotted import path --
            # better look it up ####@@@@
        self.__set_getattr_func(getattr_func) # might be None
    def __repr__(self): # only used in bug messages; UNTESTED
        return "<%s(%r) at %#x>" % (self.__class__.__name__, self.__name__, id(self))
    def __set_getattr_func(self, getattr_func):
        assert self.__getattr_func is None
        self.__getattr_func = getattr_func
    def __clear_getattr_func(self):
        # not yet used
        self.__set_getattr_func(None)
    def __getattr__(self, attr): # in class _FakeModule_for_Symbols
        if attr.startswith('__'):
            raise AttributeError, attr
        assert self.__getattr_func, "bug: symbol source not yet set in %r" % (self,)
        res = self.__getattr_func(attr)
        setattr(self, attr, res) # cache the value of this attr for reuse
        return res
    pass

import sys


## print "__name__ of exprs.__Symbols__ is %r" % (__name__,) # 'exprs.__Symbols__'
## print dir() # ['_FakeModule_for_Symbols', 'Symbol', '__author__', '__builtins__',
##   # '__doc__', '__file__', '__name__', 'sys']


sys.modules[__name__] = fakemodule = _FakeModule_for_Symbols(__name__, Symbol)

fakemodule.__file__ = __file__
    # REVIEW: does __file__ work in a Windows release build?
    # Guess: yes, since this is also assumed in canon_image_filename (exprs/images.py)
    # which I think is always run due to confirmation corner.
    # It doesn't exist in __main__ (or didn't at one time anyway)
    # but I guess that's a special case. It would be good to confirm all this.
    # [bruce 080111 comment]
fakemodule.__doc__ = __doc__
# note: __name__ and __path__ are set inside _FakeModule_for_Symbols.__init__

"""
>>> print dir(fakemodule)
fyi: fakemodule getattr got __members__
fyi: fakemodule getattr got __methods__
['_FakeModule__getattr_func', '__doc__', '__file__', '__getattr__', '__init__', '__module__', '__name__', '__path__']
"""

# end