Skip to content

Commit

Permalink
Merge pull request #638 from antonagestam/feature/py-moneyed-2
Browse files Browse the repository at this point in the history
Upgrade to py-moneyed 2.0
  • Loading branch information
benjaoming committed Jun 6, 2022
2 parents a6867ea + 389b3fa commit c6c80d4
Show file tree
Hide file tree
Showing 15 changed files with 80 additions and 224 deletions.
2 changes: 1 addition & 1 deletion djmoney/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "2.1.1"
__version__ = "3.0.0"

try:
import django
Expand Down
2 changes: 1 addition & 1 deletion djmoney/models/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ def add_currency_field(self, cls, name):
default=self.default_currency,
editable=False,
choices=self.currency_choices,
null=self.default_currency is None,
null=self.null,
)
currency_field.creation_counter = self.creation_counter - 1
currency_field_name = get_currency_field_name(name, self)
Expand Down
57 changes: 8 additions & 49 deletions djmoney/money.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import warnings
from functools import partial
from types import MappingProxyType

from django.conf import settings
Expand All @@ -10,20 +9,13 @@
from django.utils.safestring import mark_safe

import moneyed.l10n
import moneyed.localization
from moneyed import Currency, Money as DefaultMoney

from .settings import DECIMAL_PLACES, DECIMAL_PLACES_DISPLAY, IS_DECIMAL_PLACES_DISPLAY_SET, MONEY_FORMAT
from .settings import DECIMAL_PLACES, MONEY_FORMAT


__all__ = ["Money", "Currency"]

_warn_decimal_places_display_deprecated = partial(
warnings.warn,
"`Money.decimal_places_display` is deprecated and will be removed in django-money 3.0.",
DeprecationWarning,
)


@deconstructible
class Money(DefaultMoney):
Expand All @@ -33,27 +25,11 @@ class Money(DefaultMoney):

use_l10n = None

def __init__(self, *args, decimal_places_display=None, format_options=None, **kwargs):
def __init__(self, *args, format_options=None, **kwargs):
self.decimal_places = kwargs.pop("decimal_places", DECIMAL_PLACES)
self._decimal_places_display = decimal_places_display
if decimal_places_display is not None:
_warn_decimal_places_display_deprecated()
self.format_options = MappingProxyType(format_options) if format_options is not None else None
super().__init__(*args, **kwargs)

@property
def decimal_places_display(self):
_warn_decimal_places_display_deprecated()
if self._decimal_places_display is None:
return DECIMAL_PLACES_DISPLAY.get(self.currency.code, self.decimal_places)
return self._decimal_places_display

@decimal_places_display.setter
def decimal_places_display(self, value):
"""Set number of digits being displayed - `None` resets to `DECIMAL_PLACES_DISPLAY` setting"""
_warn_decimal_places_display_deprecated()
self._decimal_places_display = value

