Python Bytes
Michael Kennedy and Brian Okken

Python Bytes is a weekly podcast hosted by Michael Kennedy and Brian Okken. The show is a short discussion on the headlines and noteworthy news in the Python, developer, and data science space.

Sponsored by us! Support our work through: Our courses at Talk Python Training Test & Code Podcast Patreon Supporters Brian #1: pip-chill - Make requirements with only the packages you need Ricardo Bánffy Like pip freeze but lists only the packages that are not dependencies of installed packages. Will be great for creating requirements.txt files that look like the ones you would write by hand. I wish it had an option to not list itself, but pip-chill | grep -v pip-chill works. What do I have installed? (foo) $ pip freeze appdirs==1.4.4 black==20.8b1 click==7.1.2 mypy-extensions==0.4.3 ... No really, what did I myself install? (foo) $ pip-chill black==20.8b1 pip-chill==1.0.0 Without versions? (foo) $ pip-chill --no-version black pip-chill What did those things install as dependencies? (foo) $ pip-chill -v --no-version black pip-chill # appdirs # Installed as dependency for black # click # Installed as dependency for black ... Michael #2: Windows update broke NumPy Sent in by Daniel Mulkey A recent Windows update broke some behavior that I think OpenBLAS (used by NumPy) relied on. There's a Developer Community thread here. I am a NumPy developer. We have been trying to track down a strange issue where after updating to windows 10 2004, suddenly code that worked no longer works. Here is the NumPy issue and here is the corresponding issue in OpenBLAS

Sponsored by us! Support our work through: Our courses at Talk Python Training Test & Code Podcast Patreon Supporters Michael #1: fastapi-chameleon (and fastapi-jinja) Chameleon via Michael, Jinja via Marc Brooks Convert a FastAPI API app to a proper web app Then just decorate the FastAPI view methods (works on sync and async methods): @router.post('/') @fastapi_chameleon.template('home/index.pt') async def home_post(request: Request): form = await request.form() vm = PersonViewModel(**form) return vm.dict() # {'first':'Michael', 'last':'Kennedy', ...} The view method should return a dict to be passed as variables/values to the template. If a fastapi.Response is returned, the template is skipped and the response along with status_code and other values is directly passed through. This is common for redirects and error responses not meant for this page template. Brian #2: Django REST API in a single file, without using DRF Adam Johnson He’s been on Test & Code a couple times, 128 & 135 Not sure if you should do this, but it is possible. Example Django app that is a REST API that gives you information about characters from Rick & Morty. Specifically, just Rick and Morty. / - redirects to /characters/ /characters/ - returns a JSON list /characters - redirects to /characters/ /characters/1 - returns JSON info about Rick /characters/2 - same, but for Morty Shows off how with Django off the shelf, can do redirects and JSON output. Shows data using dataclasses. Hardcoded here, but easy to see how you could ge

Sponsored by Techmeme Ride Home podcast: pythonbytes.fm/ride Special guest: Steve Dower - @zooba Brian #1: Making Enums (as always, arguably) more Pythonic “I hate enums” Harry Percival Hilarious look at why enums are frustrating in Python and a semi-reasonable workaround to make them usable. Problems with enums of strings: Can’t directly compare enum elements with the values Having to use .value is dumb. Can’t do random choice of enum values Can’t convert directly to a list of values If you use IntEnum instead of Enum and use integer values instead of strings, it kinda works better. Making your own StringEnum also is better, but still doesn’t allow comparison. Solution: class BRAIN(str, Enum): SMALL = 'small' MEDIUM = 'medium' GALAXY = 'galaxy' def __str__(self) -> str: return str.__str__(self) Derive from both str and Enum, and add a *__str(self)__* method. Fixes everything except random.choice(). Michael #2: Python 3.10 will be up to 10% faster 4.5 years in the making, from Yury Selivanov work picked up by Pablo Galindo, Python core developer, Python 3.10/3.11 release manager LOAD_METHOD, CALL_METHOD, and LOAD_GLOBAL improved “Lot of conversations with Victor about his PEP 509, and he sent me a link to his amazing compilation of notes about CPython performance. One optimization that he pointed out to me was LOAD/CALL_METHOD opcodes, an idea first originated in PyPy.” There is a patch that implements this optimization Based on: LOAD_ATTR stores in its cache a pointer to the type of the object it works with, its tp_version_tag, and a hint for PyDict_GetItemHint. When we have a cache hit, LOAD_ATTR becomes super fast, since it only needs to lookup key/value in type's dict by a known offset (the real code is a bit more complex, to handle a

