Bug#1024171: diffoscope: autopkgtest regression: 'NoneType' object has no attribute 'add_comment'

Paul Gevers elbrus at debian.org
Tue Nov 15 20:33:29 GMT 2022


Source: diffoscope
Version: 226
Severity: serious
User: debian-ci at lists.debian.org
Usertags: regression

Dear maintainer(s),

With a recent upload of diffoscope the autopkgtest of diffoscope fails 
in testing when that autopkgtest is run with the binary packages of 
diffoscope from unstable. It passes when run with only packages from 
testing. In tabular form:

                        pass            fail
diffoscope             from testing    226
versioned deps [0]     from testing    from unstable
all others             from testing    from testing

I copied some of the output at the bottom of this report.

Currently this regression is blocking the migration to testing [1]. Can 
you please investigate the situation and fix it?

More information about this bug and the reason for filing it can be found on
https://wiki.debian.org/ContinuousIntegration/RegressionEmailInformation

Paul

[0] You can see what packages were added from the second line of the log 
file quoted below. The migration software adds source package from 
unstable to the list if they are needed to install packages from 
diffoscope/226. I.e. due to versioned dependencies or breaks/conflicts.
[1] https://qa.debian.org/excuses.php?package=diffoscope

https://ci.debian.net/data/autopkgtest/testing/amd64/d/diffoscope/28319467/log.gz

=================================== FAILURES 
===================================
_____________________________ test_no_differences 
______________________________

self = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>
other = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>
source = None

     def compare(self, other, source=None):
         difference = super().compare(other, source)
             # Show text-only differences as a sub-diff.
         try:
>           text = Difference.from_operation(Htmltotext, self.path, other.path)

__class__  = <class 'diffoscope.comparators.html.HtmlFile'>
difference = None
other      = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>
self       = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>
source     = None

/usr/lib/python3/dist-packages/diffoscope/comparators/html.py:44: _ _ _ 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
klass = <class 'diffoscope.comparators.html.Htmltotext'>
path1 = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'
path2 = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'
args = (), kwargs = {}

     @staticmethod
     def from_operation(klass, path1, path2, *args, **kwargs):
>       return Difference.from_operation_exc(
             klass, path1, path2, *args, **kwargs
         )[0]

args       = ()
klass      = <class 'diffoscope.comparators.html.Htmltotext'>
kwargs     = {}
path1      = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'
path2      = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'

/usr/lib/python3/dist-packages/diffoscope/difference.py:267: _ _ _ _ _ _ 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
klass = <class 'diffoscope.comparators.html.Htmltotext'>
path1 = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'
path2 = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'
args = (), kwargs = {}, ignore_returncodes = ()
operation_and_feeder = <function 
Difference.from_operation_exc.<locals>.operation_and_feeder at 
0x7f3447054a60>

     @staticmethod
     def from_operation_exc(klass, path1, path2, *args, **kwargs):
         operation_args = kwargs.pop("operation_args", [])
         ignore_returncodes = kwargs.pop("ignore_returncodes", ())
             def operation_and_feeder(path):
             operation = None
             if path == "/dev/null":
                 feeder = feeders.empty()
             else:
                 operation = klass(path, *operation_args)
                 feeder = feeders.from_operation(operation)
                 if operation_excluded(operation.full_name()):
                     return None, None, True
                 operation.start()
             return feeder, operation, False
     >       feeder1, operation1, excluded1 = operation_and_feeder(path1)

args       = ()
ignore_returncodes = ()
klass      = <class 'diffoscope.comparators.html.Htmltotext'>
kwargs     = {}
operation_and_feeder = <function 
Difference.from_operation_exc.<locals>.operation_and_feeder at 
0x7f3447054a60>
operation_args = []
path1      = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'
path2      = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'

