@@ -92,22 +92,25 @@ def __call__(self, PlayerClass):
92
92
pass
93
93
94
94
# Is the original strategy method a static method?
95
- signature = inspect .signature (PlayerClass .strategy )
96
- strategy_args = [p .name for p in signature .parameters .values ()
97
- if p .kind == inspect .Parameter .POSITIONAL_OR_KEYWORD ]
98
- is_static = True
99
- if len (strategy_args ) > 1 :
100
- is_static = False
95
+ # signature = inspect.signature(PlayerClass.strategy)
96
+ # strategy_args = [p.name for p in signature.parameters.values()
97
+ # if p.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD]
98
+ # is_static = True
99
+ # if len(strategy_args) > 1:
100
+ # is_static = False
101
101
102
102
# Define the new strategy method, wrapping the existing method
103
103
# with `strategy_wrapper`
104
104
def strategy (self , opponent ):
105
-
106
- if is_static :
107
- # static method
108
- proposed_action = PlayerClass .strategy (opponent )
105
+ if strategy_wrapper != dual_wrapper :
106
+ if is_strategy_static (PlayerClass ):
107
+ # static method
108
+ proposed_action = PlayerClass .strategy (opponent )
109
+ else :
110
+ proposed_action = PlayerClass .strategy (self , opponent )
109
111
else :
110
- proposed_action = PlayerClass .strategy (self , opponent )
112
+ # dummy Action for dual_wrapper to avoid calling class
113
+ proposed_action = C
111
114
112
115
# Apply the wrapper
113
116
return strategy_wrapper (self , opponent , proposed_action ,
@@ -148,41 +151,29 @@ def __repr__(self):
148
151
prefix = ', '
149
152
return name
150
153
151
- # Define a new class and wrap the strategy method
152
- # Dynamically create the new class
153
- def new_init (self , * args_ , ** kwargs_ ):
154
- super (self , PlayerClass ).__init__ (* args_ , ** kwargs_ )
155
- self .original_player = self .original_class (** self .init_kwargs )
156
-
157
- def reducer (self_ ):
154
+ def new_class_reduce (self_ ):
158
155
class_module = import_module (self_ .__module__ )
159
- if self_ .__class__ .__name__ in dir ( class_module ):
160
-
156
+ import_name = self_ .__class__ .__name__
157
+ if import_name in dir ( class_module ):
161
158
return self_ .__class__ , (), self_ .__dict__
162
159
163
160
else :
164
- decorators = [self_ .decorator ]
165
- pc = self_ .original_class
166
- original_name = pc .__name__
167
- for klass in pc .mro ():
168
- if not hasattr (klass , 'decorator' ):
169
- pc = klass
170
- original_name = pc .__name__
171
- # if hasattr(klass, 'decorator'):
172
- # decorators.append(klass.decorator)
173
- # if klass in axelrod.strategies:
174
- # pc = klass
175
- # break
176
- # if klass is axelrod.Player:
177
-
178
- return (NewRecon (),
179
- (decorators , original_name , self_ .__module__ ),
180
- self_ .__dict__ )
181
- return (Reconstitutor (),
182
- (decorators , pc , original_name ),
183
- self_ .__dict__ )
184
-
161
+ decorators = []
162
+ for klass in self_ .__class__ .mro ():
163
+ if hasattr (klass , 'decorator' ):
164
+ decorators .append (klass .decorator )
165
+ else :
166
+ import_name = klass .__name__
167
+ break
168
+
169
+ return (
170
+ NewRecon (),
171
+ (decorators , import_name , self_ .__module__ ),
172
+ self_ .__dict__
173
+ )
185
174
175
+ # Define a new class and wrap the strategy method
176
+ # Dynamically create the new class
186
177
new_class = type (
187
178
new_class_name , (PlayerClass ,),
188
179
{
@@ -194,41 +185,43 @@ def reducer(self_):
194
185
"__module__" : PlayerClass .__module__ ,
195
186
"classifier" : classifier ,
196
187
"__doc__" : PlayerClass .__doc__ ,
197
- "__reduce__" : reducer ,
188
+ "__reduce__" : new_class_reduce ,
198
189
})
199
- # if strategy_wrapper == dual_wrapper:
200
- # new_class.__init__ = new_init
190
+
201
191
return new_class
202
192
return Decorator
203
193
204
- class NewRecon (object ):
205
- def __init__ (self ):
206
194
207
- pass
208
-
209
- def __call__ (self , decorators , original_name , mod ):
210
- use_module = import_module (mod )
211
- use_class = getattr (use_module , original_name )
212
-
213
- # for decorator, args, kwargs in decorators:
214
- # use_class = decorator(*args, **kwargs)(use_class)
215
- obj = use_class ()
216
- # obj.__class__.__name__ = original_name
217
- return obj
218
-
219
- class Reconstitutor (object ):
195
+ class NewRecon (object ):
220
196
def __init__ (self ):
221
-
222
197
pass
223
198
224
- def __call__ (self , decorators , player_class , original_name ):
225
- use_class = player_class
226
-
227
- for decorator , args , kwargs in decorators :
228
- use_class = decorator (* args , ** kwargs )(use_class )
229
- obj = use_class ()
230
- obj .__class__ .__name__ = original_name
231
- return obj
199
+ def __call__ (self , decorators , import_name , module_name ):
200
+ module_ = import_module (module_name )
201
+ import_class = getattr (module_ , import_name )
202
+
203
+ if hasattr (import_class , 'decorator' ):
204
+ return import_class ()
205
+ else :
206
+ generated_class = import_class
207
+ for decorator , args , kwargs in decorators :
208
+ generated_class = decorator (* args , ** kwargs )(generated_class )
209
+ return generated_class ()
210
+
211
+
212
+ # class Reconstitutor(object):
213
+ # def __init__(self):
214
+ #
215
+ # pass
216
+ #
217
+ # def __call__(self, decorators, player_class, original_name):
218
+ # use_class = player_class
219
+ #
220
+ # for decorator, args, kwargs in decorators:
221
+ # use_class = decorator(*args, **kwargs)(use_class)
222
+ # obj = use_class()
223
+ # obj.__class__.__name__ = original_name
224
+ # return obj
232
225
233
226
def compose_transformers (t1 , t2 ):
234
227
"""Compose transformers without having to invoke the first on
@@ -300,13 +293,14 @@ def dual_wrapper(player, opponent, proposed_action):
300
293
-------
301
294
action: an axelrod.Action, C or D
302
295
"""
296
+
303
297
if not player .history :
304
298
player .use_history = []
305
299
306
300
temp = player .history [:]
307
301
player .history = player .use_history [:]
308
302
309
- if 'self' not in player .original_class . strategy . __code__ . co_varnames :
303
+ if is_strategy_static ( player .original_class ) :
310
304
action = player .original_class .strategy (opponent )
311
305
else :
312
306
action = player .original_class .strategy (player , opponent )
@@ -317,6 +311,20 @@ def dual_wrapper(player, opponent, proposed_action):
317
311
return action .flip ()
318
312
319
313
314
+ def is_strategy_static (player_class ):
315
+ # signature = inspect.signature(player_class.strategy)
316
+ # strategy_args = [p.name for p in signature.parameters.values()
317
+ # if p.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD]
318
+ # is_static = True
319
+ # if len(strategy_args) > 1:
320
+ # is_static = False
321
+ # return is_static
322
+ for klass in player_class .mro ():
323
+ method = inspect .getattr_static (klass , 'strategy' , default = None )
324
+ if method is not None :
325
+ return isinstance (method , staticmethod )
326
+
327
+
320
328
DualTransformer = StrategyTransformerFactory (dual_wrapper , name_prefix = "Dual" )
321
329
322
330
0 commit comments