<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: chukwunwike obodo</title>
    <description>The latest articles on DEV Community by chukwunwike obodo (@chuks_archy).</description>
    <link>https://dev.to/chuks_archy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3905014%2F2e3ec932-2c34-417a-8903-74f868e73a59.png</url>
      <title>DEV Community: chukwunwike obodo</title>
      <link>https://dev.to/chuks_archy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chuks_archy"/>
    <language>en</language>
    <item>
      <title>Stop Letting Python Functions Lie to You: Introducing explicit-result</title>
      <dc:creator>chukwunwike obodo</dc:creator>
      <pubDate>Wed, 29 Apr 2026 21:26:07 +0000</pubDate>
      <link>https://dev.to/chuks_archy/stop-letting-python-functions-lie-to-you-introducing-explicit-result-4gg5</link>
      <guid>https://dev.to/chuks_archy/stop-letting-python-functions-lie-to-you-introducing-explicit-result-4gg5</guid>
      <description>&lt;p&gt;Python is beautiful, readable, and highly expressive. But its built-in error handling mechanism, exceptions, has a fundamental flaw: &lt;strong&gt;Exceptions are invisible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Take a look at this standard Python function signature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;What does this signature tell you? It promises to return a &lt;code&gt;User&lt;/code&gt;. But does it? What happens if the database connection drops? What if &lt;code&gt;user_id&lt;/code&gt; doesn't exist? What if there's a permission issue?&lt;/p&gt;

&lt;p&gt;You can’t know without digging into the implementation, hoping the docstrings are accurate, or waiting for a surprise stack trace in production. The type system provides zero guarantees about what can fail. &lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;&lt;code&gt;explicit-result&lt;/code&gt;&lt;/strong&gt; comes in.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Philosophy of &lt;code&gt;explicit-result&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;explicit-result&lt;/code&gt; is a zero-dependency, fully-typed Python library that brings &lt;code&gt;Result&lt;/code&gt; and &lt;code&gt;Option&lt;/code&gt; primitives to your Python code. It is designed around three core ideas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Errors should be part of the contract.&lt;/strong&gt; A function that can fail should declare its possible errors right in its return type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The API should feel native to Python.&lt;/strong&gt; This isn’t a clunky port of Rust or Haskell. It’s built to feel perfectly natural in idiomatic Python.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adopt incrementally.&lt;/strong&gt; You don’t need to rewrite your entire codebase to benefit. Wrap existing code with simple decorators and refactor at your own pace.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Result: Bringing Errors to Light
&lt;/h2&gt;

&lt;p&gt;With &lt;code&gt;explicit-result&lt;/code&gt;, your function signatures stop hiding the truth. Instead of hoping a caller catches an implicit &lt;code&gt;ValueError&lt;/code&gt;, you declare it:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;explicit_result&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;division by zero&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The signature &lt;code&gt;Result[float, str]&lt;/code&gt; is an ironclad contract: &lt;em&gt;"I will give you either a float or a string error. I will not surprise you."&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Safely Handling Results
&lt;/h3&gt;

&lt;p&gt;Once you get a &lt;code&gt;Result&lt;/code&gt;, you have powerful, explicit ways to handle it. You can explicitly unpack values safely:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Unpack with a fallback
&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Unpack explicitly, providing context if it panics
&lt;/span&gt;&lt;span class="n"&gt;validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Division must never fail in this critical path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;On Python 3.10+, &lt;code&gt;explicit-result&lt;/code&gt; works flawlessly with &lt;strong&gt;Structural Pattern Matching&lt;/strong&gt;, allowing you to write beautiful, exhaustive handlers:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Success: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Bridging the Gap: The &lt;code&gt;@safe&lt;/code&gt; Decorator
&lt;/h2&gt;

&lt;p&gt;What if you're using third-party code that heavily relies on implicit exceptions? &lt;code&gt;explicit-result&lt;/code&gt; makes it trivial to convert exception-throwing code into predictable &lt;code&gt;Result&lt;/code&gt; boundaries.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;explicit_result&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;safe&lt;/span&gt;

