@@ -250,6 +250,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
250250					srcs .Remove (name )
251251				}
252252			}
253+ 
253254			sort .Strings (mainFileNames )
254255			for  _ , filename  :=  range  mainFileNames  {
255256				pyBinaryTargetName  :=  strings .TrimSuffix (filepath .Base (filename ), ".py" )
@@ -259,9 +260,15 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
259260						fqTarget .String (), actualPyBinaryKind , err )
260261					continue 
261262				}
263+ 
264+ 				// Add any sibling .pyi files to pyi_srcs 
265+ 				filenames  :=  treeset .NewWith (godsutils .StringComparator , filename )
266+ 				pyiSrcs , _  :=  getPyiFilenames (filenames , cfg .GeneratePyiSrcs (), args .Dir )
267+ 
262268				pyBinary  :=  newTargetBuilder (pyBinaryKind , pyBinaryTargetName , pythonProjectRoot , args .Rel , pyFileNames , cfg .ResolveSiblingImports ()).
263269					addVisibility (visibility ).
264270					addSrc (filename ).
271+ 					addPyiSrcs (pyiSrcs ).
265272					addModuleDependencies (mainModules [filename ]).
266273					addResolvedDependencies (annotations .includeDeps ).
267274					generateImportsAttribute ().
@@ -289,6 +296,9 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
289296			}
290297		}
291298
299+ 		// Add any sibling .pyi files to pyi_srcs 
300+ 		pyiSrcs , _  :=  getPyiFilenames (srcs , cfg .GeneratePyiSrcs (), args .Dir )
301+ 
292302		// Check if a target with the same name we are generating already 
293303		// exists, and if it is of a different kind from the one we are 
294304		// generating. If so, we have to throw an error since Gazelle won't 
@@ -304,6 +314,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
304314		pyLibrary  :=  newTargetBuilder (pyLibraryKind , pyLibraryTargetName , pythonProjectRoot , args .Rel , pyFileNames , cfg .ResolveSiblingImports ()).
305315			addVisibility (visibility ).
306316			addSrcs (srcs ).
317+ 			addPyiSrcs (pyiSrcs ).
307318			addModuleDependencies (allDeps ).
308319			addResolvedDependencies (annotations .includeDeps ).
309320			generateImportsAttribute ().
@@ -354,10 +365,15 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
354365			collisionErrors .Add (err )
355366		}
356367
368+ 		// Add any sibling .pyi files to pyi_srcs 
369+ 		filenames  :=  treeset .NewWith (godsutils .StringComparator , pyBinaryEntrypointFilename )
370+ 		pyiSrcs , _  :=  getPyiFilenames (filenames , cfg .GeneratePyiSrcs (), args .Dir )
371+ 
357372		pyBinaryTarget  :=  newTargetBuilder (pyBinaryKind , pyBinaryTargetName , pythonProjectRoot , args .Rel , pyFileNames , cfg .ResolveSiblingImports ()).
358373			setMain (pyBinaryEntrypointFilename ).
359374			addVisibility (visibility ).
360375			addSrc (pyBinaryEntrypointFilename ).
376+ 			addPyiSrcs (pyiSrcs ).
361377			addModuleDependencies (deps ).
362378			addResolvedDependencies (annotations .includeDeps ).
363379			setAnnotations (* annotations ).
@@ -387,8 +403,13 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
387403			collisionErrors .Add (err )
388404		}
389405
406+ 		// Add any sibling .pyi files to pyi_srcs 
407+ 		filenames  :=  treeset .NewWith (godsutils .StringComparator , conftestFilename )
408+ 		pyiSrcs , _  :=  getPyiFilenames (filenames , cfg .GeneratePyiSrcs (), args .Dir )
409+ 
390410		conftestTarget  :=  newTargetBuilder (pyLibraryKind , conftestTargetname , pythonProjectRoot , args .Rel , pyFileNames , cfg .ResolveSiblingImports ()).
391411			addSrc (conftestFilename ).
412+ 			addPyiSrcs (pyiSrcs ).
392413			addModuleDependencies (deps ).
393414			addResolvedDependencies (annotations .includeDeps ).
394415			setAnnotations (* annotations ).
@@ -419,8 +440,13 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
419440				fqTarget .String (), actualPyTestKind , err , pythonconfig .TestNamingConvention )
420441			collisionErrors .Add (err )
421442		}
443+ 
444+ 		// Add any sibling .pyi files to pyi_srcs 
445+ 		pyiSrcs , _  :=  getPyiFilenames (srcs , cfg .GeneratePyiSrcs (), args .Dir )
446+ 
422447		return  newTargetBuilder (pyTestKind , pyTestTargetName , pythonProjectRoot , args .Rel , pyFileNames , cfg .ResolveSiblingImports ()).
423448			addSrcs (srcs ).
449+ 			addPyiSrcs (pyiSrcs ).
424450			addModuleDependencies (deps ).
425451			addResolvedDependencies (annotations .includeDeps ).
426452			setAnnotations (* annotations ).
@@ -627,3 +653,23 @@ func generateProtoLibraries(args language.GenerateArgs, cfg *pythonconfig.Config
627653	}
628654
629655}
656+ 
657+ // getPyiFilenames returns a set of existing .pyi source file names for a given set of source 
658+ // file names if GeneratePyiSrcs is set. Otherwise, returns an empty set. 
659+ func  getPyiFilenames (filenames  * treeset.Set , generatePyiSrcs  bool , basePath  string ) (* treeset.Set , error ) {
660+ 	pyiSrcs  :=  treeset .NewWith (godsutils .StringComparator )
661+ 	if  generatePyiSrcs  {
662+ 		it  :=  filenames .Iterator ()
663+ 		for  it .Next () {
664+ 			pyiFilename  :=  it .Value ().(string ) +  "i"  // foo.py --> foo.pyi 
665+ 
666+ 			_ , err  :=  os .Stat (filepath .Join (basePath , pyiFilename ))
667+ 			// If the file DNE or there's some other error, there's nothing to do. 
668+ 			if  err  ==  nil  {
669+ 				// pyi file exists, add it 
670+ 				pyiSrcs .Add (pyiFilename )
671+ 			}
672+ 		}
673+ 	}
674+ 	return  pyiSrcs , nil 
675+ }
0 commit comments