import inspect


def _maybeFindSourceLine(testThing):
    """
    Try to find the source line of the given test thing.

    @param testThing: the test item to attempt to inspect
    @type testThing: an L{TestCase}, test method, or module, though only the
        former two have a chance to succeed
    @rtype: int
    @return: the starting source line, or -1 if one couldn't be found
    """

    # an instance of L{TestCase} -- locate the test it will run
    method = getattr(testThing, "_testMethodName", None)
    if method is not None:
        testThing = getattr(testThing, method)

    # If it's a function, we can get the line number even if the source file no
    # longer exists
    code = getattr(testThing, "__code__", None)
    if code is not None:
        return code.co_firstlineno

    try:
        return inspect.getsourcelines(testThing)[1]
    except (IOError, TypeError):
        # either testThing is a module, which raised a TypeError, or the file
        # couldn't be read
        return -1