Sponsored by us! Support our work through: Our courses at Talk Python Training Test & Code Podcast Patreon Supporters Michael #1: Awkward arrays via Simon Thor Awkward Array is a library for nested, variable-sized data, including arbitrary-length lists, records, mixed types, and missing data, using NumPy-like idioms. This makes it better than numpy at handling data where e.g. the rows in a 2D array have different lengths. It can even be used together with numba to jit-compile the code to make it even faster. Arrays are dynamically typed, but operations on them are compiled and fast. Their behavior coincides with NumPy when array dimensions are regular and generalizes when they’re not. Recently rewritten in C++ for the 1.0 release and can even be used from C++ as well as Python. Careful on installation: pip install awkward1 ← Notice the 1. Brian #2: Ordered dict surprises Ned Batchelder “Since Python 3.6, regular dictionaries retain their insertion order: when you iterate over a dict, you get the items in the same order they were added to the dict. Before 3.6, dicts were unordered: the iteration order was seemingly random.” The surprises: You can’t get the first item, like d[0], since that’s just the value matching key 0, if key 0 exists. (I’m not actually surprised by this.) equality and order (this I am surprised by) Python 3.6+ dicts ignores order when testing for equality {"a": 1, "b": 2} == {"b": 2, "a": 1} OrderdDicts care about order when testing for equality OrderedDict([("a", 1), ("b", 2)]) != OrderedDict([("b", 2), ("a", 1)]) Michael #3: jupyter lab autocomplete and more via Anders Källmar Examples show Python code, but

Sponsored by Techmeme Ride Home podcast: pythonbytes.fm/ride Special guests Carlton Gibson William Vincent Brian #1: nbQA : Quality Assurance for Jupyter Notebooks Sent in by listener and Patreon supporter (woohoo!!!) Marco Gorelli. We’ve now talked about running black on Jupyter notebooks in the past (at least 2) shows? Marco’s recommendation is nbQA nbQA lets you run all this on notebooks: black isort mypy flake8 pylint pyupgrade to upgrade syntax doctest to check examples Run as a pre-commit hook Configure in pyproject.toml Also (from Marco) better than standalone black due to: can run on a directory, not just one file at a time keeps diffs minimal and easier to read then black preserves trailing semicolons, as they are used to suppress output in notebooks supports most standard magic commands And the nbQA project is tested with …. drum roll …. pytest (of course) Michael #2: The PSF yearly survey is out, go take it now! This is the fourth iteration of the official Python Developers Survey. The results of this survey serve as a major source of knowledge about the current state of the Python community Takes about 10 minutes They will randomly choose 100 winners (from those who complete the survey in its entirety), who will each receive an amazing Python Surprise Gift Pack. Analysis is really well done, see the 2019 results. Will #3: From Prototype to Production in Django Django defaults to local/prototype settings initially when run startproject command. settings.py file contains global configs for a project. What needs to change for production? DEBUG set to False SECRET_KEY

