-
Notifications
You must be signed in to change notification settings - Fork 268
/
Copy pathmakes_use_of.py
48 lines (37 loc) · 1.41 KB
/
makes_use_of.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import inspect
import re
from typing import Callable, Set, Text, Type, Union
from axelrod.player import Player
def method_makes_use_of(method: Callable) -> Set[Text]:
result = set()
method_code = inspect.getsource(method)
attr_string = r".match_attributes\[\"(\w+)\"\]"
all_attrs = re.findall(attr_string, method_code)
for attr in all_attrs:
result.add(attr)
return result
def class_makes_use_of(cls) -> Set[Text]:
try:
result = cls.classifier["makes_use_of"]
except (AttributeError, KeyError):
result = set()
for method in inspect.getmembers(cls, inspect.ismethod):
if method[0] == "__init__":
continue
result.update(method_makes_use_of(method[1]))
return result
def makes_use_of(player: Type[Player]) -> Set[Text]:
if not isinstance(player, Player): # pragma: no cover
player = player()
return class_makes_use_of(player)
def makes_use_of_variant(
player_or_method: Union[Callable, Type[Player]],
) -> Set[Text]:
"""A version of makes_use_of that works on functions or player classes."""
try:
return method_makes_use_of(player_or_method)
# OSError catches the case of a transformed player, which has a dynamically
# created class.
# TypeError is the case in which we have a class rather than a method
except (OSError, TypeError):
return class_makes_use_of(player_or_method)