@@ -38,7 +38,11 @@ def _PyInfo_init(
38
38
direct_pyc_files = depset (),
39
39
transitive_pyc_files = depset (),
40
40
transitive_implicit_pyc_files = depset (),
41
- transitive_implicit_pyc_source_files = depset ()):
41
+ transitive_implicit_pyc_source_files = depset (),
42
+ direct_original_sources = depset (),
43
+ transitive_original_sources = depset (),
44
+ direct_pyi_files = depset (),
45
+ transitive_pyi_files = depset ()):
42
46
_check_arg_type ("transitive_sources" , "depset" , transitive_sources )
43
47
44
48
# Verify it's postorder compatible, but retain is original ordering.
@@ -53,14 +57,24 @@ def _PyInfo_init(
53
57
54
58
_check_arg_type ("transitive_implicit_pyc_files" , "depset" , transitive_pyc_files )
55
59
_check_arg_type ("transitive_implicit_pyc_source_files" , "depset" , transitive_pyc_files )
60
+
61
+ _check_arg_type ("direct_original_sources" , "depset" , direct_original_sources )
62
+ _check_arg_type ("transitive_original_sources" , "depset" , transitive_original_sources )
63
+
64
+ _check_arg_type ("direct_pyi_files" , "depset" , direct_pyi_files )
65
+ _check_arg_type ("transitive_pyi_files" , "depset" , transitive_pyi_files )
56
66
return {
67
+ "direct_original_sources" : direct_original_sources ,
57
68
"direct_pyc_files" : direct_pyc_files ,
69
+ "direct_pyi_files" : direct_pyi_files ,
58
70
"has_py2_only_sources" : has_py2_only_sources ,
59
71
"has_py3_only_sources" : has_py2_only_sources ,
60
72
"imports" : imports ,
61
73
"transitive_implicit_pyc_files" : transitive_implicit_pyc_files ,
62
74
"transitive_implicit_pyc_source_files" : transitive_implicit_pyc_source_files ,
75
+ "transitive_original_sources" : transitive_original_sources ,
63
76
"transitive_pyc_files" : transitive_pyc_files ,
77
+ "transitive_pyi_files" : transitive_pyi_files ,
64
78
"transitive_sources" : transitive_sources ,
65
79
"uses_shared_libraries" : uses_shared_libraries ,
66
80
}
@@ -69,6 +83,18 @@ PyInfo, _unused_raw_py_info_ctor = define_bazel_6_provider(
69
83
doc = "Encapsulates information provided by the Python rules." ,
70
84
init = _PyInfo_init ,
71
85
fields = {
86
+ "direct_original_sources" : """
87
+ :type: depset[File]
88
+
89
+ The `.py` source files (if any) that are considered directly provided by
90
+ the target. This field is intended so that static analysis tools can recover the
91
+ original Python source files, regardless of any build settings (e.g.
92
+ precompiling), so they can analyze source code. The values are typically the
93
+ `.py` files in the `srcs` attribute (or equivalent).
94
+
95
+ ::::{versionadded} 1.1.0
96
+ ::::
97
+ """ ,
72
98
"direct_pyc_files" : """
73
99
:type: depset[File]
74
100
@@ -78,6 +104,21 @@ by the target and **must be included**.
78
104
These files usually come from, e.g., a library setting {attr}`precompile=enabled`
79
105
to forcibly enable precompiling for itself. Downstream binaries are expected
80
106
to always include these files, as the originating target expects them to exist.
107
+ """ ,
108
+ "direct_pyi_files" : """
109
+ :type: depset[File]
110
+
111
+ Type definition files (usually `.pyi` files) for the Python modules provided by
112
+ this target. Usually they describe the source files listed in
113
+ `direct_original_sources`. This field is primarily for static analysis tools.
114
+
115
+ :::{note}
116
+ This may contain implementation-specific file types specific to a particular
117
+ type checker.
118
+ :::
119
+
120
+ ::::{versionadded} 1.1.0
121
+ ::::
81
122
""" ,
82
123
"has_py2_only_sources" : """
83
124
:type: bool
@@ -116,6 +157,21 @@ then {obj}`transitive_implicit_pyc_files` should be included instead.
116
157
117
158
::::{versionadded} 0.37.0
118
159
::::
160
+ """ ,
161
+ "transitive_original_sources" : """
162
+ :type: depset[File]
163
+
164
+ The transitive set of `.py` source files (if any) that are considered the
165
+ original sources for this target and its transitive dependencies. This field is
166
+ intended so that static analysis tools can recover the original Python source
167
+ files, regardless of any build settings (e.g. precompiling), so they can analyze
168
+ source code. The values are typically the `.py` files in the `srcs` attribute
169
+ (or equivalent).
170
+
171
+ This is superset of `direct_original_sources`.
172
+
173
+ ::::{versionadded} 1.1.0
174
+ ::::
119
175
""" ,
120
176
"transitive_pyc_files" : """
121
177
:type: depset[File]
@@ -125,6 +181,22 @@ The transitive set of precompiled files that must be included.
125
181
These files usually come from, e.g., a library setting {attr}`precompile=enabled`
126
182
to forcibly enable precompiling for itself. Downstream binaries are expected
127
183
to always include these files, as the originating target expects them to exist.
184
+ """ ,
185
+ "transitive_pyi_files" : """
186
+ :type: depset[File]
187
+
188
+ The transitive set of type definition files (usually `.pyi` files) for the
189
+ Python modules for this target and its transitive dependencies. this target.
190
+ Usually they describe the source files listed in `transitive_original_sources`.
191
+ This field is primarily for static analysis tools.
192
+
193
+ :::{note}
194
+ This may contain implementation-specific file types specific to a particular
195
+ type checker.
196
+ :::
197
+
198
+ ::::{versionadded} 1.1.0
199
+ ::::
128
200
""" ,
129
201
"transitive_sources" : """\
130
202
:type: depset[File]
@@ -165,7 +237,9 @@ def PyInfoBuilder():
165
237
_uses_shared_libraries = [False ],
166
238
build = lambda * a , ** k : _PyInfoBuilder_build (self , * a , ** k ),
167
239
build_builtin_py_info = lambda * a , ** k : _PyInfoBuilder_build_builtin_py_info (self , * a , ** k ),
240
+ direct_original_sources = builders .DepsetBuilder (),
168
241
direct_pyc_files = builders .DepsetBuilder (),
242
+ direct_pyi_files = builders .DepsetBuilder (),
169
243
get_has_py2_only_sources = lambda * a , ** k : _PyInfoBuilder_get_has_py2_only_sources (self , * a , ** k ),
170
244
get_has_py3_only_sources = lambda * a , ** k : _PyInfoBuilder_get_has_py3_only_sources (self , * a , ** k ),
171
245
get_uses_shared_libraries = lambda * a , ** k : _PyInfoBuilder_get_uses_shared_libraries (self , * a , ** k ),
@@ -182,7 +256,9 @@ def PyInfoBuilder():
182
256
set_uses_shared_libraries = lambda * a , ** k : _PyInfoBuilder_set_uses_shared_libraries (self , * a , ** k ),
183
257
transitive_implicit_pyc_files = builders .DepsetBuilder (),
184
258
transitive_implicit_pyc_source_files = builders .DepsetBuilder (),
259
+ transitive_original_sources = builders .DepsetBuilder (),
185
260
transitive_pyc_files = builders .DepsetBuilder (),
261
+ transitive_pyi_files = builders .DepsetBuilder (),
186
262
transitive_sources = builders .DepsetBuilder (),
187
263
)
188
264
return self
@@ -221,13 +297,39 @@ def _PyInfoBuilder_set_uses_shared_libraries(self, value):
221
297
return self
222
298
223
299
def _PyInfoBuilder_merge (self , * infos , direct = []):
300
+ """Merge other PyInfos into this PyInfo.
301
+
302
+ Args:
303
+ self: implicitly added.
304
+ *infos: {type}`PyInfo` objects to merge in, but only merge in their
305
+ information into this object's transitive fields.
306
+ direct: {type}`list[PyInfo]` objects to merge in, but also merge their
307
+ direct fields into this object's direct fields.
308
+
309
+ Returns:
310
+ {type}`PyInfoBuilder` the current object
311
+ """
224
312
return self .merge_all (list (infos ), direct = direct )
225
313
226
314
def _PyInfoBuilder_merge_all (self , transitive , * , direct = []):
315
+ """Merge other PyInfos into this PyInfo.
316
+
317
+ Args:
318
+ self: implicitly added.
319
+ transitive: {type}`list[PyInfo]` objects to merge in, but only merge in
320
+ their information into this object's transitive fields.
321
+ direct: {type}`list[PyInfo]` objects to merge in, but also merge their
322
+ direct fields into this object's direct fields.
323
+
324
+ Returns:
325
+ {type}`PyInfoBuilder` the current object
326
+ """
227
327
for info in direct :
228
328
# BuiltinPyInfo doesn't have this field
229
329
if hasattr (info , "direct_pyc_files" ):
330
+ self .direct_original_sources .add (info .direct_original_sources )
230
331
self .direct_pyc_files .add (info .direct_pyc_files )
332
+ self .direct_pyi_files .add (info .direct_pyi_files )
231
333
232
334
for info in direct + transitive :
233
335
self .imports .add (info .imports )
@@ -240,29 +342,58 @@ def _PyInfoBuilder_merge_all(self, transitive, *, direct = []):
240
342
if hasattr (info , "transitive_pyc_files" ):
241
343
self .transitive_implicit_pyc_files .add (info .transitive_implicit_pyc_files )
242
344
self .transitive_implicit_pyc_source_files .add (info .transitive_implicit_pyc_source_files )
345
+ self .transitive_original_sources .add (info .transitive_original_sources )
243
346
self .transitive_pyc_files .add (info .transitive_pyc_files )
347
+ self .transitive_pyi_files .add (info .transitive_pyi_files )
244
348
245
349
return self
246
350
247
351
def _PyInfoBuilder_merge_target (self , target ):
352
+ """Merge a target's Python information in this object.
353
+
354
+ Args:
355
+ self: implicitly added.
356
+ target: {type}`Target` targets that provide PyInfo, or other relevant
357
+ providers, will be merged into this object. If a target doesn't provide
358
+ any relevant providers, it is ignored.
359
+
360
+ Returns:
361
+ {type}`PyInfoBuilder` the current object.
362
+ """
248
363
if PyInfo in target :
249
364
self .merge (target [PyInfo ])
250
365
elif BuiltinPyInfo != None and BuiltinPyInfo in target :
251
366
self .merge (target [BuiltinPyInfo ])
252
367
return self
253
368
254
369
def _PyInfoBuilder_merge_targets (self , targets ):
370
+ """Merge multiple targets into this object.
371
+
372
+ Args:
373
+ self: implicitly added.
374
+ targets: {type}`list[Target]`
375
+ targets that provide PyInfo, or other relevant
376
+ providers, will be merged into this object. If a target doesn't provide
377
+ any relevant providers, it is ignored.
378
+
379
+ Returns:
380
+ {type}`PyInfoBuilder` the current object.
381
+ """
255
382
for t in targets :
256
383
self .merge_target (t )
257
384
return self
258
385
259
386
def _PyInfoBuilder_build (self ):
260
387
if config .enable_pystar :
261
388
kwargs = dict (
389
+ direct_original_sources = self .direct_original_sources .build (),
262
390
direct_pyc_files = self .direct_pyc_files .build (),
263
- transitive_pyc_files = self .transitive_pyc_files .build (),
391
+ direct_pyi_files = self .direct_pyi_files .build (),
264
392
transitive_implicit_pyc_files = self .transitive_implicit_pyc_files .build (),
265
393
transitive_implicit_pyc_source_files = self .transitive_implicit_pyc_source_files .build (),
394
+ transitive_original_sources = self .transitive_original_sources .build (),
395
+ transitive_pyc_files = self .transitive_pyc_files .build (),
396
+ transitive_pyi_files = self .transitive_pyi_files .build (),
266
397
)
267
398
else :
268
399
kwargs = {}
0 commit comments