25
25
from patsy .tokens import (pretty_untokenize , normalize_token_spacing ,
26
26
python_tokenize )
27
27
from patsy .compat import call_and_wrap_exc
28
+ from nose .tools import assert_raises
28
29
29
30
def _all_future_flags ():
30
31
flags = 0
@@ -71,13 +72,8 @@ def get(self, key, default=None):
71
72
def __repr__ (self ):
72
73
return "%s(%r)" % (self .__class__ .__name__ , self ._dicts )
73
74
74
- def __getstate__ (self ):
75
- return (0 , self ._dicts )
75
+ __getstate__ = no_pickling
76
76
77
- def __setstate__ (self , pickle ):
78
- version , dicts = pickle
79
- check_pickle_version (version , 0 , name = self .__class__ .__name__ )
80
- self ._dicts = dicts
81
77
82
78
def test_VarLookupDict ():
83
79
d1 = {"a" : 1 }
@@ -262,27 +258,15 @@ def __hash__(self):
262
258
tuple (self ._namespace_ids ())))
263
259
264
260
def __getstate__ (self ):
265
- self .clean ()
261
+ # self.clean()
266
262
namespaces = self ._namespaces
267
263
namespaces = _replace_un_pickleable (namespaces )
268
- return ( 0 , namespaces , self .flags )
264
+ return { 'version' : 0 , ' namespaces' : namespaces , 'flags' : self .flags }
269
265
270
266
def __setstate__ (self , pickle ):
271
- version , namespaces , flags = pickle
272
- check_pickle_version (version , 0 , self .__class__ .__name__ )
273
- self .flags = flags
274
- self ._namespaces = _return_un_pickleable (namespaces )
275
-
276
- def clean (self ):
277
- """The EvalEnvironment doesn't need the stateful transformation
278
- functions once the design matrix has been built. This will delete
279
- it. Called by __getstate__ to prepare for pickling."""
280
- namespaces = []
281
- for namespace in self ._namespaces :
282
- ns = {key : namespace [key ] for key in six .iterkeys (namespace ) if not
283
- hasattr (namespace [key ], '__patsy_stateful_transform__' )}
284
- namespaces .append (ns )
285
- self ._namespaces = namespaces
267
+ check_pickle_version (pickle ['version' ], 0 , self .__class__ .__name__ )
268
+ self .flags = pickle ['flags' ]
269
+ self ._namespaces = _return_un_pickleable (pickle ['namespaces' ])
286
270
287
271
288
272
class ObjectHolder (object ):
@@ -576,10 +560,6 @@ def memorize_passes_needed(self, state, eval_env):
576
560
577
561
eval_env = eval_env .with_outer_namespace (_builtins_dict )
578
562
env_namespace = eval_env .namespace
579
- subset_names = [name for name in ast_names (self .code )
580
- if name in env_namespace ]
581
- eval_env = eval_env .subset (subset_names )
582
- state ["eval_env" ] = eval_env
583
563
584
564
# example code: == "2 * center(x)"
585
565
i = [0 ]
@@ -596,6 +576,12 @@ def new_name_maker(token):
596
576
# example eval_code: == "2 * _patsy_stobj0__center__.transform(x)"
597
577
eval_code = replace_bare_funcalls (self .code , new_name_maker )
598
578
state ["eval_code" ] = eval_code
579
+
580
+ subset_names = [name for name in ast_names (eval_code )
581
+ if name in env_namespace ]
582
+ eval_env = eval_env .subset (subset_names )
583
+ state ["eval_env" ] = eval_env
584
+
599
585
# paranoia: verify that none of our new names appeared anywhere in the
600
586
# original code
601
587
if has_bare_variable_reference (state ["transforms" ], self .code ):
@@ -716,7 +702,10 @@ def test_EvalFactor_memorize_passes_needed():
716
702
print (state )
717
703
assert passes == 2
718
704
for name in ["foo" , "bar" , "quux" ]:
719
- assert state ["eval_env" ].namespace [name ] is locals ()[name ]
705
+ # name should be locally defined, but since its a stateful_transform,
706
+ # its unnecessary to keep it in eval_env
707
+ assert name in locals ()
708
+ assert_raises (KeyError , state ["eval_env" ].namespace .__getitem__ , name )
720
709
for name in ["w" , "x" , "y" , "z" , "e" , "state" ]:
721
710
assert name not in state ["eval_env" ].namespace
722
711
assert state ["transforms" ] == {"_patsy_stobj0__foo__" : "FOO-OBJ" ,
@@ -772,7 +761,9 @@ def test_EvalFactor_end_to_end():
772
761
print (passes )
773
762
print (state )
774
763
assert passes == 2
775
- assert state ["eval_env" ].namespace ["foo" ] is foo
764
+ # We don't want to save the stateful transforms in the eval_env, actually.
765
+ # Just
766
+ assert_raises (KeyError , state ["eval_env" ].namespace .__getitem__ , 'foo' )
776
767
for name in ["x" , "y" , "e" , "state" ]:
777
768
assert name not in state ["eval_env" ].namespace
778
769
import numpy as np
0 commit comments