Help a First-Timer Packaging Python: Miscellaneous Files


I’m working to make a python script/package I helped develop into a “real” Python package that can be installed via pip. The current code is sort of more of a “Python shell script” if you like, where you just clone the repo and add to your path and then call mepo. This was (rightly) pointed out to be not the Right Way™ to do Python, but rather it should be installed a la pip install mepo.

So, I’ve been working on a branch where I started following the setuptools docs and now have a setup.cfg, pyproject.toml, etc., figured out I had to do something like:

from command.tag.create import create


from mepo.command.tag.create import create

and I can now do:

python3 -m build && pip install .

and thanks to this magic:

console_scripts =
    mepo = mepo.__main__:main

I can see a ~/dev_env/bin/mepo command in my wee environment, and it seems to work! (Not backwardly compatible due to pickle weirdness, but works!)

But now I need more help. With mepo, I made some “etc” files like a Bash completion script, and some bash/tcsh function/aliases that users can do source mepo-cd.bash and get that functionality. The thing I don’t know is: How does one package up things like this?

I found some Stack Overflow threads talking about data_files in days, but I’m trying to be forward-looking and using setup.cfg and I saw that data_files is deprecated in the latest docs but there is no pointer to what one should use instead.

So, what is the “Right Way™” to package files like this for use with pip install etc? Once I know that, I can tell people how to go find where it’s installed and source /path/to/install/something/something/mepo-cd.bash

The current “right way” is to not try to install files to arbitrary locations outside of site-packages in the first place. A better option would be to give your package an auxiliary command that either outputs the contents of the etc files or else saves them directly to the appropriate path, then document in your project’s README/long description that users need to run this command in order to install the files. (Also, note that, if you don’t want to store the entire contents of the etc files in your Python source, you can package the files as package data and read them at runtime using importlib-resources.)

1 Like

What I have seen projects do for things like this, is provide a setup/bootstrap command.

For example, pipx (pipx · PyPI) provides pipx ensurepath which sets up the PATH variable in the relevant shell-specific configuration files.

Hmm, I guess it’ll be a fun challenge to figure out how to have python write csh/bash/zsh code.

Well, I suppose I could just be lazy and do a big ol’ triple-quote heredoc where I just embed the current scripts in a python routine that just writes to a file. I mean…that would work. :man_shrugging:

Doesn’t using package_data to include the files verbatim and then just copying the files to the our-of-tree location during your “bootstrap” command solve this problem?

1 Like