File tree Expand file tree Collapse file tree 2 files changed +25
-2
lines changed
Expand file tree Collapse file tree 2 files changed +25
-2
lines changed Original file line number Diff line number Diff line change @@ -91,10 +91,12 @@ def __str__(self):
9191 def set (self , name , value ):
9292 """Convenience method to allow assignment in expression contexts.
9393
94- Like Scheme's set! function.
94+ Like Scheme's set! function. Only rebinding is allowed.
9595
9696 For convenience, returns the `value` argument.
9797 """
98+ if not hasattr (self , name ): # allow only rebinding
99+ raise AttributeError ("name '{:s}' is not defined" .format (name ))
98100 setattr (self , name , value )
99101 return value # for convenience
100102
@@ -426,6 +428,14 @@ def result(*, env):
426428 return env .evenp (23 )
427429 assert result is False
428430
431+ try :
432+ let (x = 0 ,
433+ body = lambda e : e .set ('y' , 3 )) # error, y is not defined
434+ except AttributeError as err :
435+ pass
436+ else :
437+ assert False
438+
429439 print ("All tests PASSED" )
430440
431441if __name__ == '__main__' :
Original file line number Diff line number Diff line change @@ -146,6 +146,7 @@ def bletrec(bindings):
146146 This chains ``@dletrec`` and ``@immediate``."""
147147 return _blet (bindings , mode = "letrec" )
148148
149+ # TODO: switch to the same env implementation as let.py to avoid the k=set issue?
149150class _env :
150151 """Environment.
151152
@@ -154,11 +155,15 @@ class _env:
154155 def set (self , k , v ):
155156 """Convenience method to allow assignment in expression contexts.
156157
157- For extra convenience, return the assigned value.
158+ Like Scheme's set! function. Only rebinding is allowed.
159+
160+ For convenience, returns the `value` argument.
158161
159162 DANGER:
160163 avoid the name ``k="set"``; it will happily shadow this method,
161164 because instance attributes are seen before class attributes."""
165+ if not hasattr (self , k ): # allow only rebinding
166+ raise AttributeError ("name '{:s}' is not defined" .format (k ))
162167 setattr (self , k , v )
163168 return v
164169
@@ -272,6 +277,14 @@ def result(*, env):
272277 return env .evenp (42 )
273278 assert result is True
274279
280+ try :
281+ let ((('x' , 0 ),),
282+ lambda e : e .set ('y' , 3 )) # error, y is not defined
283+ except AttributeError :
284+ pass
285+ else :
286+ assert False
287+
275288 print ("All tests passed" )
276289
277290if __name__ == '__main__' :
You can’t perform that action at this time.
0 commit comments