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

Platform non-agnostic / dangerous functions #63

Open
njtierney opened this issue May 26, 2017 · 6 comments
Open

Platform non-agnostic / dangerous functions #63

njtierney opened this issue May 26, 2017 · 6 comments

Comments

@njtierney
Copy link

njtierney commented May 26, 2017

There are some functions, or options within functions, or patterns that can not be run on all operating systems.

After some discussion around the checkers pkg, at the rOpenSci unconf17, we thought it might be useful to create a list of these functions, options, or patterns.

  • windows(). In a windows OS, this opens up a graphics device, but not on another OS.
  • download.url(mode = "w"). On a windows OS, when mode = "w", this can create a corrupt file
  • paste0(sep = "/"). This is not appropriate for windows machines - a safer alternative is file.path(). Also, careful of specifying entire file directories.

This list may eventually turn into something that goodpractice or lintr uses.

Tagging a few folks in here who might be interested in contributing to this: @jennybc @jeroen @richierocks @stephlock @daattali @gaborcsardi

Please feel free to add others!

@gaborcsardi
Copy link
Collaborator

  • shell() only exists on windows.

@daattali
Copy link

Don't know if it counys, but many popular parallel processing packages don't work on windows

@gmbecker
Copy link

A list of functions with windows implementations (defined in /R/windows/*.R) not present in my OS X version of R (NB, the versions are different, but that probably matters in ~0 of them)

## wd is the src/library directory of a checkout of the R source code
pkgdirs = list.dirs(".", recursive=FALSE, full.names=TRUE)
pkgdirs = pkgdirs[-grep("Recommended", pkgdirs)]
windirs = file.path(pkgdirs,"R","windows")

winrfils = list.files(windirs, pattern = ".R", full.names=TRUE)

library(CodeDepends)

winfuns = unlist(lapply(winrfils,
                        function(f) {
    scr = readScript(f)
    info = getInputs(scr)
    unlist(lapply(info, function(y) y@outputs))
}))

winfuns[!sapply(winfuns, exists)]
 [1] "Sys.junction"             "shell"                   
 [3] "shell.exec"               "check_gs_type"           
 [5] ".geometry"                ".WindowsEnv"             
 [7] ".Windows.Options"         ".Windows.Options.default"
 [9] "aa.win"                   "aa.cairo"                
[11] "windows.options"          "windows"                 
[13] "win.graph"                "win.print"               
[15] "win.metafile"             "bringToTop"              
[17] "msgWindow"                "print.SavedPlots"        
[19] "[.SavedPlots"             ".Windows.Fonts"          
[21] "checkWindowsFont"         "setWindowsFonts"         
[23] "printFont"                "printFonts"              
[25] "windowsFonts"             "windowsFont"             
[27] "makeForkCluster"          "mclapply"                
[29] "pvec"                     "mcmapply"                
[31] "mcMap"                    ".TkUp"                   
[33] ".onLoad"                  ".onUnload"               
[35] "loadRconsole"             "Filters"                 
[37] "choose.files"             "choose.dir"              
[39] "unpackPkgZip"             ".install.winbinary"      
[41] "menuInstallPkgs"          "menuInstallLocal"        
[43] "zip.unpack"               "DLL.version"             
[45] "getClipboardFormats"      "readClipboard"           
[47] "writeClipboard"           "getIdentification"       
[49] "setWindowTitle"           "getWindowTitle"          
[51] "setStatusBar"             "getWindowsHandle"        
[53] "getWindowsHandles"        "arrangeWindows"          
[55] "menuShowCRAN"             "shortPathName"           
[57] "readRegistry"             "setInternet2"            
[59] "win.version"              "winDialog"               
[61] "winDialogString"          "winMenuDel"              
[63] "winMenuDelItem"           "winMenuAdd"              
[65] "winMenuAddItem"           "winMenuNames"            
[67] "winMenuItems"             "winProgressBar"          
[69] "close.winProgressBar"     "setWinProgressBar"       
[71] "getWinProgressBar"        "askYesNoWinDialog"       

@gmbecker
Copy link

gmbecker commented Aug 26, 2017

I did the above quickly, so obviously there are some false positives (the .onLoad jumps out) but most of them pass the eyeball test.

Double edit: I'll do a better version of this later today. at the very least these are functions that have windows-specific implementations.

@gmbecker
Copy link

Ok, this time with proper checking for the functions in the Mac versions I have installed, and some comments (and code highlighting...)

pkgdirs = list.dirs(".", recursive=FALSE, full.names=TRUE)
pkgdirs = pkgdirs[-grep("Recommended", pkgdirs)]
windirs = file.path(pkgdirs,"R","windows")

winrfils = list.files(windirs, pattern = ".R", full.names=TRUE)

library(CodeDepends)
basepkgs = installed.packages(priority="base")[,"Package"]

## attach all the base packages, probably overkill give new way of checking
## for existence later on...
lapply(basepkgs, function(x) library(x, character.only=TRUE))

## returns a list of vectors of functions defined in /R/windows/*.R files
## named by the file.
winfuns = sapply(winrfils,
                        function(f) {
    scr = readScript(f)
    info = getInputs(scr)
    ## the outputs here are functions defined in the .R file
    unlist(lapply(info, function(y) y@outputs))
})

## names of packages 
pkgs = gsub(".*/([^/]*)/R/windows/.*", "\\1", names(winfuns))
## vector of functions defined in /windows/*.R files in base pkgs
## will be parallel to pkgs
winfunsvec = unlist(winfuns)

## logical indicated whether each function exists in the namespace
## of the corresponding package on my mac
foundonmac = mapply(function(f, pkg) {
    ff = try(get(f, envir = asNamespace(pkg), inherits = FALSE),
             silent = TRUE)
    !is(ff, "try-error")
}, f = winfunsvec, pkg = rep(pkgs, times = lengths(winfuns)))

## functions implemented for windows versions of base packages but not
## for mac versions I have installed.
winonly = winfunsvec[!foundonmac]
names(winonly) = pkgsvec[!foundonmac]
winonly

Gives us

                     base                       base 
            "Sys.junction"                    "shell" 
                      base                  grDevices 
              "shell.exec"              ".WindowsEnv" 
                 grDevices                  grDevices 
        ".Windows.Options" ".Windows.Options.default" 
                 grDevices                  grDevices 
                  "aa.win"          "windows.options" 
                 grDevices                  grDevices 
                 "windows"                "win.graph" 
                 grDevices                  grDevices 
               "win.print"             "win.metafile" 
                 grDevices                  grDevices 
              "bringToTop"                "msgWindow" 
                 grDevices                  grDevices 
        "print.SavedPlots"             "[.SavedPlots" 
                 grDevices                  grDevices 
          ".Windows.Fonts"         "checkWindowsFont" 
                 grDevices                  grDevices 
         "setWindowsFonts"             "windowsFonts" 
                 grDevices                      tcltk 
             "windowsFont"                ".onUnload" 
                     utils                      utils 
            "loadRconsole"                  "Filters" 
                     utils                      utils 
            "choose.files"               "choose.dir" 
                     utils                      utils 
            "unpackPkgZip"       ".install.winbinary" 
                     utils                      utils 
         "menuInstallPkgs"         "menuInstallLocal" 
                     utils                      utils 
              "zip.unpack"              "DLL.version" 
                     utils                      utils 
     "getClipboardFormats"            "readClipboard" 
                     utils                      utils 
          "writeClipboard"        "getIdentification" 
                     utils                      utils 
          "setWindowTitle"           "getWindowTitle" 
                     utils                      utils 
            "setStatusBar"         "getWindowsHandle" 
                     utils                      utils 
       "getWindowsHandles"           "arrangeWindows" 
                     utils                      utils 
            "menuShowCRAN"            "shortPathName" 
                     utils                      utils 
            "readRegistry"             "setInternet2" 
                     utils                      utils 
             "win.version"                "winDialog" 
                     utils                      utils 
         "winDialogString"               "winMenuDel" 
                     utils                      utils 
          "winMenuDelItem"               "winMenuAdd" 
                     utils                      utils 
          "winMenuAddItem"             "winMenuNames" 
                     utils                      utils 
            "winMenuItems"           "winProgressBar" 
                     utils                      utils 
    "close.winProgressBar"        "setWinProgressBar" 
                     utils                      utils 
       "getWinProgressBar"        "askYesNoWinDialog" 

@njtierney
Copy link
Author

Thanks @gmbecker ! This is great :)

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

6 participants