&lt;span class="nd"&gt;@safe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;catch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;parse_float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.14&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# Ok(3.14)
&lt;/span&gt;&lt;span class="nf"&gt;parse_float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;abc&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# Err(ValueError("could not convert string to float..."))
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Your low-level exceptions instantly become trackable, manageable objects that map directly into your type checker.&lt;/p&gt;
&lt;h2&gt;
  
  
  Chaining and Do-Notation: Kiss Try/Except Hell Goodbye
&lt;/h2&gt;

&lt;p&gt;The true power of &lt;code&gt;Result&lt;/code&gt; shines when operations are chained. You can cleanly sequence logic without ever writing nested &lt;code&gt;try/except&lt;/code&gt; blocks.&lt;/p&gt;

&lt;p&gt;If you don't want to use method chaining, &lt;code&gt;explicit-result&lt;/code&gt; provides &lt;strong&gt;pure Python Do-notation&lt;/strong&gt; using generators, which fully embraces python controls like &lt;code&gt;if/else&lt;/code&gt; and loops!&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;explicit_result&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;do&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;

&lt;span class="nd"&gt;@do&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user_profile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;fetch_user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;            &lt;span class="c1"&gt;# Returns dict if Ok, short-circuits if Err
&lt;/span&gt;    &lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nf"&gt;fetch_profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;           &lt;span class="c1"&gt;# Automatically wrapped in Ok
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;Option&lt;/code&gt;: The End of the &lt;code&gt;None&lt;/code&gt; Mystery
&lt;/h2&gt;

&lt;p&gt;Returning &lt;code&gt;None&lt;/code&gt; when something fails is tempting, but &lt;code&gt;None&lt;/code&gt; is completely silent about &lt;em&gt;why&lt;/em&gt; something didn't work. Furthermore, sometimes &lt;code&gt;None&lt;/code&gt; is an entirely valid value!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Option[T]&lt;/code&gt; solves this by giving you explicit &lt;code&gt;Some(value)&lt;/code&gt; and &lt;code&gt;Nothing&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;explicit_result&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Nothing&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Archy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Chuks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;Nothing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Never get lost in ambiguous NullType errors again. When a function returns &lt;code&gt;Option[T]&lt;/code&gt;, you know the absence of a value is a completely valid business case, not a crash.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why You Should Try It Today
&lt;/h2&gt;

&lt;p&gt;If you’re building production systems in Python, confidence and predictability matter. &lt;code&gt;explicit-result&lt;/code&gt; removes the guesswork from error handling and forces developers to deal with edge cases explicitly, before the bug ships. &lt;/p&gt;

&lt;p&gt;It is completely lightweight, installs instantly with &lt;code&gt;pip install explicit-result&lt;/code&gt;, has zero external dependencies, and integrates beautifully with linters like Pyright and Mypy. &lt;/p&gt;

&lt;p&gt;Stop letting your functions lie. Make your error paths as robust as your happy paths.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/chukwunwike/explicit-result" rel="noopener noreferrer"&gt;&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;a href="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;&lt;/a&gt;
      &lt;a href="https://github.com/chukwunwike" rel="noopener noreferrer"&gt;
        chukwunwike
      &lt;/a&gt; / &lt;a href="https://github.com/chukwunwike/explicit-result" rel="noopener noreferrer"&gt;
        explicit-result
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Result and Option types for Python  zero dependencies, fully typed.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;explicit-result&lt;/h1&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Result and Option types for Python — zero dependencies, fully typed.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://www.python.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0bc512e1bdf1845306c37fdcd12588f541a0931ad3ffa8a40f329a534f2c886d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e392532422d626c75652e737667" alt="Python"&gt;&lt;/a&gt;
&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://peps.python.org/pep-0561/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2bd06ede87bd6ebc5ed33bf022212529dbbee9ccb4b87348a372552384ed6e4e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74797065642d7965732d627269676874677265656e2e737667" alt="Typed"&gt;&lt;/a&gt;
&lt;a href=""&gt;&lt;img src="https://camo.githubusercontent.com/8f55ef5aea13011a3bf62bc50776a147c57b71f1b11cb50252d61b48e5c88d7d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d7a65726f2d627269676874677265656e2e737667" alt="Zero Dependencies"&gt;&lt;/a&gt;
&lt;a href="https://chukwunwike.github.io/explicit-result/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1ae2d7bd56019403a733e99117a6abffb8a71c42db44c2cc5cdc1fbeda08cb1f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d47697448756225323050616765732d626c75652e737667" alt="Docs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;&lt;a href="https://chukwunwike.github.io/explicit-result/" rel="nofollow noopener noreferrer"&gt;Read the Full Documentation here&lt;/a&gt;&lt;/h3&gt;
&lt;/div&gt;




