Tuesday, August 18, 2020

Python Bytes: #195 Runtime type checking for Python type hints

<p>Sponsored by us! Support our work through:</p> <ul> <li>Our <a href="https://training.talkpython.fm/"><strong>courses at Talk Python Training</strong></a></li> <li><a href="https://testandcode.com/">Test &amp; Code</a> Podcast</li> </ul> <p><strong>Michael #1:</strong> <a href="https://github.com/gorakhargosh/watchdog"><strong>watchdog</strong></a></p> <ul> <li>via Prayson Daniel</li> <li>Python API and shell utilities to monitor file system events.</li> <li>Example:</li> </ul> <pre><code> observer = Observer() observer.schedule(event_handler, path, recursive=True) observer.start() </code></pre> <ul> <li>Watchdog comes with an <em>optional</em> utility script called <code>watchmedo</code></li> <li>try <code>$ watchmedo log</code> and see what happens in that folder.</li> <li>Why Watchdog? Compared to other similar libs</li> </ul> <p><strong>Brian #2:</strong> <strong>Status code 418</strong></p> <ul> <li>Thanks Andy Howe for the suggestion</li> <li>Python 3.9 rc1 is out.</li> <li>One nice enhancement that has made it into 3.9, a fix for http library missing HTTP status code 418 “I’m a teapot”.</li> <li><a href="https://bugs.python.org/issue39507">https://bugs.python.org/issue39507</a> <ul> <li>Title: http library missing HTTP status code 418 "I'm a teapot"</li> </ul></li> <li>See also status code 418 is also supported by HTCPCP, Hyper Text Coffee Pot Control Protocol, https://ift.tt/1c1UUc2 <br /> <ul> <li>418 I'm a teapot</li> </ul></li> </ul> <pre><code>Any attempt to brew coffee with a teapot should result in the error code "418 I'm a teapot". The resulting entity body MAY be short and stout. </code></pre> <ul> <li>The only other unique HTCPCP code is 406 <ul> <li>406 Not Acceptable</li> </ul></li> </ul> <pre><code>… In HTCPCP, this response code MAY be returned if the operator of the coffee pot cannot comply with the Accept-Addition request. Unless the request was a HEAD request, the response SHOULD include an entity containing a list of available coffee additions. </code></pre> <ul> <li>This has been going on since 1998 and I'm just now hearing about it.</li> <li>A nice reference site: <a href="https://httpstatuses.com/">httpstatuses.com</a></li> <li>References <ul> <li><a href="https://en.wikipedia.org/wiki/Hyper_Text_Coffee_Pot_Control_Protocol">https://en.wikipedia.org/wiki/Hyper_Text_Coffee_Pot_Control_Protocol</a> </li> <li><a href="https://cstrobbe.github.io/WC3/TR/2008/RFC-htcpcp-in-rdf-20080401/">https://cstrobbe.github.io/WC3/TR/2008/RFC-htcpcp-in-rdf-20080401/</a> </li> <li><a href="https://cstrobbe.github.io/WC3/TR/2008/RFC-htcpcp-in-rdf-20080401/">https://cstrobbe.github.io/WC3/TR/2008/RFC-htcpcp-in-rdf-20080401/</a></li> </ul></li> </ul> <p><strong>Michael #3:</strong> <a href="https://pydantic-docs.helpmanual.io/usage/validation_decorator/"><strong>pydantic’s new Validation decorator</strong></a></p> <ul> <li>via Andy Shapiro </li> <li>Built-in type checking for any function via a decorator</li> <li>easy to add for any public methods in a package</li> <li>pydantic uses lots of cython under the hood so it should be fast....</li> <li>The validate_arguments decorator allows the arguments passed to a function to be parsed and validated using the function's annotations before the function is called. </li> <li>Under the hood this uses the same approach of model creation and initialization; it provides an extremely easy way to apply validation to your code with minimal boilerplate.</li> <li>Example:</li> </ul> <pre><code> from pydantic import validate_arguments, ValidationError @validate_arguments def repeat(s: str, count: int, *, separator: bytes = b'') -&gt; bytes: b = s.encode() return separator.join(b for _ in range(count)) a = repeat('hello', 3) print(a) #&gt; b'hellohellohello' b = repeat('x', '4', separator=' ') print(b) #&gt; b'x x x x' try: c = repeat('hello', 'wrong') except ValidationError as exc: print(exc) """ 1 validation error for Repeat count value is not a valid integer (type=type_error.integer) """ </code></pre> <p><strong>Brian #4:</strong> <a href="https://github.com/tonybaloney/python-assembly-poc"><strong>Building Python Extension Modules in Assembly</strong></a></p> <ul> <li>Anthony Shaw</li> <li>From twitter announcement: <ul> <li>“After a series of highly questionable life decisions, my Python extension written in pure assembly is now on PyPI. <a href="https://ift.tt/323okHs> it required writing an Assembly extension for distutils, I also added GitHub Actions support so its running CI/CD and testing with pytest”.</li> </ul></li> <li>A proof-of-concept to demonstrate how you can create a Python Extension in 100% assembly.</li> <li>Demonstrates: <ul> <li>How to write a Python module in pure assembly</li> <li>How to write a function in pure assembly and call it from Python with Python objects</li> <li>How to call the C API to create a PyObject and parse PyTuple (arguments) into raw pointers</li> <li>How to pass data back into Python</li> <li>How to register a module from assembly</li> <li>How to create a method definition in assembly</li> <li>How to write back to the Python stack using the dynamic module loader</li> <li>How to package a NASM/Assembly Python extension with distutils</li> </ul></li> <li>The simple proof-of-concept function takes 2 parameters,</li> </ul> <pre><code> &gt;&gt;&gt; import pymult &gt;&gt;&gt; pymult.multiply(2, 4) 8 </code></pre> <ul> <li>May need a few more test cases:</li> </ul> <pre><code> &gt;&gt;&gt; pymult.multiply(2, 3) 6 &gt;&gt;&gt; pymult.multiply(-2, -3) 6 &gt;&gt;&gt; pymult.multiply(-2, 3) 4294967290 </code></pre> <ul> <li>Also, clearly Anthony has too much time on his hands. Just saying.</li> </ul> <p><strong>Michael #5:</strong> <a href="https://github.com/salabim/easy_property"><strong>easy property</strong></a></p> <ul> <li>via Ruud van der Ham</li> <li>The easy_property module, developed by me, offers a more intuitive way to define a Python property with getter, setter, deleter, getter_setter and documenter decorators.</li> <li>Normally when you want to define a property that has a getter and a setter, you have to do something like</li> </ul> <pre><code> Class Demo: def __init__(self, val): self.a = val @property def a(self): return self._a @a.setter def a(self, val): self._a = val </code></pre> <ul> <li>IMHO, the @a.setter is a rather ugly decorator, and hard to remember. And there's no way to not define the getter.</li> <li>With the easy_property module, one can use the decorators <ul> <li>getter</li> <li>setter</li> <li>deleted</li> </ul></li> <li>as in:</li> </ul> <pre><code> Class Demo: def __init__(self, val): self.a = val @getter def a(self): return self._a @setter def a(self, val): self._a = val @deleter def a(self): print('delete') del self._a </code></pre> <ul> <li>In contrast with an ordinary property, the order of definition of getter, setter and deleter is not important. And it is even possible to define a setter only (without a getter), just in case.</li> <li>With easy_property, you can even create a <strong>combined getter/setter decorator</strong>:</li> </ul> <pre><code> Class Demo: def __init__(self, val): self.a = val @getter_setter def a(self, val=None): if val is None: return self._a self._a = val </code></pre> <ul> <li>Finally, it is possible to add a docstring to the property, with the @documenter decorator:</li> </ul> <pre><code> Class Demo: def __init__(self, val): self.a = val @getter def a(self): return self._a @documenter: def a(self): return "this is the docstring of Demo.a" </code></pre> <p>Although this might not be always a good solution, I think in many cases this will make it easier and more intuitive to define properties.</p> <p><strong>Brian #6:</strong> <a href="https://blog.testproject.io/2020/08/11/non-blocking-assertion-failures-with-pytest-check/"><strong>Non Blocking Assertion Failures with pytest-check</strong></a></p> <ul> <li>Ryan Howard wrote an article about a project of mine on the TestProject blog.</li> <li>I think it’s a first that someone else wrote an article about something I made. So that’s cool.</li> <li>Most tests do the “check” part with assert statements.</li> <li>The problem is assert stops after the first failure and you often want to check lots of stuff, and you want to see all the failures.</li> <li>Ryan has a good example with checking web pages using selenium and a simple example of wanting to check both the content of an element on the page, and the url.</li> <li>Cool use of pytest-check</li> <li>See also: <ul> <li><a href="https://pypi.org/project/pytest-check/">pytest-check</a></li> <li>This plugin started as a discussion I started online in 2015 with a blog post: <a href="https://pythontesting.net/strategy/delayed-assert/">Delayed assert / multiple failures per test</a>.</li> </ul></li> </ul> <p>Extras:</p> <p>Brian</p> <ul> <li>PSA: There are no capital letters in pytest, even if it begins a sentence.</li> </ul> <p>Michael</p> <ul> <li><a href="https://docs.pymc.io/">PyMC</a> core devs, we are currently planning <a href="https://pymc-devs.github.io/pymcon/">the first ever PyMCon</a> (pronounce "PyMC ON", because "it is oooon" ;))! This is an asynchronous-first conference for the Bayesian community, with three goals: <ul> <li>Create a space and time for community members to meet each other and interact</li> <li>Record and organize the expertise and experience around PyMC</li> <li>Help folks find ways to contribute to PyMC, authentic to themselves</li> </ul></li> <li>urlify! <a href="https://twitter.com/mkennedy/status/1292955438552506370">https://twitter.com/mkennedy/status/1292955438552506370</a> get it on github at <a href="https://github.com/mikeckennedy/urlify">https://github.com/mikeckennedy/urlify</a></li> <li>Thumbnails in the video player at talk python training</li> </ul> <p>Joke:</p> <ul> <li>XKCD git - <a href="https://xkcd.com/1597/"><strong>xkcd.com/1597</strong></a> </li> <li>“I used to do low-level programming. Then a product I bought told me, "No assembly required." Since then, I've been coding in Python.” - From Rueven Lerner, Inspired by Anthony Shaw</li> </ul>

from Planet Python
via read more

No comments:

Post a Comment

TestDriven.io: Working with Static and Media Files in Django

This article looks at how to work with static and media files in a Django project, locally and in production. from Planet Python via read...