def numparser(strict=False):
    """Return a function that will attempt to parse the value as a number,
    trying :func:`int`, :func:`long`, :func:`float` and :func:`complex` in
    that order. If all fail, return the value as-is, unless ``strict=True``,
    in which case raise the underlying exception.

    """

    def f(v):
        try:
            return int(v)
        except (ValueError, TypeError):
            pass
        try:
            return long(v)
        except (ValueError, TypeError):
            pass
        try:
            return float(v)
        except (ValueError, TypeError):
            pass
        try:
            return complex(v)
        except (ValueError, TypeError) as e:
            if strict:
                raise e
        return v

    return f