Sponsored by DataDog: pythonbytes.fm/datadog Michael #1: Introducing DigitalOcean App Platform Reimagining PaaS to make it simpler for you to build, deploy, and scale apps. Many of our customers have come to DigitalOcean after their PaaS became too expensive, or after hitting various limitations. You can build, deploy, and scale apps and static sites by simply pointing to your GitHub repository. Built on DigitalOcean Kubernetes, the App Platform brings the power, scale, and flexibility of Kubernetes without exposing you to any of its complexity. App Platform is built on open standards providing more visibility into the underlying infrastructure than in a typical closed PaaS environment. You can also enable ‘Autodeploy on Push,’ which automatically re-deploys the app each time you push to the branch containing the source code. To efficiently handle traffic spikes (planned or unplanned), the App Platform lets you scale apps horizontally (i.e., add more instances that serve your app) and vertically (beef up the instances with more CPU and memory resources). (with zero downtime) What can you build with the App Platform? Web apps, Static sites, APIs, Background workers Brian #2: Announcing Playwright for Python playwright-python playwrignt-pytest it’s a Microsoft thing the pitch: “With the Playwright API, you can author end-to-end tests that run on all modern web browsers. Playwright delivers automation that is faster, more reliable and more capable than existing testing tools.” timeout-free automation automatically waits for the UI to be ready Intended to stay modern emulation of mobile viewports geolocation web permissions can automate scenarios across multiple pages

Sponsored by DataDog: pythonbytes.fm/datadog Brian #1: New in Python 3.9 scheduled to be released Oct 5 Python 3.9.0rc2 released Sept 17 New features (highlights) Dictionary merge (|) and update (|=) operators. String str.removeprefix(prefix) and str.removesuffix(suffix). This have also been added to bytes, bytearray, and collections.UserString. In type annotations you can now use built-in collection types such as list and dict as generic types instead of importing the corresponding capitalized types (e.g. List or Dict) from typing. New PEG parser Any valid expression can be used as a decorator. see PEP 614. Haven’t quite wrapped my head around the possibilities yet. [zoneinfo](https://docs.python.org/3.9/library/zoneinfo.html#module-zoneinfo) module brings support for the IANA time zone database to the standard library. Lots of other great stuff too, please check out the changelog and give 3.9 a spin Michael #2: jupyter-black via Mary Hoang I recently tuned into the auto racing episode on Talk Python and liked Kane’s pypi suggestion of blackcellmagic. There are a couple of other pypi packages that envelop the idea of black formatting Jupyter Notebooks and I recently started using a new pypi tool called jupyterblack! This tool lets you black format Notebooks like you would Python files, only you call jblack instead of black. Then the extension provides a toolbar button a keyboard shortcut for reformatting the current code-cell (default: Ctrl-B) a keyboard shortcut for reformatting whole code-cells (default: Ctrl-Shift-B) It will also point basic syntax errors. Brian #3:

Sponsored by us! Support our work through: Our courses at Talk Python Training Python Testing with pytest Michael #1: Under the hood of calling C/C++ from Python Basics first: what C compiles to? Each operating system features some exact format to work with. Among the most popular ones are: ELF (Executable and Linkable Format), used by most of Linux distros PE (Portable Executable), used by Windows Mach-O (Mach object), used by Apple products We also need to make our library visible to our programs. An easiest way to do so is to copy it to /usr/lib/ - default system-wide directory for libraries. Maybe put it in system / system32 on Windows? ctypes: the simplest way With the shared object compiled, we are ready to call it. Consider ctypes to be the easiest way to execute some C code, because: it’s included in the standard library, writing a wrapper uses plain Python. lib = ctypes.CDLL(f'/usr/lib/libdullmath.so') lib.get_pi For C: You need to be clear about the calling convention (extern “C” for example) Now we can load libraries at runtime, but we are still missing the way to generate correct caller ABI to use external C libraries. Do deal with it, libffi was created. Libffi is a portable C library, designed for implementing FFI tools, hence the name. Given structs and functions definitions, it calculates an ABI of function calls at runtime. A mature approach to improve in this area is to allow libraries to introduce themselves. We can oblige every library to define a function named entry_point, which will return metadata about functions it contains. Final destination: C/C++ extensions and Python/C API CPython provides a similar API for implementing C-based

