Skip to content

Commit 6c50756

Browse files
committed
First checkpoint in validating readers, processors, and configurations via metaclass contracts
1 parent 5b0d5fa commit 6c50756

File tree

6 files changed

+307
-227
lines changed

6 files changed

+307
-227
lines changed

sc2reader/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ def read_file(filename,config=DefaultConfig()):
3535
raise NotYetImplementedError("No parser was found that accepted the replay file;check configuration")
3636

3737
#Do cleanup and post processing
38-
for process in config.processors:
39-
replay = process(replay)
38+
for processor in config.processors:
39+
replay = processor.process(replay)
4040

4141
return replay
4242

4343
__all__ = [DefaultConfig,read,read_file]
44-
__version__ = "0.1.0"
44+
__version__ = "0.1.0"

sc2reader/config.py

Lines changed: 66 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,42 +6,71 @@
66
from sc2reader.objects import Replay
77
from sc2reader.processors import *
88
from sc2reader.readers import *
9+
from sc2reader.utils import key_in_bases
910

10-
class DefaultConfig(object):
11-
def __init__(self):
12-
self.ReplayClass = Replay
13-
14-
self.readers = OrderedDict()
15-
self.readers['replay.initData'] = [ ReplayInitDataReader() ]
16-
self.readers['replay.details'] = [ ReplayDetailsReader() ]
17-
self.readers['replay.attributes.events'] = [ AttributeEventsReader_17326(), AttributeEventsReader() ]
18-
self.readers['replay.message.events'] = [ MessageEventsReader() ]
19-
self.readers['replay.game.events'] = [ GameEventsReader_17326(), GameEventsReader_16561(), GameEventsReader() ]
20-
21-
self.processors = [
22-
PeopleProcessor,
23-
AttributeProcessor,
24-
TeamsProcessor,
25-
MessageProcessor,
26-
RecorderProcessor,
27-
EventProcessor,
28-
ApmProcessor,
29-
ResultsProcessor
30-
]
31-
32-
class NoEventsConfig(object):
33-
def __init__(self):
34-
self.ReplayClass = Replay
35-
self.readers = OrderedDict()
36-
self.readers['replay.initData'] = [ ReplayInitDataReader() ]
37-
self.readers['replay.details'] = [ ReplayDetailsReader() ]
38-
self.readers['replay.attributes.events'] = [ AttributeEventsReader_17326(), AttributeEventsReader() ]
39-
self.readers['replay.message.events'] = [ MessageEventsReader() ]
40-
41-
self.processors = [
42-
PeopleProcessor,
43-
AttributeProcessor,
44-
TeamsProcessor,
45-
MessageProcessor,
46-
RecorderProcessor,
11+
#####################################################
12+
# Metaclass used to help enforce the usage contract
13+
#####################################################
14+
class MetaConfig(type):
15+
def __new__(meta, class_name, bases, class_dict):
16+
if class_name != 'Config': #Parent class is exempt from checks
17+
assert 'ReplayClass' in class_dict or key_in_bases('ReplayClass',bases), \
18+
"%s must specify 'ReplayClass' to be the class acting as a replay container" % class_name
19+
20+
assert 'readers' in class_dict or key_in_bases('readers',bases), \
21+
"%s must specify 'dict<string,list<Reader>> readers'" % class_name
22+
23+
assert 'processors' in class_dict or key_in_bases('processors',bases), \
24+
"%s must specify 'list<Processor> processors'" % class_name
25+
26+
return type.__new__(meta, class_name, bases, class_dict)
27+
28+
class Config(object):
29+
__metaclass__ = MetaConfig
30+
31+
#####################################################
32+
33+
class DefaultConfig(Config):
34+
ReplayClass = Replay
35+
36+
''' The dict([ (key1,value1),(key2,value2).... ]) method has been applied
37+
here in order to keep the reading order intact
38+
'''
39+
readers = OrderedDict([
40+
('replay.initData', [ReplayInitDataReader()]),
41+
('replay.details', [ReplayDetailsReader()]),
42+
('replay.attributes.events', [AttributeEventsReader_17326(), AttributeEventsReader()]),
43+
('replay.message.events', [MessageEventsReader()]),
44+
('replay.game.events', [GameEventsReader_17326(), GameEventsReader_16561(), GameEventsReader()]),
45+
])
46+
47+
processors = [
48+
PeopleProcessor(),
49+
AttributeProcessor(),
50+
TeamsProcessor(),
51+
MessageProcessor(),
52+
RecorderProcessor(),
53+
EventProcessor(),
54+
ApmProcessor(),
55+
ResultsProcessor()
4756
]
57+
58+
#####################################################
59+
60+
class NoEventsConfig(DefaultConfig):
61+
62+
readers = OrderedDict([
63+
('replay.initData', [ReplayInitDataReader()]),
64+
('replay.details', [ReplayDetailsReader()]),
65+
('replay.attributes.events', [AttributeEventsReader_17326(), AttributeEventsReader()]),
66+
('replay.message.events', [MessageEventsReader()]),
67+
])
68+
69+
processors = [
70+
PeopleProcessor(),
71+
AttributeProcessor(),
72+
TeamsProcessor(),
73+
MessageProcessor(),
74+
RecorderProcessor(),
75+
]
76+

0 commit comments

Comments
 (0)