def _copy_attributes(self, source, target):
"""Copy attributes to the new `Money` instance.
Expand Down Expand Up @@ -124,13 +100,6 @@ def is_localized(self):
return self.use_l10n

def __str__(self):
if self._decimal_places_display is not None or IS_DECIMAL_PLACES_DISPLAY_SET:
kwargs = {"money": self, "decimal_places": self.decimal_places_display}
if self.is_localized:
locale = get_current_locale(for_babel=False)
if locale:
kwargs["locale"] = locale
return moneyed.localization.format_money(**kwargs)
format_options = {
**MONEY_FORMAT,
**(self.format_options or {}),
Expand Down Expand Up @@ -181,22 +150,12 @@ def __rmod__(self, other):
__rmul__ = __mul__


def get_current_locale(for_babel=True):
# get_language can return None starting from Django 1.8
language = translation.get_language() or settings.LANGUAGE_CODE
locale = translation.to_locale(language)

if for_babel:
return locale

if locale.upper() in moneyed.localization._FORMATTER.formatting_definitions:
return locale

locale = f"{locale}_{locale}".upper()
if locale in moneyed.localization._FORMATTER.formatting_definitions:
return locale

return ""
def get_current_locale():
return translation.to_locale(
translation.get_language()
# get_language can return None starting from Django 1.8
or settings.LANGUAGE_CODE
)


def maybe_convert(value, currency):
Expand Down
15 changes: 3 additions & 12 deletions djmoney/settings.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import operator
import warnings
from types import MappingProxyType

from django.conf import settings

from moneyed import CURRENCIES, DEFAULT_CURRENCY, DEFAULT_CURRENCY_CODE
from moneyed import CURRENCIES, Currency


# The default currency, you can define this in your project's settings module
# This has to be a currency object imported from moneyed
DEFAULT_CURRENCY = getattr(settings, "DEFAULT_CURRENCY", DEFAULT_CURRENCY)
DEFAULT_CURRENCY: Currency = getattr(settings, "DEFAULT_CURRENCY", None)


# The default currency choices, you can define this in your project's
Expand All @@ -21,18 +20,10 @@
if PROJECT_CURRENCIES:
CURRENCY_CHOICES = [(code, CURRENCIES[code].name) for code in PROJECT_CURRENCIES]
else:
CURRENCY_CHOICES = [(c.code, c.name) for i, c in CURRENCIES.items() if c.code != DEFAULT_CURRENCY_CODE]
CURRENCY_CHOICES = [(c.code, c.name) for i, c in CURRENCIES.items() if c != DEFAULT_CURRENCY]

CURRENCY_CHOICES.sort(key=operator.itemgetter(1, 0))
DECIMAL_PLACES = getattr(settings, "CURRENCY_DECIMAL_PLACES", 2)
_decimal_display_value = getattr(settings, "CURRENCY_DECIMAL_PLACES_DISPLAY", None)
if _decimal_display_value is not None:
warnings.warn(
"`CURRENCY_DECIMAL_PLACES_DISPLAY` is deprecated and will be removed in django-money 3.0.",
DeprecationWarning,
)
DECIMAL_PLACES_DISPLAY = _decimal_display_value or {currency[0]: DECIMAL_PLACES for currency in CURRENCY_CHOICES}
IS_DECIMAL_PLACES_DISPLAY_SET = _decimal_display_value is not None

OPEN_EXCHANGE_RATES_URL = getattr(settings, "OPEN_EXCHANGE_RATES_URL", "https://openexchangerates.org/api/latest.json")
OPEN_EXCHANGE_RATES_APP_ID = getattr(settings, "OPEN_EXCHANGE_RATES_APP_ID", None)
Expand Down
8 changes: 8 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Changelog
`Unreleased`_ - TBA
-------------------

**Changed**
- Update py-moneyed to 2.0. `#638`_ (`antonagestam`_, `flaeppe`_, `paoloxnet`_)
- Remove the deprecated ``Money.decimal_places_display`` property and argument. `#638`_ (`antonagestam`_, `flaeppe`_, `paoloxnet`_)
- Remove the deprecated ``CURRENCY_DECIMAL_PLACES_DISPLAY`` setting. `#638`_ (`antonagestam`_, `flaeppe`_, `paoloxnet`_)
- Null constraint on an implicit ``CurrencyField`` is now declared from ``null=...`` argument to ``MoneyField``. `#638`_ (`antonagestam`_, `flaeppe`_, `paoloxnet`_)

**Fixed**

- Improve the internal check for whether a currency is provided `#657`_ (`davidszotten`_)
Expand Down Expand Up @@ -798,6 +804,7 @@ wrapping with ``money_manager``.
.. _#657: https://github.com/django-money/django-money/issues/657
.. _#648: https://github.com/django-money/django-money/issues/648
.. _#646: https://github.com/django-money/django-money/issues/646
.. _#638: https://github.com/django-money/django-money/issues/638
.. _#637: https://github.com/django-money/django-money/issues/637
.. _#630: https://github.com/django-money/django-money/pull/630
.. _#629: https://github.com/django-money/django-money/pull/629
Expand Down Expand Up @@ -966,6 +973,7 @@ wrapping with ``money_manager``.
.. _mstarostik: https://github.com/mstarostik
.. _niklasb: https://github.com/niklasb
.. _nerdoc: https://github.com/nerdoc
.. _paoloxnet: https://github.com/paoloxnet
.. _pjdelport: https://github.com/pjdelport
.. _plumdog: https://github.com/plumdog
.. _rach: https://github.com/rach
Expand Down
3 changes: 0 additions & 3 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,4 @@
DJANGO_SETTINGS_MODULE=tests.settings
filterwarnings =
error::DeprecationWarning
ignore:This module and all its contents is deprecated in favour of new moneyed.l10n.format_money\.:DeprecationWarning
ignore:`Money\.decimal_places_display` is deprecated and will be removed in django-money 3\.0\.:DeprecationWarning
ignore:`CURRENCY_DECIMAL_PLACES_DISPLAY` is deprecated and will be removed in django-money 3\.0\.:DeprecationWarning
addopts = "--no-cov-on-fail"
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def find_version():
maintainer_email="greg@reinbach.com",
license="BSD",
packages=find_packages(include=["djmoney", "djmoney.*"]),
install_requires=["setuptools", "Django>=2.2", "py-moneyed>=1.2,<2.0"],
install_requires=["setuptools", "Django>=2.2", "py-moneyed>=2.0,<3.0"],
python_requires=">=3.7",
platforms=["Any"],
keywords=["django", "py-money", "money"],
Expand Down
8 changes: 0 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from unittest import mock

import pytest

from djmoney.contrib.exchange.models import ExchangeBackend, Rate, get_default_backend_name
Expand Down Expand Up @@ -31,9 +29,3 @@ def concrete_instance(m2m_object):


pytest_plugins = "pytester"


@pytest.yield_fixture
def legacy_formatting():
with mock.patch("djmoney.money.IS_DECIMAL_PLACES_DISPLAY_SET", True):
yield
3 changes: 1 addition & 2 deletions tests/contrib/test_django_rest_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,9 @@ def test_to_representation(self, model_class, create_kwargs, expected):
(NullMoneyFieldModel, "field", {"default_currency": "EUR", "allow_null": True}, None, None),
(NullMoneyFieldModel, "field", None, Money(10, "USD"), Money(10, "USD")),
(NullMoneyFieldModel, "field", {"default_currency": "EUR"}, Money(10, "USD"), Money(10, "USD")),
(NullMoneyFieldModel, "field", {"default_currency": "EUR"}, 10, Money(10, "EUR")),
(ModelWithVanillaMoneyField, "money", {"default_currency": "EUR"}, 10, Money(10, "EUR")),
(ModelWithVanillaMoneyField, "money", None, Money(10, "USD"), Money(10, "USD")),
(ModelWithVanillaMoneyField, "money", {"default_currency": "EUR"}, Money(10, "USD"), Money(10, "USD")),
(ModelWithVanillaMoneyField, "money", None, 10, Money(10, "XYZ")),
(ModelWithVanillaMoneyField, "money", {"default_currency": "EUR"}, 10, Money(10, "EUR")),
),
)
Expand Down
16 changes: 0 additions & 16 deletions tests/settings.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import warnings
from decimal import ROUND_HALF_EVEN

import django

import moneyed
from moneyed.localization import _FORMATTER, DEFAULT


DATABASES = {"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}}
Expand Down Expand Up @@ -41,20 +39,6 @@
USE_L10N = True


_FORMATTER.add_sign_definition("pl_PL", moneyed.PLN, suffix=" zł")
_FORMATTER.add_sign_definition(DEFAULT, moneyed.PLN, suffix=" zł")
_FORMATTER.add_formatting_definition(
"pl_PL",
group_size=3,
group_separator=" ",
decimal_point=",",
positive_sign="",
trailing_positive_sign="",
negative_sign="-",
trailing_negative_sign="",
rounding_method=ROUND_HALF_EVEN,
)

moneyed.add_currency("USDT", "000", "Tether", None)

OPEN_EXCHANGE_RATES_APP_ID = "test"
Expand Down
21 changes: 0 additions & 21 deletions tests/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,10 @@
INTEGER_FIELD = ModelWithVanillaMoneyField._meta.get_field("integer")


@pytest.mark.parametrize(
"value, expected",
(
(Money(10, "RUB"), "10.00 руб."), # Issue 232
(Money(1234), "1,234.00 XYZ"), # Issue 220
(Money(1000, "SAR"), "ر.س1,000.00"), # Issue 196
(Money(1000, "PLN"), "1,000.00 zł"), # Issue 102
(Money("3.33", "EUR"), "3.33 €"), # Issue 90
),
)
def test_display_for_field_with_legacy_formatting(legacy_formatting, settings, value, expected):
# This now defaults to True and raises RemovedInDjango50Warning
if django.VERSION < (4, 0):
settings.USE_L10N = True
# This locale has no definitions in py-moneyed, so it will work for localized money representation.
settings.LANGUAGE_CODE = "cs"
settings.DECIMAL_PLACES_DISPLAY = {}
assert admin_utils.display_for_field(value, MONEY_FIELD, "") == expected


@pytest.mark.parametrize(
"value, expected",
(
(Money(10, "RUB"), "10,00\xa0RUB"), # Issue 232
(Money(1234), "1\xa0234,00\xa0XYZ"), # Issue 220
(Money(1000, "SAR"), "1\xa0000,00\xa0SAR"), # Issue 196
(Money(1000, "PLN"), "1\xa0000,00\xa0PLN"), # Issue 102
(Money("3.33", "EUR"), "3,33\xa0€"), # Issue 90
Expand Down

0 comments on commit c6c80d4

Please sign in to comment.