Skip to content

Commit e57b145

Browse files
dbrattliclaude
andauthored
chore: Upgrade to Fable 5.2 (#316)
* chore: Upgrade to Fable 5.2 Bump the Fable compiler tool and fable-library runtime from 5.1.0 to 5.2.0. Also bound the consumer-facing fable-library dependency in src/pyproject.toml to >=5.0.0,<6 to encode the major-must-match-Fable rule (previously the very-loose >=0.8.0). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * style: Apply fantomas formatting Fix pre-existing formatting drift flagged by `just format-check` in four stdlib binding files and four test files. No behavioral changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 2254d98 commit e57b145

12 files changed

Lines changed: 157 additions & 143 deletions

.config/dotnet-tools.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"rollForward": false
1111
},
1212
"fable": {
13-
"version": "5.1.0",
13+
"version": "5.2.0",
1414
"commands": [
1515
"fable"
1616
],

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ requires-python = ">= 3.12, < 4"
77
readme = "README.md"
88
license = "MIT"
99
dependencies = [
10-
"fable-library==5.1.0",
10+
"fable-library==5.2.0",
1111
"pyright>=1.1.410",
1212
]
1313

src/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description = "Python bindings for Fable"
55
authors = [{ name = "Dag Brattli", email = "dag@brattli.net" }]
66
requires-python = ">= 3.12, < 4.0"
77
license = "MIT"
8-
dependencies = ["fable-library>=0.8.0"]
8+
dependencies = ["fable-library>=5.0.0,<6"]
99

1010
[build-system]
1111
requires = ["hatchling"]

src/stdlib/Collections.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ type deque<'T>() =
162162
member _.Item(index: int) : 'T = nativeOnly
163163

164164
/// Maximum length of the deque, or None if unbounded
165-
member _.maxlen : int option = nativeOnly
165+
member _.maxlen: int option = nativeOnly
166166

167167
/// Add item to the right end
168168
member _.append(item: 'T) : unit = nativeOnly

src/stdlib/Os.fs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,18 @@ type IExports =
4848
/// Recursive directory creation function
4949
/// See https://docs.python.org/3/library/os.html#os.makedirs
5050
abstract makedirs: path: string -> unit
51+
5152
/// Recursive directory creation, creating parent directories as needed.
5253
/// Raises FileExistsError if the directory already exists and exist_ok is false.
5354
/// See https://docs.python.org/3/library/os.html#os.makedirs
5455
[<Emit("$0.makedirs($1, exist_ok=$2)")>]
5556
abstract makedirs: path: string * exist_ok: bool -> unit
57+
5658
/// Recursive directory creation with explicit mode and exist_ok flag.
5759
/// See https://docs.python.org/3/library/os.html#os.makedirs
5860
[<Emit("$0.makedirs($1, $2, $3)")>]
5961
abstract makedirs: path: string * mode: int * exist_ok: bool -> unit
62+
6063
/// Set the environment variable named key to the string value
6164
/// See https://docs.python.org/3/library/os.html#os.putenv
6265
abstract putenv: key: string * value: string -> unit
@@ -77,10 +80,12 @@ type IExports =
7780
/// to prune the search or impose a specific visiting order.
7881
/// See https://docs.python.org/3/library/os.html#os.walk
7982
abstract walk: top: string -> seq<string * ResizeArray<string> * ResizeArray<string>>
83+
8084
/// Walk a directory tree top-down or bottom-up (topdown=false).
8185
/// See https://docs.python.org/3/library/os.html#os.walk
8286
[<Emit("$0.walk($1, topdown=$2)")>]
8387
abstract walk: top: string * topdown: bool -> seq<string * ResizeArray<string> * ResizeArray<string>>
88+
8489
/// Test whether a path exists
8590
/// See https://docs.python.org/3/library/os.path.html#os.path.exists
8691
abstract path: PathModule

src/stdlib/Pathlib.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ type Path() =
7575
/// This mirrors Python's ``path / "child"`` operator.
7676
/// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.__truediv__
7777
[<Emit("$0 / $1")>]
78-
static member (/) (left: Path, right: string) : Path = nativeOnly
78+
static member (/)(left: Path, right: string) : Path = nativeOnly
7979

8080
/// Return a new Path by appending another Path.
8181
/// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.__truediv__
8282
[<Emit("$0 / $1")>]
83-
static member (/) (left: Path, right: Path) : Path = nativeOnly
83+
static member (/)(left: Path, right: Path) : Path = nativeOnly
8484

8585
/// Join one or more path segments to this path and return the result.
8686
/// See https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.joinpath

src/stdlib/Threading.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ type Event() =
6969
/// Set the internal flag to true
7070
[<Emit("$0.set()")>]
7171
member _.set() : unit = nativeOnly
72+
7273
/// Reset the internal flag to false
7374
member _.clear() : unit = nativeOnly
7475
/// Return true if and only if the internal flag is true

test/TestBuiltins.fs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,7 @@ let ``test len with string works`` () =
158158

159159
[<Fact>]
160160
let ``test map with single iterable works`` () =
161-
builtins.map ((fun x -> x * 2), [ 1; 2; 3 ])
162-
|> Seq.toList
163-
|> equal [ 2; 4; 6 ]
161+
builtins.map ((fun x -> x * 2), [ 1; 2; 3 ]) |> Seq.toList |> equal [ 2; 4; 6 ]
164162

165163
[<Fact>]
166164
let ``test map with two iterables works`` () =

test/TestCollections.fs

Lines changed: 67 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -27,150 +27,155 @@ let ``test Counter missing key returns 0`` () =
2727
[<Fact>]
2828
let ``test Counter most_common returns all elements sorted by count`` () =
2929
let c = Counter.ofSeq [ "a"; "b"; "a"; "c"; "a"; "b" ]
30-
let top = c.most_common() |> Seq.head
30+
let top = c.most_common () |> Seq.head
3131
top |> equal ("a", 3)
3232

3333
[<Fact>]
3434
let ``test Counter most_common n returns top n elements`` () =
3535
let c = Counter.ofSeq [ "a"; "b"; "a"; "c"; "a"; "b" ]
36-
let topTwo = c.most_common(2) |> Seq.toList
36+
let topTwo = c.most_common (2) |> Seq.toList
3737
topTwo |> List.length |> equal 2
3838
topTwo |> List.head |> equal ("a", 3)
3939

4040
[<Fact>]
4141
let ``test Counter elements returns repeated sequence`` () =
4242
let c = Counter.ofSeq [ "a"; "a"; "b" ]
43-
let elems = c.elements() |> Seq.toList |> List.sort
43+
let elems = c.elements () |> Seq.toList |> List.sort
4444
elems |> equal [ "a"; "a"; "b" ]
4545

4646
[<Fact>]
4747
let ``test Counter total sums all counts`` () =
4848
let c = Counter.ofSeq [ "a"; "b"; "a"; "c" ]
49-
c.total() |> equal 4
49+
c.total () |> equal 4
5050

5151
[<Fact>]
5252
let ``test Counter update adds counts`` () =
5353
let c = Counter.ofSeq [ "a"; "b" ]
54-
c.update([ "a"; "c" ])
54+
c.update ([ "a"; "c" ])
5555
c.Item("a") |> equal 2
5656
c.Item("c") |> equal 1
5757

5858
[<Fact>]
5959
let ``test Counter subtract reduces counts`` () =
6060
let c = Counter.ofSeq [ "a"; "a"; "b" ]
61-
c.subtract([ "a" ])
61+
c.subtract ([ "a" ])
6262
c.Item("a") |> equal 1
6363

6464
[<Fact>]
6565
let ``test Counter contains reflects key presence`` () =
6666
let c = Counter.ofSeq [ "a"; "b" ]
67-
c.contains("a") |> equal true
68-
c.contains("z") |> equal false
67+
c.contains ("a") |> equal true
68+
c.contains ("z") |> equal false
6969

7070
[<Fact>]
7171
let ``test Counter keys and values enumerate the counter`` () =
7272
let c = Counter.ofSeq [ "a"; "b"; "a" ]
73-
c.keys() |> Seq.toList |> List.sort |> equal [ "a"; "b" ]
74-
c.values() |> Seq.sum |> equal 3
73+
c.keys () |> Seq.toList |> List.sort |> equal [ "a"; "b" ]
74+
c.values () |> Seq.sum |> equal 3
7575

7676
[<Fact>]
7777
let ``test Counter pop removes and returns count`` () =
7878
let c = Counter.ofSeq [ "a"; "a"; "b" ]
79-
c.pop("a") |> equal 2
80-
c.contains("a") |> equal false
79+
c.pop ("a") |> equal 2
80+
c.contains ("a") |> equal false
8181

8282
// ============================================================================
8383
// defaultdict tests
8484
// ============================================================================
8585

8686
[<Fact>]
8787
let ``test defaultdict missing key invokes factory`` () =
88-
let d = defaultdict<string, ResizeArray<int>>.withFactory(fun () -> ResizeArray())
88+
let d = defaultdict<string, ResizeArray<int>>.withFactory (fun () -> ResizeArray())
8989
let list = d.Item("key")
9090
list.Count |> equal 0
9191

9292
[<Fact>]
9393
let ``test defaultdict factory creates separate instances`` () =
94-
let d = defaultdict<string, ResizeArray<int>>.withFactory(fun () -> ResizeArray())
94+
let d = defaultdict<string, ResizeArray<int>>.withFactory (fun () -> ResizeArray())
9595
let list1 = d.Item("a")
9696
list1.Add(1)
9797
let list2 = d.Item("b")
9898
list2.Count |> equal 0
9999

100100
[<Fact>]
101101
let ``test defaultdict int factory starts at zero`` () =
102-
let d = defaultdict<string, int>.withFactory(fun () -> 0)
102+
let d = defaultdict<string, int>.withFactory (fun () -> 0)
103103
d.Item("key") |> equal 0
104104

105105
[<Fact>]
106106
let ``test defaultdict get returns None for missing key without invoking factory`` () =
107107
let mutable factoryCalled = false
108-
let d = defaultdict<string, int>.withFactory(fun () -> factoryCalled <- true; 0)
109-
let result = d.get("missing")
108+
109+
let d =
110+
defaultdict<string, int>.withFactory (fun () ->
111+
factoryCalled <- true
112+
0)
113+
114+
let result = d.get ("missing")
110115
result |> equal None
111116
factoryCalled |> equal false
112117

113118
[<Fact>]
114119
let ``test defaultdict get with default returns default for missing key`` () =
115-
let d = defaultdict<string, int>.withFactory(fun () -> 0)
116-
d.get("missing", 42) |> equal 42
120+
let d = defaultdict<string, int>.withFactory (fun () -> 0)
121+
d.get ("missing", 42) |> equal 42
117122

118123
[<Fact>]
119124
let ``test defaultdict contains returns false for missing key`` () =
120-
let d = defaultdict<string, int>.withFactory(fun () -> 0)
121-
d.contains("key") |> equal false
125+
let d = defaultdict<string, int>.withFactory (fun () -> 0)
126+
d.contains ("key") |> equal false
122127

123128
[<Fact>]
124129
let ``test defaultdict contains returns true after access`` () =
125-
let d = defaultdict<string, int>.withFactory(fun () -> 99)
130+
let d = defaultdict<string, int>.withFactory (fun () -> 99)
126131
let _ = d.Item("key")
127-
d.contains("key") |> equal true
132+
d.contains ("key") |> equal true
128133

129134
// ============================================================================
130135
// deque tests
131136
// ============================================================================
132137

133138
[<Fact>]
134139
let ``test deque empty deque has length 0`` () =
135-
let d = deque<int>()
136-
d.length() |> equal 0
140+
let d = deque<int> ()
141+
d.length () |> equal 0
137142

138143
[<Fact>]
139144
let ``test deque ofSeq creates deque from sequence`` () =
140145
let d = deque.ofSeq [ 1; 2; 3 ]
141-
d.length() |> equal 3
146+
d.length () |> equal 3
142147

143148
[<Fact>]
144149
let ``test deque append adds to right`` () =
145150
let d = deque.ofSeq [ 1; 2 ]
146-
d.append(3)
151+
d.append (3)
147152
d.Item(2) |> equal 3
148153

149154
[<Fact>]
150155
let ``test deque appendleft adds to left`` () =
151156
let d = deque.ofSeq [ 1; 2 ]
152-
d.appendleft(0)
157+
d.appendleft (0)
153158
d.Item(0) |> equal 0
154-
d.length() |> equal 3
159+
d.length () |> equal 3
155160

156161
[<Fact>]
157162
let ``test deque pop removes from right`` () =
158163
let d = deque.ofSeq [ 1; 2; 3 ]
159-
let v = d.pop()
164+
let v = d.pop ()
160165
v |> equal 3
161-
d.length() |> equal 2
166+
d.length () |> equal 2
162167

163168
[<Fact>]
164169
let ``test deque popleft removes from left`` () =
165170
let d = deque.ofSeq [ 1; 2; 3 ]
166-
let v = d.popleft()
171+
let v = d.popleft ()
167172
v |> equal 1
168-
d.length() |> equal 2
173+
d.length () |> equal 2
169174

170175
[<Fact>]
171176
let ``test deque rotate shifts elements right`` () =
172177
let d = deque.ofSeq [ 1; 2; 3; 4; 5 ]
173-
d.rotate(2)
178+
d.rotate (2)
174179
d.Item(0) |> equal 4
175180
d.Item(1) |> equal 5
176181

@@ -181,29 +186,29 @@ let ``test deque maxlen is None for unbounded deque`` () =
181186

182187
[<Fact>]
183188
let ``test deque withMaxlen creates bounded deque`` () =
184-
let d = deque<int>.withMaxlen(3)
185-
d.append(1)
186-
d.append(2)
187-
d.append(3)
188-
d.append(4) // should push out 1
189-
d.length() |> equal 3
189+
let d = deque<int>.withMaxlen (3)
190+
d.append (1)
191+
d.append (2)
192+
d.append (3)
193+
d.append (4) // should push out 1
194+
d.length () |> equal 3
190195
d.Item(0) |> equal 2
191196

192197
[<Fact>]
193198
let ``test deque ofSeq with maxlen creates bounded deque`` () =
194199
let d = deque.ofSeq ([ 1; 2; 3; 4; 5 ], 3)
195-
d.length() |> equal 3
200+
d.length () |> equal 3
196201
d.maxlen |> equal (Some 3)
197202

198203
[<Fact>]
199204
let ``test deque count occurrences`` () =
200205
let d = deque.ofSeq [ 1; 2; 1; 3; 1 ]
201-
d.count(1) |> equal 3
206+
d.count (1) |> equal 3
202207

203208
[<Fact>]
204209
let ``test deque extendleft reverses iterable order`` () =
205210
let d = deque.ofSeq [ 3 ]
206-
d.extendleft([ 1; 2 ])
211+
d.extendleft ([ 1; 2 ])
207212
// Each element pushed onto the left in turn => final order [2; 1; 3]
208213
d.Item(0) |> equal 2
209214
d.Item(1) |> equal 1
@@ -216,43 +221,43 @@ let ``test deque extendleft reverses iterable order`` () =
216221
[<Fact>]
217222
let ``test OrderedDict preserves insertion order`` () =
218223
let od = OrderedDict<string, int>()
219-
od.set("a", 1)
220-
od.set("b", 2)
221-
od.set("c", 3)
222-
od.keys() |> Seq.toList |> equal [ "a"; "b"; "c" ]
224+
od.set ("a", 1)
225+
od.set ("b", 2)
226+
od.set ("c", 3)
227+
od.keys () |> Seq.toList |> equal [ "a"; "b"; "c" ]
223228

224229
[<Fact>]
225230
let ``test OrderedDict get existing key`` () =
226231
let od = OrderedDict<string, int>()
227-
od.set("x", 42)
232+
od.set ("x", 42)
228233
od.Item("x") |> equal 42
229234

230235
[<Fact>]
231236
let ``test OrderedDict get returns None for missing key`` () =
232237
let od = OrderedDict<string, int>()
233-
od.get("missing") |> equal None
238+
od.get ("missing") |> equal None
234239

235240
[<Fact>]
236241
let ``test OrderedDict move_to_end moves last element`` () =
237242
let od = OrderedDict<string, int>()
238-
od.set("a", 1)
239-
od.set("b", 2)
240-
od.set("c", 3)
241-
od.move_to_end("a")
242-
od.keys() |> Seq.toList |> equal [ "b"; "c"; "a" ]
243+
od.set ("a", 1)
244+
od.set ("b", 2)
245+
od.set ("c", 3)
246+
od.move_to_end ("a")
247+
od.keys () |> Seq.toList |> equal [ "b"; "c"; "a" ]
243248

244249
[<Fact>]
245250
let ``test OrderedDict move_to_end with last false moves to front`` () =
246251
let od = OrderedDict<string, int>()
247-
od.set("a", 1)
248-
od.set("b", 2)
249-
od.set("c", 3)
250-
od.move_to_end("c", false)
251-
od.keys() |> Seq.toList |> equal [ "c"; "a"; "b" ]
252+
od.set ("a", 1)
253+
od.set ("b", 2)
254+
od.set ("c", 3)
255+
od.move_to_end ("c", false)
256+
od.keys () |> Seq.toList |> equal [ "c"; "a"; "b" ]
252257

253258
[<Fact>]
254259
let ``test OrderedDict contains returns correct result`` () =
255260
let od = OrderedDict<string, int>()
256-
od.set("a", 1)
257-
od.contains("a") |> equal true
258-
od.contains("b") |> equal false
261+
od.set ("a", 1)
262+
od.contains ("a") |> equal true
263+
od.contains ("b") |> equal false

0 commit comments

Comments
 (0)