Python's repr() for Go

Overview

Python's repr() for Go CircleCI

This package attempts to represent Go values in a form that can be used almost directly in Go source code.

Unfortunately, some values (such as pointers to basic types) can not be represented directly in Go. These values will be represented as &<value>. eg. &23

Example

type test struct {
  S string
  I int
  A []int
}

func main() {
  repr.Print(&test{
    S: "String",
    I: 123,
    A: []int{1, 2, 3},
  })
}

Outputs

&main.test{S: "String", I: 123, A: []int{1, 2, 3}}

Why repr and not pp?

pp is designed for printing coloured output to consoles, with (seemingly?) no way to disable this. If you don't want coloured output (eg. for use in diffs, logs, etc.) repr is for you.

Why repr and not go-spew?

Repr deliberately contains much less metadata about values. It is designed to (generally) be copyable directly into source code.

Compare go-spew:

(parser.expression) (len=1 cap=1) {
 (parser.alternative) (len=1 cap=1) {
  ([]interface {}) (len=1 cap=1) {
   (*parser.repitition)(0xc82000b220)({
    expression: (parser.expression) (len=2 cap=2) {
     (parser.alternative) (len=1 cap=1) {
      ([]interface {}) (len=1 cap=1) {
       (parser.str) (len=1) "a"
      }
     },
     (parser.alternative) (len=1 cap=1) {
      ([]interface {}) (len=1 cap=1) {
       (*parser.self)(0x593ef0)({
       })
      }
     }
    }
   })
  }
 }
}

To repr:

