Failed to run tests for Django Cartridge in an Alpine Docker environment
File "/var/src/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 958, in prepare_value
value = field.get_db_prep_save(value, connection=self.connection)
File "/var/src/venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1612, in get_db_prep_save
self.max_digits, self.decimal_places)
File "/var/src/venv/lib/python3.6/site-packages/django/db/backends/base/operations.py", line 493, in adapt_decimalfield_value
return utils.format_number(value, max_digits, decimal_places)
File "/var/src/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 200, in format_number
value = value.quantize(decimal.Decimal(".1") ** decimal_places, context=context)
decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]
InvalidOperation: [<class 'decimal.InvalidOperation'>]
was encountered.
Upon investigation, it was found that
decimal_places was set to 127.
(In another test environment, it was set to 0, and the tests passed)
decimal_places is determined by
./manage.py shell
from locale import localeconv; localeconv()
{'currency_symbol': '¥',
'decimal_point': '.',
'frac_digits': 0,
'grouping': [],
'int_curr_symbol': 'JPY ',
'int_frac_digits': 0,
'mon_decimal_point': '.',
'mon_grouping': [3, 3, 0],
'mon_thousands_sep': ',',
'n_cs_precedes': 1,
'n_sep_by_space': 0,
'n_sign_posn': 4,
'negative_sign': '-',
'p_cs_precedes': 1,
'p_sep_by_space': 0,
'p_sign_posn': 1,
'positive_sign': '',
'thousands_sep': ''}
This uses the frac_digits value.
In the environment where the test fails:
{'currency_symbol': '',
'decimal_point': '.',
'frac_digits': 127,
'grouping': [],
'int_curr_symbol': '',
'int_frac_digits': 127,
'mon_decimal_point': '',
'mon_grouping': [],
'mon_thousands_sep': '',
'n_cs_precedes': 127,
'n_sep_by_space': 127,
'n_sign_posn': 127,
'negative_sign': '',
'p_cs_precedes': 127,
'p_sep_by_space': 127,
'p_sign_posn': 127,
'positive_sign': '',
'thousands_sep': ''}
The locale settings seem to be insufficient.
I tried to create the musl-locales by writing the Dockerfile as follows:
ENV MUSL_LOCPATH="/usr/share/i18n/locales/musl"
RUN apk --no-cache add libintl && \
apk --no-cache --virtual .locale_build add cmake make musl-dev gcc gettext-dev git && \
git clone https://gitlab.com/ytyng/musl-locales && \
cd musl-locales && cmake -DLOCALE_PROFILE=OFF -DCMAKE_INSTALL_PREFIX:PATH=/usr . && make && make install && \
cd .. && rm -r musl-locales && \
apk del .locale_build
However, the int_frac_digits value did not change.
Since I couldn't figure out another way, I patched
the locale settings in Django as follows:
setattr(locale, '_override_localeconv',
{'currency_symbol': '¥',
'decimal_point': '.',
'frac_digits': 0,
'grouping': [],
'int_curr_symbol': 'JPY ',
'int_frac_digits': 0,
'mon_decimal_point': '.',
'mon_grouping': [3, 3, 0],
'mon_thousands_sep': ',',
'n_cs_precedes': 1,
'n_sep_by_space': 0,
'n_sign_posn': 4,
'negative_sign': '-',
'p_cs_precedes': 1,
'p_sep_by_space': 0,
'p_sign_posn': 1,
'positive_sign': '',
'thousands_sep': ''})
By patching locale._override_localeconv in this way, the tests passed successfully.
In environments dealing with locales, it might be better to use Debian or similar instead of Alpine Linux.
Comments