@@ -38,7 +38,11 @@ def _PyInfo_init(
3838 direct_pyc_files = depset (),
3939 transitive_pyc_files = depset (),
4040 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 ()):
4246 _check_arg_type ("transitive_sources" , "depset" , transitive_sources )
4347
4448 # Verify it's postorder compatible, but retain is original ordering.
@@ -53,14 +57,24 @@ def _PyInfo_init(
5357
5458 _check_arg_type ("transitive_implicit_pyc_files" , "depset" , transitive_pyc_files )
5559 _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 )
5666 return {
67+ "direct_original_sources" : direct_original_sources ,
5768 "direct_pyc_files" : direct_pyc_files ,
69+ "direct_pyi_files" : direct_pyi_files ,
5870 "has_py2_only_sources" : has_py2_only_sources ,
5971 "has_py3_only_sources" : has_py2_only_sources ,
6072 "imports" : imports ,
6173 "transitive_implicit_pyc_files" : transitive_implicit_pyc_files ,
6274 "transitive_implicit_pyc_source_files" : transitive_implicit_pyc_source_files ,
75+ "transitive_original_sources" : transitive_original_sources ,
6376 "transitive_pyc_files" : transitive_pyc_files ,
77+ "transitive_pyi_files" : transitive_pyi_files ,
6478 "transitive_sources" : transitive_sources ,
6579 "uses_shared_libraries" : uses_shared_libraries ,
6680 }
@@ -69,6 +83,18 @@ PyInfo, _unused_raw_py_info_ctor = define_bazel_6_provider(
6983 doc = "Encapsulates information provided by the Python rules." ,
7084 init = _PyInfo_init ,
7185 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+ """ ,
7298 "direct_pyc_files" : """
7399:type: depset[File]
74100
@@ -78,6 +104,21 @@ by the target and **must be included**.
78104These files usually come from, e.g., a library setting {attr}`precompile=enabled`
79105to forcibly enable precompiling for itself. Downstream binaries are expected
80106to 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+ ::::
81122""" ,
82123 "has_py2_only_sources" : """
83124:type: bool
@@ -116,6 +157,21 @@ then {obj}`transitive_implicit_pyc_files` should be included instead.
116157
117158::::{versionadded} 0.37.0
118159::::
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+ ::::
119175""" ,
120176 "transitive_pyc_files" : """
121177:type: depset[File]
@@ -125,6 +181,22 @@ The transitive set of precompiled files that must be included.
125181These files usually come from, e.g., a library setting {attr}`precompile=enabled`
126182to forcibly enable precompiling for itself. Downstream binaries are expected
127183to 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+ ::::
128200""" ,
129201 "transitive_sources" : """\
130202 :type: depset[File]
@@ -165,7 +237,9 @@ def PyInfoBuilder():
165237 _uses_shared_libraries = [False ],
166238 build = lambda * a , ** k : _PyInfoBuilder_build (self , * a , ** k ),
167239 build_builtin_py_info = lambda * a , ** k : _PyInfoBuilder_build_builtin_py_info (self , * a , ** k ),
240+ direct_original_sources = builders .DepsetBuilder (),
168241 direct_pyc_files = builders .DepsetBuilder (),
242+ direct_pyi_files = builders .DepsetBuilder (),
169243 get_has_py2_only_sources = lambda * a , ** k : _PyInfoBuilder_get_has_py2_only_sources (self , * a , ** k ),
170244 get_has_py3_only_sources = lambda * a , ** k : _PyInfoBuilder_get_has_py3_only_sources (self , * a , ** k ),
171245 get_uses_shared_libraries = lambda * a , ** k : _PyInfoBuilder_get_uses_shared_libraries (self , * a , ** k ),
@@ -182,7 +256,9 @@ def PyInfoBuilder():
182256 set_uses_shared_libraries = lambda * a , ** k : _PyInfoBuilder_set_uses_shared_libraries (self , * a , ** k ),
183257 transitive_implicit_pyc_files = builders .DepsetBuilder (),
184258 transitive_implicit_pyc_source_files = builders .DepsetBuilder (),
259+ transitive_original_sources = builders .DepsetBuilder (),
185260 transitive_pyc_files = builders .DepsetBuilder (),
261+ transitive_pyi_files = builders .DepsetBuilder (),
186262 transitive_sources = builders .DepsetBuilder (),
187263 )
188264 return self
@@ -221,13 +297,39 @@ def _PyInfoBuilder_set_uses_shared_libraries(self, value):
221297 return self
222298
223299def _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+ """
224312 return self .merge_all (list (infos ), direct = direct )
225313
226314def _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+ """
227327 for info in direct :
228328 # BuiltinPyInfo doesn't have this field
229329 if hasattr (info , "direct_pyc_files" ):
330+ self .direct_original_sources .add (info .direct_original_sources )
230331 self .direct_pyc_files .add (info .direct_pyc_files )
332+ self .direct_pyi_files .add (info .direct_pyi_files )
231333
232334 for info in direct + transitive :
233335 self .imports .add (info .imports )
@@ -240,29 +342,58 @@ def _PyInfoBuilder_merge_all(self, transitive, *, direct = []):
240342 if hasattr (info , "transitive_pyc_files" ):
241343 self .transitive_implicit_pyc_files .add (info .transitive_implicit_pyc_files )
242344 self .transitive_implicit_pyc_source_files .add (info .transitive_implicit_pyc_source_files )
345+ self .transitive_original_sources .add (info .transitive_original_sources )
243346 self .transitive_pyc_files .add (info .transitive_pyc_files )
347+ self .transitive_pyi_files .add (info .transitive_pyi_files )
244348
245349 return self
246350
247351def _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+ """
248363 if PyInfo in target :
249364 self .merge (target [PyInfo ])
250365 elif BuiltinPyInfo != None and BuiltinPyInfo in target :
251366 self .merge (target [BuiltinPyInfo ])
252367 return self
253368
254369def _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+ """
255382 for t in targets :
256383 self .merge_target (t )
257384 return self
258385
259386def _PyInfoBuilder_build (self ):
260387 if config .enable_pystar :
261388 kwargs = dict (
389+ direct_original_sources = self .direct_original_sources .build (),
262390 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 (),
264392 transitive_implicit_pyc_files = self .transitive_implicit_pyc_files .build (),
265393 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 (),
266397 )
267398 else :
268399 kwargs = {}
0 commit comments