Sponsored by us! Support our work through: Our courses at Talk Python Training Python Testing with pytest Brian #1: How to be helpful online Ned Batchelder When answering questions. Lots of great advice. We’ll focus on just a few here. Answer the question first. There may be other problems with their code that they are not asking about that you want to point out. But keep that for after you’ve helped them and built up trust. No third rails. “It should be OK for someone to ask for help with a program using sockets, and not have to defend using sockets, especially if the specific question has nothing to do with sockets.” Same for pickle, threads, globals, singletons, etc. Don’t let your strong opinions derail the conversation. The goal is to help people. Strong reactions can make the asker feel attacked. No dog-piling. Meet their level. “Try to determine what they know, and give them a reasonable next step, not the ultimate solution. A suboptimal solution they understand is better than a gold standard they can’t make use of.” Say yes. Avoid absolutes. Step back. Take some blame. Use more words. “IRC and other online mediums encourage quick short responses, which are exactly the kinds of responses that will be easy to misinterpret. Try to use more words, especially encouraging optimistic words.” Understand your motivations. Humility. Make connections. Finally: It’s hard. All of Ned’s advice is great. Good meditations for when you read a question and your mouth drops open and your eyes stare in shock. Michael #2: blackcellmagic IPython magic command to format python code in cell using black. Has a great animated gif ;) Just do: %load_ext blackcellmagic Then in any cell %%black and magic! Accepts “argument

Sponsored by us! Support our work through: Our courses at Talk Python Training Python Testing with pytest Michael #1: micropython updated via Matt Trentini v1.13 is packed with features and bugfixes including solid asyncio support and tasty BLE improvements. Heck, we've even got the walrus operator. a new implementation of the uasyncio module which aims to be more compatible with CPython's asyncio module. The main change is to use a Task object for each coroutine, allowing more flexibility to queue tasks in various places, eg the main run loop, tasks waiting on events, locks or other tasks. It no longer requires pre-allocating a fixed queue size for the main run loop. Most code in this repository is now auto-formatted using uncrustify for C code and Black for Python code. BlueKitchen BTstack bindings have been added for the ubluetooth module, as an optional alternative to the NimBLE stack. The unix port can now be built with BLE support using these bindings Other Bluetooth additions include: new events for service/characteristic/ descriptor discovery complete; new events for read done and indicate acknowledgement; and support for active scanning in BLE.gap_scan(). PEP 526 has been (Walrus) There has been an important bug fix when importing ARM machine code from an .mpy file: the system now correctly tracks the executable memory allocated to the machine code so this memory is not reclaimed by the garbage collector. For testing, a multi-instance test runner has been added (see tests/run-multitests.py) which allows running a synchronised test across two or more MicroPython targets. There are breaking changes First release since Dec 19, 2019 Brian #2: respx: A utility for mocking out the Python HTTPX library When using requests, you can mock it with responses. When using

Sponsored by us! Support our work through: Our courses at Talk Python Training Test & Code Podcast Special guest: Anna-Lena Popkes Brian #1: Easily create Python scripts using argparse Back in the day, when I was writing most of my utility scripts in bash, I’d keep around an example.bash file with different types of arguments and flags and control structures, etc to use as a template for new scripts. Python has the same problem, or worse, if you use the built in argparse instead of something like click or typer. However, there are many times where you don’t want to have any external dependencies on a script, so built in argparse it is. But I definitely relate to this tweet: “Every time I write a python script, I have to go back to an old script of mine to remember how to set up argparse. For some reason it just does not stick in my mind AT ALL.” - Joshua Schraiber Well, then steps in Ken Youens-Clark with a little utility called new.py. It’s not pip install-able, so you gotta clone it or fork it or copy it or whatever. But it’s cool and fairly simple to hack on yourself, and you’re going to want to make it your own anyway, so that’s fine. You do something like python new.py foo.py and it creates an example starter foo.py for you with: a positional argument a string argument an integer argument a file argument (which also checks to make sure the file is readable) a boolean flag Modify, copy, paste, delete, whatever you want to it now to make it the script you need super fast. Also, add a -t flag to it, like this python new.py -t foo.py, and it generates a test stub to test your new script. Michael #2: DBeaver Database UI Tool via exhuma Remember I mentioned BeeKeeper Free multi-platform datab

