Back to godoc.org

Package builtins

v0.0.0-...-1557bcf
Latest Go to latest

The latest major version is .

Published: Aug 13, 2020 | License: Apache-2.0 | Module: github.com/luci/luci-go

Overview

Package builtins is a collection of potentially useful Starlark builtins.

Index

Variables

var (
	// Struct is struct(**kwargs) builtin.
	//
	//  def struct(**kwargs):
	//    """Returns an immutable object with fields set to given values."""
	Struct = starlark.NewBuiltin("struct", starlarkstruct.Make)

	// GenStruct is genstruct(name) builtin.
	//
	//  def genstruct(name):
	//    """Returns a callable constructor for "branded" struct instances."""
	GenStruct = starlark.NewBuiltin("genstruct", func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
		var name string
		if err := starlark.UnpackArgs("genstruct", args, kwargs, "name", &name); err != nil {
			return nil, err
		}
		return &ctor{name: name}, nil
	})

	// Ctor is ctor(obj) builtin.
	//
	//  def ctor(obj):
	//    """Returns a constructor used to construct this struct or None."""
	Ctor = starlark.NewBuiltin("ctor", func(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
		var obj starlark.Value
		if err := starlark.UnpackArgs("ctor", args, kwargs, "obj", &obj); err != nil {
			return nil, err
		}
		if st, ok := obj.(*starlarkstruct.Struct); ok {
			return st.Constructor(), nil
		}
		return starlark.None, nil
	})
)
var Fail = starlark.NewBuiltin("fail", func(th *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	sep := " "
	var trace starlark.Value
	err := starlark.UnpackArgs("fail", nil, kwargs,
		"sep?", &sep,
		"trace?", &trace)
	if err != nil {
		return nil, err
	}

	var userTrace *CapturedStacktrace
	if trace != nil && trace != starlark.None {
		if userTrace, _ = trace.(*CapturedStacktrace); userTrace == nil {
			return nil, fmt.Errorf("fail: bad 'trace' - got %s, expecting stacktrace", trace.Type())
		}
	}

	buf := strings.Builder{}
	for i, v := range args {
		if i > 0 {
			buf.WriteString(sep)
		}
		if s, ok := starlark.AsString(v); ok {
			buf.WriteString(s)
		} else {
			buf.WriteString(v.String())
		}
	}
	msg := buf.String()

	if fc := GetFailureCollector(th); fc != nil {
		failTrace, _ := CaptureStacktrace(th, 0)
		fc.failure = &Failure{
			Message:   msg,
			UserTrace: userTrace,
			FailTrace: failTrace,
		}
	}

	return nil, errors.New(msg)
})

Fail is fail(*args, sep=" ", trace=None) builtin.

def fail(*args, sep=" ", trace=None):
  """Aborts the script execution with an error message."

  Args:
    args: values to print in the message.
    sep: separator to use between values from `args`.
    trace: a trace (as returned by stacktrace()) to attach to the error.
  """

Custom stack traces are recoverable through FailureCollector. This is due to Starlark's insistence on stringying all errors. If there's no FailureCollector in the thread locals, custom traces are silently ignored.

Note that the assert.fails(...) check in the default starlark tests library doesn't clear the failure collector state when it "catches" an error, so tests that use assert.fails(...) should be careful with using the failure collector (or just don't use it at all).

var Stacktrace = starlark.NewBuiltin("stacktrace", func(th *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	skip := starlark.MakeInt(0)
	if err := starlark.UnpackArgs("stacktrace", args, kwargs, "skip?", &skip); err != nil {
		return nil, err
	}
	switch lvl, err := starlark.AsInt32(skip); {
	case err != nil:
		return nil, fmt.Errorf("stacktrace: bad 'skip' value %s - %s", skip, err)
	case lvl < 0:
		return nil, fmt.Errorf("stacktrace: bad 'skip' value %d - must be non-negative", lvl)
	default:
		return CaptureStacktrace(th, lvl)
	}
})

Stacktrace is stacktrace(...) builtin.

def stacktrace(skip=0):
  """Capture and returns a stack trace of the caller.

  A captured stacktrace is an opaque object that can be stringified to get a
  nice looking trace (e.g. for error messages).

  Args:
    skip: how many inner most frames to skip.
  """
var ToJSON = starlark.NewBuiltin("to_json", func(_ *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
	var v starlark.Value
	if err := starlark.UnpackPositionalArgs(fn.Name(), args, kwargs, 1, &v); err != nil {
		return nil, err
	}
	obj, err := ToGoNative(v)
	if err != nil {
		return nil, err
	}
	blob, err := json.Marshal(obj)
	if err != nil {
		return nil, err
	}
	return starlark.String(blob), nil
})

