TestASTFollowUp exercises Python patterns the AST analyzer used to drop silently or mishandle. Each subtest invokes “dagger call“ end-to-end so the AST analyzer's schema, the engine's validation, and the runtime's dispatch all have to agree — anything that survives an integration run here matches wh
(ctx context.Context, t *testctx.T)
| 1593 | // dispatch all have to agree — anything that survives an integration run |
| 1594 | // here matches what a real user would see. |
| 1595 | func (PythonSuite) TestASTFollowUp(ctx context.Context, t *testctx.T) { |
| 1596 | t.Run("aliased dagger module and decorators", func(ctx context.Context, t *testctx.T) { |
| 1597 | c := connect(ctx, t) |
| 1598 | |
| 1599 | // ``import dagger as d`` plus ``from dagger import object_type as ot, |
| 1600 | // function as fn`` — the decorator name allow-list used to miss |
| 1601 | // every aliased form. |
| 1602 | modGen := pythonModInit(t, c, ` |
| 1603 | import dagger as d |
| 1604 | from dagger import object_type as ot, function as fn, field as fld |
| 1605 | |
| 1606 | @ot |
| 1607 | class Test: |
| 1608 | name: str = fld(default="aliased") |
| 1609 | |
| 1610 | @fn |
| 1611 | def hello(self, msg: str = "world") -> str: |
| 1612 | return self.name + ":" + msg |
| 1613 | |
| 1614 | @d.function |
| 1615 | def echo(self, msg: str) -> str: |
| 1616 | return msg |
| 1617 | `) |
| 1618 | out, err := modGen.With(daggerCall("hello")).Stdout(ctx) |
| 1619 | require.NoError(t, err) |
| 1620 | require.Equal(t, "aliased:world", out) |
| 1621 | |
| 1622 | out, err = modGen.With(daggerCall("echo", "--msg=hi")).Stdout(ctx) |
| 1623 | require.NoError(t, err) |
| 1624 | require.Equal(t, "hi", out) |
| 1625 | }) |
| 1626 | |
| 1627 | t.Run("inherited @function across MRO", func(ctx context.Context, t *testctx.T) { |
| 1628 | c := connect(ctx, t) |
| 1629 | |
| 1630 | // ``@function`` methods on an undecorated base flow through to |
| 1631 | // ``Test`` via Python MRO. Fields on the same base do *not* |
| 1632 | // (the runtime's ``dataclasses.fields(cls)`` only walks |
| 1633 | // dataclass parents) — that's why ``Base`` here doesn't |
| 1634 | // declare a field. |
| 1635 | modGen := pythonModInit(t, c, ` |
| 1636 | from typing import Self |
| 1637 | |
| 1638 | import dagger |
| 1639 | from dagger import function, object_type |
| 1640 | |
| 1641 | class Base: |
| 1642 | @function |
| 1643 | def shout(self, msg: str) -> str: |
| 1644 | return msg.upper() |
| 1645 | |
| 1646 | @object_type |
| 1647 | class Test(Base): |
| 1648 | @function |
| 1649 | def whisper(self, msg: str) -> str: |
| 1650 | return msg.lower() |
| 1651 | `) |
| 1652 | // Inherited from Base. |
nothing calls this directly
no test coverage detected