After 12 years of hacking in Python, what did I learn the hard way? From biology to the web, across startups and now French government, I realized one thing: making your code resilient requires empathy.
It is the subject of a talk (slides) I gave at the Montreal-Python meetup.
I’ve been using Python for more than a decade now. Such a ride. And still, time doesn’t really matter. It’s more the diversity of projects and interactions that made me who I am as a developer. As such, I’m more and more concerned about the life of the code than ever. The transmission of the associated knowledge is the key to success of a project and to achieve this you have to think as a team. Lone wolves are burning out with their products. And it’s a real loss of energy. And happiness. And that sucks.
But first, let’s define inclusive. Given the Wiktionary the first definition is:
Including (almost) everything within its scope.
For this article, I would like to slightly rephrase that definition:
Including (almost) everybody within its scope.
I prefer that definition because coding is a social and political act. As such, each and every line of Python you produce should be put into that context. With whom. And why.
So, how do you make everybody capable of working with you(r Python code)?
Yesterday I was clever, so I wanted to change the world. Today I am wise, so I am changing myself. — Jalaluddin Rumi
That might seem obvious but do yourself a favour and do not reject yourself from your own code! We all have (please confirm :p) a project with no tests, no docs and yet critical and running in production that you have to maintain. Reshaping the project is not an option because you are short on attention/budget so it became a patchwork of ugly bug fixes. At that point, even you are unable to fix something without a week of procrastination to avoid that painful task. The challenge is not technical but the amount of motivation required is tremendous.
Try to be empathetic with a
older wiser self. Ease the installation process, reduce dependencies, have fixtures. Document, automate, speed up the feedback loop when you are modifying something. All basic things that I rarely saw well implemented (including my projects).
Include your colleagues
— “But if all of our programmers are pairing, won’t they write half as much code?”
— “No, hopefully they’ll write even less than that.”
Being part of a team is a way to duplicate the knowledge around the project. And that’s clearly not a lack of time or energy when you see the turn-over within our profession. I see three ways to do it:
- before: discussing strategies all together regularly, your mileage may vary on the frequency. The whole team needs to have a clear picture of what will be developed and why.
- during: pair-programming and/or quick sessions to discuss a particular issue mainly focused on the how.
- after: performing code-reviews and user-testing on each and every pull/merge-request. Check that the “why” of point 1. has been addressed and tested. Do not hesitate to trash everything at that point if it’s not relevant anymore.
Besides that, newcomers are a chance to rethink together a better process to onboard people. It only happens once per people, do not miss it and block at least half a day dedicated to that task. Observe them installing your project and trying to figure out how to make it run. Observe, do not help, do not say anything, let them find out alone. It’s not a user-testing session but a developer one. Collect everything to improve the developer experience later. Once the task is performed or worse your colleague is stuck, it’s time to discuss of the improvements. Is that a documentation issue? Or an environment one? Are you really explaining the purpose of your project? Which are the communication channels? And so on. We all have an illusion of the simplicity of our processes until they confront the diversity of others’ experiences.
The knowledge of your product is in your team, not in your code. We probably need new practices to get rid of that situation, it’s still too hard to find the right cursor between documenting and delivering value. Not only sharing how it works but why it failed and how do we addressed it at that time.
Include your (re)users
My suggestions can be expensive in time, money and energy. When you’re building something for the first time, all of this comes down to you. Focus on the documentation in the beginning. By doing that, you’ll create a welcoming place for others and then they can start helping you with the rest of it.
Lowering the barriers (cache)
This is a particular case that might be biased by my situation but when you are open-sourcing your developments and working for
a government citizens you want people to be able to contribute to your work one way or another. Lowering the barriers of the contributions is still very hard.
Labelling some easy-picking issues (cache) might be worth it and your reactivity to answer to declared issues is key. Especially by people who just created an account just to submit them. Which does happen more than I expected in my case! Performing pedagogic reviews might be worth it on the long term to help contributors level up and produce better code with you.
Note: if your project only runs on top-of-the-market computers and requires to download megabytes of dependencies, you are closing the door to a lot of potential contributors.
While I empathize with maintainers burning out and asking for support, trying to tackle sustainability from a maintainer centric view is a to paddle against the flow of the river. We continue to see barriers to adoption and participation fall away, enabling a new generation of contributors to be involved as long as we can view them as part of the solution rather than the problem itself.
Developers like to think they code their way out of any problem. We know how to scale servers but most of us are inexperienced with scaling people.
Maintainer vs. Community (cache)
Each and every time you contribute to an open-source project, you give your technical debt to a maintainer. Sad but true so help them with tests and documentation too! Lowering the barriers to other contributors is a way to increase the sustainability of the project which directly benefits to you.
As a maintainer, try to involve more people in the governance and maintenance of your project (I’m terrible at this…). This is somehow your escape lane because interest in projects will vanish from time to time. If you are the only one keeping the keys it will be lost forever once abandoned. At least, be a Minimally-nice Open Source Software Maintainer (cache).
Write code for complex logic so elegantly simple that it won’t make you look smart.
Think about it each and every time you plan to add a metaclass, a signal, a decorator or introduce the latest hyped lib to name a few. The beauty of your code is somewhat ugly to somebody having a hard time understanding these concepts. Really, nobody will blame you for writing dumb code that anyone understand at first sight. Not to mention yourself when you are stressed by a deadline or reopening this code six months later.
The best programmers write code beginners understand. It is as simple as this. You can write idiomatic Python and still be readable by a developer using another programming language. Make it a target and enjoy crossed code-reviews to identify these issues.
Document tools you use for your project (pycodestyle, isort to name a few), you can even add pre-commit hooks or automated checks via the pull/merge-request.
In an ever-more intricate and connected world, where software plays a larger and larger role in everyday life, it’s irresponsible to speak of coding as a lightweight activity. Software is not simply lines of code, nor is it blandly technical. In just a few years, understanding programming will be an indispensable part of active citizenship.
Coding is not ‘fun’, it’s technically and ethically complex (cache)
I’m not only talking about fixing typos in documentation here. How do you include people in the process of building the product? How do you make them aware that they can have a direct impact on what is done with their taxes? That part is yet to be experimented because it requires a shift in minds. A nation is a cooperative that scaled and as such each individual should act as part of a community.
Maybe some day, micro-payments will be available to remunerate the time spent by citizens on collective projects but — apart from the technical issue — the complexity to evaluate the value of each contribution is a real problem.
An important point of maturity as a developer is realizing that writing code is a relatively insignificant part of software development.
Steven R. Baker
Embrace the diversity of others point of views, make them count. Your code is not a book, it’s a continuous discussion on a given goal. You are maybe familiar with the concept of progressive enhancement, you can push the first draft of your code/documentation as a proof of concept and then progressively enhance the inclusivity of your project too. As for Web literacy, it’s a matter of Python literacy. We have the chance to use a language that is easy to learn, let’s be worthy of it.
I had to confess that I’m not doing half of the things I described, it is mostly self-criticism here. And that’s OK, really, because inclusiveness is a journey. Just be sure to keep moving toward a direction that makes you feel good at the end of each and every day.
What makes a good pull-request for a developer and a good code review from a maintainer?
On the developer side, documenting clearly what is the aim of your contribution is key. It looks obvious but that’s not always the case. Adding clean code, tests and documentation is great. We use to add an entry in the changelog with every pull-request nowadays to ease the communication with our international team.
A good code review is a one that is both respectful and engaging. You can be inspired (cache) by a checklist (cache) but once again, don’t take it too dogmatically. It’s up on your team to define its own check points.
How do you handle technical debt and contributions?
We actually (and sadly) don’t have pull-requests related to technical debt clean up. We mostly initiate that kind of change during workweeks (about twice per year) when everybody is in the same room to coordinate and evaluate alternatives together.