Summary
Fable.Python.Builtins currently exposes int, float, str, len, isinstance, etc. as methods on the IExports interface. This is great for calling builtins.int(x) etc., but for isinstance checks the Python type values themselves are also needed — and they aren't currently exposed. Three small additions would let downstream libraries drop a recurring chunk of [<Emit>] boilerplate.
What's missing
1. Type references as values
To use the idiomatic Fable.Core.PyInterop.pyInstanceof, the caller needs a value reference to each Python type:
pyInstanceof v pyInt // compiles to isinstance(v, int)
Today every consumer redeclares them privately. Both Thoth.Json.Python and Fable.TypedJson do exactly this:
[<Global; Emit("int")>] let pyInt: obj = nativeOnly
[<Global; Emit("float")>] let pyFloat: obj = nativeOnly
[<Global; Emit("bool")>] let pyBool: obj = nativeOnly
[<Global; Emit("str")>] let pyStr: obj = nativeOnly
[<Global; Emit("list")>] let pyList: obj = nativeOnly
[<Global; Emit("dict")>] let pyDict: obj = nativeOnly
Suggested home: a new Fable.Python.Types module, or top-level let bindings under Fable.Python.Builtins.
2. The None singleton
json.dumps, JSON-null sentinels, default values, and many other interop sites need a value reference to Python's None:
[<Global; Emit("None")>] let pyNone: obj = nativeOnly
3. dict() / list(...) constructors on IExports
Builtins.IExports already has int, float, str constructors (abstract int: obj -> int, etc.). The two collection constructors are missing:
abstract dict: unit -> obj
abstract dict: IEnumerable<string * obj> -> obj
abstract list: IEnumerable<'T> -> obj
Today consumers fall back to [<Emit("dict()")>] / [<Emit("list($0)")>] even though the type values exist as Python builtins.
Why it's worth shipping
Once these land, libraries that wrap Python interop can drop the boilerplate and use:
open Fable.Core.PyInterop
open Fable.Python.Builtins
// type tests
pyInstanceof v pyInt // was: [<Emit("isinstance($0, int)")>]
pyInstanceof v pyDict // was: [<Emit("isinstance($0, dict)")>]
// constructors
builtins.dict () // was: [<Emit("dict()")>]
builtins.list items // was: [<Emit("list($0)")>]
// null
pyNone // was: [<Emit("None")>]
Each of these is a one-liner today, but every Fable Python library reinvents the same set. Centralizing them in Fable.Python.Builtins (or a small Fable.Python.Types module) keeps consumer code clean and matches Fable's existing pattern of providing first-class wrappers for everything the Python stdlib offers.
Reference
Concrete consumer that currently has these as private declarations:
Happy to put up a PR if the proposed shape looks right.
Summary
Fable.Python.Builtinscurrently exposesint,float,str,len,isinstance, etc. as methods on theIExportsinterface. This is great for callingbuiltins.int(x)etc., but forisinstancechecks the Python type values themselves are also needed — and they aren't currently exposed. Three small additions would let downstream libraries drop a recurring chunk of[<Emit>]boilerplate.What's missing
1. Type references as values
To use the idiomatic
Fable.Core.PyInterop.pyInstanceof, the caller needs a value reference to each Python type:pyInstanceof v pyInt // compiles to isinstance(v, int)Today every consumer redeclares them privately. Both Thoth.Json.Python and Fable.TypedJson do exactly this:
Suggested home: a new
Fable.Python.Typesmodule, or top-levelletbindings underFable.Python.Builtins.2. The
Nonesingletonjson.dumps, JSON-null sentinels, default values, and many other interop sites need a value reference to Python'sNone:3.
dict()/list(...)constructors onIExportsBuiltins.IExportsalready hasint,float,strconstructors (abstract int: obj -> int, etc.). The two collection constructors are missing:Today consumers fall back to
[<Emit("dict()")>]/[<Emit("list($0)")>]even though the type values exist as Python builtins.Why it's worth shipping
Once these land, libraries that wrap Python interop can drop the boilerplate and use:
Each of these is a one-liner today, but every Fable Python library reinvents the same set. Centralizing them in
Fable.Python.Builtins(or a smallFable.Python.Typesmodule) keeps consumer code clean and matches Fable's existing pattern of providing first-class wrappers for everything the Python stdlib offers.Reference
Concrete consumer that currently has these as private declarations:
Happy to put up a PR if the proposed shape looks right.