<commit_before>---
layout: post
author: <NAME>
title: "Renaming published python packages"
subtitle: "Some tips and tricks to avoid headaches"
---

So you have decided to rename your package, but all your continuous integration, deployment to [PyPi](https://pypi.org) and/or [conda-forge](https://conda-forge.org/#page-top), and automatic documentation generation with [readthedocs](https://readthedocs.org) is already set up with the old name. The obvious fear is that everything will break and lead to a big 'ol mess, but the process is actually easier than one might think if you follow these steps ... 

I learned this the hard way recently, when I  went through the renaming of a package with - ahem - [mixed emotions](https://twitter.com/JuliusBusecke/status/1545521169419444224?s=20&t=hCcJ36MLmjSeRPxiLkOW3g) along the way. 

## Why tho?
Why would you want to rename your package in the first place? The short answer is: **Don't do it if you don not absolutely have to**. 
More importantly, try to spend a bit more time to find a concise name when you create a repo, which might also coincidentally help you to refine the scope of your project. This is always a win-win in my eyes. 

But maybe you still need to rename your package. Wether that is due to the fact that you inadvertently (I promise!) created a name that is [NSFW](https://github.com/jbusecke/xmovie) or maybe the scope of your project did change.  
Whatever the reason is there seems to be [some interest](https://twitter.com/JuliusBusecke/status/1547674960134426628?s=20&t=kInsJ15bPRjtKWMFTplrQg)) in the community how to go about this. And thankfully it really isn't that hard to do. 

## Find a new name
Whether you have a brilliant name idea right away or go through a longer [name search](https://github.com/jbusecke/xMIP/issues/124), the most important thing to do is to check that your new name is available on all the platforms you want to use it. 
In my example experience this was actually turned out to be the biggest pain in the rear. For the renaming of [`cmip6_preprocessing`](https://github.com/jbusecke/xMIP) I initially wanted to use `pyMIP` but while this was available on Github, it turned out that someone published a PyPi package with that name without a connected Github name. We ended up with [`xMIP`](), and I quite like the name. 

The biggest lesson I learned from this experience, is to check **all** the platforms you want to connect to the package:
- GitHub
- Pypi
- [conda-forge](https://conda-forge.org/feedstock-outputs/)
- any other platform that is linked in some way to your package (readthedocs, ...)

## Actually renaming the package

1. Backup all code locally in a separate location. You can never be too careful!
2. **Rename your package on Github**. Go to your repo page, and navigate to `Settings > General` and edit the `Repository Name`.  
Thats it on the Github side!  
Issues and Pull Requests are automatically migrated and the old url to your repo is automatically forwarded to the new one, which means you can keep your local repo as is and keep pushing from it, even though you might want to change the folder name and remotes just to keep things neat in the future.
3. Make a big renaming PR to your repo. The easiest way to rename things is to do a global search and replace. I however recommend to check each renaming instance manually to avoid e.g. breaking links to the readthedocs documentation (more on that below). Dont forget to rename the module folder and run pre-commit locally (since the order of imports and other little things might change with different naming). This eventually should pass all of your CI.
4. Issue a test release on github to test if the automatic deployment to pypi (if you implemented that works). !!! Before actually pulling the trigger, you should make sure that the token you use for pypi has global scope, rather than being restricted to your old namespace. Otherwise your deployment will inevitably break. You can replace the secrets with a new restricted token afterwards if you wish. Double check that your package was indeed released to pypi. Then we can take care of the conda-forge feedstock
6. The last required step is renaming the recipe in the conda-feedstock. Note that you should **NEVER rename the feedstock repo itself**, or you will [break the conda-forge bots](https://twitter.com/condaforge/status/1544394452529299462?s=20&t=ZdMEx0Lw2xDh7T7aBD2eAQ). All you need to do is swap the `package.name` parameter in the `meta.yaml`.


<div class="text-center" style="padding-bottom: 50px">
  <img src="/img/posts/renaming/conda-forge.png" class="img-fluid" style="max-width:100%">
  <p class="text-muted">Note how the feedstock still reflects the old name. This has to stay that way!</p>
</div>

## Nice to haves
That is it with the basics. There are a few more things that might come in handy: 
- Have a new logo ready (ideally insert it at step 3 above). Someone might [shout out](https://twitter.com/juliusbusecke/status/1547308270393720838?s=21&t=uttUyU5szgNY4WOKpueqPA) your work right away after you made the name change 🤗.
- Fix backward compatibility in PyPi. The [basic idea](https://stackoverflow.com/questions/61363534/whats-the-recommended-way-of-renaming-a-project-in-pypi) is to release a 'final' version of your old name package manually that only contains your new package as a single dependency, so that users who do 
```<commit_msg>Create 2022-07-20-renaming.md<commit_after>---
layout: post
author: <NAME>
title: "Renaming published python packages"
subtitle: "Some tips and tricks to avoid headaches"
---

So you have decided to rename your package, but all your continuous integration, deployment to [PyPi](https://pypi.org) and/or [conda-forge](https://conda-forge.org/#page-top), and automatic documentation generation with [readthedocs](https://readthedocs.org) is already set up with the old name. The obvious fear is that everything will break and lead to a big 'ol mess, but the process is actually easier than one might think if you follow these steps ... 

I learned this the hard way recently, when I  went through the renaming of a package with - ahem - [mixed emotions](https://twitter.com/JuliusBusecke/status/1545521169419444224?s=20&t=hCcJ36MLmjSeRPxiLkOW3g) along the way. 

## Why tho?
Why would you want to rename your package in the first place? The short answer is: **Don't do it if you don not absolutely have to**. 
More importantly, try to spend a bit more time to find a concise name when you create a repo, which might also coincidentally help you to refine the scope of your project. This is always a win-win in my eyes. 

But maybe you still need to rename your package. Wether that is due to the fact that you inadvertently (I promise!) created a name that is [NSFW](https://github.com/jbusecke/xmovie) or maybe the scope of your project did change.  
Whatever the reason is there seems to be [some interest](https://twitter.com/JuliusBusecke/status/1547674960134426628?s=20&t=kInsJ15bPRjtKWMFTplrQg)) in the community how to go about this. And thankfully it really isn't that hard to do. 

## Find a new name
Whether you have a brilliant name idea right away or go through a longer [name search](https://github.com/jbusecke/xMIP/issues/124), the most important thing to do is to check that your new name is available on all the platforms you want to use it. 
In my example experience this was actually turned out to be the biggest pain in the rear. For the renaming of [`cmip6_preprocessing`](https://github.com/jbusecke/xMIP) I initially wanted to use `pyMIP` but while this was available on Github, it turned out that someone published a PyPi package with that name without a connected Github name. We ended up with [`xMIP`](), and I quite like the name. 

The biggest lesson I learned from this experience, is to check **all** the platforms you want to connect to the package:
- GitHub
- Pypi
- [conda-forge](https://conda-forge.org/feedstock-outputs/)
- any other platform that is linked in some way to your package (readthedocs, ...)

## Actually renaming the package

1. Backup all code locally in a separate location. You can never be too careful!
2. **Rename your package on Github**. Go to your repo page, and navigate to `Settings > General` and edit the `Repository Name`.  
Thats it on the Github side!  
Issues and Pull Requests are automatically migrated and the old url to your repo is automatically forwarded to the new one, which means you can keep your local repo as is and keep pushing from it, even though you might want to change the folder name and remotes just to keep things neat in the future.
3. **Make a renaming PR to your repo**. The easiest way to rename things is to do a global search and replace. I however recommend to check each renaming instance manually to avoid e.g. breaking links to the readthedocs documentation (more on that below). Dont forget to rename the module folder and run pre-commit locally (since the order of imports and other little things might change with different naming). This eventually should pass all of your CI.
4. **Issue a test release** on github to test if the automatic deployment to pypi (if you had that implemented in your repo like [here] for example). !!! Before actually pulling the trigger, you should make sure that the token you use for pypi has global scope, rather than being restricted to your old namespace. Otherwise your deployment will inevitably break. You can replace the secrets with a new restricted token afterwards if you wish. Double check that your package was indeed released to pypi. Then we can take care of the conda-forge feedstock
5. The last required step is **editing the recipe in the conda-forge feedstock**. Note that you should *NEVER rename the feedstock repo itself*, or you will [break the conda-forge bots](https://twitter.com/condaforge/status/1544394452529299462?s=20&t=ZdMEx0Lw2xDh7T7aBD2eAQ). All you need to do is swap the `package.name` parameter in the `meta.yaml`.


<div class="text-center" style="padding-bottom: 50px">
  <img src="/img/posts/renaming/conda-forge.png" class="img-fluid" style="max-width:100%">
  <p class="text-muted">Note how the feedstock still reflects the old name. This has to stay that way!</p>
</div>

## Nice to haves
That is it with the basics. There are a few more things that might come in handy: 
- Have a new logo ready (ideally insert it at step 3 above). Someone might [shout out](https://twitter.com/juliusbusecke/status/1547308270393720838?s=21&t=uttUyU5szgNY4WOKpueqPA) your work right away after you made the name change 🤗.
- Fix backward compatibility in PyPi. The [basic idea](https://stackoverflow.com/questions/61363534/whats-the-recommended-way-of-renaming-a-project-in-pypi) is to release a 'final' version of your old name package manually that only contains your new package as a single dependency, so that users who do 
```
{'fraction_non_alphanumeric': 0.07059039237257059, 'fraction_numerical': 0.022552255225522552, 'mean_word_length': 4.413895781637717, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 24, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2948267', 'n_tokens_mistral': 3200, 'n_tokens_neox': 2938, 'n_words': 1594}