summaryrefslogtreecommitdiff
path: root/cad/src/exprs/reload.py
blob: f5fcfd96e51c479ec5b92c713de2e5c352e02e35 (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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# Copyright 2006-2007 Nanorex, Inc.  See LICENSE file for details. 

"""
reload.py -- handle dynamic reloading of code for developers

$Id$

Note: as of 070921 reload_once is no longer called except in testdraw.py.
"""

from utilities import debug_flags
import utilities.EndUser as EndUser
from utilities.debug import reload_once_per_event

ENABLE_RELOAD = True and debug_flags.atom_debug

# WARNING: the reload feature implemented herein has become broken, probably
# ever since the confirmation corner started importing exprs modules without
# using reload_once. Its calls were then significantly modified when import *
# was removed from exprs, which may have further broken it, but this is
# unknown. It should be considered dead until it can be analyzed and fixed,
# or preferably, replaced with a better feature. The above init of ENABLE_RELOAD
# is safe enough for now, since it only sets it when ATOM_DEBUG is turned on
# before this module is first imported (probably at startup due to confirmation
# corner imports of other exprs modules -- not sure). [bruce 070829 comment]

# ==

#bruce 071102 moved vv from testdraw and renamed it vv -> exprs_globals,
# to avoid an import cycle.

class _attrholder: pass


try:
    # see whether this module was loaded before; if so, don't disturb
    # these globals unless we've modified this code by adding globals
    exprs_globals
    exprs_globals.reload_counter
        # note: this is public, used by other modules
    exprs_globals.start_time
##    exprs_globals.state
##    exprs_globals.havelist
except:
    # the module wasn't loaded before, or we added globals --
    # reinitialize all these globals
    exprs_globals = _attrholder()
    exprs_globals.reload_counter = -1
    exprs_globals.start_time = -1
##    exprs_globals.state = {} # prototype of a place to store persistent state (presuming some persistent way of allocating keys, eg hardcoding)
##    ##e should modify to make it easier to set up defaults; sort of like a debug_pref?
##    exprs_globals.havelist = False

# ==

def reload_once(module):
    """
    This function is used to support automatic runtime reloading of modules
    within this package, for developer convenience. To use it, add this code
    before any import of symbols from a module (or use this code in place of
    any direct import of a module):

    #  import module
    #  reload_once(module)

    Warning: not all modules support runtime reload. Those that don't should
    say so in their docstrings.
    
    Warning: this system does not yet properly handle indirect imports, when
    only the inner module has been modified. See code comments for details,
    especially the docstring of debug.reload_once_per_event(). As a workaround,
    if A imports B and you edit B.py, also edit A.py in order to trigger the
    desired runtime reload of B.py.
    """

    # this comment become obsolete when exprs.basic was split into separate files:    
    ##Note: this function's module (exprs.basic itself) is fast and harmless enough to reload that it can be
    ##reloaded on every use, without bothering to use reload_once. Therefore, external callers of anything
    ##in the exprs package can always "import basic;reload(basic)" first, and if they do, all modules within
    ##exprs can just start with "from basic import *". But for clarity, some of them call reload_once on basic too.
    
    if (not EndUser.enableDeveloperFeatures()): #070627 precaution; should improve by making this only affect default value of a debug_pref ###TODO
        return
    
    if not ENABLE_RELOAD:
        def printfyi(msg): # WARNING: dup code, inlining py_utils version since not yet imported
            msg = "fyi (printonce): " + msg
            from foundation.env import seen_before
            if not seen_before(msg):
                print msg
        if 1:
            ## printfyi( "exprs modules won't be reloaded during this session" ) # 070627 removed this
            return
    reload_once_per_event(module,
                          always_print = True,
                          never_again = False,
                          counter = exprs_globals.reload_counter,
                          check_modtime = True)
    return

# end