Skip to content
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8b4e0e7
Add alloy-js/python dependency
mauriciogardini Jul 30, 2025
58d87c6
Merge pull request #33 from pinterest/feature/add-alloy
mauriciogardini Jul 30, 2025
a50600b
Add python scaffolding
Jul 31, 2025
1e46327
Merge pull request #35 from pinterest/feature/add_python_folder
swatkatz Jul 31, 2025
dea3541
Add starting test structure (#34)
mauriciogardini Jul 31, 2025
6d73458
Add Atom (#36)
mauriciogardini Aug 11, 2025
79581e6
Add typing (#38)
mauriciogardini Aug 14, 2025
2006978
Unify test utils (#42)
mauriciogardini Aug 14, 2025
97a8e9b
Add models and interfaces
mauriciogardini Sep 18, 2025
ba5a58e
Merge branch 'feature/ef-python' into feature/model-interface
mauriciogardini Oct 1, 2025
6ed75c8
Remove file
mauriciogardini Oct 1, 2025
6cee8f1
Changes
mauriciogardini Oct 3, 2025
5c176ce
Missing files
mauriciogardini Oct 7, 2025
933ea95
Add Literal import
mauriciogardini Oct 7, 2025
2d5c1f9
Accounting for feedback
mauriciogardini Oct 8, 2025
8bca1d6
Handle floats in a better way
mauriciogardini Oct 8, 2025
4810257
Accounting for feedback
mauriciogardini Oct 8, 2025
11afa9f
Merge branch 'feature/ef-python' into feature/model-interface
mauriciogardini Oct 21, 2025
3ae121a
Fix
mauriciogardini Oct 22, 2025
5458b72
Update
mauriciogardini Oct 31, 2025
4b759c3
Merge branch 'feature/ef-python' into feature/model-interface
mauriciogardini Oct 31, 2025
e813cc0
Rebase
mauriciogardini Oct 31, 2025
5e61e05
Fix tests
mauriciogardini Oct 31, 2025
b3536b8
Fix
mauriciogardini Oct 31, 2025
666292f
Add comments
mauriciogardini Nov 3, 2025
edc4b54
Remove typing module import
mauriciogardini Nov 3, 2025
fd0d378
Fix
mauriciogardini Nov 4, 2025
1485d60
Fix
mauriciogardini Nov 4, 2025
92c3704
Fix
mauriciogardini Nov 5, 2025
ab879d7
Changing docstrings
mauriciogardini Nov 10, 2025
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
20 changes: 19 additions & 1 deletion packages/emitter-framework/src/python/builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import { createModule } from "@alloy-js/python";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
type dummy = SymbolCreator;

export const abcModule = createModule({
name: "abc",
descriptor: {
".": ["ABC"],
},
});

export const datetimeModule = createModule({
name: "datetime",
descriptor: {
Expand All @@ -21,6 +28,17 @@ export const decimalModule = createModule({
export const typingModule = createModule({
name: "typing",
descriptor: {
".": ["Any", "Never", "NoReturn", "TypeAlias", "Tuple", "Callable", "Protocol"],
".": [
"Any",
"Callable",
"Generic",
"Literal",
"Never",
"Optional",
"Protocol",
"TypeAlias",
"TypeVar",
"Tuple",
],
},
});
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,54 @@ describe("NumericValue", () => {
});

it("decimals", async () => {
const value = $(program).value.createNumeric(42.5);
const fractional = $(program).value.createNumeric(42.5);
await testValueExpression(fractional, `42.5`);
});

it("decimals with .0", async () => {
// Generic Atom (no hint) normalizes 42.0 to 42 because it uses asNumber()
const value = $(program).value.createNumeric(42.0);
await testValueExpression(value, `42`);
});

it("decimals with .0 when assumeFloat", async () => {
const value = $(program).value.createNumeric(42.0);
expect(getOutput(program, [<Atom value={value} assumeFloat />])).toRenderTo(`42.0`);
});

it("negative integers", async () => {
const value = $(program).value.createNumeric(-42);
await testValueExpression(value, `-42`);
});

it("negative decimals", async () => {
const value = $(program).value.createNumeric(-42.5);
await testValueExpression(value, `-42.5`);
});

it("zero", async () => {
const value = $(program).value.createNumeric(0);
await testValueExpression(value, `0`);
});

it("zero with assumeFloat", async () => {
const value = $(program).value.createNumeric(0);
expect(getOutput(program, [<Atom value={value} assumeFloat />])).toRenderTo(`0.0`);
});

it("exponent that resolves to integer", async () => {
const value = $(program).value.createNumeric(1e3);
await testValueExpression(value, `1000`);
});

it("exponent that resolves to integer with assumeFloat", async () => {
const value = $(program).value.createNumeric(1e3);
expect(getOutput(program, [<Atom value={value} assumeFloat />])).toRenderTo(`1000.0`);
});

await testValueExpression(value, `42.5`);
it("small decimal via exponent", async () => {
const value = $(program).value.createNumeric(1e-3);
await testValueExpression(value, `0.001`);
});
});

Expand Down
13 changes: 11 additions & 2 deletions packages/emitter-framework/src/python/components/atom/atom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ interface AtomProps {
* The TypeSpec value to be converted to a Python expression.
*/
value: Value;
/**
* Hint that this numeric value should be emitted as a float (e.g., 42 -> 42.0).
* Only affects NumericValue.
*/
assumeFloat?: boolean;
}

/**
Expand All @@ -23,8 +28,12 @@ export function Atom(props: Readonly<AtomProps>): Children {
case "BooleanValue":
case "NullValue":
return <py.Atom jsValue={props.value.value} />;
case "NumericValue":
return <py.Atom jsValue={props.value.value.asNumber()} />;
case "NumericValue": {
const num = props.value.value.asNumber();
const isNonInteger = num != null && !Number.isInteger(num);
const asFloat = isNonInteger || props.assumeFloat === true;
return <py.Atom jsValue={num} asFloat={asFloat} />;
}
case "ArrayValue":
return (
<py.Atom
Expand Down
Loading