Sponsored by us! Support our work through: Our courses at Talk Python Training Test & Code Podcast Michael #1: Structured concurrency in Python with AnyIO AnyIO is a Python library providing structured concurrency primitives on top of asyncio. Structured concurrency is a programming paradigm aimed at improving the clarity, quality, and development time of a computer program by using a structured approach to concurrent programming. The core concept is the encapsulation of concurrent threads of execution (here encompassing kernel and userland threads and processes) by way of control flow constructs that have clear entry and exit points and that ensure all spawned threads have completed before exit. — Wikipedia The best overview is Notes on structured concurrency by Nathaniel Smith (or his video if you prefer). Python has three well-known concurrency libraries built around the async/await syntax: asyncio, Curio, and Trio. (WHERE IS unsync?!?! 🙂 ) Since it's the default, the overwhelming majority of async applications and libraries are written with asyncio. The second and third are attempts to improve on asyncio, by David Beazley and Nathaniel Smith respectively The AnyIO library by Alex Grönholm describes itself as follows: > an asynchronous compatibility API that allows applications and libraries written against it to run unmodified on asyncio, curio and trio. Example: import anyio async def task(n): await

Sponsored by Datadog: pythonbytes.fm/datadog Brian #1: Surviving Django (if you care about databases) Daniele Varazzo Hard to summarize, but this is an interesting perspective on getting to know your database better and using database migrations and database schemas, etc. instead of relying on Django’s seemingly agnostic view of databases. Following the article is a nice civilized discussion in the comments between the author, Paolo Melchiorre, Andrew Godwin, and others. Interesting comment by Andrew: “I agree that at some point in a project/company's life, if it's big enough, SQL migrations are the way to go. … Migrations in the out-of-the-box state are mostly there to supplement rapid prototyping, and then like a lot of Django, can be removed/ignored progressively if and when you outgrow the single set of design constraints we had to choose for them.” Michael #2: Python Numbers and the Flyweight design pattern Working on allocation and other memory internals from my upcoming Python Memory Management and Tips course Flyweight design pattern via Wikipedia Python numbers are expensive ( >= 28 bytes each) Python does not allocate more than one int in the range [-5, 256] Example code: app_flyweight.py Also working on a Python Design Patterns course and Flyweight is back there too. Brian #3: What Are Python Wheels and Why Should You Care? Brad Solomon Second half is about creating wheels I’m more interested in the first half, a discussion of wheels from the users perspective. Most package authors now all this stuff, or most of it. But this is a nice quick intro for the rest of the Python ecosystem as package users. If you pip install something that isn’t a wheel, it’s probably a tarball. pip downloads the tar.gz file

Sponsored by us! Support our work through: Our courses at Talk Python Training Test & Code Podcast Michael #1: watchdog via Prayson Daniel Python API and shell utilities to monitor file system events. Example: observer = Observer() observer.schedule(event_handler, path, recursive=True) observer.start() Watchdog comes with an optional utility script called watchmedo try $ watchmedo log and see what happens in that folder. Why Watchdog? Compared to other similar libs Brian #2: Status code 418 Thanks Andy Howe for the suggestion Python 3.9 rc1 is out. One nice enhancement that has made it into 3.9, a fix for http library missing HTTP status code 418 “I’m a teapot”. https://bugs.python.org/issue39507 Title: http library missing HTTP status code 418 "I'm a teapot" See also status code 418 is also supported by HTCPCP, Hyper Text Coffee Pot Control Protocol, https://tools.ietf.org/html/rfc2324 418 I'm a teapot 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. The only other unique HTCPCP code is 406 406 Not Acceptable … 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. This has been going on since 1998 and I'm just now hearing about it. A nice reference site: httpstatuses.com References https://en.wikipedia.org/wiki/Hyper_Text_Coffee_Pot_Control_Protocol https:

