Skip to content

Commit fd057fb

Browse files
committed
Add type annotation and docstrings to workload automation.
1 parent 2d14c82 commit fd057fb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+7017
-3613
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ libs/armeabi
3232
doc/source/developer_information/developer_guide/instrument_method_map.rst
3333
doc/source/run_config/
3434
.eggs
35+
*venv*/*
36+
.vscode/*

doc/build_instrument_method_map.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@
2222
from wa.framework.signal import CallbackPriority
2323
from wa.utils.doc import format_simple_table
2424

25-
OUTPUT_TEMPLATE_FILE = os.path.join(os.path.dirname(__file__), 'source', 'instrument_method_map.template')
25+
OUTPUT_TEMPLATE_FILE = os.path.join(os.path.dirname(__file__), 'source', 'instrument_method_map.template')
2626

2727

2828
def generate_instrument_method_map(outfile):
2929
signal_table = format_simple_table([(k, v) for k, v in SIGNAL_MAP.items()],
3030
headers=['method name', 'signal'], align='<<')
3131
decorator_names = map(lambda x: x.replace('high', 'fast').replace('low', 'slow'), CallbackPriority.names)
3232
priority_table = format_simple_table(zip(decorator_names, CallbackPriority.names, CallbackPriority.values),
33-
headers=['decorator', 'CallbackPriority name', 'CallbackPriority value'], align='<>')
33+
headers=['decorator', 'CallbackPriority name', 'CallbackPriority value'], align='<>')
3434
with open(OUTPUT_TEMPLATE_FILE) as fh:
3535
template = string.Template(fh.read())
3636
with open(outfile, 'w') as wfh:

wa/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
from wa.framework.resource import (NO_ONE, JarFile, ApkFile, ReventFile, File,
3131
Executable)
3232
from wa.framework.target.descriptor import (TargetDescriptor, TargetDescription,
33-
create_target_description, add_description_for_target)
33+
create_target_description)
3434
from wa.framework.workload import (Workload, ApkWorkload, ApkUiautoWorkload,
3535
ApkReventWorkload, UIWorkload, UiautoWorkload,
3636
PackageHandler, ReventWorkload, TestPackageHandler)

wa/commands/create.py

Lines changed: 232 additions & 122 deletions
Large diffs are not rendered by default.

wa/commands/list.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,21 @@
1919
from wa.framework.target.descriptor import list_target_descriptions
2020
from wa.utils.doc import get_summary
2121
from wa.utils.formatter import DescriptionListFormatter
22+
from argparse import Namespace
23+
from typing import TYPE_CHECKING, cast, Optional, List, Dict, Type
24+
if TYPE_CHECKING:
25+
from wa.framework.pluginloader import __LoaderWrapper
26+
from wa.framework.execution import ExecutionContext, ConfigManager
27+
from wa.framework.plugin import Plugin
2228

2329

2430
class ListCommand(Command):
2531

26-
name = 'list'
27-
description = 'List available WA plugins with a short description of each.'
32+
name: str = 'list'
33+
description: str = 'List available WA plugins with a short description of each.'
2834

29-
def initialize(self, context):
30-
kinds = get_kinds()
35+
def initialize(self, context: Optional['ExecutionContext']) -> None:
36+
kinds: List[str] = get_kinds()
3137
kinds.extend(['augmentations', 'all'])
3238
self.parser.add_argument('kind', metavar='KIND',
3339
help=('Specify the kind of plugin to list. Must be '
@@ -48,8 +54,8 @@ def initialize(self, context):
4854
''')
4955

5056
# pylint: disable=superfluous-parens
51-
def execute(self, state, args):
52-
filters = {}
57+
def execute(self, state: 'ConfigManager', args: Namespace) -> None:
58+
filters: Dict[str, str] = {}
5359
if args.name:
5460
filters['name'] = args.name
5561

@@ -74,16 +80,22 @@ def execute(self, state, args):
7480
list_plugins(args, filters)
7581

7682

77-
def get_kinds():
78-
kinds = pluginloader.kinds
83+
def get_kinds() -> List[str]:
84+
"""
85+
get a list of kinds of commands
86+
"""
87+
kinds = cast('__LoaderWrapper', pluginloader).kinds
7988
if 'target_descriptor' in kinds:
8089
kinds.remove('target_descriptor')
8190
kinds.append('target')
8291
return ['{}s'.format(name) for name in kinds]
8392

8493

8594
# pylint: disable=superfluous-parens
86-
def list_targets():
95+
def list_targets() -> None:
96+
"""
97+
print out target descriptions
98+
"""
8799
targets = list_target_descriptions()
88100
targets = sorted(targets, key=lambda x: x.name)
89101

@@ -94,8 +106,11 @@ def list_targets():
94106
print('')
95107

96108

97-
def list_plugins(args, filters):
98-
results = pluginloader.list_plugins(args.kind[:-1])
109+
def list_plugins(args, filters: Dict[str, str]) -> None:
110+
"""
111+
print list of plugins
112+
"""
113+
results = cast('__LoaderWrapper', pluginloader).list_plugins(args.kind[:-1])
99114
if filters or args.platform:
100115
filtered_results = []
101116
for result in results:
@@ -113,14 +128,14 @@ def list_plugins(args, filters):
113128

114129
if filtered_results:
115130
output = DescriptionListFormatter()
116-
for result in sorted(filtered_results, key=lambda x: x.name):
117-
output.add_item(get_summary(result), result.name)
131+
for result in sorted(filtered_results, key=lambda x: x.name or ''):
132+
output.add_item(get_summary(result), result.name or '')
118133
print(output.format_data())
119134

120135
print('')
121136

122137

123-
def check_platform(plugin, platform):
138+
def check_platform(plugin: Type['Plugin'], platform: str) -> bool:
124139
supported_platforms = getattr(plugin, 'supported_platforms', [])
125140
if supported_platforms:
126141
return platform in supported_platforms

wa/commands/process.py

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,36 @@
1919
from wa import discover_wa_outputs
2020
from wa.framework.configuration.core import Status
2121
from wa.framework.exception import CommandError
22-
from wa.framework.output import RunOutput
22+
from wa.framework.output import RunOutput, JobOutput
2323
from wa.framework.output_processor import ProcessorManager
2424
from wa.utils import log
25+
from argparse import Namespace
26+
from typing import Optional, TYPE_CHECKING, List, cast
27+
from types import ModuleType
28+
if TYPE_CHECKING:
29+
from wa.framework.target.info import TargetInfo
30+
from wa.framework.execution import ExecutionContext, ConfigManager
2531

2632

2733
class ProcessContext(object):
28-
29-
def __init__(self):
30-
self.run_output = None
31-
self.target_info = None
32-
self.job_output = None
34+
"""
35+
process context
36+
"""
37+
def __init__(self) -> None:
38+
self.run_output: Optional[RunOutput] = None
39+
self.target_info: Optional['TargetInfo'] = None
40+
self.job_output: Optional[JobOutput] = None
3341

3442
def add_augmentation(self, aug):
3543
pass
3644

3745

3846
class ProcessCommand(Command):
3947

40-
name = 'process'
41-
description = 'Process the output from previously run workloads.'
48+
name: str = 'process'
49+
description: str = 'Process the output from previously run workloads.'
4250

43-
def initialize(self, context):
51+
def initialize(self, context: Optional['ExecutionContext']) -> None:
4452
self.parser.add_argument('directory', metavar='DIR',
4553
help="""
4654
Specify a directory containing the data
@@ -69,14 +77,14 @@ def initialize(self, context):
6977
instead of just processing the root.
7078
""")
7179

72-
def execute(self, config, args): # pylint: disable=arguments-differ,too-many-branches,too-many-statements
73-
process_directory = os.path.expandvars(args.directory)
80+
def execute(self, config: 'ConfigManager', args: Namespace): # pylint: disable=arguments-differ,too-many-branches,too-many-statements
81+
process_directory: str = os.path.expandvars(args.directory)
7482
self.logger.debug('Using process directory: {}'.format(process_directory))
7583
if not os.path.exists(process_directory):
76-
msg = 'Path `{}` does not exist, please specify a valid path.'
84+
msg: str = 'Path `{}` does not exist, please specify a valid path.'
7785
raise CommandError(msg.format(process_directory))
7886
if not args.recursive:
79-
output_list = [RunOutput(process_directory)]
87+
output_list: List[RunOutput] = [RunOutput(process_directory)]
8088
else:
8189
output_list = list(discover_wa_outputs(process_directory))
8290

@@ -96,14 +104,14 @@ def execute(self, config, args): # pylint: disable=arguments-differ,too-many-br
96104
self.logger.info('Install output processors for run in path `{}`'
97105
.format(run_output.basepath))
98106

99-
logfile = os.path.join(run_output.basepath, 'process.log')
107+
logfile: str = os.path.join(run_output.basepath, 'process.log')
100108
i = 0
101109
while os.path.exists(logfile):
102110
i += 1
103111
logfile = os.path.join(run_output.basepath, 'process-{}.log'.format(i))
104112
log.add_file(logfile)
105113

106-
pm = ProcessorManager(loader=config.plugin_cache)
114+
pm = ProcessorManager(loader=cast(ModuleType, config.plugin_cache))
107115
for proc in config.get_processors():
108116
pm.install(proc, pc)
109117
if args.additional_processors:
@@ -128,11 +136,12 @@ def execute(self, config, args): # pylint: disable=arguments-differ,too-many-br
128136
pc.job_output = job_output
129137
pm.enable_all()
130138
if not args.force:
131-
for augmentation in job_output.spec.augmentations:
132-
try:
133-
pm.disable(augmentation)
134-
except ValueError:
135-
pass
139+
if job_output.spec:
140+
for augmentation in job_output.spec.augmentations:
141+
try:
142+
pm.disable(augmentation)
143+
except ValueError:
144+
pass
136145

137146
msg = 'Processing job {} {} iteration {}'
138147
self.logger.info(msg.format(job_output.id, job_output.label,

0 commit comments

Comments
 (0)