se2p / pynguin

The PYthoN General UnIt Test geNerator is a test-generation tool for Python
https://www.pynguin.eu
MIT License
1.24k stars 75 forks source link

New test and handling for maybe_compare_idx==None; fixes TypeError causing Pynguin to abort. #51

Closed jaltmayerpizzorno closed 8 months ago

jaltmayerpizzorno commented 11 months ago

The new test I include in this PR reproduces conditions that lead to maybe_compare_idx == None in _instrument_cond_jump (from instrumentation.py), causing the error

TypeError: list indices must be integers or slices, not NoneType

I just added handling to avoid the TypeError; Pynguin maintainers, please decide if this is the right thing to do, and provide any appropriate assertions in the new test.

This was tested with Python 3.10.12, as distributed by homebrew, on a MacOS system.

stephanlukasczyk commented 11 months ago

Thank you for your PR! To get a better understanding of when this is actually happening and to allow me to reason about your changes and appropriate assertions, do you have a minimal Python module and Pynguin command line that triggers the exception you've mentioned?

jaltmayerpizzorno commented 11 months ago

Thank you for your PR! To get a better understanding of when this is actually happening and to allow me to reason about your changes and appropriate assertions, do you have a minimal Python module and Pynguin command line that triggers the exception you've mentioned?

You're welcome! :) I was using the command below on https://github.com/astanin/python-tabulate :

PYNGUIN_DANGER_AWARE=1 python3.10 -m pynguin --project-path tabulate --output-path pynguin-out --module-name tabulate  -v

The function it aborted while instrumenting is _isint:

def _isint(string, inttype=int):
    """
    >>> _isint("123")
    True
    >>> _isint("123.45")
    False
    """
    return (
        type(string) is inttype
        or (
            (hasattr(string, "is_integer") or hasattr(string, "__array__"))
            and str(type(string)).startswith("<class 'numpy.int")
        )  # numpy.int64 and similar
        or (
            isinstance(string, (bytes, str)) and _isconvertible(inttype, string)
        )  # integer as string
    )

The new test in this PR is a somewhat minimized version of this function.

But I've come across the same problem while trying Pynguin on on other code as well. I didn't look deeper to see what exactly was causing it (but it seems that the Python compiler is generating bytecode that the instrumentation layer doesn't expect).

stephanlukasczyk commented 11 months ago

Thank you for the details. I'll look into the proposed changes as soon as possible, but most likely not before next week.

stephanlukasczyk commented 8 months ago

I've merged this PR (extended by some assertions) in ed7c6a8377400d85e62c01e0750ba4e9a0300546