def mt_node_id( node ): # 070207; the name 'node_id' itself conflicts with a function in Utility.py (which we import and use here, btw) """ return the mt_node_id property of the node, regardless of which model tree node interface it's trying to use [slight kluge] """ # look for value of ModelTreeNodeInterface attr try: node.mt_node_id except AttributeError: pass else: if print_mt_node_id: print "this node %r has mt_node_id %r" % (node, node.mt_node_id) # old Q: where do our Rects get it? # A: they don't -- the bug fixed by bugfix070218 meant this was never called except for World!! # [note: on 070302 the comments about bugfix070218, and the code affected by it, was rewritten and removed # (becoming MapListToExpr). # it might still be in an outtakes file not in cvs on bruce's g5 -- or in cvs rev 1.21 or earlier of this file.] # btw, we want it to be for the # underlying model object... sort of like how we ask for name or type... [bug noticed 070218 late; see below comment] return node.mt_node_id ## assert not is_expr_Instance(node), "what node is this? %r" % (node,) # most to the point if is_expr_Instance(node): # All Instances ought to have that, or delegate to something which does -- which ought to be their contained ModelObject. ####FIX SOMETIME (implem that properly) # Until that's implemented properly (hard now -- see _e_model_type_you_make for the hoops you have to jump thru now), # use the ipath (non-ideal, since captures wrappers like Draggable etc, but tolerable, # esp since this effectively means use the world-index, which will work ok for now [070218 late]) return node.ipath ###e should intern it as optim assert not is_Expr( node), "pure exprs like %r don't belong as nodes in the model tree" % ( node, ) # look for legacy Node property from foundation.Utility import node_id res = node_id( node ) # not sure what to do if this fails -- let it be an error for now -- consider using id(node) if we need to if print_mt_node_id: print "legacy node %r has effective mt_node_id %r" % (node, res) return res
def mt_node_id( node ): # 070207; the name 'node_id' itself conflicts with a function in Utility.py (which we import and use here, btw) """ return the mt_node_id property of the node, regardless of which model tree node interface it's trying to use [slight kluge] """ # look for value of ModelTreeNodeInterface attr try: node.mt_node_id except AttributeError: pass else: if print_mt_node_id: print "this node %r has mt_node_id %r" % (node, node.mt_node_id) # old Q: where do our Rects get it? # A: they don't -- the bug fixed by bugfix070218 meant this was never called except for World!! # [note: on 070302 the comments about bugfix070218, and the code affected by it, was rewritten and removed # (becoming MapListToExpr). # it might still be in an outtakes file not in cvs on bruce's g5 -- or in cvs rev 1.21 or earlier of this file.] # btw, we want it to be for the # underlying model object... sort of like how we ask for name or type... [bug noticed 070218 late; see below comment] return node.mt_node_id ## assert not is_expr_Instance(node), "what node is this? %r" % (node,) # most to the point if is_expr_Instance(node): # All Instances ought to have that, or delegate to something which does -- which ought to be their contained ModelObject. ####FIX SOMETIME (implem that properly) # Until that's implemented properly (hard now -- see _e_model_type_you_make for the hoops you have to jump thru now), # use the ipath (non-ideal, since captures wrappers like Draggable etc, but tolerable, # esp since this effectively means use the world-index, which will work ok for now [070218 late]) return node.ipath ###e should intern it as optim assert not is_Expr(node), "pure exprs like %r don't belong as nodes in the model tree" % (node,) # look for legacy Node property from foundation.Utility import node_id res = node_id( node ) # not sure what to do if this fails -- let it be an error for now -- consider using id(node) if we need to if print_mt_node_id: print "legacy node %r has effective mt_node_id %r" % (node, res) return res
def _CV__i_instance_CVdict(self, index): """ [private] value-recomputing function for self._i_instance_CVdict. Before calling this, the caller must store an expr for this instance into self._i_instance_decl_data[index] (an ordinary dict). If it's permitted for that expr to change with time (which I doubt, but don't know yet for sure #k), then whenever the caller changes it (other than when initially setting it), the caller must invalidate the entry with the same key (our index arg) in the LvalDict2 that implements self._i_instance_CVdict (but the API for the caller to do that is not yet worked out #e). (Implem note: _CV_ stands for "compute value" to ExprsMeta, which implements the LvalDict2 associated with this. This method needs no corresponding _CK_ keylist function, since any key (instance index) asked for is assumed valid.) """ assert self._e_is_instance # This method needs to create a new instance, by instantiating expr and giving it index. # Implem notes: # - the glue code added by _CV_ from self._i_instance_CVdict to this method (by ExprsMeta) uses LvalDict2 # to cache values computed by this method, and recompute them if needed (which may never happen, I'm not sure). # - the access to self._i_instance_decl_data[index] is not usage tracked; # thus if we change it above w/o error, an inval is needed. data = self._i_instance_decl_data[index] expr, lvalflag = data # 061204 ## print "fyi, using kid expr %r" % expr # (these tend to be longish, and start with eval_Expr -- what we'd rather print is the result of the first eval it does) # Note, this expr can be very simplifiable, if it came from an Arg macro, # but present code [061105] reevals the full macro expansion each time -- suboptimal. # To fix, we'd need an "expr simplify", whether we used it only once or not... # the reason to use it more than once is if it becomes partly final at some later point than when it starts out. # The simplify implem would need decls about finality of, e.g., getting of some bound methods and (determinism of) # their retvals -- namely (for Arg macro etc) for _i_instance and _i_grabarg and maybe more. # Feasible but not simple; worthwhile optim someday but not right away. ##e if not EVAL_REFORM: # three increasingly strict asserts: assert expr is not None assert is_Expr(expr), "not is_Expr: %r" % (expr, ) assert is_pure_expr( expr ) ###k?? what if someone passes an instance -- is that permitted, but a noop for instantiation?? assert is_Expr_pyinstance( expr), "can't instantiate a class: %r" % ( expr, ) # new, 070117, untested### -- i'm not even sure it's correct # also assume expr is "canonicalized" and even "understood" -- not sure if this is justified printnim( "don't we need understand_expr somewhere in here? (before kidmaking in IorE)" ) ###@@@ else: # EVAL_REFORM case 070117 if not (is_pure_expr(expr) and is_Expr_pyinstance(expr)): print "this should never happen as of 070118 since we handle it above: non pure expr %r in _CV__i_instance_CVdict" % ( expr, ) ## print "FYI: EVAL_REFORM: _CV__i_instance_CVdict is identity on %r" % (expr,) # this is routine on e.g. None, small ints, colors, other tuples... and presumably Instances (not tested) assert not lvalflag # see comments at start of _i_instance return expr pass ####e: [061105] is _e_eval actually needing to be different from _e_make_in?? yes, _e_eval needs to be told _self # and the other needs to make one... no wait, wrong, different selves -- # the _self told to eval is the one _make_in *should make something inside of*! (ie should make a kid of) # So it may be that these are actually the same thing. (See paper notes from today for more about this.) # For now, tho, we'll define _e_make_in on OpExpr to use eval. [not done, where i am] # actually this is even faster -- review sometime (note, in constant_Expr they're both there & equiv #k): ###@@@ ## this is just the kid expr: print "_CV__i_instance_CVdict needs to make expr %r" % (expr,) ## if hasattr(expr, '_e_make_in'): ## print("REJECTED using _e_make_in case, on a pyinstance of class %s" % expr.__class__.__name__)###was printfyi til 061208 921p ## ## res = expr._e_make_in(env, index_path) ## #k we might have to fix bugs caused by not using this case, by defining (or modifying?) defs of _e_eval on some classes; ## # addendum 061212, we now do that on If_expr. if not EVAL_REFORM: # WARNING: following code is very similar to _i_eval_dfltval_expr as of 061203 # printfyi("used _e_eval case (via _e_compute_method)") # this case is usually used, as of 061108 -- now always, 061110 # note: this (used-to-be-redundantly) grabs env from self try: res = expr._e_compute_method( self, index, _lvalue_flag=lvalflag)() ##e optim someday: inline this # 061105 bug3, if bug2 was in held_dflt_expr and bug1 was 'dflt 10' except: # we expect caller to exit now, so we might as well print this first: [061114] print "following exception concerns self = %r, index = %r in _CV__i_instance_CVdict calling _e_compute_method" % \ (self, index) raise else: # EVAL_REFORM case, 070117 if kluge070119: # also pass an env retrieved from... env = self._i_instance_decl_env[index] env, ipath = self._i_env_ipath_for_formula_at_index( index, env) # note: retval's env is modified from the one passed # THIS MUST BE WHERE THE INCORRECT BINDING _self = self gets added, in the kluge070119 ###BUG in _5x! [070120 844p] # GUESS at basic bug: an Instance self really needs to know two envs: the one for its args (_self refers to # whoeever lexically created the expr they were made from), and the one for their internal formulae (_self = self). # self.env is the one for the args (since it's thought of as "self's (outer) environment"), # and the one for internal formulae has (until now -- this should change #e) been recreated as needed in # _e_compute_method and now in _i_env_ipath_for_formula_at_index, by extending self.env by _self = self. # But to be correct, this should be done BEFORE the burrowing and env-extension done by the kluge070119, # but in this wrong current code it's done after it. The old code also had wrongness of order, in principle # (doing this _self addition here rather than in env_for_args, with env_for_args done first when it should # be done 2nd), but it didn't matter since env_for_args only added _this_xxx and _my. WAIT, THAT'S WRONG -- # env_for_args is for external (in lexenv) args, so it should have SAME _self as self.env, so it's correct now, # and never gets or needs _self = self, either before or after its _my and _this_xxx bindings. # What we need here is NOT env_for_args but env_for_internal_formulae. It should be used for dflt exprs in Arg, # and for all exprs sitting on class assignments. We've been making it before *using* those formulae # (probably getting it onto dflt exprs only because they end up being *used* in the right place for that). # We've been making it in each call of _i_env_ipath_for_formula_at_index or _e_compute_method, but we ought to # make it once and let those use it, and make sure that happens before the env mods from the burrowing done by # kluge070119. (We can't make it in the class (eg ExprsMeta) -- we have to wait until _init_instance or so, # because it depends on self which is only known around then.) # # SUGGESTED FIX ###e: make self.env_for_internal_formulae (#e shorter name -- env_for_formulae?) # before (??) calling _init_instance [or after if _init_instance can modify self.env ##k]; # use it in _i_env_ipath_for_formula_at_index and some of our uses of _e_compute_method; # and review all uses of self.env for whether they ought to be env_for_formulae. # Doing it 070120 circa 942p -- I made _C_env_for_formulae instead of setting it in _init_instance # (optim, since some Instances never need it (I hope -- not sure) and since it creates a cyclic ref. else: env, ipath = self._i_env_ipath_for_formula_at_index( index) # equivalent to how above other case computes them assert not lvalflag # see comments at start of _i_instance res = expr._e_make_in( env, ipath ) # only pure IorE exprs have this method; should be ok since only they are returned from expr evals return res # from _CV__i_instance_CVdict
def _CV__i_instance_CVdict(self, index): """ [private] value-recomputing function for self._i_instance_CVdict. Before calling this, the caller must store an expr for this instance into self._i_instance_decl_data[index] (an ordinary dict). If it's permitted for that expr to change with time (which I doubt, but don't know yet for sure #k), then whenever the caller changes it (other than when initially setting it), the caller must invalidate the entry with the same key (our index arg) in the LvalDict2 that implements self._i_instance_CVdict (but the API for the caller to do that is not yet worked out #e). (Implem note: _CV_ stands for "compute value" to ExprsMeta, which implements the LvalDict2 associated with this. This method needs no corresponding _CK_ keylist function, since any key (instance index) asked for is assumed valid.) """ assert self._e_is_instance # This method needs to create a new instance, by instantiating expr and giving it index. # Implem notes: # - the glue code added by _CV_ from self._i_instance_CVdict to this method (by ExprsMeta) uses LvalDict2 # to cache values computed by this method, and recompute them if needed (which may never happen, I'm not sure). # - the access to self._i_instance_decl_data[index] is not usage tracked; # thus if we change it above w/o error, an inval is needed. data = self._i_instance_decl_data[index] expr, lvalflag = data # 061204 ## print "fyi, using kid expr %r" % expr # (these tend to be longish, and start with eval_Expr -- what we'd rather print is the result of the first eval it does) # Note, this expr can be very simplifiable, if it came from an Arg macro, # but present code [061105] reevals the full macro expansion each time -- suboptimal. # To fix, we'd need an "expr simplify", whether we used it only once or not... # the reason to use it more than once is if it becomes partly final at some later point than when it starts out. # The simplify implem would need decls about finality of, e.g., getting of some bound methods and (determinism of) # their retvals -- namely (for Arg macro etc) for _i_instance and _i_grabarg and maybe more. # Feasible but not simple; worthwhile optim someday but not right away. ##e if not EVAL_REFORM: # three increasingly strict asserts: assert expr is not None assert is_Expr(expr), "not is_Expr: %r" % (expr,) assert is_pure_expr(expr) ###k?? what if someone passes an instance -- is that permitted, but a noop for instantiation?? assert is_Expr_pyinstance(expr), "can't instantiate a class: %r" % (expr,) # new, 070117, untested### -- i'm not even sure it's correct # also assume expr is "canonicalized" and even "understood" -- not sure if this is justified printnim("don't we need understand_expr somewhere in here? (before kidmaking in IorE)") ###@@@ else: # EVAL_REFORM case 070117 if not (is_pure_expr(expr) and is_Expr_pyinstance(expr)): print "this should never happen as of 070118 since we handle it above: non pure expr %r in _CV__i_instance_CVdict" % (expr,) ## print "FYI: EVAL_REFORM: _CV__i_instance_CVdict is identity on %r" % (expr,) # this is routine on e.g. None, small ints, colors, other tuples... and presumably Instances (not tested) assert not lvalflag # see comments at start of _i_instance return expr pass ####e: [061105] is _e_eval actually needing to be different from _e_make_in?? yes, _e_eval needs to be told _self # and the other needs to make one... no wait, wrong, different selves -- # the _self told to eval is the one _make_in *should make something inside of*! (ie should make a kid of) # So it may be that these are actually the same thing. (See paper notes from today for more about this.) # For now, tho, we'll define _e_make_in on OpExpr to use eval. [not done, where i am] # actually this is even faster -- review sometime (note, in constant_Expr they're both there & equiv #k): ###@@@ ## this is just the kid expr: print "_CV__i_instance_CVdict needs to make expr %r" % (expr,) ## if hasattr(expr, '_e_make_in'): ## print("REJECTED using _e_make_in case, on a pyinstance of class %s" % expr.__class__.__name__)###was printfyi til 061208 921p ## ## res = expr._e_make_in(env, index_path) ## #k we might have to fix bugs caused by not using this case, by defining (or modifying?) defs of _e_eval on some classes; ## # addendum 061212, we now do that on If_expr. if not EVAL_REFORM: # WARNING: following code is very similar to _i_eval_dfltval_expr as of 061203 # printfyi("used _e_eval case (via _e_compute_method)") # this case is usually used, as of 061108 -- now always, 061110 # note: this (used-to-be-redundantly) grabs env from self try: res = expr._e_compute_method(self, index, _lvalue_flag = lvalflag)() ##e optim someday: inline this # 061105 bug3, if bug2 was in held_dflt_expr and bug1 was 'dflt 10' except: # we expect caller to exit now, so we might as well print this first: [061114] print "following exception concerns self = %r, index = %r in _CV__i_instance_CVdict calling _e_compute_method" % \ (self, index) raise else: # EVAL_REFORM case, 070117 if kluge070119: # also pass an env retrieved from... env = self._i_instance_decl_env[index] env, ipath = self._i_env_ipath_for_formula_at_index( index, env) # note: retval's env is modified from the one passed # THIS MUST BE WHERE THE INCORRECT BINDING _self = self gets added, in the kluge070119 ###BUG in _5x! [070120 844p] # GUESS at basic bug: an Instance self really needs to know two envs: the one for its args (_self refers to # whoeever lexically created the expr they were made from), and the one for their internal formulae (_self = self). # self.env is the one for the args (since it's thought of as "self's (outer) environment"), # and the one for internal formulae has (until now -- this should change #e) been recreated as needed in # _e_compute_method and now in _i_env_ipath_for_formula_at_index, by extending self.env by _self = self. # But to be correct, this should be done BEFORE the burrowing and env-extension done by the kluge070119, # but in this wrong current code it's done after it. The old code also had wrongness of order, in principle # (doing this _self addition here rather than in env_for_args, with env_for_args done first when it should # be done 2nd), but it didn't matter since env_for_args only added _this_xxx and _my. WAIT, THAT'S WRONG -- # env_for_args is for external (in lexenv) args, so it should have SAME _self as self.env, so it's correct now, # and never gets or needs _self = self, either before or after its _my and _this_xxx bindings. # What we need here is NOT env_for_args but env_for_internal_formulae. It should be used for dflt exprs in Arg, # and for all exprs sitting on class assignments. We've been making it before *using* those formulae # (probably getting it onto dflt exprs only because they end up being *used* in the right place for that). # We've been making it in each call of _i_env_ipath_for_formula_at_index or _e_compute_method, but we ought to # make it once and let those use it, and make sure that happens before the env mods from the burrowing done by # kluge070119. (We can't make it in the class (eg ExprsMeta) -- we have to wait until _init_instance or so, # because it depends on self which is only known around then.) # # SUGGESTED FIX ###e: make self.env_for_internal_formulae (#e shorter name -- env_for_formulae?) # before (??) calling _init_instance [or after if _init_instance can modify self.env ##k]; # use it in _i_env_ipath_for_formula_at_index and some of our uses of _e_compute_method; # and review all uses of self.env for whether they ought to be env_for_formulae. # Doing it 070120 circa 942p -- I made _C_env_for_formulae instead of setting it in _init_instance # (optim, since some Instances never need it (I hope -- not sure) and since it creates a cyclic ref. else: env, ipath = self._i_env_ipath_for_formula_at_index( index) # equivalent to how above other case computes them assert not lvalflag # see comments at start of _i_instance res = expr._e_make_in(env,ipath) # only pure IorE exprs have this method; should be ok since only they are returned from expr evals return res # from _CV__i_instance_CVdict