@@ -26,6 +26,8 @@ const (
2626 pyBinaryEntrypointFilename = "__main__.py"
2727 pyTestEntrypointFilename = "__test__.py"
2828 pyTestEntrypointTargetname = "__test__"
29+ conftestFilename = "conftest.py"
30+ conftestTargetname = "conftest"
2931)
3032
3133var (
@@ -71,6 +73,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
7173 // be generated for this package or not.
7274 hasPyTestFile := false
7375 hasPyTestTarget := false
76+ hasConftestFile := false
7477
7578 for _ , f := range args .RegularFiles {
7679 if cfg .IgnoresFile (filepath .Base (f )) {
@@ -81,6 +84,8 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
8184 hasPyBinary = true
8285 } else if ! hasPyTestFile && f == pyTestEntrypointFilename {
8386 hasPyTestFile = true
87+ } else if f == conftestFilename {
88+ hasConftestFile = true
8489 } else if strings .HasSuffix (f , "_test.py" ) || (strings .HasPrefix (f , "test_" ) && ext == ".py" ) {
8590 pyTestFilenames .Add (f )
8691 } else if ext == ".py" {
@@ -196,10 +201,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
196201
197202 pyLibraryTargetName := cfg .RenderLibraryName (packageName )
198203
199- // Check if a target with the same name we are generating alredy exists,
200- // and if it is of a different kind from the one we are generating. If
201- // so, we have to throw an error since Gazelle won't generate it
202- // correctly.
204+ // Check if a target with the same name we are generating already
205+ // exists, and if it is of a different kind from the one we are
206+ // generating. If so, we have to throw an error since Gazelle won't
207+ // generate it correctly.
203208 if args .File != nil {
204209 for _ , t := range args .File .Rules {
205210 if t .Name () == pyLibraryTargetName && t .Kind () != pyLibraryKind {
@@ -233,10 +238,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
233238
234239 pyBinaryTargetName := cfg .RenderBinaryName (packageName )
235240
236- // Check if a target with the same name we are generating alredy exists,
237- // and if it is of a different kind from the one we are generating. If
238- // so, we have to throw an error since Gazelle won't generate it
239- // correctly.
241+ // Check if a target with the same name we are generating already
242+ // exists, and if it is of a different kind from the one we are
243+ // generating. If so, we have to throw an error since Gazelle won't
244+ // generate it correctly.
240245 if args .File != nil {
241246 for _ , t := range args .File .Rules {
242247 if t .Name () == pyBinaryTargetName && t .Kind () != pyBinaryKind {
@@ -267,6 +272,43 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
267272 result .Imports = append (result .Imports , pyBinary .PrivateAttr (config .GazelleImportsKey ))
268273 }
269274
275+ var conftest * rule.Rule
276+ if hasConftestFile {
277+ deps , err := parser .parseSingle (conftestFilename )
278+ if err != nil {
279+ log .Fatalf ("ERROR: %v\n " , err )
280+ }
281+
282+ // Check if a target with the same name we are generating already
283+ // exists, and if it is of a different kind from the one we are
284+ // generating. If so, we have to throw an error since Gazelle won't
285+ // generate it correctly.
286+ if args .File != nil {
287+ for _ , t := range args .File .Rules {
288+ if t .Name () == conftestTargetname && t .Kind () != pyLibraryKind {
289+ fqTarget := label .New ("" , args .Rel , conftestTargetname )
290+ err := fmt .Errorf ("failed to generate target %q of kind %q: " +
291+ "a target of kind %q with the same name already exists." ,
292+ fqTarget .String (), pyLibraryKind , t .Kind ())
293+ collisionErrors .Add (err )
294+ }
295+ }
296+ }
297+
298+ conftestTarget := newTargetBuilder (pyLibraryKind , conftestTargetname , pythonProjectRoot , args .Rel ).
299+ setUUID (uuid .Must (uuid .NewUUID ()).String ()).
300+ addSrc (conftestFilename ).
301+ addModuleDependencies (deps ).
302+ addVisibility (visibility ).
303+ setTestonly ().
304+ generateImportsAttribute ()
305+
306+ conftest = conftestTarget .build ()
307+
308+ result .Gen = append (result .Gen , conftest )
309+ result .Imports = append (result .Imports , conftest .PrivateAttr (config .GazelleImportsKey ))
310+ }
311+
270312 if hasPyTestFile || hasPyTestTarget {
271313 if hasPyTestFile {
272314 // Only add the pyTestEntrypointFilename to the pyTestFilenames if
@@ -280,10 +322,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
280322
281323 pyTestTargetName := cfg .RenderTestName (packageName )
282324
283- // Check if a target with the same name we are generating alredy exists,
284- // and if it is of a different kind from the one we are generating. If
285- // so, we have to throw an error since Gazelle won't generate it
286- // correctly.
325+ // Check if a target with the same name we are generating already
326+ // exists, and if it is of a different kind from the one we are
327+ // generating. If so, we have to throw an error since Gazelle won't
328+ // generate it correctly.
287329 if args .File != nil {
288330 for _ , t := range args .File .Rules {
289331 if t .Name () == pyTestTargetName && t .Kind () != pyTestKind {
@@ -317,6 +359,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
317359 pyTestTarget .addModuleDependency (module {Name : pyLibrary .PrivateAttr (uuidKey ).(string )})
318360 }
319361
362+ if conftest != nil {
363+ pyTestTarget .addModuleDependency (module {Name : conftest .PrivateAttr (uuidKey ).(string )})
364+ }
365+
320366 pyTest := pyTestTarget .build ()
321367
322368 result .Gen = append (result .Gen , pyTest )
0 commit comments