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

gomacro/fast: spurious '-quickchecks' flag leaks into user program #94

Open
sbinet opened this issue May 6, 2020 · 10 comments
Open

gomacro/fast: spurious '-quickchecks' flag leaks into user program #94

sbinet opened this issue May 6, 2020 · 10 comments
Assignees
Labels

Comments

@sbinet
Copy link

sbinet commented May 6, 2020

with gomacro@30b9859a00de, using this simple program:

package main

import (
	"flag"

	_ "github.com/cosmos72/gomacro/fast"
)

func main() {
	_ = flag.Bool("v", false, "verbose")
	flag.Parse()
}

I get:

$> ./a.out -h
Usage of ./a.out:
  -quickchecks int
    	The default number of iterations for each check (default 100)
  -v	verbose

could -quickchecks be removed as a side effect of importing gomacro/fast?

thanks.

@cosmos72 cosmos72 self-assigned this May 6, 2020
@cosmos72 cosmos72 added the bug label May 6, 2020
@sbinet
Copy link
Author

sbinet commented May 6, 2020

I suspect this is coming from (transitively) importing gomacro/imports which imports testing and testing/quick

@cosmos72
Copy link
Owner

cosmos72 commented May 6, 2020

Yes, it's an unwanted side effect of gomacro interpreter pre-importing all packages of Go standard library.

In particular, the "guilty" package is testing/quick, which contains the following code:

var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check")

It seems that package flag only allows to register command-line options, with no mechanism to unregister them.
Thus the only workaround coming to my mind is not to import testing/quick, by removing the file gomacro/imports/testing_quick.go and recompiling.

@sbinet
Copy link
Author

sbinet commented May 6, 2020

yes, removing it fixes it.
could we have an opt-in mechanism for importing stuff when using the gomacro/fast.Interp via fast.New() ?

@cosmos72
Copy link
Owner

cosmos72 commented May 6, 2020

In theory you can add/remove imported packages from the global variable gomacro/imports.Packages at runtime,
but this only affects which packages are immediately available to the interpreter - i.e. which ones can be imported without having to compile and load a plugin.

If I understand correctly, what you ask amounts to changing at runtime the list of (transitively) imported packages of a compiled Go program - that's not possible: it is fixed at compile-time for any Go program.

@sbinet
Copy link
Author

sbinet commented May 6, 2020

by opt-in I mean that, rather than pre-importing all the packages from the stdlib, have the consumer of the gomacro/fast.Interp API selectively import the ones they want (when writing the code that uses fast.Interp)

would that break things in gomacro/fast if one were to do that?

@cosmos72
Copy link
Owner

cosmos72 commented May 6, 2020

That's what I wrote above, perhaps not explicitly enough: not pre-importing all the packages from stdlib it's possible:
just remove all files and directories from gomacro/imports except the ones named a_package.go and recompile.

Instead there is currently no mechanism to blacklist or whitelist which packages can be imported at runtime:
when trying to import at runtime (either from REPL or with the API gomacro/fast.Import.ImportPackage*()) a package not imported at compile-time, the interpreter will automatically invoke the Go compiler to create a plugin containing the package symbols, then load it.

Clearly, such a blacklist or whitelist mechanism could be added.

@sbinet
Copy link
Author

sbinet commented May 6, 2020

would it be acceptable to empty out gomacro/imports, and add the following packages:

  • gomacro/imports/all
  • gomacro/imports/stdlib/math
  • gomacro/imports/stdlib/encoding
  • ...
    and let consumers blank-import the ones they want or just imports/all (that would do what imports does for now) ?

@cosmos72
Copy link
Owner

cosmos72 commented May 6, 2020

I'd say yes, it's acceptable.
AFAIK few programs, if any, are directly importing gomacro/imports/... so they can surely be reorganized to better suite advanced usage.

One possible unwanted side effect is that a program currently using gomacro/fast and its API would now also need to blank-import gomacro/imports/all to preserve the old behaviour "all packages from stdlib are availble to the interpreter"

A little bikeshedding: I'd omit the 'stdlib/' part from the paths.

@sbinet
Copy link
Author

sbinet commented May 7, 2020

I'd be willing to work on this (also b/c right now, gomacro blows up the size of my binaries, see go-hep/hep#700).

it seems most of the code under gomacro/imports is auto-generated, via genimports.gomacro.
but I don't know how that works.

@cosmos72
Copy link
Owner

cosmos72 commented May 7, 2020

It's some time since I last regenerated them, and the procedure is undocumented :(

In theory you could move the files to different directories, but you'd also need to change some lines: at least the package ... directive and the imports, so it's probably better to just check that the code generating them still works, and update it to write the files in subdirectories as you proposed.

If you feel adventurous, the generated files are created as a side-effect of executing

import _b "PKG/FULL/PATH"

at REPL, and you can find the corresponding code in github.com/cosmos72/gomacro/base/genimport/ - look at the functions dealing with ImBuiltin.

For the above to work, you must first remove the "offending" Go files from github.com/cosmos72/gomacro/import and recompile. Remember to keep at least github.com/cosmos72/gomacro/import/a_package.go

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants