Skip to content

Commit 467c20a

Browse files
authored
Merge pull request #50 from dispatchrun/python-value-2
run: improve formatting of Python input/output values
2 parents 55af7c4 + 1cd789c commit 467c20a

File tree

2 files changed

+72
-16
lines changed

2 files changed

+72
-16
lines changed

cli/any.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,28 @@ package cli
22

33
import (
44
"fmt"
5+
"log/slog"
56

6-
"github.com/charmbracelet/lipgloss"
77
"google.golang.org/protobuf/proto"
88
"google.golang.org/protobuf/types/known/anypb"
99
"google.golang.org/protobuf/types/known/wrapperspb"
1010
)
1111

12-
var (
13-
anyTypeStyle = lipgloss.NewStyle().Foreground(grayColor)
14-
anyNilStyle = lipgloss.NewStyle().Foreground(grayColor)
15-
)
16-
1712
func anyString(any *anypb.Any) string {
1813
if any == nil {
19-
return anyNilStyle.Render("nil")
14+
return "nil"
2015
}
2116
switch any.TypeUrl {
2217
case "type.googleapis.com/google.protobuf.BytesValue":
23-
if s, err := anyBytesString(any); err == nil && s != "" {
18+
s, err := anyBytesString(any)
19+
if err != nil {
20+
slog.Debug("cannot parse input/output value", "error", err)
21+
// fallthrough
22+
} else {
2423
return s
2524
}
26-
// Suppress the error; render the type only.
2725
}
28-
return anyTypeStyle.Render(fmt.Sprintf("<%s>", any.TypeUrl))
29-
26+
return fmt.Sprintf("%s(?)", any.TypeUrl)
3027
}
3128

3229
func anyBytesString(any *anypb.Any) (string, error) {

cli/python.go

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cli
33
import (
44
"bytes"
55
"fmt"
6+
"log/slog"
67
"strings"
78

89
"github.com/charmbracelet/lipgloss"
@@ -48,11 +49,10 @@ func pythonValueString(value interface{}) (string, error) {
4849
return pythonSetString(v)
4950
case *pythonArgumentsObject:
5051
return pythonArgumentsString(v)
51-
case *types.GenericClass:
52+
case *genericClass:
5253
return fmt.Sprintf("%s.%s", v.Module, v.Name), nil
53-
case *types.GenericObject:
54-
s, _ := pythonValueString(v.Class)
55-
return fmt.Sprintf("%s(?)", s), nil
54+
case *genericObject:
55+
return pythonGenericObjectString(v)
5656
default:
5757
return "", fmt.Errorf("unsupported Python value: %T", value)
5858
}
@@ -180,6 +180,42 @@ func pythonArgumentsString(a *pythonArgumentsObject) (string, error) {
180180
}
181181
}
182182

183+
b.WriteByte(')')
184+
return b.String(), nil
185+
}
186+
187+
func pythonGenericObjectString(o *genericObject) (string, error) {
188+
var b strings.Builder
189+
b.WriteString(o.class.Name)
190+
b.WriteByte('(')
191+
192+
for i, e := 0, o.dict.List.Front(); e != nil; i++ {
193+
if i > 0 {
194+
b.WriteString(", ")
195+
}
196+
entry := e.Value.(*types.OrderedDictEntry)
197+
198+
var keyStr string
199+
if s, ok := entry.Key.(string); ok {
200+
keyStr = s
201+
} else {
202+
var err error
203+
keyStr, err = pythonValueString(entry.Key)
204+
if err != nil {
205+
return "", err
206+
}
207+
}
208+
b.WriteString(kwargStyle.Render(keyStr + "="))
209+
210+
valueStr, err := pythonValueString(entry.Value)
211+
if err != nil {
212+
return "", err
213+
}
214+
b.WriteString(valueStr)
215+
216+
e = e.Next()
217+
}
218+
183219
b.WriteByte(')')
184220
return b.String(), nil
185221

@@ -190,7 +226,12 @@ func findPythonClass(module, name string) (interface{}, error) {
190226
if module == "dispatch.proto" && name == "Arguments" {
191227
return &pythonArgumentsClass{}, nil
192228
}
193-
return types.NewGenericClass(module, name), nil
229+
// If a custom class is encountered, we don't have enough information
230+
// to be able to format it. In many cases though (e.g. dataclasses),
231+
// it's sufficient to collect and format the module/name of the class,
232+
// and then data that arrives through PyDictSettable interface.
233+
slog.Debug("deserializing Python class", "module", module, "name", name)
234+
return &genericClass{&types.GenericClass{Module: module, Name: name}}, nil
194235
}
195236

196237
type pythonArgumentsClass struct{}
@@ -222,3 +263,21 @@ func (a *pythonArgumentsObject) PyDictSet(key, value interface{}) error {
222263
}
223264
return nil
224265
}
266+
267+
type genericClass struct {
268+
*types.GenericClass
269+
}
270+
271+
func (c *genericClass) PyNew(args ...interface{}) (interface{}, error) {
272+
return &genericObject{c, types.NewOrderedDict()}, nil
273+
}
274+
275+
type genericObject struct {
276+
class *genericClass
277+
dict *types.OrderedDict
278+
}
279+
280+
func (o *genericObject) PyDictSet(key, value interface{}) error {
281+
o.dict.Set(key, value)
282+
return nil
283+
}

0 commit comments

Comments
 (0)