gopherdata / gophernotes

The Go kernel for Jupyter notebooks and nteract.
MIT License
3.82k stars 265 forks source link

Odd Interaction between standard packages and some third party packages #151

Closed vsivsi closed 5 years ago

vsivsi commented 5 years ago

Hi, We just started noticing errors related to the use of the standard runtime.NumCPU() package/method after adding a third party import (that otherwise works fine).

Reproduction:

package main

import (
   "runtime"

   // "gonum.org/v1/plot/plotter"
)

func main () int {
   return runtime.NumCPU()
}

main()   // Returns 20 on my machine

If you uncomment the "gonum" import and re-run, then we get this error when executing the definition of func main:

inconsistent function type: func() int has 1 params - including receiver type interface{Len() int; XError(int) (float64, float64); XY(int) (float64, float64)} but its reflect.Type: func() int has 0 params

Once it is in this state, removing the gonum import is not sufficient to reverse the error. The gophernotes kernel needs to be restarted for that to work again.

This bevhavior is new. On my machine, it manifested after upgrading to golang 1.11.2 and rebuilding/reinstalling gophernotes.

vsivsi commented 5 years ago

BTW, Declaring main above is not required to reproduce. Simply invoking runtime.NumCPU() on its own is sufficient.

vsivsi commented 5 years ago

I see the same issue if I import "math/rand" and use rand.Int() instead of runtime.NumCPU(). So this doesn't seem to be related to the runtime package specifically.

vsivsi commented 5 years ago

I can also reproduce the same issue using gomacro (latest commit, built with golang 1.11.2 on MacOS 10.13.6) alone:

// GOMACRO, an interactive Go interpreter with generics and macros
// Copyright (C) 2017-2018 Massimiliano Ghilardi <https://github.com/cosmos72/gomacro>
// License MPL v2.0+: Mozilla Public License version 2.0 or later <http://mozilla.org/MPL/2.0/>
// This is free software with ABSOLUTELY NO WARRANTY.
//
// Type :help for help
gomacro> import "runtime"
gomacro> runtime.NumCPU()
20  // int
gomacro> import "gonum.org/v1/plot/plotter"
// debug: created file "/Users/vsi/go/src/gomacro_imports/gonum.org/v1/plot/plotter/plotter.go"...
// debug: compiling "/Users/vsi/go/src/gomacro_imports/gonum.org/v1/plot/plotter/plotter.go" ...
gomacro> runtime.NumCPU()
inconsistent function type: func() int has 1 params - including receiver type interface{Len() int; XY(int) (float64, float64); YError(int) (float64, float64)}
      but its reflect.Type: func() int has 0 params

It affects some standard packages, but not all....

gomacro> import "math/rand"
gomacro> rand.Int()
inconsistent function type: func() int has 1 params - including receiver type interface{Len() int; XY(int) (float64, float64); YError(int) (float64, float64)}
      but its reflect.Type: func() int has 0 params
gomacro> import "math"
gomacro> math.Abs(-1)
1   // float64

Seems to have something to do with functions/methods that take zero parameters:

gomacro> rand.Intn(12)
5   // int
cosmos72 commented 5 years ago

Confirmed. Definitely a weird bug, thanks for spotting this!

The same happens with runtime.NumGoroutine() and with any other function whose type is func () int, as for example:

gomacro> func one() int { return 1 }
gomacro> one()
1       // int
gomacro> import "gonum.org/v1/plot/plotter"
// debug: created file "/home/max/go/src/gomacro_imports/gonum.org/v1/plot/plotter/plotter.go"...
// debug: compiling "/home/max/go/src/gomacro_imports/gonum.org/v1/plot/plotter/plotter.go" ...
gomacro> one()
inconsistent function type: func() int has 1 params - including receiver type interface{Len() int; XY(int) (float64, float64); YError(int) (float64, float64)}
      but its reflect.Type: func() int has 0 params

I will analyze it, for the moment my guess is that go/types.Type compare as equal two functions or methods that only differ in their receiver.

cosmos72 commented 5 years ago

Update: a minimal example reproducing the problem is: create a file $HOME/go/src/github.com/cosmos72/experiments/main.go containing

package experiments

var NewYErrorBars interface { Len() int }

then run go install github.com/cosmos72/gomacro/experiments and finally type at gomacro prompt:

gomacro> func one() int { return 1 }
gomacro> one()
1       // int
gomacro> import "github.com/cosmos72/gomacro/experiments"
// debug: created file "/home/max/go/src/gomacro_imports/github.com/cosmos72/gomacro/experiments/experiments.go"...
// debug: compiling "/home/max/go/src/gomacro_imports/github.com/cosmos72/gomacro/experiments/experiments.go" ...
gomacro> one()
inconsistent function type: func() int has 1 params - including receiver type interface{Len() int}
      but its reflect.Type: func() int has 0 params
vsivsi commented 5 years ago

Thanks for confirming the issue and looking into this!