#Enum issue inside nested connection

1 messages · Page 1 of 1 (latest)

late wigeon
#

@hexed saddle 👋 There seems to be a problem with enums. When running codegen from inside a ExperimentalPrivilegedNesting container the TypeDefKind enum only has the STRING_KIND, INTEGER_KIND, etc, values and not STRING, INTEGER, etc.

hexed saddle
#

what version is inside the nesting?

#

it should only be appearing past v0.18.11

late wigeon
#

It's the same version, and dev build: v0.18.15-010101000000-dev-5efecbf8f2e5

#

Hmmm... this seems to happen only on the new self calls PR, specifically in the new moduleTypeDefs function so it's in a phase where the module isn't fully loaded yet. Maybe that view isn't being applied yet at this point? Can we move that needle? Or maybe it's just missing the thing that applies the view?

hexed saddle
#

hm, okay, that's odd 🤔

#

definitely only on this branch? or also on main?

late wigeon
#

I made a repro and it's ok in v0.18.14. Will test against main now, but I suspect it only happens in the self calls PR since it changes how modules are loaded.

#

Btw, when you changed the codegen to refer to other members like:

class TypeDefKind(Enum):
  STRING = "STRING_KIND"
  STRING_KIND = STRING

Was the motivation simply to make an alias or is there a reason not to:


class TypeDefKind(Enum):
  STRING = "STRING"
  STRING_KIND = "STRING_KIND"
hexed saddle
#

no real reason, it can just be changed back if you like

#

but go/typescript did it - i found it much clearer as to which ones were aliases

#

oh wait wait. yes there is a reason.

#

the values should be the same

#

otherwise, we lose the property that STRING == STRING_KIND

late wigeon
#

Thing is in the first case the type of STRING is a string, while the type of STRING_KIND is an enum member.

#

The proper way to make an alias in a Python enum is just to have the same value.

hexed saddle
#

😢 right okay, sorry, that's a my bad then

#

the codegen result should be:

class TypeDefKind(Enum):
  STRING = "STRING_KIND"
  STRING_KIND = "STRING_KIND"
late wigeon
#

A simple example:

import enum


class Test(enum.Enum):
    ONE = "ONE"
    UNO = "ONE"


print("By name:", Test["UNO"].name)
# Output: By name: ONE
late wigeon
#

Just reverting will produce:

class TypeDefKind(Enum):
  STRING = "STRING"
  STRING_KIND = "STRING_KIND"

Instead of this though:

class TypeDefKind(Enum):
  STRING = "STRING_KIND"
  STRING_KIND = "STRING_KIND"
hexed saddle
#

here

#

have a pr ❤️

late wigeon
late wigeon
#

@hexed saddle, is there a way to confirm enum values with a GraphQL query (with dagger listen)?

I've created this repro:

package main

import (
    "context"
    "dagger/nested/internal/dagger"
)

type Nested struct{}

func (m *Nested) Test(ctx context.Context) (string, error) {
    var code string = `
import pprint

import anyio
import graphql
from gql.dsl import DSLSchema

import dagger
from dagger import dag

def get_value(value, schema) -> str:
    if value.ast_node and (directive := schema.get_directive("enumValue")):
        args = graphql.get_directive_values(directive, value.ast_node)
        if args:
            return args["value"]
    return value.value

async def main():
    async with await dagger.connect():
        print("Version:", await dag.version())
        schema = DSLSchema(await dag._ctx.conn.session.get_schema())
        pprint.pprint(
            {
                name: get_value(value, schema)
                for name, value in schema.TypeDef.withKind._get_argument(
                    "kind"
                ).type.of_type.values.items()
            }
        )

anyio.run(main)
`
    return dag.Container().
        From("ghcr.io/astral-sh/uv:debian-slim").
        WithNewFile("/script.py", code).
        WithExec([]string{"uv", "run", "--with", "dagger-io", "/script.py"}, dagger.ContainerWithExecOpts{
            ExperimentalPrivilegedNesting: true,
        }).
        Stdout(ctx)
}
#

But it's returning this:

{'BOOLEAN': 'BOOLEAN',
 'BOOLEAN_KIND': 'BOOLEAN_KIND',
 'ENUM': 'ENUM',
 'ENUM_KIND': 'ENUM_KIND',
 'FLOAT': 'FLOAT',
 'FLOAT_KIND': 'FLOAT_KIND',
 'INPUT': 'INPUT',
 'INPUT_KIND': 'INPUT_KIND',
 'INTEGER': 'INTEGER',
 'INTEGER_KIND': 'INTEGER_KIND',
 'INTERFACE': 'INTERFACE',
 'INTERFACE_KIND': 'INTERFACE_KIND',
 'LIST': 'LIST',
 'LIST_KIND': 'LIST_KIND',
 'OBJECT': 'OBJECT',
 'OBJECT_KIND': 'OBJECT_KIND',
 'SCALAR': 'SCALAR',
 'SCALAR_KIND': 'SCALAR_KIND',
 'STRING': 'STRING',
 'STRING_KIND': 'STRING_KIND',
 'VOID': 'VOID',
 'VOID_KIND': 'VOID_KIND'}

I expected 'STRING': 'STRING_KIND' for example.

hexed saddle
#

it potentially looks like you're always following the return value.value path

late wigeon
#

Oh wait, I may need the insert_stubs thing?

hexed saddle
#

and not looking at the enumValue

hexed saddle
#

you definitely need that

late wigeon
# hexed saddle https://github.com/dagger/dagger/pull/10802\

The order may still be wrong, right?

class TypeDefKind(Enum):
    STRING = "STRING_KIND"
    STRING_KIND = "STRING_KIND"

It's declared like so:

TypeDefKindString = TypeDefKinds.Register("STRING_KIND", "A string value.")
_                 = TypeDefKinds.AliasView("STRING", "STRING_KIND", enumView)

Which means that it should have this order:

class TypeDefKind(Enum):
    STRING_KIND = "STRING_KIND"
    STRING = "STRING_KIND"

Otherwise dagger.TypeDefKind.STRING_KIND becomes an alias of dagger.TypeDefKind.STRING instead, meaning the member's name will be "STRING" instead of "STRING_KIND".

hexed saddle
#

mmmm, indeed. the name should be the original STRING_KIND

#

this is definitely true in go already

late wigeon
#

So you can't sort those values. How can you tell in codegen which one is the alias or not? In this case I can check if name == value, but what about user defined ones?

hexed saddle
#

they're not sorted, they're bucketed by value first

#

then the first value in the bucket is the "original"

#

i think the only fix for python needed is to avoid the sorting step?

late wigeon
#

Yep, I think so.

late wigeon
#

@hexed saddle, indeed this fixes my problem. I've sorted by value after grouping which effectively keeps the same overall sort but flips the original value vs alias. I can push the change to your branch.