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

first pass at implementing a backport_linter #622

Merged
merged 17 commits into from
Dec 5, 2020
Merged

Conversation

MichaelChirico
Copy link
Collaborator

Closes #506

For now it's just a simple version. We simply gather all* the new functions mentioned in NEWS.3 and NEWS and check if those names are used at all in the script. My guess is that the chance of namespace collisions is low for base functions, so I didn't bother with any namespace qualification complexity.

I think adding a check for raw strings is doable in this PR, the only thing is I think we need to do a skip for related tests right? Since we rely on parse() to work.

My gut says checking R-level env variables which are added over time is not likely to bear much fruit -- a test of this would be to identify a few and cran-search whether any are used in CRAN packages.

Checking argument consistency I would say is beyond scope for now. In particular, note how complicated this will be for use cases involving lapply & co. I would wait on seeing if there's FR for that first 😃

  • I did this by eye so there's a chance I missed something

@lintr-bot
Copy link

R/backport_linter.R:48:11: style: Use <-, not =, for assignment.

backports = list(
          ^

R/backport_linter.R Outdated Show resolved Hide resolved
#' @export
backport_linter <- function(r_version = "4.0.3") {
function(source_file) {
if (is.null(source_file$xml_parsed_content) || r_version >= "r-devel") return(list())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a lexicographic comparison to "r-devel"?
Both "r-release" and "r-oldrel" would trigger this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I should just leave this as "r" -- I don't think we want to support tracking devel dependencies, I just wanted something that would be bigger than all R version numbers (at first I used "999999" as the name, "r-devel" felt better but you raise a good point)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't we consult names(backports) to find whether the selected version is supported?
The highest of those versions wouldn't cause lints anyway so we can tail() it to obtain a definitive list of R versions that can result in lints if I'm not mistaken.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if so we'd have to include in the list all released versions (e.g. 3.5.3).

And sorry I'm just waking up, I'm not following your second point

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point.
Wouldn't we never lint if r_version is at least getRversion()?
i.e. if (r_version >= getRversion()) return(list()).
That way if r_version is older than the current environment, backport problems can be detected.
If it isn't there are no backports that can be used from the current R version which would be a problem in r_version, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's basically right, but I do think it's possible to run this on a machine that has a different environment than required. Say I work on two machines and the one I'm using today has an old version. We wouldn't want to skip then necessarily right?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the old version, the used backports would either break the code completely (which you'd notice), or the backports were already safely ported to your old version. No?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's if we run tests, but lintr is static analysis so we could in principle run it on a different machine that doesn't execute code.

If that machine is running for a bigger library of R code (say a local CRAN), there may be different code requirements.

I think it's basically an edge case... but taking a step back, the goal of this is to get around/change the r_version >= "r" part? I'm happier with that now than I was with r_version >= "r-devel"

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Let's just leave it as-is for now.
Maybe later become smart about what r_versions are found in backports and thus will potentially cause lints.

R/backport_linter.R Show resolved Hide resolved
R/backport_linter.R Outdated Show resolved Hide resolved
@@ -0,0 +1,83 @@
#' @describeIn linters that checks for usage of unavailable functions. Not reliable for testing r-devel dependencies.
#' @export
backport_linter <- function(r_version = "4.0.3") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the default auto-detect, e.g. getRversion()?
Or even better for Packages, get the R version from the Depends field in DESCRIPTION? (this might be worth a separate PR, also suppressing lints for stuff imported from {backports})

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea, and a good direction for follow-up. Actually I think we can go beyond backports (there may be other backport packages) and try to check namespace imports and/or internally defined functions & skip those. New argument skip= defaulting to infer_skips where we apply some logic.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest using except as the argument name - it's already used in missing_argument_linter with the same purpose:

#' @param except a character vector of function names as exceptions.

@@ -0,0 +1,83 @@
#' @describeIn linters that checks for usage of unavailable functions. Not reliable for testing r-devel dependencies.
#' @export
backport_linter <- function(r_version = "4.0.3") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the default r_version be the current R version?

If a package author wants to use this linter, then one must specify the r_version to be consistent with that appears in the package DESCRIPTION?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I used getRversion(), I guess we could make it guess_r_version() & check the description first before defaulting to getRversion()?

R/backport_linter.R Outdated Show resolved Hide resolved
R/backport_linter.R Outdated Show resolved Hide resolved
AshesITR
AshesITR previously approved these changes Nov 29, 2020
backport_linter <- function(r_version = getRversion()) {
function(source_file) {
if (inherits(r_version, "numeric_version")) r_version <- format(r_version)
if (r_version < "3.0.0") {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use numeric_version comparison here, else it will bite us when R 10.0.0 rolls out ;)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha that can be a problem for our future selves -- after 2050 at the current rate 😸

I prefer this way because the test below makes the same assumption by doing r_version < names(backports)

So really this assumption is backed into names(backports) as well. Maybe by R 10.0 R will allow objects to have objects as names like python

@MichaelChirico
Copy link
Collaborator Author

MichaelChirico commented Nov 29, 2020

BTW @AshesITR we should come up with a procedure for new linters & whether/how to include them as default linters / whether/how to include them in the GH action for linting lintr...

e.g. we could make that part of a separate PR, but in this PR we could add it in .lintr with a TODO & follow-up issue?

@AshesITR
Copy link
Collaborator

What do you mean?
add backports_linter to our .lintr now with a TODO for adding it to default linters?
The GH action (and travis) currently use our .lintr and I think that's a good way to have it because everyone can run lintr::lint_package() locally and expect the same results.

IMO adding a linter to the default linters should always be a separate issue.

@MichaelChirico
Copy link
Collaborator Author

Do we only lint lintr itself with default linters?

@MichaelChirico
Copy link
Collaborator Author

Hmm I want to include a test for raw strings, however, there's an issue:

The parse data for raw strings is not returned correctly in 4.0.0 (only in 4.0.1), so the test can't work on 4.0?

I'll have to think about it more; for now, let's merge this and file that as a follow-up?

@AshesITR
Copy link
Collaborator

Sounds good to me.
WRT linting lintr with only the default linters: I don't mind having more strict linting in lintr itself than default.

renkun-ken
renkun-ken previously approved these changes Nov 30, 2020
Copy link
Collaborator

@renkun-ken renkun-ken left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@MichaelChirico MichaelChirico dismissed stale reviews from renkun-ken and AshesITR via 038df29 November 30, 2020 15:57
AshesITR
AshesITR previously approved these changes Nov 30, 2020
AshesITR
AshesITR previously approved these changes Dec 1, 2020
@AshesITR AshesITR merged commit 9104a00 into master Dec 5, 2020
@AshesITR AshesITR deleted the backports-warning branch December 5, 2020 21:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

R version compatibility linter
4 participants