-
Notifications
You must be signed in to change notification settings - Fork 187
Lint comparison to "NA" and "NULL" #2130
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
Comments
When working with databases it can often be necessary to test for |
This linter, like many others, would be not be enabled by default. That would hopefully avoid problems like the situation you're describing. |
I'm afraid the second case is out of scope for {lintr}... my guess would be comparison to the actual strings "NA" or "NULL" is the correct/intended behavior far more often than it's a mistake. If you encounter this enough in your code base I'd encourage writing a custom linter. |
ditto for the first case as strings. a case like |
While I can easily understand how false positives could be generated, I confirm that all cases I have seen were incorrect usage. So I followed your suggestion. I went ahead and added this as a custom linter in our internal development package: epiverse-trace/etdev#7 For future reference in case anyone else is interested in this linter: na_null_strings_linter <- function() {
# Code mostly adapted from lintr::equals_na_linter() (MIT license)
# nolint next: undesirable_operator_linter
na_null_strings <- lintr:::xp_text_in_table(c(
glue::double_quote(c("NA", "NULL")),
glue::single_quote(c("NA", "NULL"))
))
xpath <- glue::glue("
//STR_CONST[{ na_null_strings }]
/parent::expr
/parent::expr[EQ or NE]
|
//SPECIAL[
text() = '%in%' and
following-sibling::expr/STR_CONST[{ na_null_strings }]
]
/parent::expr
")
lintr::Linter(function(source_expression) {
if (!lintr::is_lint_level(source_expression, "expression")) {
return(list())
}
xml <- source_expression$xml_parsed_content
bad_expr <- xml2::xml_find_all(xml, xpath)
lintr::xml_nodes_to_lints(
bad_expr,
source_expression,
lint_message = paste(
"Are you sure you want to compare to *the string* 'NA' or 'NULL'?",
"To compare to the special values NA or NULL,",
"please use `is.null()` or `is.na()` instead."
),
type = "warning"
)
})
} I initially tried to use the new Any chance |
Yes, please file an issue. I have a copy of it in our package too... better to export. Side note: Note that you can still use na_null_strings_linter <- local({
# nolint next: undesirable_operator_linter
na_null_strings <- lintr:::xp_text_in_table(c(
glue::double_quote(c("NA", "NULL")),
glue::single_quote(c("NA", "NULL"))
))
make_linter_from_xpath(
xpath = glue::glue("
//STR_CONST[{ na_null_strings }]
/parent::expr
/parent::expr[EQ or NE]
|
//SPECIAL[
text() = '%in%' and
following-sibling::expr/STR_CONST[{ na_null_strings }]
]
/parent::expr
"),
lint_message = paste(
"Are you sure you want to compare to *the string* 'NA' or 'NULL'?",
"To compare to the special values NA or NULL,",
"please use `is.null()` or `is.na()` instead."
)
)
}) |
A pattern I sometimes see to "fix" the fact that comparison to
NA
andNULL
don't returnTRUE
/FALSE
is to convert them as character.There are two situations. The first one sort of works but it's still a code smell and the second doesn't work at all.
First case: comparison with
%in%
This code works as expected I guess but we should still direct users toward better alternatives such as
anyNA()
:Created on 2023-09-09 with reprex v2.0.2
The last two lines should produce lints.
Second case: comparison with
==
/!=
This doesn't work at all but users might miss it because they are not testing it with cases where their variable is
NA
orNULL
:Created on 2023-09-09 with reprex v2.0.2
New linter
This could either be a new linter in the category "common mistakes", especially for the second case which doesn't work at all like expected.
Alternatively, the code with
NA
could be part of theequals_na_linter()
. Not sure about the code withNULL
in this scenario.I expect these cases to be relatively simple so I'm happy to try and submit a PR for this.
The text was updated successfully, but these errors were encountered: