I'm developing a Flask application using Babel. Thanks to Distutils/Setuptools Integration, all the parameters of compile/extract/... functions are stored in setup.cfg
and compiling the i18n files is as easy as
./setup.py compile_catalog
Great. Now I would like this to be done automatically when running
./setup.py install
In make
's words, that would be letting install
target depend on compile_catalog
target.
We store only translation (.po
) files in the code repository. .gitignore excludes .mo
and .pot
files from being tracked.
When a developer pulls a new revision of the code, he runs
pip install -r requirements.txt
to update dependencies and install the project in development mode. Then, using above command line, he compiles the translation binary (.mo
) files.
Is there a simple and recommended way to modify setup.py
to do both operations in one step? Or am I trying to misuse setuptools
?
Using a script that like this would work for development purposes:
#!/bin/sh
./setup.py compile_catalog
pip install -r requirements.txt
but I would like a solution that also works when the package is installed with usual setup.py
install instructions, like if installed from PyPi.
Should I understand that setuptools
are not meant to be used like this, and people distributing software compile their translation files either manually or using custom scripts when creating their archives, rather than relying on setup.py
to compile them at installation time?
I didn't find many posts on the Internet addressing this. The ones I found involved running pybabel
command line interface from a function in setup.py
, which sounds like a shame as it misses the point of setuptools integration.
I think your demand is totally valid and I'm quite surprised that there seems to be no official guideline on how to accomplish this.
The project I working on now also went multilingual and this is what I did:
In setup.cfg
, make appropriate entries so that compile_catalog
can be run without options.
In setup.py
, subclass the install command from setuptools
:
setup.py:
from setuptools import setup
from setuptools.command.install import install
class InstallWithCompile(install):
def run(self):
from babel.messages.frontend import compile_catalog
compiler = compile_catalog(self.distribution)
option_dict = self.distribution.get_option_dict('compile_catalog')
compiler.domain = [option_dict['domain'][1]]
compiler.directory = option_dict['directory'][1]
compiler.run()
super().run()
Then, when calling setup(), register our InstallWithCompile command with the name "install" and make sure that the *.mo files will be included in the package:
setup(
...
cmdclass={
'install': InstallWithCompile,
},
...
package_data={'': ['locale/*/*/*.mo', 'locale/*/*/*.po']},
)
Since babel is used during the setup, you should add it as a setup dependency:
setup_requires=[
'babel',
],
Note that a package (here, babel) appearing in both setup_requires
and install_requires
won't be installed correctly using python setup.py install
due to an issue in setuptools
, but it works fine with pip install
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With