Search code examples
pythonintegerliteralsdocstringdoctest

Specify expected outcome in a docstring as hexadecimal?


Is there a way to specify expected integer outcomes in a docstring in hex notation?

def identity(val):
    """
    >>> identity(243)
    243
    >>> identity(243)
    0xf3
    """
    return val

if __name__ == "__main__":
    import doctest
    doctest.testmod()

Doctest doesn't interpret the hex notation, resulting in a failure:

**********************************************************************
File "hextest.py", line 5, in __main__.identity
Failed example:
    identity(243)
Expected:
    0xf3
Got:
    243
**********************************************************************
1 items had failures:
   1 of   2 in __main__.identity
***Test Failed*** 1 failures.

I'm aware that I could wrestle the docstring:

def identity(val):
    """
    >>> hex(identity(243))
    '0xf3'
    """
    return val

But it'd seem natural to have doctest understand literal integers in bases 8, 16 next to decimal.


Solution

  • Sure, you can write your own OutputChecker class to handle numbers however you want:

    def identity(val):
        """
        >>> identity(243)
        0xf3
        >>> identity(243)
        243
        """
    
        return val
    
    
    if __name__ == "__main__":
        import doctest
    
        OutputChecker = doctest.OutputChecker
    
        class HexOutputChecker(OutputChecker):
    
            def check_output(self, want, got, optionflags):
    
                if want.startswith('0x'):
                    want_str = str(int(want, 16)) + '\n'
                    return super().check_output(want_str, got, optionflags)
                else:
                    return super().check_output(want, got, optionflags)
    
        doctest.OutputChecker = HexOutputChecker
        doctest.testmod(verbose=True)