@@ -64,10 +64,10 @@ def get_user_by_email(email: str) -> Result[User, str]:
64
64
return Ok(user)
65
65
66
66
user_result = get_user_by_email(email)
67
- if isinstance (user_result, Ok): # or ` is_ok(user_result)`
67
+ if is_ok(user_result):
68
68
# type(user_result.ok_value) == User
69
69
do_something(user_result.ok_value)
70
- else : # or `elif is_err(user_result)`
70
+ else :
71
71
# type(user_result.err_value) == str
72
72
raise RuntimeError (' Could not fetch user: %s ' % user_result.err_value)
73
73
```
@@ -97,12 +97,9 @@ for a, b in values:
97
97
98
98
Not all methods
99
99
(< https://doc.rust-lang.org/std/result/enum.Result.html > ) have been
100
- implemented, only the ones that make sense in the Python context. By
101
- using ` isinstance ` to check for ` Ok ` or ` Err ` you get type safe access
102
- to the contained value when using [ MyPy] ( https://mypy.readthedocs.io/ )
103
- to typecheck your code. All of this in a package allowing easier
104
- handling of values that can be OK or not, without resorting to custom
105
- exceptions.
100
+ implemented, only the ones that make sense in the Python context.
101
+ All of this in a package allowing easier handling of values that can
102
+ be OK or not, without resorting to custom exceptions.
106
103
107
104
## API
108
105
@@ -117,26 +114,29 @@ Creating an instance:
117
114
>> > res2 = Err(' nay' )
118
115
```
119
116
120
- Checking whether a result is ` Ok ` or ` Err ` . You can either use ` is_ok `
121
- and ` is_err ` type guard ** functions** or ` isinstance ` . This way you get
122
- type safe access that can be checked with MyPy. The ` is_ok() ` or
123
- ` is_err() ` ** methods** can be used if you don't need the type safety
124
- with MyPy:
117
+ Checking whether a result is ` Ok ` or ` Err ` :
125
118
126
119
``` python
127
- >> > res = Ok(' yay' )
128
- >> > isinstance (res, Ok)
129
- True
130
- >> > is_ok(res)
131
- True
132
- >> > isinstance (res, Err)
133
- False
134
- >> > is_err(res)
135
- False
136
- >> > res.is_ok()
137
- True
138
- >> > res.is_err()
139
- False
120
+ if is_err(result):
121
+ raise RuntimeError (result.err_value)
122
+ do_something(result.ok_value)
123
+ ```
124
+ or
125
+ ``` python
126
+ if is_ok(result):
127
+ do_something(result.ok_value)
128
+ else :
129
+ raise RuntimeError (result.err_value)
130
+ ```
131
+
132
+ Alternatively, ` isinstance ` can be used (interchangeably to type guard functions
133
+ ` is_ok ` and ` is_err ` ). However, relying on ` isinstance ` may result in code that
134
+ is slightly less readable and less concise:
135
+
136
+ ``` python
137
+ if isinstance (result, Err):
138
+ raise RuntimeError (result.err_value)
139
+ do_something(result.ok_value)
140
140
```
141
141
142
142
You can also check if an object is ` Ok ` or ` Err ` by using the ` OkErr `
@@ -156,27 +156,6 @@ False
156
156
True
157
157
```
158
158
159
- The benefit of ` isinstance ` is better type checking that type guards currently
160
- do not offer,
161
-
162
- ``` python
163
- res1: Result[int , str ] = some_result()
164
- if isinstance (res1, Err):
165
- print (" Error...:" , res1.err_value) # res1 is narrowed to an Err
166
- return
167
- res1.ok()
168
-
169
- res2: Result[int , str ] = some_result()
170
- if res1.is_err():
171
- print (" Error...:" , res2.err_value) # res1 is NOT narrowed to an Err here
172
- return
173
- res1.ok()
174
- ```
175
-
176
- There is a proposed [ PEP 724 – Stricter Type Guards] ( https://peps.python.org/pep-0724/ )
177
- which may allow the ` is_ok ` and ` is_err ` type guards to work as expected in
178
- future versions of Python.
179
-
180
159
Convert a ` Result ` to the value or ` None ` :
181
160
182
161
``` python
@@ -358,7 +337,7 @@ x = third_party.do_something(...) # could raise; who knows?
358
337
safe_do_something = as_result(Exception )(third_party.do_something)
359
338
360
339
res = safe_do_something(... ) # Ok(...) or Err(...)
361
- if isinstance (res, Ok ):
340
+ if is_ok (res):
362
341
print (res.ok_value)
363
342
```
364
343
@@ -468,6 +447,24 @@ from the non-unix shell you're using on Windows.
468
447
469
448
## FAQ
470
449
450
+ - ** Why should I use the ` is_ok ` (` is_err ` ) type guard function over the ` is_ok ` (` is_err ` ) method?**
451
+
452
+ As you can see in the following example, MyPy can only narrow the type correctly
453
+ while using the type guard ** functions** :
454
+ ``` python
455
+ result: Result[int , str ]
456
+
457
+ if is_ok(result):
458
+ reveal_type(result) # "result.result.Ok[builtins.int]"
459
+ else :
460
+ reveal_type(result) # "result.result.Err[builtins.str]"
461
+
462
+ if result.is_ok():
463
+ reveal_type(result) # "Union[result.result.Ok[builtins.int], result.result.Err[builtins.str]]"
464
+ else :
465
+ reveal_type(result) # "Union[result.result.Ok[builtins.int], result.result.Err[builtins.str]]"
466
+ ```
467
+
471
468
- ** Why do I get the "Cannot infer type argument" error with MyPy?**
472
469
473
470
There is [ a bug in MyPy] ( https://github.com/python/mypy/issues/230 )
0 commit comments