Skip to content

Commit b0b05d3

Browse files
committed
Use @_disfavoredOverload to enable more ergonomic syntax for PythonFunction
1 parent 8de2a3f commit b0b05d3

File tree

2 files changed

+27
-23
lines changed

2 files changed

+27
-23
lines changed

PythonKit/Python.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1558,6 +1558,7 @@ public struct PythonFunction {
15581558
/// Called directly by the Python C API
15591559
private var function: PyFunction
15601560

1561+
@_disfavoredOverload
15611562
public init(_ fn: @escaping (PythonObject) throws -> PythonConvertible) {
15621563
function = PyFunction { argumentsAsTuple in
15631564
return try fn(argumentsAsTuple[0])
@@ -1681,6 +1682,7 @@ struct PyMethodDef {
16811682
public struct PythonInstanceMethod {
16821683
private var function: PythonFunction
16831684

1685+
@_disfavoredOverload
16841686
public init(_ fn: @escaping (PythonObject) throws -> PythonConvertible) {
16851687
function = PythonFunction(fn)
16861688
}

Tests/PythonKitTests/PythonFunctionTests.swift

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ class PythonFunctionTests: XCTestCase {
1313
return
1414
}
1515

16-
let pythonAdd = PythonFunction { (params: [PythonObject]) in
17-
let lhs = params[0]
18-
let rhs = params[1]
16+
let pythonAdd = PythonFunction { args in
17+
let lhs = args[0]
18+
let rhs = args[1]
1919
return lhs + rhs
2020
}.pythonObject
2121

@@ -30,27 +30,25 @@ class PythonFunctionTests: XCTestCase {
3030
return
3131
}
3232

33-
let constructor = PythonInstanceMethod { (params: [PythonObject]) in
34-
let `self` = params[0]
35-
let arg = params[1]
36-
`self`.constructor_arg = arg
33+
let constructor = PythonInstanceMethod { args in
34+
let `self` = args[0]
35+
`self`.constructor_arg = args[1]
3736
return Python.None
3837
}
3938

4039
// Instead of calling `print`, use this to test what would be output.
4140
var printOutput: String?
4241

43-
let displayMethod = PythonInstanceMethod { (params: [PythonObject]) in
44-
// let `self` = params[0]
45-
let arg = params[1]
46-
printOutput = String(arg)
42+
// Example of function using an alternative syntax for `args`.
43+
let displayMethod = PythonInstanceMethod { (args: [PythonObject]) in
44+
// let `self` = args[0]
45+
printOutput = String(args[1])
4746
return Python.None
4847
}
4948

50-
let classMethodOriginal = PythonInstanceMethod { (params: [PythonObject]) in
51-
// let cls = params[0]
52-
let arg = params[1]
53-
printOutput = String(arg)
49+
let classMethodOriginal = PythonInstanceMethod { args in
50+
// let cls = args[0]
51+
printOutput = String(args[1])
5452
return Python.None
5553
}
5654

@@ -121,16 +119,17 @@ class PythonFunctionTests: XCTestCase {
121119
members: [
122120
"str_prefix": "HelloException-prefix ",
123121

124-
"__init__": PythonInstanceMethod { (params: [PythonObject]) in
125-
let `self` = params[0]
126-
let message = "hello \(params[1])"
122+
"__init__": PythonInstanceMethod { args in
123+
let `self` = args[0]
124+
let message = "hello \(args[1])"
127125
helloOutput = String(message)
128126

129127
// Conventional `super` syntax causes problems; use this instead.
130128
Python.Exception.__init__(`self`, message)
131129
return Python.None
132130
},
133131

132+
// Example of function using the `self` convention instead of `args`.
134133
"__str__": PythonInstanceMethod { (`self`: PythonObject) in
135134
return `self`.str_prefix + Python.repr(`self`)
136135
}
@@ -143,18 +142,19 @@ class PythonFunctionTests: XCTestCase {
143142
members: [
144143
"str_prefix": "HelloWorldException-prefix ",
145144

146-
"__init__": PythonInstanceMethod { (params: [PythonObject]) in
147-
let `self` = params[0]
148-
let message = "world \(params[1])"
145+
"__init__": PythonInstanceMethod { args in
146+
let `self` = args[0]
147+
let message = "world \(args[1])"
149148
helloWorldOutput = String(message)
150149

151-
`self`.int_param = params[2]
150+
`self`.int_param = args[2]
152151

153152
// Conventional `super` syntax causes problems; use this instead.
154153
HelloException.__init__(`self`, message)
155154
return Python.None
156155
},
157156

157+
// Example of function using the `self` convention instead of `args`.
158158
"custom_method": PythonInstanceMethod { (`self`: PythonObject) in
159159
return `self`.int_param
160160
}
@@ -178,7 +178,9 @@ class PythonFunctionTests: XCTestCase {
178178

179179
// Test that subclasses behave like Python exceptions
180180

181-
let testFunction = PythonFunction { (_: [PythonObject]) in
181+
// Example of function with no named parameters, which can be stated
182+
// ergonomically using an underscore. The ignored input is a [PythonObject].
183+
let testFunction = PythonFunction { _ in
182184
throw HelloWorldException("EXAMPLE ERROR MESSAGE", 2)
183185
}.pythonObject
184186

0 commit comments

Comments
 (0)