Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of type-inference errors (file named 3)? #19

Open
sharkdp opened this issue Apr 1, 2018 · 1 comment
Open

Handling of type-inference errors (file named 3)? #19

sharkdp opened this issue Apr 1, 2018 · 1 comment

Comments

@sharkdp
Copy link
Owner

sharkdp commented Apr 1, 2018

As we always read strings via stdin, we have to guess the type of each input line (via add_dynamic_type). This can lead to errors:

> touch a b
> ls | map filesize  # okay
> touch 3
> ls | map filesize  # Incompatible input type: expected 'Path', got 'Int'

How should we handle this? Add explicit type annotations? Always assume everything to be a string?

@jdhedden
Copy link

jdhedden commented May 9, 2022

Offering for fix to numeric file/directory names. Also, adds file_age function.

For README.md:

filesize            :: Path   → Int
file_size           :: Path   → Int
fileage             :: Path   → Int
file_age            :: Path   → Int

For ft/ft/functions.py:

@register("basename")
@typed(None, T_PATH)
def basename(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.basename(str(inp))


@register("abspath")
@typed(None, T_PATH)
def abspath(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.abspath(str(inp))


@register("filesize", "file_size")
@typed(None, T_INT)
def filesize(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.getsize(str(inp))


@register("fileage", "file_age")
@typed(None, T_INT)
def fileage(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return int(os.path.getmtime(str(inp)))


@register("file_ext")
@typed(None, T_STRING)
def file_ext(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.splitext(str(inp))[1]


@register("dirname")
@typed(None, T_PATH)
def dirname(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.dirname(str(inp))


@register("replace_ext")
@typed(None, T_PATH)
def replace_ext(new_ext, inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    new_ext = dynamic_cast(T_STRING, new_ext).value
    (base, ext) = os.path.splitext(str(inp))
    if ext != "":
        return base + "." + new_ext
    return inp

@register("strip_ext")
@typed(None, T_STRING)
def strip_ext(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.splitext(str(inp))[0]


@register("has_ext")
@typed(None, T_BOOL)
def has_ext(ext, inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    ext = dynamic_cast(T_STRING, ext).value
    (_, file_ext) = os.path.splitext(str(inp))
    file_ext = file_ext[1:]  # strip leading dot
    return file_ext == ext


@register("split_ext")
@typed(None, T_ARRAY)
def split_ext(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    parts = os.path.splitext(str(inp))
    return [TypedValue(parts[0], T_STRING), TypedValue(parts[1][1:], T_STRING)]


@register("exists")
@typed(None, T_BOOL)
def exists(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.exists(str(inp))


@register("is_dir")
@typed(None, T_BOOL)
def is_dir(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.isdir(str(inp))


@register("is_file")
@typed(None, T_BOOL)
def is_file(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.isfile(str(inp))


@register("is_link")
@typed(None, T_BOOL)
def is_link(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.islink(str(inp))


@register("is_executable")
@typed(None, T_BOOL)
def is_executable(inp):
    if type(inp) == list:
        panic("'{}' cannot take an array as input.  Use the command's '--column' option.".format(inspect.stack()[0][3]))
    if type(inp) not in (str, int):
        panic("Incompatible input type to '{}': expected 'str', got '{}'".format(inspect.stack()[0][3], type(inp).__name__))

    return os.path.isfile(str(inp)) and os.access(str(inp), os.X_OK)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants