@@ -64,10 +64,10 @@ def get_user_by_email(email: str) -> Result[User, str]:
6464 return Ok(user)
6565
6666user_result = get_user_by_email(email)
67- if isinstance (user_result, Ok): # or ` is_ok(user_result)`
67+ if is_ok(user_result):
6868 # type(user_result.ok_value) == User
6969 do_something(user_result.ok_value)
70- else : # or `elif is_err(user_result)`
70+ else :
7171 # type(user_result.err_value) == str
7272 raise RuntimeError (' Could not fetch user: %s ' % user_result.err_value)
7373```
@@ -97,12 +97,9 @@ for a, b in values:
9797
9898Not all methods
9999(< 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.
106103
107104## API
108105
@@ -117,26 +114,29 @@ Creating an instance:
117114>> > res2 = Err(' nay' )
118115```
119116
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 ` :
125118
126119``` 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)
140140```
141141
142142You can also check if an object is ` Ok ` or ` Err ` by using the ` OkErr `
@@ -156,27 +156,6 @@ False
156156True
157157```
158158
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-
180159Convert a ` Result ` to the value or ` None ` :
181160
182161``` python
@@ -358,7 +337,7 @@ x = third_party.do_something(...) # could raise; who knows?
358337safe_do_something = as_result(Exception )(third_party.do_something)
359338
360339res = safe_do_something(... ) # Ok(...) or Err(...)
361- if isinstance (res, Ok ):
340+ if is_ok (res):
362341 print (res.ok_value)
363342```
364343
@@ -468,6 +447,24 @@ from the non-unix shell you're using on Windows.
468447
469448## FAQ
470449
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+
471468- ** Why do I get the "Cannot infer type argument" error with MyPy?**
472469
473470There is [ a bug in MyPy] ( https://github.com/python/mypy/issues/230 )
0 commit comments