parser.expression{
  parser.alternative{
    []interface {}{
      &parser.repitition{
        expression: parser.expression{
          parser.alternative{
            []interface {}{
              parser.str("a"),
            },
          },
          parser.alternative{
            []interface {}{
              &parser.self{              },
            },
          },
        },
      },
    },
  },
}
Comments
  • Add go.mod and time.Time human readable representation

    Add go.mod and time.Time human readable representation

    It always bugs me how time.Time gets printed ... so here is a fix.

    If a struct is time.Time it gets printed as time.Date(...) which hides the private fields of time.Time.

    If you have other suggestions or don't like it. Let me know :-)

    opened by SchumacherFM 3
  • TestReprByteArray fails with latest commit ead2165 dated 2018-07-24

    TestReprByteArray fails with latest commit ead2165 dated 2018-07-24

    Hi @alecthomas.

    TestReprByteArray fails with latest commit ead2165 dated 2018-07-24, as seen on Travis CI:

    === RUN   TestReprByteArray
    --- FAIL: TestReprByteArray (0.00s)
    	repr_test.go:77: 
    			Error Trace:	repr_test.go:77
    			Error:      	Not equal: 
    			            	expected: "[]uint8{1, 2, 3}"
    			            	actual  : "[]byte(\"\\x01\\x02\\x03\")"
    			            	
    			            	Diff:
    			            	--- Expected
    			            	+++ Actual
    			            	@@ -1 +1 @@
    			            	-[]uint8{1, 2, 3}
    			            	+[]byte("\x01\x02\x03")
    			Test:       	TestReprByteArray
    

    I encountered this exact same error on my Debian box while I was trying to update the Debian packaging for golang-github-alecthomas-repr.

    Thanks in advance for looking into this.

    opened by anthonyfok 2
  • "LICENSE" file does not exist

    I want to use this package, but I couldn’t find “LICENSE” file anywhere. What license do you adopt to this package? (This question is as same as colour package.)

    opened by legnoh 2
  • Fix zero-length slice field with omitempty

    Fix zero-length slice field with omitempty

    There were two problems here, the combination of which caused incorrect output. The first is that we should really only check omitempty on a struct field; a slice alone should ignore it. For example repr.String([]int{}) should return []int{}, not "" (and likewise for []int(nil)). The second is that the check in the slice code was checking len(s) == 0, whereas the check in the struct-field code was checking s == nil. Either would be reasonable, but having both means they need to match! This generated output like repr.intSliceStruct{f: } which is a syntax error.

    Anyway, to fix this I just removed the check in slice. We still omit nil correctly, we just handle it at the point of the struct field.

    opened by benjaminjkraft 1
  • infinite loop while dumping structures containing pointers

    infinite loop while dumping structures containing pointers

    i have a struct like

    type data struct {
    	parent *data
    	children   []*data
    }
    type dataInterface interface {
    	AddChild(data)
    	SetParent(parent *data)
    }
    

    if i want to dump such a structure, i got infinite loop repr is trying to dereference every pointer then it will do d->parent->child->parent->child..on and on.. any ideas to avoid this?

    opened by pnck 1
  • Fix panic for private fields which cannot Interface

    Fix panic for private fields which cannot Interface

    Also: Skip trailing comma.

    Also: maybe you can help how to access the private time.Time field and print it like the publicly accessible time.Time field...

    opened by SchumacherFM 0
  • fix ordering of non-string keyed maps

    fix ordering of non-string keyed maps

    reflect.Value.String() only prints the value of string types. For other types it just prints the type information.

    // String returns the string v's underlying value, as a string.
    // String is a special case because of Go's String method convention.
    // Unlike the other getters, it does not panic if v's Kind is not String.
    // Instead, it returns a string of the form "<T value>" where T is v's type.
    // The fmt package treats Values specially. It does not call their String
    // method implicitly but instead prints the concrete values they hold.
    func (v Value) String() string {
    	switch k := v.kind(); k {
    	case Invalid:
    		return "<invalid Value>"
    	case String:
    		return *(*string)(v.ptr)
    	}
    	// If you call String on a reflect.Value of other type, it's better to
    	// print something than to panic. Useful in debugging.
    	return "<" + v.Type().String() + " Value>"
    }
    
    opened by mightyguava 0
  •  Add poweron architecture ppc64le to travis build

    Add poweron architecture ppc64le to travis build

    Please review and merge the changes ,This is part of the Ubuntu distribution for ppc64le. This helps us simplify testing later when distributions are re-building and re-releasing. For more info tag @gerrith3.

    opened by asellappen 0
  • panic: reflect: call of reflect.Value.Type on zero Value

    panic: reflect: call of reflect.Value.Type on zero Value

    Minimum working example:

    package main
    
    import (
        "github.com/alecthomas/repr"
    )
    
    func main() {
        var err error
        repr.Println(err)
    }
    

    What I got:

    panic: reflect: call of reflect.Value.Type on zero Value
    
    goroutine 1 [running]:
    reflect.Value.Type(0x0, 0x0, 0x0, 0x0, 0x0)
    	/usr/lib/go-1.9/src/reflect/value.go:1688 +0x1a3
    github.com/alecthomas/repr.(*Printer).reprValue(0xc42007c1b0, 0x0, 0x0, 0x0, 0x0, 0x0)
    	/home/jmt/go/src/github.com/alecthomas/repr/repr.go:119 +0x7f
    github.com/alecthomas/repr.(*Printer).Println(0xc42007c1b0, 0xc420045f60, 0x1, 0x1)
    	/home/jmt/go/src/github.com/alecthomas/repr/repr.go:113 +0x7c
    github.com/alecthomas/repr.Println(0xc420045f60, 0x1, 0x1)
    	/home/jmt/go/src/github.com/alecthomas/repr/repr.go:239 +0x80
    main.main()
    	/home/jmt/git/repr/tiny.go:9 +0x61
    

    What I expected:

    nil
    
    opened by mathuin 0
  • Add IgnorePrivate option to skip private fields

    Add IgnorePrivate option to skip private fields

    This patch adds IgnorePrivate option to prevent private fields in a structure from being displayed. It takes care to remove trailing comma if a private field ends the structure.

    Tests have been updated to validate this new option.

    Signed-off-by: Sébastien Gross <seb•ɑƬ•chezwam•ɖɵʈ•org>

    opened by renard 2
Owner
Alec Thomas
Alec Thomas