
Just for fun, I decided to go through some recently written code by some genuine Python experts (without their permission...) to see what changes would be worth taking. So I went to the sources of our github bots. Honestly, I only found three places that were worth changing (though I'm now kind of leaning towards ?[] eating LookupError, since that seems much more useful when traversing the result of json.loads()...). I'm also not holding up the third one as the strongest example :)
From https://github.com/python/miss-islington/blob/master/miss_islington/status_c...:
async def check_status(event, gh, *args, **kwargs): if ( event.data["commit"].get("committer") and event.data["commit"]["committer"]["login"] == "miss-islington" ): sha = event.data["sha"] await check_ci_status_and_approval(gh, sha, leave_comment=True) After: async def check_status(event, gh, *args, **kwargs): if event.data["commit"].get("committer")?["login"] == "miss-islington": sha = event.data["sha"] await check_ci_status_and_approval(gh, sha, leave_comment=True)
From https://github.com/python/bedevere/blob/master/bedevere/__main__.py:
try: print('GH requests remaining:', gh.rate_limit.remaining) except AttributeError: pass Assuming you want to continue hiding the message when no value is available: if (remaining := gh.rate_limit?.remaining) is not None: print('GH requests remaining:', remaining) Assuming you want the message printed anyway: print(f'GH requests remaining: {gh.rate_limit?.remaining ?? "N/A"}')
From https://github.com/python/bedevere/blob/master/bedevere/news.py (this is the one I'm including for completeness, not because it's the most compelling example I've ever seen):
async def check_news(gh, pull_request, filenames=None): if not filenames: filenames = await util.filenames_for_PR(gh, pull_request) After: async def check_news(gh, pull_request, filenames=None): filenames ??= await util.filenames_for_PR(gh, pull_request) On 19Jul2018 2222, Steven D'Aprano wrote:
In other words, we ought to be comparing the expressiveness of
process(spam ?? something)
versus:
process(something if spam is None else spam)
Agreed, though to make it a more favourable comparison I'd replace "spam" with "spam()?.eggs" and put it in a class/module definition where you don't want temporary names leaking ;) Cheers, Steve