Repository: pytest-dev/pytest
File: src/_pytest/compat.py (Python)

Code before:
def ascii_escaped(val: bytes | str) -> str:
    r"""If val is pure ASCII, return it as an str, otherwise, escape
    bytes objects into a sequence of escaped bytes:

    b'\xc3\xb4\xc5\xd6' -> r'\xc3\xb4\xc5\xd6'

    and escapes strings into a sequence of escaped unicode ids, e.g.:

    r'4\nV\U00043efa\x0eMXWB\x1e\u3028\u15fd\xcd\U0007d944'

    Note:
       The obvious "v.decode('unicode-escape')" will return
       valid UTF-8 unicode if it finds them in bytes, but we
       want to return escaped bytes for any byte, even if they match
       a UTF-8 string.
    """
    if isinstance(val, bytes):
        ret = val.decode("ascii", "backslashreplace")
    else:
        ret = val.encode("unicode_escape").decode("ascii")
    return ret.translate(_non_printable_ascii_translate_table)


def get_real_func(obj):
    """Get the real function object of the (possibly) wrapped object by
    functools.wraps or functools.partial or pytest.fixture"""
    from _pytest.fixtures import FixtureFunctionDefinition

    start_obj = obj
    for _ in range(100):
        if isinstance(obj, FixtureFunctionDefinition):
            obj = obj._get_wrapped_function()
            break
        new_obj = getattr(obj, "__wrapped__", None)
        if new_obj is None:
            break
        obj = new_obj
    else:
        from _pytest._io.saferepr import saferepr

        raise ValueError(
            f"could not find real function of {saferepr(start_obj)}\nstopped at {saferepr(obj)}"
        )
    if isinstance(obj, functools.partial):
        obj = obj.func
    return obj


def getimfunc(func):
    try:
        return func.__func__

Review comment (suggestion):
```suggestion
    :func:`functools.wraps`, or :func:`functools.partial`, or :func:`pytest.fixture`."""
```


Code after:

    and escapes strings into a sequence of escaped unicode ids, e.g.:

    r'4\nV\U00043efa\x0eMXWB\x1e\u3028\u15fd\xcd\U0007d944'

    Note:
       The obvious "v.decode('unicode-escape')" will return
       valid UTF-8 unicode if it finds them in bytes, but we
       want to return escaped bytes for any byte, even if they match
       a UTF-8 string.
    """
    if isinstance(val, bytes):
        ret = val.decode("ascii", "backslashreplace")
    else:
        ret = val.encode("unicode_escape").decode("ascii")
    return ret.translate(_non_printable_ascii_translate_table)


def get_real_func(obj):
    """Get the real function object of the (possibly) wrapped object by
    :func:`functools.wraps`, or :func:`functools.partial`."""
    obj = inspect.unwrap(obj)

    if isinstance(obj, functools.partial):
        obj = obj.func
    return obj


def getimfunc(func):
    try:
        return func.__func__
    except AttributeError:
        return func


def safe_getattr(object: Any, name: str, default: Any) -> Any:
    """Like getattr but return default upon any Exception or any OutcomeException.

    Attribute access can potentially fail for 'evil' Python objects.
    See issue #214.
    It catches OutcomeException because of #2490 (issue #580), new outcomes
    are derived from BaseException instead of Exception (for more details
    check #2707).
    """
    from _pytest.outcomes import TEST_OUTCOME

    try:
        return getattr(object, name, default)
    except TEST_OUTCOME:
        return default