Skip to content

Commit be4ff14

Browse files
committed
Add type annotations to ProductPipeline in build-script
This prevents possible runtime type errors and helped uncovering #82777. It also server as an improvement o documentation, as provides inferred type annotations for users of this class and callers of its methods.
1 parent 576a378 commit be4ff14

File tree

4 files changed

+29
-23
lines changed

4 files changed

+29
-23
lines changed

utils/build-script

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The ultimate tool for building Swift.
1414
"""
1515

1616

17+
from argparse import Namespace
1718
import json
1819
import os
1920
import platform
@@ -187,7 +188,7 @@ def tar(source, destination):
187188
# -----------------------------------------------------------------------------
188189
# Argument Validation
189190

190-
def validate_arguments(toolchain, args):
191+
def validate_arguments(toolchain, args: Namespace):
191192
if toolchain.cc is None or toolchain.cxx is None:
192193
fatal_error(
193194
"can't find clang (please install clang-3.5 or a "

utils/build_swift/build_swift/migration.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"""
1313

1414

15+
from argparse import ArgumentParser
1516
import itertools
1617
import subprocess
1718

@@ -97,7 +98,7 @@ def _process_disambiguation_arguments(args, unknown_args):
9798
return args, unknown_args
9899

99100

100-
def parse_args(parser, args, namespace=None):
101+
def parse_args(parser: ArgumentParser, args, namespace=None):
101102
"""Parses a given argument list with the given argparse.ArgumentParser.
102103
103104
Return a processed arguments object. Any unknown arguments are stored in

utils/swift_build_support/swift_build_support/productpipeline_list_builder.py

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
import platform
1414

15+
from typing import Optional
16+
from products.product import Product
1517
from swift_build_support.swift_build_support import build_graph
1618

1719

@@ -23,14 +25,14 @@ class ProductPipeline(object):
2325
2426
This class is meant to just be state.
2527
"""
26-
def __init__(self, should_run_epilogue_operations, identity, is_impl):
28+
def __init__(self, should_run_epilogue_operations: bool, identity: int, is_impl: bool):
2729
assert isinstance(identity, int)
2830
self.identity = identity
29-
self.products = []
31+
self.products: list[tuple[type[Product], bool]] = []
3032
self.is_impl = is_impl
3133
self.should_run_epilogue_operations = should_run_epilogue_operations
3234

33-
def append(self, product, is_enabled):
35+
def append(self, product: type[Product], is_enabled: bool):
3436
self.products.append((product, is_enabled))
3537

3638
def finalize(self):
@@ -41,7 +43,7 @@ def finalize(self):
4143
def __iter__(self):
4244
return iter(self.products)
4345

44-
def __getitem__(self, i):
46+
def __getitem__(self, i) -> tuple[type[Product], bool]:
4547
return self.products[i]
4648

4749
def __len__(self):
@@ -65,9 +67,9 @@ class ProductPipelineListBuilder(object):
6567
def __init__(self, args):
6668
self.args = args
6769
self.current_count = 0
68-
self.current_pipeline = None
70+
self.current_pipeline: Optional[ProductPipeline] = None
6971
self.is_current_pipeline_impl = False
70-
self.pipeline_list = []
72+
self.pipeline_list: list[ProductPipeline] = []
7173

7274
def begin_pipeline(self):
7375
if self.current_pipeline is not None:
@@ -93,14 +95,14 @@ def reset(self):
9395
self.is_current_pipeline_impl = False
9496
self.pipelinst_list = []
9597

96-
def add_product(self, product_cls, is_enabled):
98+
def add_product(self, product_cls: type[Product], is_enabled: bool):
9799
"""Add a non-impl product to the current pipeline begin constructed"""
98100
assert self.current_pipeline is not None
99101
assert not self.is_current_pipeline_impl
100102
assert not product_cls.is_build_script_impl_product()
101103
self.current_pipeline.append(product_cls, is_enabled)
102104

103-
def add_impl_product(self, product_cls, is_enabled):
105+
def add_impl_product(self, product_cls: type[Product], is_enabled: bool):
104106
"""Add an impl product to the current pipeline begin constructed"""
105107
assert self.current_pipeline is not None
106108
assert self.is_current_pipeline_impl
@@ -109,14 +111,16 @@ def add_impl_product(self, product_cls, is_enabled):
109111

110112
def infer(self):
111113
products_to_generation_index = {}
112-
enabled_products = set()
113-
inferred_pipeline_list = []
114+
enabled_products: set[type[Product]] = set()
115+
inferred_pipeline_list: list[list[Optional[type[Product]]]] = []
114116
last_impl_pipeline_index = None
117+
115118
for i in range(len(self.pipeline_list)):
116-
pipeline = self.pipeline_list[i]
119+
pipeline: ProductPipeline = self.pipeline_list[i]
117120
if pipeline.is_impl:
118121
last_impl_pipeline_index = i
119-
final_pipeline = []
122+
123+
final_pipeline: list[Optional[type[Product]]] = []
120124
for pipeline_i in range(len(pipeline)):
121125
(p, is_enabled) = pipeline[pipeline_i]
122126
# Make sure p has not been added multiple times to the builder.
@@ -137,11 +141,11 @@ def infer(self):
137141
p.get_dependencies()))
138142

139143
for i in range(len(inferred_pipeline_list)):
140-
pipeline = inferred_pipeline_list[i]
144+
inferred_pipeline = inferred_pipeline_list[i]
141145

142146
# Filter out any of the pipelines that before inference were not
143147
# selected.
144-
enabled_pipeline = [p for p in pipeline if p is not None]
148+
enabled_pipeline: list = [p for p in inferred_pipeline if p is not None]
145149

146150
if self.args.verbose_build:
147151
print("-- Build Graph Inference --")
@@ -170,18 +174,18 @@ def infer(self):
170174
inferred_pipeline_list[gen_offset][index] = p
171175

172176
filtered_results = []
173-
for pipeline in inferred_pipeline_list:
174-
filtered_results.append([p for p in pipeline if p is not None])
177+
for inferred_pipeline in inferred_pipeline_list:
178+
filtered_results.append([p for p in inferred_pipeline if p is not None])
175179

176180
if self.args.verbose_build:
177181
print("Final Build Order:")
178-
for pipeline in filtered_results:
179-
for p in pipeline:
182+
for filtered_pipeline in filtered_results:
183+
for p in filtered_pipeline:
180184
print(" {}".format(p.product_name()))
181185

182186
return (filtered_results, last_impl_pipeline_index)
183187

184-
def finalize(self, shouldInfer):
188+
def finalize(self, shouldInfer: bool):
185189
"""Product a final schedule and return a list of our product pipelines. Resets
186190
the builder when done so is a consuming operation.
187191
"""

utils/swift_build_support/swift_build_support/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import sys
1717
import time
1818

19-
19+
from typing import NoReturn
2020
from build_swift.build_swift.constants import SWIFT_BUILD_ROOT
2121

2222

@@ -30,7 +30,7 @@ def fatal_error(message, stream=sys.stderr):
3030
sys.exit(1)
3131

3232

33-
def exit_rejecting_arguments(message, parser=None):
33+
def exit_rejecting_arguments(message, parser=None) -> NoReturn:
3434
print(message, file=sys.stderr)
3535
if parser:
3636
parser.print_usage(sys.stderr)

0 commit comments

Comments
 (0)