/usr/lib/python3/dist-packages/diffoscope/difference.py:288: _ _ _ _ _ _ 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
path = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'

     def operation_and_feeder(path):
         operation = None
         if path == "/dev/null":
             feeder = feeders.empty()
         else:
             operation = klass(path, *operation_args)
             feeder = feeders.from_operation(operation)
>           if operation_excluded(operation.full_name()):

feeder     = <function from_operation.<locals>.feeder at 0x7f3447056e60>
klass      = <class 'diffoscope.comparators.html.Htmltotext'>
operation  = <diffoscope.comparators.html.Htmltotext object at 
0x7f344d280a00>
operation_args = []
path       = 
'/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html'

/usr/lib/python3/dist-packages/diffoscope/difference.py:283: _ _ _ _ _ _ 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <diffoscope.comparators.html.Htmltotext object at 0x7f344d280a00>
args = ()
kwargs = {'replace': 
('/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html',)}

     def full_name(self, *args, **kwargs):
         kwargs.setdefault("replace", (self.path,))
>       return format_cmdline(self.cmdline(), *args, **kwargs)

args       = ()
kwargs     = {'replace': 
('/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html',)}
self       = <diffoscope.comparators.html.Htmltotext object at 
0x7f344d280a00>

/usr/lib/python3/dist-packages/diffoscope/comparators/utils/command.py:71: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ _
args = (<diffoscope.comparators.html.Htmltotext object at 0x7f344d280a00>,)
kwargs = {}

     @functools.wraps(fn)
     def tool_check(*args, **kwargs):
         """
         Due to the way decorators are executed at import-time we defer the
         execution of `find_executable` until we actually run the decorated
         function (instead of prematurely returning a different version of
         `tool_check`).
             This ensures that any os.environ['PATH'] modifications are
         performed prior to the `find_executable` tests.
         """
         if not tool_check_installed(command):
>           raise RequiredToolNotFound(command)
E           diffoscope.exc.RequiredToolNotFound

RequiredToolNotFound = <class 'diffoscope.exc.RequiredToolNotFound'>
args       = (<diffoscope.comparators.html.Htmltotext object at 
0x7f344d280a00>,)
command    = 'html2text'
fn         = <function Htmltotext.cmdline at 0x7f344d4629e0>
kwargs     = {}

/usr/lib/python3/dist-packages/diffoscope/tools.py:137: RequiredToolNotFound

During handling of the above exception, another exception occurred:

html1 = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>

     def test_no_differences(html1):
>       assert html1.compare(html1) is None

html1      = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>

tests/comparators/test_html.py:36: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>
other = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>
source = None

     def compare(self, other, source=None):
         difference = super().compare(other, source)
             # Show text-only differences as a sub-diff.
         try:
             text = Difference.from_operation(Htmltotext, self.path, 
other.path)
             if text is not None:
                 difference.add_details([text])
         except RequiredToolNotFound as exc:  # noqa
>           difference.add_comment(exc.get_comment())
E           AttributeError: 'NoneType' object has no attribute 'add_comment'

__class__  = <class 'diffoscope.comparators.html.HtmlFile'>
difference = None
other      = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>
self       = <<class 'abc.HtmlFile'> 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html>
source     = None

/usr/lib/python3/dist-packages/diffoscope/comparators/html.py:48: 
AttributeError
__________________________________ test_diff 
___________________________________

differences = <Difference 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html 
-- 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test2.html 
[]>

     def test_diff(differences):
         assert_diff(differences, "html_expected_diff")
>       assert_diff(differences.details[0], "html_text_expected_diff")
E       IndexError: list index out of range

differences = <Difference 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test1.html 
-- 
/tmp/autopkgtest-lxc.0soup5pu/downtmp/autopkgtest_tmp/tests/data/test2.html 
[]>

tests/comparators/test_html.py:46: IndexError
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 495 bytes
Desc: OpenPGP digital signature
URL: <http://alioth-lists.debian.net/pipermail/reproducible-builds/attachments/20221115/86a1ddfe/attachment.sig>


More information about the Reproducible-builds mailing list