Sponsored by us! Support our work through: Our courses at Talk Python Training Test & Code Podcast Brian #1: An introduction to mutation testing in Python Moshe Zadka This article uses mutmut, but there are other mutation testing packages. The example shows 3 methods, and one test case that actually hits 100% code coverage. The mutmut is used and finds 16 surviving mutants. “Mutation testing algorithmically modifies source code and checks if any "mutants" survived each test. Any mutant that survives the unit test is a problem: it means that a modification to the code, likely introducing a bug, was not caught by the standard test suite.” “For each mutation test, mutmut modified portions of your source code that simulates potential bugs. An example of a modification is changing a > comparison to >= to see what happens. If there is no unit test for this boundary condition, this mutation will "survive": this is a potential bug that none of the tests will detect.” Cool example of how to check mission critical parts of your code and the tests around them above and beyond code coverage. BTW, mutmut is also used codechalleng.es in the challenges asking users to write the tests. Michael #2: asynq From Quora, a little old but still interesting and active A library for asynchronous programming in Python with a focus on batching requests to external services. Also provides seamless interoperability with synchronous code, support for asynchronous context managers, and tools to make writing and testing asynchronous code easier. Developed at Quora and is a core component of Quora's architecture. The most important use case for asynq is batching. asynq's asynchronous functions are implemented as Python generator functions. Every time an asynchronous functions yields one or more Futures, it cedes control the asynq scheduler, Brian #3:

Sponsored by us! Support our work through: Our courses at Talk Python Training Brian’s pytest book Brian #1: Start using pip install --use-feature=2020-resolver if you aren’t already Mathew Feickert You may see something interesting when you run pip This is not a problem. Do not adjust your sets. But, you should be aware of it. Especially if you install from requirements generated with pip freeze, you’ll want to use --use-feature=2020-resolver everywhere: $ python -m pip install --use-feature=2020-resolver -r requirements_original.txt $ python -m pip freeze > requirements_lock.txt $ python -m pip install --use-feature=2020-resolver -r requirements_lock.txt Otherwise, you may run into issues see Example of --use-feature=2020-resolver breaking a pip freeze requirements.txt and Changes to the pip dependency resolver in 20.2 (2020) Michael #2: Profiling Python import statements Conversation with Brandon Braner lead to import-profiler A basic python import profiler to find bottlenecks in import times. Not often a problem, imports can be an issue for applications that need to start quickly, such as CLI tools. Goal of import profiler is to help find the bottlenecks when importing a given package. Example from import_profiler import profile_import with profile_import() as context: # Anything expensive in here import requests # Print cumulative and inline times. The number of + in the 3rd column # indicates the depth of the stack. context.print_info() Output: umtime (ms) intime (ms) name 83 0.5 requ

Sponsored by us! Support our work through: Our courses at Talk Python Training Test & Code Podcast Brian #1: Building a self-updating profile README for GitHub Simon Willison, co-createor of Django “GitHub quietly released a new feature at some point in the past few days: profile READMEs. Create a repository with the same name as your GitHub account (in my case that’s github.com/simonw/simonw), add a README.md to it and GitHub will render the contents at the top of your personal profile page—for me that’s github.com/simonw” Simon takes it one further, and uses GitHub actions to keep the README up to date. Uses Python to: Grab recent releases from certain GH repos using GH GraphQL API Links to blog entries using feedparser Retrieve latest links using SQL queries Michael #2: Handcalcs Created by Connor Ferster In design engineering, you need to do lots of calculations and have those calculation sheets be kept as legal records as part of the project's design history. If they are not being done by hand, then often Excel is used but formatting calculations in Excel is time consuming and a maintenance nightmare. However, doing calculations in Jupyter is not any better even if you fill it up with print() statements and print to PDF: it just looks like a bunch of code output. Even proprietary software like MathCAD cannot render math as good as a hand calculation because it does not show the numerical substitution step. No software does Why handcalcs exists: Type the formula once into a Jupyter cell Have the calculation be rendered out as beautifully as though you had written it by hand. Write your notebooks once, and use them for calculation again and again; the formula you write is the same as the representation of the formula.

