@@ -318,6 +318,39 @@ def test_accented_directory(self) -> None:
318
318
"name" : "â" ,
319
319
}
320
320
321
+ def test_no_duplicate_packages (self ) -> None :
322
+ self .make_file (
323
+ "namespace/package/__init__.py" ,
324
+ "from . import sample; from . import test; from .subpackage import test"
325
+ )
326
+ self .make_file ("namespace/package/sample.py" , "print('package.sample')" )
327
+ self .make_file ("namespace/package/test.py" , "print('package.test')" )
328
+ self .make_file ("namespace/package/subpackage/test.py" , "print('package.subpackage.test')" )
329
+
330
+ # no source path passed to coverage!
331
+ # problem occurs when they are dynamically generated during xml report
332
+ cov = coverage .Coverage ()
333
+
334
+ cov .start ()
335
+ import_local_file ("foo" , "namespace/package/__init__.py" ) # pragma: nested
336
+ cov .stop () # pragma: nested
337
+
338
+ cov .xml_report ()
339
+
340
+ dom = ElementTree .parse ("coverage.xml" )
341
+
342
+ # only two packages should be present
343
+ packages = dom .findall (".//package" )
344
+ assert len (packages ) == 2
345
+
346
+ # one of them is namespace.package
347
+ named_package = dom .findall (".//package[@name='namespace.package']" )
348
+ assert len (named_package ) == 1
349
+
350
+ # the other one namespace.package.subpackage
351
+ named_sub_package = dom .findall (".//package[@name='namespace.package.subpackage']" )
352
+ assert len (named_sub_package ) == 1
353
+
321
354
322
355
def unbackslash (v : Any ) -> Any :
323
356
"""Find strings in `v`, and replace backslashes with slashes throughout."""
0 commit comments