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 ):
@@ -504,21 +488,6 @@ def test_EvalEnvironment_eq():
504
488
assert env3 != env4
505
489
506
490
507
- def test_EvalEnvironment_clean ():
508
- from patsy .state import center , standardize
509
- from patsy .splines import bs
510
-
511
- env1 = EvalEnvironment ([{'center' : center }])
512
- env2 = EvalEnvironment ([{'standardize' : standardize }])
513
- env3 = EvalEnvironment ([{'bs' : bs }])
514
- env1 .clean ()
515
- env2 .clean ()
516
- env3 .clean ()
517
-
518
- env1 ._namespaces == [{}]
519
- env2 ._namespaces == [{}]
520
- env3 ._namespaces == [{}]
521
-
522
491
_builtins_dict = {}
523
492
six .exec_ ("from patsy.builtins import *" , {}, _builtins_dict )
524
493
# This is purely to make the existence of patsy.builtins visible to systems
@@ -576,10 +545,6 @@ def memorize_passes_needed(self, state, eval_env):
576
545
577
546
eval_env = eval_env .with_outer_namespace (_builtins_dict )
578
547
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
548
584
549
# example code: == "2 * center(x)"
585
550
i = [0 ]
@@ -596,6 +561,12 @@ def new_name_maker(token):
596
561
# example eval_code: == "2 * _patsy_stobj0__center__.transform(x)"
597
562
eval_code = replace_bare_funcalls (self .code , new_name_maker )
598
563
state ["eval_code" ] = eval_code
564
+
565
+ subset_names = [name for name in ast_names (eval_code )
566
+ if name in env_namespace ]
567
+ eval_env = eval_env .subset (subset_names )
568
+ state ["eval_env" ] = eval_env
569
+
599
570
# paranoia: verify that none of our new names appeared anywhere in the
600
571
# original code
601
572
if has_bare_variable_reference (state ["transforms" ], self .code ):
@@ -716,7 +687,10 @@ def test_EvalFactor_memorize_passes_needed():
716
687
print (state )
717
688
assert passes == 2
718
689
for name in ["foo" , "bar" , "quux" ]:
719
- assert state ["eval_env" ].namespace [name ] is locals ()[name ]
690
+ # name should be locally defined, but since its a stateful_transform,
691
+ # its unnecessary to keep it in eval_env
692
+ assert name in locals ()
693
+ assert_raises (KeyError , state ["eval_env" ].namespace .__getitem__ , name )
720
694
for name in ["w" , "x" , "y" , "z" , "e" , "state" ]:
721
695
assert name not in state ["eval_env" ].namespace
722
696
assert state ["transforms" ] == {"_patsy_stobj0__foo__" : "FOO-OBJ" ,
@@ -772,7 +746,9 @@ def test_EvalFactor_end_to_end():
772
746
print (passes )
773
747
print (state )
774
748
assert passes == 2
775
- assert state ["eval_env" ].namespace ["foo" ] is foo
749
+ # We don't want to save the stateful transforms in the eval_env, actually.
750
+ # Just
751
+ assert_raises (KeyError , state ["eval_env" ].namespace .__getitem__ , 'foo' )
776
752
for name in ["x" , "y" , "e" , "state" ]:
777
753
assert name not in state ["eval_env" ].namespace
778
754
import numpy as np
0 commit comments