&lt;p&gt;Python functions lie. A function typed as &lt;code&gt;-&amp;gt; int&lt;/code&gt; might return an integer, raise a &lt;code&gt;ValueError&lt;/code&gt;, raise a &lt;code&gt;ConnectionError&lt;/code&gt;, or return &lt;code&gt;None&lt;/code&gt; depending on conditions the caller cannot see. The type system gives you no warning. You discover the truth at runtime, usually in production.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;explicit-result&lt;/code&gt; fixes this by making errors &lt;strong&gt;visible in the function signature itself&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="highlight highlight-source-python notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s1"&gt;explicit_result&lt;/span&gt; &lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-v"&gt;Ok&lt;/span&gt;, &lt;span class="pl-v"&gt;Err&lt;/span&gt;, &lt;span class="pl-v"&gt;Result&lt;/span&gt;

&lt;span class="pl-k"&gt;def&lt;/span&gt; &lt;span class="pl-en"&gt;divide&lt;/span&gt;(&lt;span class="pl-s1"&gt;a&lt;/span&gt;: &lt;span class="pl-smi"&gt;float&lt;/span&gt;, &lt;span class="pl-s1"&gt;b&lt;/span&gt;: &lt;span class="pl-smi"&gt;float&lt;/span&gt;) &lt;span class="pl-c1"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="pl-v"&gt;Result&lt;/span&gt;[&lt;span class="pl-smi"&gt;float&lt;/span&gt;, &lt;span class="pl-smi"&gt;str&lt;/span&gt;]:
    &lt;span class="pl-k"&gt;if&lt;/span&gt; &lt;span class="pl-s1"&gt;b&lt;/span&gt; &lt;span class="pl-c1"&gt;==&lt;/span&gt; &lt;span class="pl-c1"&gt;0&lt;/span&gt;:
        &lt;span class="pl-k"&gt;return&lt;/span&gt; &lt;span class="pl-en"&gt;Err&lt;/span&gt;(&lt;span class="pl-s"&gt;"division by zero"&lt;/span&gt;)
    &lt;span class="pl-k"&gt;return&lt;/span&gt; &lt;span class="pl-en"&gt;Ok&lt;/span&gt;(&lt;span class="pl-s1"&gt;a&lt;/span&gt; &lt;span class="pl-c1"&gt;/&lt;/span&gt; &lt;span class="pl-s1"&gt;b&lt;/span&gt;)

&lt;span class="pl-s1"&gt;result&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-en"&gt;divide&lt;/span&gt;(&lt;span class="pl-c1"&gt;10&lt;/span&gt;, &lt;span class="pl-c1"&gt;2&lt;/span&gt;)   &lt;span class="pl-c"&gt;# Ok(5.0)&lt;/span&gt;
&lt;span class="pl-s1"&gt;result&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-en"&gt;divide&lt;/span&gt;(&lt;span class="pl-c1"&gt;10&lt;/span&gt;, &lt;span class="pl-c1"&gt;0&lt;/span&gt;)   &lt;span class="pl-c"&gt;# Err("division by zero")&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The signature &lt;code&gt;Result[float, str]&lt;/code&gt; is a…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/chukwunwike/explicit-result" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
