lintr
lintr copied to clipboard
Unhelpful Error Message for linting
With the update to lintr 3.0.1 I receive the following error message:
Error in if (allow_cascading_assign) "" else "[text() = '<-']" :
argument is not interpretable as logical
In addition: Warning message:
In if (allow_cascading_assign) "" else "[text() = '<-']" :
the condition has length > 1 and only the first element will be used
Unfortunately, the error message is not very helpful and I didn´t find any information online.
Is this a problem with lintr 3.0.1 or is my .lintr
file badly specified.
Here my .lintr
file:
linters: linters_with_defaults(
line_length_linter = line_length_linter(100),
T_and_F_symbol_linter = lintr::T_and_F_symbol_linter,
assignment_linter = lintr::assignment_linter,
closed_curly_linter = lintr::brace_linter(allow_single_line = FALSE),
commas_linter = lintr::commas_linter,
commented_code_linter = lintr::commented_code_linter,
cyclocomp_linter = lintr::cyclocomp_linter(complexity_limit = 25),
object_name_linter = lintr::object_name_linter(styles = c("snake_case", "camelCase", "CamelCase", "SNAKE_CASE")),
object_length_linter = lintr::object_length_linter(length = 30L),
equals_na_linter = lintr::equals_na_linter,
function_left_parentheses_linter = lintr::function_left_parentheses_linter,
infix_spaces_linter = lintr::infix_spaces_linter,
no_tab_linter = lintr::no_tab_linter,
paren_brace_linter = lintr::paren_brace_linter,
absolute_path_linter = lintr::absolute_path_linter(lax = TRUE),
nonportable_path_linter = lintr::nonportable_path_linter(lax = TRUE),
pipe_continuation_linter = lintr::pipe_continuation_linter,
semicolon_terminator_linter = lintr::semicolon_linter(allow_compound = FALSE, allow_trailing = FALSE),
seq_linter = lintr::seq_linter,
single_quotes_linter = lintr::single_quotes_linter,
spaces_inside_linter = lintr::spaces_inside_linter,
spaces_left_parentheses_linter = lintr::spaces_left_parentheses_linter,
undesirable_function_linter = lintr::undesirable_function_linter(fun = lintr::default_undesirable_functions),
undesirable_operator_linter = lintr::undesirable_operator_linter(op = lintr::default_undesirable_operators),
unneeded_concatenation_linter = lintr::unneeded_concatenation_linter
)
exclusions: list("file_to_exclude.R", "another_file_to_exclude.R")
exclude: "# Exclude Linting"
exclude_start: "# Begin Exclude Linting"
exclude_end: "# End Exclude Linting"
that message is certainly no good :)
FWIW, all linters' are factories since 3.0.0 -- that means all your entries should be converted to function calls, e.g.
-assignment_linter = lintr::assignment_linter
+assignment_linter = lintr::assignment_linter()
see if that makes your error go away
I reproduce the issue:
cd /tmp
echo "linters: linters_with_defaults(assignment_linter = lintr::assignment_linter)" > .lintr
echo "a = 1" > file.R
Rscript -e "lintr::lint_dir()"
# Error: Linter 'assignment_linter' failed in /tmp/file.R: argument is not interpretable as logical
# In addition: Warning message:
# In if (allow_cascading_assign) "" else "[text() = '<-']" :
# the condition has length > 1 and only the first element will be used
# Execution halted
as well as confirming assignment_linter = lintr::assignment_linter()
fixes the issue
Somehow, the factory is not being evaluated, assignment_linter
is being run on the expression, i.e., the error is essentially:
assignment_linter(get_source_expressions("file.R")$expressions[[1L]])
# Error in if (allow_cascading_assign) "" else "[text() = '<-']" :
# argument is not interpretable as logical
# In addition: Warning message:
# In if (allow_cascading_assign) "" else "[text() = '<-']" :
# the condition has length > 1 and only the first element will be used
The correct code should instead be:
assignment_linter()(get_source_expressions("file.R")$expressions[[1L]])
# file.R:1:3: style: [NA] Use <-, not =, for assignment.
# a = 1
# ^
Great - that did the job! Thank you @MichaelChirico!
Great! Glad to un-break you.
Leaving the issue open because it should fail in a much friendlier way for you to unstick yourself.
Smaller reprex, showing that linters_with_defaults()
is necessary to trigger the problem:
lintr::lint(text = "a = 1", linters = list(assignment_linter = lintr::assignment_linter))
#> Warning: Passing linters as variables was deprecated in lintr version 3.0.0. Use
#> a call to the linters (see ?linters) instead.
#> <text>:1:3: style: [assignment_linter] Use <-, not =, for assignment.
#> a = 1
#> ^
lintr::lint(text = "a = 1", linters = lintr::linters_with_defaults(assignment_linter = lintr::assignment_linter))
#> Error: Linter 'assignment_linter' failed in /tmp/RtmpHSaTXh/filec155373c23d6: the condition has length > 1
Created on 2022-12-03 with reprex v2.0.2
waldo::compare(lintr::linters_with_defaults(assignment_linter = lintr::assignment_linter)["assignment_linter"], list(assignment_linter = lintr::assignment_linter))
#> `old$assignment_linter` is an S3 object of class <linter/function>, a function
#> `new$assignment_linter` is a function
Created on 2022-12-03 with reprex v2.0.2