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

S3 inheritance should be ignored #223

Closed
bmwilly opened this issue Mar 13, 2017 · 7 comments
Closed

S3 inheritance should be ignored #223

bmwilly opened this issue Mar 13, 2017 · 7 comments
Assignees
Labels
bug an unexpected problem or unintended behavior object linters 🏀

Comments

@bmwilly
Copy link

bmwilly commented Mar 13, 2017

Since 27a5d95, S3 objects are incorrectly linted

Reproducible example:

$ cat ~/tmp/ex.R
f <- function(x, ...) UseMethod("f", x)
f.character <- function(x) x
$ Rscript -e 'lintr::lint("~/tmp/ex.R")'
~/tmp/ex.R:2:1: style: Variable or function name should be snake_case.
f.character <- function(x) x
^~~~~~~~~~~
@jimhester
Copy link
Member

@fangly Can you look into this regression and add an additional test for it, thanks!

@fangly
Copy link
Contributor

fangly commented Mar 14, 2017

To enfore a given naming style, e.g. "snake_case":

  • Before: You would have used multiple_dots_linter() and camel_case_linter(). All names with a single dot were ignored, whether they corresponded to S3 generics or not (e.g. "my.function" was wrongly ignored). Also, names with multiple dot were linted, whether they corresponded to S3 generics or not (e.g. "as.data.frame.data.frame" would have been wrongly linted).
  • Now: The idea is to use a single linter, object_name_linter("snake_case"). This function lints names regardless of the number of does, and is aware of base S3 generics but not aware of user-defined generics.

In short, before, you got some false positive and some false negative lints, and now you should only get some false positives. False positives are annoying, but you can ignore them with a "#nolint" comment. False negatives are more problematic, because as a user, you cannot do anything against them.

Workarounds and solutions:

  1. As mentionned above, you could add "#nolint" comments on lines where you declare S3 methods. It is not ideal if you have many S3 methods,
  2. A simple lintr fix:
    2.1. Have object_name_linter() explicitly ignore single dotted names, like in the old behavior. As explained in the examples above, this is not foolproof.
    2.2. Add a "lax" option to object_name_linter(). Just like in absolute_path_linter(), it would default to TRUE and allow users to select whether they prefer to be strict (and lint too much) or lax (and lint too little).
  3. Ideally, lintr would have a mechanism to whitelist user-defined generics. This is difficult to do well because a S3 generic could be declared after a S3 method declaration or even in a different file. We also have to keep in mind that lintr works on a package level with lint_package() and on a single file level with lint(). Working on a package level with the NAMESPACE file would not be ideal, because not all S3 methods need to be exported.

What are your thoughts?

@jimhester
Copy link
Member

We could load the package namespace like was done previously and get the defined generics that way. The downside is if the project is not a package or if the package is not installed the generics won't be found.

Alternatively we can parse all project code regardless of which file is being linted and whitelist S3 generics. This approach would also be useful for the object_usage_linter(), we could just look for symbol assignment in the package / file namespace.

The latter can be done by using the call_names() definition and looking for length(call_names(f, "UseMethod")) > 0 where f is the parsed function definition.

@bfgray3
Copy link
Contributor

bfgray3 commented May 10, 2019

I'd like to add my vote for this issue after encountering a lint for a data.frame S3 method.

@jimhester
Copy link
Member

jimhester commented Sep 27, 2019

This seems to be fixed in the current master.

@dpprdan
Copy link
Contributor

dpprdan commented Oct 22, 2019

It seems that this is not fixed for data.frame S3 methods (and potentially other classes with a dot in their name):

$ cat lintr.data.frame.R
f <- function(x, ...) UseMethod("f", x)
f.data.frame <- function(x) x
$ Rscript -e 'lintr::lint("lintr.data.frame.R")'
lintr.data.frame.R:2:1: style: Variable and function name style should be snake_case.
f.data.frame <- function(x) x
^~~~~~~~~~~~

This is from current master (d86407d).

@dpprdan
Copy link
Contributor

dpprdan commented Feb 21, 2020

@jimhester Regarding my comment above, would you consider reopening this or should I rather open a new issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior object linters 🏀
Projects
None yet
Development

No branches or pull requests

5 participants