Nowadays most software developed using the Python language relies on external packages (dependencies) to get the job done. Correctly managing this “supply-chain” ends up being very important and having a big impact on the end product.
As a developer you should be cautious about the dependencies you include on your project, as I explained in a previous post, but you are always dependent on the job done by the maintainers of those packages.
As a public package owner/maintainer, you also have to be aware that the code you write, your decisions and your actions will have an impact on the projects that depend directly or indirectly on your package.
With this small introduction we arrive to the topic of this post, which is “What to do as a maintainer when you no longer want to support a given package?” or ” How to properly rename my package?”.
In both of these situations you might think “I will start by removing the package from PyPI”, I hope the next lines will convince you that this is the worst you can do, for two reasons:
- You will break the code or the build systems of all projects that depend on the current or past versions of your package.
- You will free the namespace for others to use and if your package is popular enough this might become a juicy target for any malicious actor.
TLDR: your will screw your “users”.
The left-pad incident, while it didn’t happen in the python ecosystem, is a well known example of the first point and shows what happens when a popular package gets removed from the public index.
Malicious actors usually register packages using names that are similar to other popular packages with the hope that a user will end up installing them by mistake, something that already has been found multiple times on PyPI. Now imagine if that package name suddenly becomes available and is already trusted by other projects.
What should you do it then?
Just don’t delete the package.
I admit that in some rare occasions it might be required, but most of the time the best thing to do is to leave it there (specially for open-source ones).
Adding a warning to the code and informing the users in the
README file that the package is no longer maintained or safe to use is also a nice thing to do.
A good example of this process being done properly was the renaming of
model-bakery, as a user it was painless. Here’s an overview of the steps they took:
- A new source code repository was created with the same contents. (This step is optional)
- After doing the required changes a new package was uploaded to PyPI.
- Deprecation warnings were added to the old code, mentioning the new package.
- The documentation was updated mentioning the new package and making it clear the old package will no longer be maintained.
- A new release of the old package was created, so the user could see the deprecation warnings.
- All further development was done on the new package.
- The old code repository was archived.
So here is what is shown every time the test suite of an affected project is executed:
/lib/python3.7/site-packages/model_mommy/__init__.py:7: DeprecationWarning: Important: model_mommy is no longer maintained. Please use model_bakery instead: https://pypi.org/project/model-bakery/
In the end, even though I didn’t update right away, everything kept working and I was constantly reminded that I needed to make the change.