Special guest: Ines Montani Michael #1: VS Code Device Simulator Want to experiment with MicroPython? Teaching a course with little IoT devices? Circuit Playground Express BBC micro:bit Adafruit CLUE with a screen Get a free VS code extension that adds a high fidelity simulator Easily create the starter code (main.py) Interact with all the sensors (buttons, motion sensors, acceleration detection, device shake detection, etc.) Deploy and debug on a real device when ready Had the team over on Talk Python. Brian #2: pytest 6.0.0rc1 New features You can put configuration in pyproject.toml Inline type annotations. Most user facing API and internal code. New flags - --no-header - --no-summary - --strict-config : error on unknown config key - --code-highlight : turn on/off code highlighting in terminal Recursive comparison for dataclass and attrs Tons of fixes Improved documentation There’s a list of breaking changes and deprications. But really, nothing in the list seems like a big deal to me. Plugin authors, including myself, should go test this. Already found one problem. pytest-check: stop on fail works fine, but failing tests marked with xfail show up as xpass. Gonna have to look into that. And might have to recruit Anthony to help out again. To try it: pip install pytest==6.0.0rc1 I’m currently running through the pytest book to make sure it all still works with pytest 6. So far, so good. The one hiccup I’ve found so far, TinyDB had a breaking change with 4.0, so you need to pip install tinydb==3.15.2 to get the tasks project to run right. I should have pinned that in the origi

Our courses at Talk Python Training Brian’s pytest book Brian #1: Python async frameworks - Beyond developer tribalism Tom Christie Written on encode.io. encode also encompasses several awesome projects: Django REST framework HTTPX async projects: starlette, uvicorn, orm, databases, broadcaster Partly a reaction to “Async Python is not faster” Tom would like to see the Python community move beyond polarizing discussions. “… we could probably benefit from a bit more recognition of where there is shared ground. And in areas where there’s less clarity, to be able to have constructive conversations around the relative merits in differing approaches.” Some points about performance You probably shouldn’t care about performance when you start a project. Success of a project is more related to development experience and strength of the surrounding ecosystem. We should care enough about performance that people don’t dismiss Python due to performance issues. Be careful about the word “performance”. Single async function calls are slightly slower. But as concurrency increases on I/O bound systems, async Python will remain more efficient at interleaving the concurrent tasks. There are no good benchmarks. There are valid unknowns. Should we have hybrid frameworks or have new async frameworks? There are different approaches asyncio, trio, twisted, curio In general, Python async discussions continue to move toward positive discourse, even with this divisive topic and strong opinions. “In short this is a call for the benefits of adopting a genuinely collaborative mindset rather than a competitive mindset. We may all working on different little corners of the landscape, but we’re can still all appreciate that in the bigger view, we’re all working together.” Michael #2: comm

Sponsored by us! Support our work through: Our courses at Talk Python Training Brian’s pytest book Brian #1: Improving Python exception chaining with raise-from Ram Rachum Python3 has a change called PEP 3134: Exception Chaining and Embedded Tracebacks It should be used more than it is. If an exception is raised from an except clause, it could be because: something unexpected happened “An exception was raised, and we decided to replace it with a different exception that will make more sense to whoever called this code. Maybe the new exception will make more sense because we’re giving a more helpful error message. Or maybe we’re using an exception class that’s more relevant to the problem domain, and whoever’s calling our code could wrap the call with an except clause that’s tailored for this failure mode.” If it’s the second case, you should change your code to something like this: try: [HTML_REMOVED] except ExpectedExceptionType as e: raise BetterException('Better explanation') from e It’s the from e that does the magic. And now instead of getting During handling of the above exception, another exception occurred: You get: The above exception was the direct cause of the following exception: “That’s how you know you have a case of a friendly wrapping of an exception.” Michael #2: Create and publish interactive reports in Python via Tim Pogue Datapane is an open source framework which makes it easy to turn scripts and notebooks into interactive reports. Free for individuals, paid(?) for teams Build reports in Python and deploy scripts and notebooks as self-service reporting tools. Analyze data in your own tools: Write code and analyze data in your own editor or environment, whether its Jupyter, Colab, or Airflow. Build