ToJSON is to_json(value) builtin.

def to_json(value):
  """Serializes a value to compact JSON.

  Doesn't support integers that do not fit int64. Fails if the value being
  converted has cycles.

  Args:
    value: a starlark value: scalars, lists, tuples, dicts containing only
      starlark values.

  Returns:
    A string with its compact JSON serialization.
  """

func NormalizeStacktrace

func NormalizeStacktrace(trace string) string

NormalizeStacktrace removes mentions of line and column numbers from a rendered stack trace: "main:1:5: in <toplevel>" => "main: in <toplevel>".

Useful when comparing stack traces in tests to make the comparison less brittle.

func RegexpMatcher

func RegexpMatcher(name string) *starlark.Builtin

RegexpMatcher returns a function (with given name) that allows Starlark code to do regular expression matches:

def submatches(pattern, str):
  """Returns a tuple of submatches with the leftmost match of the regular
  expression.

  The returned tuple has the full match as a first item, followed by
  subexpression matches.

  If the string doesn't match the expression returns an empty tuple. Fails if
  the regular expression can't be compiled.
  """

Uses Go regexp engine, which is slightly different from Python's. API also explicitly does NOT try to mimic Python's 're' module.

Each separate instance of the builtin holds a cache of compiled regular expressions internally. The cache is never cleaned up. Errors are not cached, since we don't expect to see them often.

Safe for concurrent use.

func ToGoNative

func ToGoNative(v starlark.Value) (interface{}, error)

ToGoNative takes a Starlark value and returns native Go value for it.

E.g. it takes *starlark.Dict and returns map[string]interface{}. Works recursively.

type CapturedStacktrace

type CapturedStacktrace struct {
	// contains filtered or unexported fields
}

CapturedStacktrace represents a stack trace returned by stacktrace(...).

At the present time it can only be stringified (via str(...) in Starlark or via .String() in Go).

func CaptureStacktrace

func CaptureStacktrace(th *starlark.Thread, skip int) (*CapturedStacktrace, error)

CaptureStacktrace captures thread's stack trace, skipping some number of innermost frames.

Returns an error if the stack is not deep enough to skip the requested number of frames.

func (*CapturedStacktrace) Freeze

func (*CapturedStacktrace) Freeze()

Freeze is part of starlark.Value interface.

func (*CapturedStacktrace) Hash

func (*CapturedStacktrace) Hash() (uint32, error)

Hash is part of starlark.Value interface.

func (*CapturedStacktrace) String

func (s *CapturedStacktrace) String() string

String is part of starlark.Value interface.

Renders the stack trace as string.

func (*CapturedStacktrace) Truth

func (*CapturedStacktrace) Truth() starlark.Bool

Truth is part of starlark.Value interface.

func (*CapturedStacktrace) Type

func (*CapturedStacktrace) Type() string

Type is part of starlark.Value interface.

type Failure

type Failure struct {
	Message   string              // the error message, as passed to fail(...)
	UserTrace *CapturedStacktrace // value of 'trace' passed to fail or nil
	FailTrace *CapturedStacktrace // where 'fail' itself was called
}

Failure is an error emitted by fail(...) and captured by FailureCollector.

func (*Failure) Backtrace

func (f *Failure) Backtrace() string

Backtrace returns a user-friendly error message describing the stack of calls that led to this error.

If fail(...) was called with a custom stack trace, this trace is shown here. Otherwise the trace of where fail(...) happened is used.

func (*Failure) Error

func (f *Failure) Error() string

Error is the short error message, as passed to fail(...).

type FailureCollector

type FailureCollector struct {
	// contains filtered or unexported fields
}

FailureCollector receives structured error messages from fail(...).

It should be installed into Starlark thread locals (via Install) for fail(...) to be able to discover it. If it's not there, fail(...) will not return any additional information (like a custom stack trace) besides the information contained in *starlark.EvalError.

func GetFailureCollector

func GetFailureCollector(th *starlark.Thread) *FailureCollector

GetFailureCollector returns a failure collector installed in the thread.

func (*FailureCollector) Clear

func (fc *FailureCollector) Clear()

Clear resets the state.

Useful if the same FailureCollector is reused between calls to Starlark.

func (*FailureCollector) Install

func (fc *FailureCollector) Install(t *starlark.Thread)

Install installs this failure collector into the thread.

func (*FailureCollector) LatestFailure

func (fc *FailureCollector) LatestFailure() *Failure

LatestFailure returns the latest captured failure or nil if there are none.

Package Files

Documentation was rendered with GOOS=linux and GOARCH=amd64.

Jump to identifier

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to identifier