Skip to content

Staticcheck #181

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

Merged
merged 6 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ jobs:

- name: Checkout code
uses: actions/checkout@v2
with:
fetch-depth: 1

- name: Cache-Go
uses: actions/cache@v1
Expand Down Expand Up @@ -90,6 +92,12 @@ jobs:
if: matrix.platform == 'macos-latest'
run: |
go run ./ci/run-tests.go $TAGS -race
- name: static-check
uses: dominikh/staticcheck-action@v1.2.0
with:
install-go: false
cache-key: ${{ matrix.platform }}
version: "2022.1"
- name: Upload-Coverage
if: matrix.platform == 'ubuntu-latest'
uses: codecov/codecov-action@v1
205 changes: 110 additions & 95 deletions compile/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,9 +435,11 @@ func (c *compiler) Jump(Op vm.OpCode, Dest *Label) {
c.OpCodes.Add(instr)
}

/* The test for LOCAL must come before the test for FREE in order to
handle classes where name is both local and free. The local var is
a method and the free var is a free var referenced within a method.
/*
The test for LOCAL must come before the test for FREE in order to

handle classes where name is both local and free. The local var is
a method and the free var is a free var referenced within a method.
*/
func (c *compiler) getRefType(name string) symtable.Scope {
if c.scopeType == compilerScopeClass && name == "__class__" {
Expand Down Expand Up @@ -666,27 +668,31 @@ func (c *compiler) class(Ast ast.Ast, class *ast.ClassDef) {
}

/*
Implements the with statement from PEP 343.

The semantics outlined in that PEP are as follows:

with EXPR as VAR:
BLOCK

It is implemented roughly as:

context = EXPR
exit = context.__exit__ # not calling it
value = context.__enter__()
try:
VAR = value # if VAR present in the syntax
BLOCK
finally:
if an exception was raised:
exc = copy of (exception, instance, traceback)
else:
exc = (None, None, None)
exit(*exc)
Implements the with statement from PEP 343.

The semantics outlined in that PEP are as follows:

with EXPR as VAR:

BLOCK

It is implemented roughly as:

context = EXPR
exit = context.__exit__ # not calling it
value = context.__enter__()
try:

VAR = value # if VAR present in the syntax
BLOCK

finally:

if an exception was raised:
exc = copy of (exception, instance, traceback)
else:
exc = (None, None, None)
exit(*exc)
*/
func (c *compiler) with(node *ast.With, pos int) {
item := node.Items[pos]
Expand Down Expand Up @@ -728,37 +734,38 @@ func (c *compiler) with(node *ast.With, pos int) {
c.Op(vm.END_FINALLY)
}

/* Code generated for "try: <body> finally: <finalbody>" is as follows:

SETUP_FINALLY L
<code for body>
POP_BLOCK
LOAD_CONST <None>
L: <code for finalbody>
END_FINALLY

The special instructions use the block stack. Each block
stack entry contains the instruction that created it (here
SETUP_FINALLY), the level of the value stack at the time the
block stack entry was created, and a label (here L).

SETUP_FINALLY:
Pushes the current value stack level and the label
onto the block stack.
POP_BLOCK:
Pops en entry from the block stack, and pops the value
stack until its level is the same as indicated on the
block stack. (The label is ignored.)
END_FINALLY:
Pops a variable number of entries from the *value* stack
and re-raises the exception they specify. The number of
entries popped depends on the (pseudo) exception type.

The block stack is unwound when an exception is raised:
when a SETUP_FINALLY entry is found, the exception is pushed
onto the value stack (and the exception condition is cleared),
and the interpreter jumps to the label gotten from the block
stack.
/*
Code generated for "try: <body> finally: <finalbody>" is as follows:

SETUP_FINALLY L
<code for body>
POP_BLOCK
LOAD_CONST <None>
L: <code for finalbody>
END_FINALLY

The special instructions use the block stack. Each block
stack entry contains the instruction that created it (here
SETUP_FINALLY), the level of the value stack at the time the
block stack entry was created, and a label (here L).

SETUP_FINALLY:
Pushes the current value stack level and the label
onto the block stack.
POP_BLOCK:
Pops en entry from the block stack, and pops the value
stack until its level is the same as indicated on the
block stack. (The label is ignored.)
END_FINALLY:
Pops a variable number of entries from the *value* stack
and re-raises the exception they specify. The number of
entries popped depends on the (pseudo) exception type.

The block stack is unwound when an exception is raised:
when a SETUP_FINALLY entry is found, the exception is pushed
onto the value stack (and the exception condition is cleared),
and the interpreter jumps to the label gotten from the block
stack.
*/
func (c *compiler) tryFinally(node *ast.Try) {
end := new(Label)
Expand All @@ -780,35 +787,36 @@ func (c *compiler) tryFinally(node *ast.Try) {
}

/*
Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
(The contents of the value stack is shown in [], with the top
at the right; 'tb' is trace-back info, 'val' the exception's
associated value, and 'exc' the exception.)

Value stack Label Instruction Argument
[] SETUP_EXCEPT L1
[] <code for S>
[] POP_BLOCK
[] JUMP_FORWARD L0

[tb, val, exc] L1: DUP )
[tb, val, exc, exc] <evaluate E1> )
[tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1
[tb, val, exc, 1-or-0] POP_JUMP_IF_FALSE L2 )
[tb, val, exc] POP
[tb, val] <assign to V1> (or POP if no V1)
[tb] POP
[] <code for S1>
JUMP_FORWARD L0

[tb, val, exc] L2: DUP
.............................etc.......................

[tb, val, exc] Ln+1: END_FINALLY # re-raise exception

[] L0: <next statement>

Of course, parts are not generated if Vi or Ei is not present.
Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
(The contents of the value stack is shown in [], with the top
at the right; 'tb' is trace-back info, 'val' the exception's
associated value, and 'exc' the exception.)

Value stack Label Instruction Argument
[] SETUP_EXCEPT L1
[] <code for S>
[] POP_BLOCK
[] JUMP_FORWARD L0

[tb, val, exc] L1: DUP )
[tb, val, exc, exc] <evaluate E1> )
[tb, val, exc, exc, E1] COMPARE_OP EXC_MATCH ) only if E1
[tb, val, exc, 1-or-0] POP_JUMP_IF_FALSE L2 )
[tb, val, exc] POP
[tb, val] <assign to V1> (or POP if no V1)
[tb] POP
[] <code for S1>

JUMP_FORWARD L0

[tb, val, exc] L2: DUP
.............................etc.......................

[tb, val, exc] Ln+1: END_FINALLY # re-raise exception

[] L0: <next statement>

Of course, parts are not generated if Vi or Ei is not present.
*/
func (c *compiler) tryExcept(node *ast.Try) {
c.loops.Push(loop{Type: exceptLoop})
Expand Down Expand Up @@ -897,11 +905,13 @@ func (c *compiler) try(node *ast.Try) {
}
}

/* The IMPORT_NAME opcode was already generated. This function
merely needs to bind the result to a name.
/*
The IMPORT_NAME opcode was already generated. This function

merely needs to bind the result to a name.

If there is a dot in name, we need to split it and emit a
LOAD_ATTR for each name.
If there is a dot in name, we need to split it and emit a
LOAD_ATTR for each name.
*/
func (c *compiler) importAs(name ast.Identifier, asname ast.Identifier) {
attrs := strings.Split(string(name), ".")
Expand All @@ -913,12 +923,14 @@ func (c *compiler) importAs(name ast.Identifier, asname ast.Identifier) {
c.NameOp(string(asname), ast.Store)
}

/* The Import node stores a module name like a.b.c as a single
string. This is convenient for all cases except
import a.b.c as d
where we need to parse that string to extract the individual
module names.
XXX Perhaps change the representation to make this case simpler?
/*
The Import node stores a module name like a.b.c as a single

string. This is convenient for all cases except
import a.b.c as d
where we need to parse that string to extract the individual
module names.
XXX Perhaps change the representation to make this case simpler?
*/
func (c *compiler) import_(node *ast.Import) {
//n = asdl_seq_LEN(s.v.Import.names);
Expand Down Expand Up @@ -1207,6 +1219,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
l := c.loops.Top()
if l == nil {
c.panicSyntaxErrorf(node, loopError)
panic("impossible")
}
switch l.Type {
case loopLoop:
Expand Down Expand Up @@ -1393,7 +1406,9 @@ func (c *compiler) callHelper(n int, Args []ast.Expr, Keywords []*ast.Keyword, S
c.OpArg(op, uint32(args+kwargs<<8))
}

/* List and set comprehensions and generator expressions work by creating a
/*
List and set comprehensions and generator expressions work by creating a

nested function to perform the actual iteration. This means that the
iteration variables don't leak into the current scope.
The defined function is called immediately following its definition, with the
Expand Down
3 changes: 0 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ import (
_ "github.com/go-python/gpython/stdlib"
)

// Globals
var (
// Flags
debug = flag.Bool("d", false, "Print lots of debugging")
cpuprofile = flag.String("cpuprofile", "", "Write cpu profile to file")
)

Expand Down
19 changes: 2 additions & 17 deletions parser/lexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ package parser
import (
"bytes"
"fmt"
"log"
"math"
"testing"

"github.com/go-python/gpython/ast"
Expand Down Expand Up @@ -569,19 +567,6 @@ func TestLexerReadOperator(t *testing.T) {
}
}

// Whether two floats are more or less the same
func approxEq(a, b float64) bool {
log.Printf("ApproxEq(a = %#v, b = %#v)", a, b)
diff := a - b
log.Printf("ApproxEq(diff = %e)", diff)
if math.Abs(diff) > 1e-10 {
log.Printf("ApproxEq(false)")
return false
}
log.Printf("ApproxEq(true)")
return true
}

func TestLexerReadNumber(t *testing.T) {
x := yyLex{}
for _, test := range []struct {
Expand Down Expand Up @@ -710,10 +695,10 @@ func TestLexerReadString(t *testing.T) {
if testValueBytes, ok := test.value.(py.Bytes); !ok {
t.Error("Expecting py.Bytes")
} else {
equal = (bytes.Compare(valueBytes, testValueBytes) == 0)
equal = bytes.Equal(valueBytes, testValueBytes)
}
} else {
equal = (value == test.value)
equal = value == test.value
}

if token != test.token || !equal || x.line != test.out {
Expand Down
1 change: 1 addition & 0 deletions parser/y.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 0 additions & 7 deletions py/complex.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,6 @@ func complexFloor(a Complex) Complex {
return Complex(complex(math.Floor(real(a)), math.Floor(imag(a))))
}

// Floor divide two complex numbers
func complexFloorDiv(a, b Complex) Complex {
q := complexFloor(a / b)
r := a - q*b
return Complex(r)
}

func (a Complex) M__floordiv__(other Object) (Object, error) {
if b, ok := convertToComplex(other); ok {
return complexFloor(a / b), nil
Expand Down
2 changes: 1 addition & 1 deletion py/exception.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ func ExceptionGivenMatches(err, exc Object) bool {

// IsException matches the result of recover to an exception
//
// For use to catch a single python exception from go code
// # For use to catch a single python exception from go code
//
// It can be an instance or the class itself
func IsException(exception *Type, r interface{}) bool {
Expand Down
Loading