<div dir="auto">We could support both options on the frontend side. It's only a tiny bit of duplication in pip.</div><div class="gmail_extra"><br><div class="gmail_quote">On Aug 25, 2017 11:50 AM, "Thomas Kluyver" <<a href="mailto:thomas@kluyver.me.uk">thomas@kluyver.me.uk</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><u></u>




<div><div>Can I gently ask everyone involved to consider whether the notimplemented/error discussion is verging into bikeshedding (<a href="http://bikeshed.org/" target="_blank">http://bikeshed.org/</a>)?<br></div>
<div><br></div>
<div>The technical arguments I have seen so far are:<br></div>
<div>- The exception can include a message<br></div>
<div>- The return value can't  'bubble up' from the internals of a hook like an exception<br></div>
<div><br></div>
<div>I don't think the discussion of semantics is going to go anywhere: they are both reasonable ways for the backend to reply "sorry, Dave, I can't do that".<br></div>
<div><br></div>
<div>On Fri, Aug 25, 2017, at 05:38 PM, xoviat wrote:<br></div>
<blockquote type="cite"><div>According to the documentation, NotImplemented isn't appropriate either, as is for binary operations only. There is no one value that's taylor made for this situation, but an exception may be more appropriate as the underlying cause is probably an error.<br></div>
<div><div><br></div>
<div><div>On Aug 25, 2017 11:11 AM, "Donald Stufft" <<a href="mailto:donald@stufft.io" target="_blank">donald@stufft.io</a>> wrote:<br></div>
<blockquote style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div><div><br></div>
<div><blockquote type="cite"><div>On Aug 24, 2017, at 10:52 AM, Nick Coghlan <<a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a>> wrote:<br></div>
<div><br></div>
<div><div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">Aye, I do, and it should be "raise NotImplementedError('Explanati<wbr>on of</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">the failed check')"</span></span><br></div>
<div><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">Rationale:</span></span><br></div>
<div><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">- Python isn't C or Go, so we indicate failures with exceptions, not</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">error codes (NotImplemented is an necessary performance hack for</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">operand coercion in tight loops, not an example to be emulated in</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">other APIs)</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">- allows the backend to provide information on what went wrong</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">- means an unhandled backend error results in a traceback pointing to</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">where the build failed, not some later point in the frontend code</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">- if a backend developer is sufficiently worried about accidentally</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">propagating NotImplementedError that they want to pretend they're not</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">writing Python any more, they can use this idiom:</span></span><br></div>
<div><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">   def public_hook_api(*args, **kwds):</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">       try:</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">           result, error_msg = _internal_hook_implementation(<wbr>*args, **kwds)</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">       except NotImplementedError as exc:</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">           raise RuntimeError("Unexpected NotImplementedError") from exc</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">       if result is NotImplemented:</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">           raise NotImplementedError(error_msg)</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">       return result</span></span><br></div>
<div><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">That provides the backend with all the same assurances against</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">accidentally letting NotImplementedError escape that a return code</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">based public API would, without frontends even needing to be aware of</span></span><br></div>
<div><span class="m_-5331935942972951519font" style="font-family:OperatorMono-Book"><span class="m_-5331935942972951519size" style="font-size:11px">the backend developer's aversion to reporting errors as exceptions.</span></span><br></div>
</div>
</blockquote></div>
<div><br></div>
<div><br></div>
<div>I’m not really a fan of using NotImplementedError instead of NotImplemented. We’re not going to implement it by showing a traceback to where the NotImplementedError happened because it’s not an error case. And really that’s the important bit here, this is not an error case (as far as the API is concerned), this is just one of the possible return values that this function can produce. <br></div>
<div><div><br></div>
<div>A front end may *choose* to make this an error case of course, but that is at a different layer than this API is operating.<br></div>
<div><br></div>
<div><div>It’s arguably not even the correct usage of NotImplementedError, since that is (and I quote from the Python docs): "In user defined base classes, abstract methods should raise this exception when they require derived classes to override the method, or while the class is being developed to indicate that the real implementation still needs to be added.”<br></div>
<div><br></div>
<div>This is not a case of some real implementation not having yet been added or some stub code getting called before it’s ready. This use case more closely resembles NotImplemented.<br></div>
<div><div style="color:rgb(0,0,0);font-family:Helvetica;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><br></div>
<div>—<br></div>
<div>Donald Stufft<br></div>
</div>
<div style="color:rgb(0,0,0);font-family:Helvetica;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><br></div>
<div><br></div>
</div>
<div><br></div>
</div>
</div>
</div>
<div><br></div>
<div>______________________________<wbr>_________________<br></div>
<div> Distutils-SIG maillist  -  <a href="mailto:Distutils-SIG@python.org" target="_blank">Distutils-SIG@python.org</a><br></div>
<div> <a href="https://mail.python.org/mailman/listinfo/distutils-sig" target="_blank">https://mail.python.org/mailma<wbr>n/listinfo/distutils-sig</a><br></div>
<div> <br></div>
</blockquote></div>
</div>
<div><u>______________________________<wbr>_________________</u><br></div>
<div>Distutils-SIG maillist  -  <a href="mailto:Distutils-SIG@python.org" target="_blank">Distutils-SIG@python.org</a><br></div>
<div><a href="https://mail.python.org/mailman/listinfo/distutils-sig" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/distutils-sig</a><br></div>
</blockquote><div><br></div>
</div>

<br>______________________________<wbr>_________________<br>
Distutils-SIG maillist  -  <a href="mailto:Distutils-SIG@python.org">Distutils-SIG@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/distutils-sig" rel="noreferrer" target="_blank">https://mail.python.org/<wbr>mailman/listinfo/distutils-sig</a><br>
<br></blockquote></div></div>