From 162b81ff1740f1e09de5f05871508ca3c17d9819 Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sat, 11 Jul 2015 23:31:39 +0900 Subject: [PATCH 01/11] Add travis-ci configuration --- .travis.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..9e72073 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,8 @@ +language: python +python: + - "2.6" + - "2.7" + - "3.2" + - "3.3" + - "3.4" +script: python setup.py test From 3e1cbb8c97f2f637109a7993aee3d150dbab63f2 Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sat, 11 Jul 2015 23:34:21 +0900 Subject: [PATCH 02/11] Test only Python 2.7 and 3.4 --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9e72073..2a07c8d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,5 @@ language: python python: - - "2.6" - "2.7" - - "3.2" - - "3.3" - "3.4" script: python setup.py test From 3ec30e171b7940c88c5767c6aede458dd72516b2 Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sat, 11 Jul 2015 23:36:38 +0900 Subject: [PATCH 03/11] Ignore .eggs --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ef74e87..229ff4b 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ RELEASE-VERSION dist *.egg-info *.egg +*.eggs *.komodoproject *.esproj *.pyc From 7301df7c1463355272deb7c0e773cdbe83ec8f9e Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sat, 11 Jul 2015 23:46:48 +0900 Subject: [PATCH 04/11] Support Python 3.4 --- README.md | 4 ++-- money/__init__.py | 1 - money/contrib/django/forms/__init__.py | 4 ++-- money/contrib/django/forms/fields.py | 4 ++-- money/contrib/django/models/fields.py | 4 ++-- money/contrib/django/models/managers.py | 8 ++++---- money/money.py | 14 ++++++-------- money/tests/models.py | 22 +++++++++++++--------- money/tests/test_currency.py | 2 +- money/tests/test_dajngo_defaults.py | 2 +- money/tests/test_django.py | 21 ++++++++++----------- money/tests/test_django_rendering.py | 6 +++++- money/tests/test_money.py | 2 +- money/tests/test_money_operations.py | 11 ++++------- money/tests/views.py | 11 ++++++----- setup.py | 5 +++-- version.py | 3 ++- 17 files changed, 64 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 1b8430e..629b7d2 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ For example: There is a dict of all ISO-4217 currencies: - >>> from money import CURRENCY + >>> from money.money import CURRENCY >>> print CURRENCY['GBP'].name Pound Sterling @@ -96,7 +96,7 @@ currencies. For example: This package assumes that you have a preferred default currency. Somewhere in your software's initialization you should set that currency: - >>> from money import set_default_currency + >>> from money.money import set_default_currency >>> set_default_currency(code='USD') >>> print Money(amount=23.45) USD 23.45 diff --git a/money/__init__.py b/money/__init__.py index 4ca3f60..e69de29 100644 --- a/money/__init__.py +++ b/money/__init__.py @@ -1 +0,0 @@ -from money import * diff --git a/money/contrib/django/forms/__init__.py b/money/contrib/django/forms/__init__.py index ad6b12e..2f76c29 100644 --- a/money/contrib/django/forms/__init__.py +++ b/money/contrib/django/forms/__init__.py @@ -1,2 +1,2 @@ -from fields import * -from widgets import * \ No newline at end of file +from .fields import * +from .widgets import * diff --git a/money/contrib/django/forms/fields.py b/money/contrib/django/forms/fields.py index 86951b4..f9a387d 100644 --- a/money/contrib/django/forms/fields.py +++ b/money/contrib/django/forms/fields.py @@ -1,7 +1,7 @@ from django import forms -from widgets import CurrencySelectWidget +from .widgets import CurrencySelectWidget -from money import Money, CURRENCY +from money.money import Money, CURRENCY class MoneyField(forms.MultiValueField): diff --git a/money/contrib/django/models/fields.py b/money/contrib/django/models/fields.py index e2744f7..a63e4dd 100644 --- a/money/contrib/django/models/fields.py +++ b/money/contrib/django/models/fields.py @@ -4,7 +4,7 @@ from django.utils.translation import ugettext_lazy as _ from money.contrib.django import forms -from money import Money +from money.money import Money __all__ = ('MoneyField', 'currency_field_name', 'NotSupportedLookup') @@ -195,7 +195,7 @@ def contribute_to_class(self, cls, name): # Set our custom manager if not hasattr(cls, '_default_manager'): - from managers import MoneyManager + from .managers import MoneyManager cls.add_to_class('objects', MoneyManager()) def get_db_prep_save(self, value, *args, **kwargs): diff --git a/money/contrib/django/models/managers.py b/money/contrib/django/models/managers.py index 0a77e2d..d84c6b4 100755 --- a/money/contrib/django/models/managers.py +++ b/money/contrib/django/models/managers.py @@ -1,7 +1,7 @@ from django.db import models from django.db.models.query import QuerySet -from django.utils.encoding import smart_unicode -from fields import currency_field_name +from django.utils.encoding import smart_text +from .fields import currency_field_name __all__ = ('QuerysetWithMoney', 'MoneyManager',) @@ -10,7 +10,7 @@ class QuerysetWithMoney(QuerySet): def _update_params(self, kwargs): from django.db.models.constants import LOOKUP_SEP - from money import Money + from money.money import Money to_append = {} for name, value in kwargs.items(): if isinstance(value, Money): @@ -19,7 +19,7 @@ def _update_params(self, kwargs): field_name = currency_field_name(path[0]) else: field_name = currency_field_name(name) - to_append[field_name] = smart_unicode(value.currency) + to_append[field_name] = smart_text(value.currency) kwargs.update(to_append) return kwargs diff --git a/money/money.py b/money/money.py index 542574f..14e3a17 100644 --- a/money/money.py +++ b/money/money.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- -from __future__ import division -import six +from __future__ import division, unicode_literals + +from builtins import str -import exceptions +import six from decimal import Decimal @@ -43,11 +44,11 @@ def __ne__(self, other): DEFAULT_CURRENCY = CURRENCY['XXX'] -class IncorrectMoneyInputError(exceptions.Exception): +class IncorrectMoneyInputError(Exception): """Invalid input for the Money object""" -class CurrencyMismatchException(exceptions.ArithmeticError): +class CurrencyMismatchException(ArithmeticError): """Raised when an operation is not allowed between differing currencies""" @@ -154,9 +155,6 @@ def currency(self): def __str__(self): return "{} {}".format(self._currency, self._amount) - def __unicode__(self): - return u"{} {}".format(self._currency, self._amount) - def __repr__(self): return str(self) diff --git a/money/tests/models.py b/money/tests/models.py index fbcdc7f..b9dce87 100644 --- a/money/tests/models.py +++ b/money/tests/models.py @@ -1,6 +1,10 @@ +from __future__ import unicode_literals + +from builtins import str + from django.db import models from money.contrib.django.models import fields -from money import Money +from money.money import Money # Tests for Django models. We set up three types of models with different @@ -10,8 +14,8 @@ class SimpleMoneyModel(models.Model): price = fields.MoneyField(max_digits=12, decimal_places=3) - def __unicode__(self): - return self.name + u" " + unicode(self.price) + def __str__(self): + return self.name + u" " + str(self.price) class Meta: app_label = 'tests' @@ -22,8 +26,8 @@ class MoneyModelDefaultMoneyUSD(models.Model): price = fields.MoneyField(max_digits=12, decimal_places=3, default=Money("123.45", "USD")) zero = fields.MoneyField(max_digits=12, decimal_places=3, default=Money("0", "USD")) - def __unicode__(self): - return self.name + u" " + unicode(self.price) + def __str__(self): + return self.name + u" " + str(self.price) class Meta: app_label = 'tests' @@ -34,8 +38,8 @@ class MoneyModelDefaults(models.Model): price = fields.MoneyField('Price', max_digits=12, decimal_places=3, default="123.45", default_currency="USD") zero = fields.MoneyField('Zero', max_digits=12, decimal_places=3, default="0", default_currency="USD") - def __unicode__(self): - return self.name + u" " + unicode(self.price) + def __str__(self): + return self.name + u" " + str(self.price) class Meta: app_label = 'tests' @@ -46,8 +50,8 @@ class NullableMoneyModel(models.Model): price = fields.MoneyField(max_digits=12, decimal_places=3, null=True) - def __unicode__(self): - return self.name + u" " + unicode(self.price) + def __str__(self): + return self.name + u" " + str(self.price) class Meta: app_label = 'tests' diff --git a/money/tests/test_currency.py b/money/tests/test_currency.py index 8133f10..cbd9765 100644 --- a/money/tests/test_currency.py +++ b/money/tests/test_currency.py @@ -1,4 +1,4 @@ -from money import ( +from money.money import ( Currency, ) diff --git a/money/tests/test_dajngo_defaults.py b/money/tests/test_dajngo_defaults.py index 9f01dbe..690bbc8 100644 --- a/money/tests/test_dajngo_defaults.py +++ b/money/tests/test_dajngo_defaults.py @@ -1,6 +1,6 @@ import pytest -from money import Money +from money.money import Money from money.tests.models import ALL_PARAMETRIZED_MODELS diff --git a/money/tests/test_django.py b/money/tests/test_django.py index 64ec2af..775d460 100644 --- a/money/tests/test_django.py +++ b/money/tests/test_django.py @@ -1,8 +1,12 @@ +from __future__ import unicode_literals + +from builtins import str + import pytest from django.test import TestCase from django.db import IntegrityError -from money import Money, CURRENCY +from money.money import Money, CURRENCY from money.contrib.django.models.fields import NotSupportedLookup from money.tests.models import ( SimpleMoneyModel, @@ -15,12 +19,12 @@ @pytest.mark.django_db class MoneyFieldTestCase(TestCase): - def assertSameCurrency(self, moneys, currency=None): + def assertSameCurrency(self, moneys, currency_code=None): """ Utility function to assert a collection of currencies are all the same """ - currencies = set([m.currency for m in moneys]) - self.assertTrue(len(currencies) == 1) - if currency: - self.assertEqual(currencies.pop().code, currency) + currency_codes = set([m.currency.code for m in moneys]) + self.assertTrue(len(currency_codes) == 1) + if currency_code: + self.assertEqual(currency_codes.pop(), currency_code) def test_non_null(self): instance = SimpleMoneyModel() @@ -212,22 +216,17 @@ def test_price_amount_to_string(self): e2 = SimpleMoneyModel(price=Money('200.0', 'JPY')) self.assertEqual(str(e1.price), "JPY 200") - self.assertEqual(unicode(e1.price), "JPY 200") self.assertEqual(str(e1.price.amount), "200") - self.assertEqual(unicode(e1.price.amount), "200") self.assertEqual(str(e2.price.amount), "200.0") - self.assertEqual(unicode(e2.price.amount), "200.0") def test_price_amount_to_string_non_money(self): e1 = MoneyModelDefaults() self.assertEqual(str(e1.price), "USD 123.45") - self.assertEqual(unicode(e1.price), "USD 123.45") self.assertEqual(str(e1.price.amount), "123.45") - self.assertEqual(unicode(e1.price.amount), "123.45") def test_zero_edge_case(self): created = SimpleMoneyModel.objects.create(name="zero dollars", price=Money(0, "USD")) diff --git a/money/tests/test_django_rendering.py b/money/tests/test_django_rendering.py index 49dfd14..91c384f 100644 --- a/money/tests/test_django_rendering.py +++ b/money/tests/test_django_rendering.py @@ -1,3 +1,7 @@ +from __future__ import unicode_literals + +from builtins import str + import pytest from django.core.urlresolvers import reverse @@ -92,7 +96,7 @@ def test_form_POST(self): # Find the object we created... obj = SimpleMoneyModel.objects.last() - self.assertEqual(unicode(obj.price), u"JPY 555.5") + self.assertEqual(str(obj.price), u"JPY 555.5") self.assertContains(response, '|item:name|value:ABC|') self.assertContains(response, '|item:price|value:JPY 555.5|') diff --git a/money/tests/test_money.py b/money/tests/test_money.py index 968cdd7..89a63da 100644 --- a/money/tests/test_money.py +++ b/money/tests/test_money.py @@ -1,7 +1,7 @@ from decimal import Decimal from unittest import TestCase -from money import ( +from money.money import ( Money, CURRENCY, Currency, diff --git a/money/tests/test_money_operations.py b/money/tests/test_money_operations.py index c614f29..fe6b61a 100644 --- a/money/tests/test_money_operations.py +++ b/money/tests/test_money_operations.py @@ -1,9 +1,11 @@ -from __future__ import division +from __future__ import division, unicode_literals + +from builtins import str import pytest from decimal import Decimal -from money import Money, CurrencyMismatchException +from money.money import Money, CurrencyMismatchException MONEY_STRINGS = [ @@ -32,11 +34,6 @@ def test_str(value, expected): assert str(value) == expected -@pytest.mark.parametrize("value,expected", MONEY_STRINGS) -def test_unicode(value, expected): - assert unicode(value) == expected - - @pytest.mark.parametrize("value,expected", MONEY_STRINGS) def test_repr(value, expected): assert repr(value) == expected diff --git a/money/tests/views.py b/money/tests/views.py index c6a594f..55a6c0a 100644 --- a/money/tests/views.py +++ b/money/tests/views.py @@ -1,8 +1,9 @@ +from __future__ import print_function from django import forms from django.shortcuts import render_to_response, get_object_or_404 -from money import Money +from money.money import Money from money.contrib.django.forms.fields import MoneyField from money.tests.models import SimpleMoneyModel @@ -32,7 +33,7 @@ def model_from_db_view(request, amount='0', currency='XXX'): instance = SimpleMoneyModel.objects.create(price=Money(amount, currency)) instance = SimpleMoneyModel.objects.get(pk=instance.pk) - print instance, instance.pk + print(instance, instance.pk) money = instance.price return render_to_response('view.html', {'money': money}) @@ -55,7 +56,7 @@ def model_form_view(request, amount='0', currency='XXX'): def regular_form(request): if request.method == 'POST': form = TestForm(request.POST) - print form.is_valid() + print(form.is_valid()) if form.is_valid(): price = form.cleaned_data['price'] return render_to_response('form.html', {'price':price} ) @@ -67,7 +68,7 @@ def regular_form_edit(request, id): instance = get_object_or_404(SimpleMoneyModel, pk=id) if request.method == 'POST': form = TestForm(request.POST, initial={'price':instance.price}) - print form.is_valid() + print(form.is_valid()) if form.is_valid(): price = form.cleaned_data['price'] return render_to_response('form.html', {'price':price} ) @@ -81,7 +82,7 @@ def model_form_edit(request, id): instance = get_object_or_404(SimpleMoneyModel, pk=id) if request.method == 'POST': form = TestModelForm(request.POST, instance=instance) - print form.is_valid() + print(form.is_valid()) if form.is_valid(): price = form.cleaned_data['price'] form.save() diff --git a/setup.py b/setup.py index 598b038..ff9e338 100644 --- a/setup.py +++ b/setup.py @@ -38,8 +38,9 @@ def run_tests(self): tests_require = [ 'pytest-django', 'pytest-cov', - 'django<1.7', + 'django<1.8', 'psycopg2', + 'six', ] requirements = [ @@ -47,7 +48,7 @@ def run_tests(self): ] extras_require = { - 'django': ['Django < 1.7', ], + 'django': ['Django < 1.8', ], } dependency_links = [] diff --git a/version.py b/version.py index db3e65c..caab2a6 100644 --- a/version.py +++ b/version.py @@ -46,6 +46,7 @@ # first number: major business changes/milestones # second number: database changes # third number: code changes/patches +from __future__ import unicode_literals from subprocess import Popen, PIPE @@ -151,4 +152,4 @@ def get_git_hash(): return sha if __name__ == "__main__": - print get_git_version() + print(get_git_version()) From 376d92b34cc4f481f34fdfc0552e52dbd0fa72cc Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sat, 11 Jul 2015 23:58:34 +0900 Subject: [PATCH 05/11] Fix str() problems --- money/money.py | 2 -- money/tests/models.py | 10 ++++------ money/tests/test_django.py | 2 -- money/tests/test_django_rendering.py | 4 +--- money/tests/test_money_operations.py | 2 -- 5 files changed, 5 insertions(+), 15 deletions(-) diff --git a/money/money.py b/money/money.py index 14e3a17..3327252 100644 --- a/money/money.py +++ b/money/money.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import division, unicode_literals -from builtins import str - import six from decimal import Decimal diff --git a/money/tests/models.py b/money/tests/models.py index b9dce87..95df976 100644 --- a/money/tests/models.py +++ b/money/tests/models.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -from builtins import str - from django.db import models from money.contrib.django.models import fields from money.money import Money @@ -15,7 +13,7 @@ class SimpleMoneyModel(models.Model): price = fields.MoneyField(max_digits=12, decimal_places=3) def __str__(self): - return self.name + u" " + str(self.price) + return self.name + " " + str(self.price) class Meta: app_label = 'tests' @@ -27,7 +25,7 @@ class MoneyModelDefaultMoneyUSD(models.Model): zero = fields.MoneyField(max_digits=12, decimal_places=3, default=Money("0", "USD")) def __str__(self): - return self.name + u" " + str(self.price) + return self.name + " " + str(self.price) class Meta: app_label = 'tests' @@ -39,7 +37,7 @@ class MoneyModelDefaults(models.Model): zero = fields.MoneyField('Zero', max_digits=12, decimal_places=3, default="0", default_currency="USD") def __str__(self): - return self.name + u" " + str(self.price) + return self.name + " " + str(self.price) class Meta: app_label = 'tests' @@ -51,7 +49,7 @@ class NullableMoneyModel(models.Model): price = fields.MoneyField(max_digits=12, decimal_places=3, null=True) def __str__(self): - return self.name + u" " + str(self.price) + return self.name + " " + str(self.price) class Meta: app_label = 'tests' diff --git a/money/tests/test_django.py b/money/tests/test_django.py index 775d460..3cc416a 100644 --- a/money/tests/test_django.py +++ b/money/tests/test_django.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -from builtins import str - import pytest from django.test import TestCase diff --git a/money/tests/test_django_rendering.py b/money/tests/test_django_rendering.py index 91c384f..ed93020 100644 --- a/money/tests/test_django_rendering.py +++ b/money/tests/test_django_rendering.py @@ -1,7 +1,5 @@ from __future__ import unicode_literals -from builtins import str - import pytest from django.core.urlresolvers import reverse @@ -96,7 +94,7 @@ def test_form_POST(self): # Find the object we created... obj = SimpleMoneyModel.objects.last() - self.assertEqual(str(obj.price), u"JPY 555.5") + self.assertEqual(str(obj.price), "JPY 555.5") self.assertContains(response, '|item:name|value:ABC|') self.assertContains(response, '|item:price|value:JPY 555.5|') diff --git a/money/tests/test_money_operations.py b/money/tests/test_money_operations.py index fe6b61a..a4bb560 100644 --- a/money/tests/test_money_operations.py +++ b/money/tests/test_money_operations.py @@ -1,7 +1,5 @@ from __future__ import division, unicode_literals -from builtins import str - import pytest from decimal import Decimal From 8a94788b17057603b29314885ad9bacf238348a1 Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sun, 1 May 2016 18:52:23 +0900 Subject: [PATCH 06/11] Support Python 3.5 instead of 3.4 --- .travis.yml | 2 +- money/__init__.py | 1 + money/contrib/django/models/fields.py | 2 +- money/contrib/django/models/managers.py | 2 +- money/money.py | 5 +- money/tests/models.py | 7 ++ money/tests/test_django.py | 96 ++++++++++++------------- money/tests/test_django_rendering.py | 8 ++- money/tests/views.py | 32 +++++---- setup.py | 2 +- version.py | 2 +- 11 files changed, 88 insertions(+), 71 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a07c8d..e910ea5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: python python: - "2.7" - - "3.4" + - "3.5" script: python setup.py test diff --git a/money/__init__.py b/money/__init__.py index e69de29..17576c8 100644 --- a/money/__init__.py +++ b/money/__init__.py @@ -0,0 +1 @@ +from .money import * diff --git a/money/contrib/django/models/fields.py b/money/contrib/django/models/fields.py index e748691..055268d 100644 --- a/money/contrib/django/models/fields.py +++ b/money/contrib/django/models/fields.py @@ -93,7 +93,7 @@ class InfiniteDecimalField(models.DecimalField): def db_type(self, connection): engine = connection.settings_dict['ENGINE'] - if 'psycopg2' in engine: + if 'postgresql' in engine: return 'numeric' return super(InfiniteDecimalField, self).db_type(connection=connection) diff --git a/money/contrib/django/models/managers.py b/money/contrib/django/models/managers.py index d84c6b4..8708903 100755 --- a/money/contrib/django/models/managers.py +++ b/money/contrib/django/models/managers.py @@ -81,5 +81,5 @@ def values(self, *args, **kwargs): class MoneyManager(models.Manager): - def get_query_set(self): + def get_queryset(self): return QuerysetWithMoney(self.model) diff --git a/money/money.py b/money/money.py index 3327252..1357824 100644 --- a/money/money.py +++ b/money/money.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- from __future__ import division, unicode_literals -import six - from decimal import Decimal +import six + class Currency(object): code = "XXX" @@ -54,6 +54,7 @@ class InvalidOperationException(TypeError): """Raised when an operation is never allowed""" +@six.python_2_unicode_compatible class Money(object): """ An amount of money with an optional currency diff --git a/money/tests/models.py b/money/tests/models.py index 95df976..01c0e90 100644 --- a/money/tests/models.py +++ b/money/tests/models.py @@ -1,12 +1,16 @@ from __future__ import unicode_literals +import six + from django.db import models + from money.contrib.django.models import fields from money.money import Money # Tests for Django models. We set up three types of models with different # ways of specifying defaults +@six.python_2_unicode_compatible class SimpleMoneyModel(models.Model): name = models.CharField(max_length=100) @@ -19,6 +23,7 @@ class Meta: app_label = 'tests' +@six.python_2_unicode_compatible class MoneyModelDefaultMoneyUSD(models.Model): name = models.CharField(max_length=100) price = fields.MoneyField(max_digits=12, decimal_places=3, default=Money("123.45", "USD")) @@ -31,6 +36,7 @@ class Meta: app_label = 'tests' +@six.python_2_unicode_compatible class MoneyModelDefaults(models.Model): name = models.CharField('Name', max_length=100) price = fields.MoneyField('Price', max_digits=12, decimal_places=3, default="123.45", default_currency="USD") @@ -43,6 +49,7 @@ class Meta: app_label = 'tests' +@six.python_2_unicode_compatible class NullableMoneyModel(models.Model): name = models.CharField(max_length=100) diff --git a/money/tests/test_django.py b/money/tests/test_django.py index 3cc416a..3f2aa9e 100644 --- a/money/tests/test_django.py +++ b/money/tests/test_django.py @@ -33,7 +33,7 @@ def test_creating(self): ind = 0 for code, currency in CURRENCY.items(): ind = ind + 1 - price = Money(ind*1000.0, code) + price = Money(ind * 1000.0, code) SimpleMoneyModel.objects.create(name=currency.name, price=price.amount, price_currency=price.currency) count = SimpleMoneyModel.objects.all().count() self.assertEqual(len(CURRENCY), count) @@ -70,42 +70,42 @@ def test_assign(self): price = Money(100, "USD") ent = SimpleMoneyModel(name='test', price=price.amount, price_currency=price.currency) ent.save() - self.assertEquals(ent.price, Money(100, "USD")) + self.assertEqual(ent.price, Money(100, "USD")) ent.price = Money(10, "USD") ent.save() - self.assertEquals(ent.price, Money(10, "USD")) + self.assertEqual(ent.price, Money(10, "USD")) ent_same = SimpleMoneyModel.objects.get(pk=ent.id) - self.assertEquals(ent_same.price, Money(10, "USD")) + self.assertEqual(ent_same.price, Money(10, "USD")) - def test_retreive_and_update(self): + def test_retrieve_and_update(self): created = SimpleMoneyModel.objects.create(name="one hundred dollars", price=Money(100, "USD")) created.save() - self.assertEquals(created.price, Money(100, "USD")) + self.assertEqual(created.price, Money(100, "USD")) ent = SimpleMoneyModel.objects.filter(price__exact=Money(100, "USD")).get() - self.assertEquals(ent.price, Money(100, "USD")) + self.assertEqual(ent.price, Money(100, "USD")) ent.price = Money(300, "USD") ent.save() ent = SimpleMoneyModel.objects.filter(price__exact=Money(300, "USD")).get() - self.assertEquals(ent.price, Money(300, "USD")) + self.assertEqual(ent.price, Money(300, "USD")) def test_defaults_as_money_objects(self): ent = MoneyModelDefaultMoneyUSD.objects.create(name='123.45 USD') - self.assertEquals(ent.price, Money('123.45', 'USD')) + self.assertEqual(ent.price, Money('123.45', 'USD')) ent = MoneyModelDefaultMoneyUSD.objects.get(pk=ent.id) - self.assertEquals(ent.price, Money('123.45', 'USD')) + self.assertEqual(ent.price, Money('123.45', 'USD')) def test_defaults_as_separate_values(self): ent = MoneyModelDefaults.objects.create(name='100 USD', price=100) - self.assertEquals(ent.price, Money(100, 'USD')) + self.assertEqual(ent.price, Money(100, 'USD')) ent = MoneyModelDefaults.objects.get(pk=ent.id) - self.assertEquals(ent.price, Money(100, 'USD')) + self.assertEqual(ent.price, Money(100, 'USD')) def test_lookup(self): USD100 = Money(100, "USD") @@ -113,16 +113,16 @@ def test_lookup(self): UAH100 = Money(100, "UAH") SimpleMoneyModel.objects.create(name="one hundred dollars", price=USD100) - SimpleMoneyModel.objects.create(name="one hundred and one dollars", price=USD100+1) - SimpleMoneyModel.objects.create(name="ninety nine dollars", price=USD100-1) + SimpleMoneyModel.objects.create(name="one hundred and one dollars", price=USD100 + 1) + SimpleMoneyModel.objects.create(name="ninety nine dollars", price=USD100 - 1) SimpleMoneyModel.objects.create(name="one hundred euros", price=EUR100) - SimpleMoneyModel.objects.create(name="one hundred and one euros", price=EUR100+1) - SimpleMoneyModel.objects.create(name="ninety nine euros", price=EUR100-1) + SimpleMoneyModel.objects.create(name="one hundred and one euros", price=EUR100 + 1) + SimpleMoneyModel.objects.create(name="ninety nine euros", price=EUR100 - 1) SimpleMoneyModel.objects.create(name="one hundred hrivnyas", price=UAH100) - SimpleMoneyModel.objects.create(name="one hundred and one hrivnyas", price=UAH100+1) - SimpleMoneyModel.objects.create(name="ninety nine hrivnyas", price=UAH100-1) + SimpleMoneyModel.objects.create(name="one hundred and one hrivnyas", price=UAH100 + 1) + SimpleMoneyModel.objects.create(name="ninety nine hrivnyas", price=UAH100 - 1) #Exact: qset = SimpleMoneyModel.objects.filter(price__exact=USD100) @@ -135,28 +135,28 @@ def test_lookup(self): #Less than: qset = SimpleMoneyModel.objects.filter(price__lt=USD100) self.assertEqual(qset.count(), 1) - self.assertEqual(qset[0].price, USD100-1) + self.assertEqual(qset[0].price, USD100 - 1) qset = SimpleMoneyModel.objects.filter(price__lt=EUR100) self.assertEqual(qset.count(), 1) - self.assertEqual(qset[0].price, EUR100-1) + self.assertEqual(qset[0].price, EUR100 - 1) qset = SimpleMoneyModel.objects.filter(price__lt=UAH100) self.assertEqual(qset.count(), 1) - self.assertEqual(qset[0].price, UAH100-1) + self.assertEqual(qset[0].price, UAH100 - 1) #Greater than: qset = SimpleMoneyModel.objects.filter(price__gt=USD100) self.assertEqual(qset.count(), 1) - self.assertEqual(qset[0].price, USD100+1) + self.assertEqual(qset[0].price, USD100 + 1) qset = SimpleMoneyModel.objects.filter(price__gt=EUR100) self.assertEqual(qset.count(), 1) - self.assertEqual(qset[0].price, EUR100+1) + self.assertEqual(qset[0].price, EUR100 + 1) qset = SimpleMoneyModel.objects.filter(price__gt=UAH100) self.assertEqual(qset.count(), 1) - self.assertEqual(qset[0].price, UAH100+1) + self.assertEqual(qset[0].price, UAH100 + 1) #Less than or equal: qset = SimpleMoneyModel.objects.filter(price__lte=USD100) @@ -228,10 +228,10 @@ def test_price_amount_to_string_non_money(self): def test_zero_edge_case(self): created = SimpleMoneyModel.objects.create(name="zero dollars", price=Money(0, "USD")) - self.assertEquals(created.price, Money(0, "USD")) + self.assertEqual(created.price, Money(0, "USD")) ent = SimpleMoneyModel.objects.filter(price__exact=Money(0, "USD")).get() - self.assertEquals(ent.price, Money(0, "USD")) + self.assertEqual(ent.price, Money(0, "USD")) def test_unsupported_lookup(self): with pytest.raises(NotSupportedLookup): @@ -244,22 +244,22 @@ def test_currency_accessor(self): # can be removed as well. created = SimpleMoneyModel.objects.create(name="zero dollars", price=Money(0)) - self.assertEquals(created.price_currency, "XXX") - self.assertEquals(created.price.currency, "XXX") + self.assertEqual(created.price_currency, "XXX") + self.assertEqual(created.price.currency, "XXX") created = SimpleMoneyModel.objects.create(name="zero dollars", price=Money(0, "USD")) - self.assertEquals(created.price_currency, "USD") - self.assertEquals(created.price.currency, "USD") + self.assertEqual(created.price_currency, "USD") + self.assertEqual(created.price.currency, "USD") # This actually wouldn't work in the old code without a round trip to the db created.price_currency = 'EUR' - self.assertEquals(created.price_currency, "EUR") - self.assertEquals(created.price.currency, "EUR") + self.assertEqual(created.price_currency, "EUR") + self.assertEqual(created.price.currency, "EUR") created.save() created = SimpleMoneyModel.objects.get(pk=created.pk) - self.assertEquals(created.price_currency, "EUR") - self.assertEquals(created.price.currency, "EUR") + self.assertEqual(created.price_currency, "EUR") + self.assertEqual(created.price.currency, "EUR") @pytest.mark.django_db @@ -267,18 +267,18 @@ class TestNullability(TestCase): def test_nullable_model_instance(self): instance = NullableMoneyModel() - self.assertEquals(instance.price, None) + self.assertEqual(instance.price, None) def test_nullable_model_save(self): instance = NullableMoneyModel() instance.save() - self.assertEquals(instance.price, None) + self.assertEqual(instance.price, None) def test_nullable_model_create_and_lookup(self): name = "test_nullable_model_create_and_lookup" NullableMoneyModel.objects.create(name=name) instance = NullableMoneyModel.objects.get(name=name) - self.assertEquals(instance.price, None) + self.assertEqual(instance.price, None) def test_nullable_model_lookup_by_null_amount(self): name = "test_nullable_model_lookup_by_null_amount" @@ -286,7 +286,7 @@ def test_nullable_model_lookup_by_null_amount(self): # Assert NULL currency has "blank" currency instance = NullableMoneyModel.objects.filter(price_currency='')[0] - self.assertEquals(instance.name, name) + self.assertEqual(instance.name, name) def test_nullable_model_lookup_by_null_currency(self): name = "test_nullable_model_lookup_by_null_currency" @@ -294,26 +294,26 @@ def test_nullable_model_lookup_by_null_currency(self): # Assert NULL currency has "blank" currency instance = NullableMoneyModel.objects.filter(price__isnull=True)[0] - self.assertEquals(instance.name, name) + self.assertEqual(instance.name, name) def test_nullable_null_currency_vs_undefined_currency(self): name = "test_nullable_null_currency_vs_undefined_currency" - NullableMoneyModel.objects.create(name=name+"_null", price=None) - NullableMoneyModel.objects.create(name=name+"_undefined", price=Money(0)) - self.assertEquals(NullableMoneyModel.objects.all().count(), 2) + NullableMoneyModel.objects.create(name=name + "_null", price=None) + NullableMoneyModel.objects.create(name=name + "_undefined", price=Money(0)) + self.assertEqual(NullableMoneyModel.objects.all().count(), 2) # Assert NULL currency has "blank" currency - self.assertEquals(NullableMoneyModel.objects.filter(price__isnull=True).count(), 1) + self.assertEqual(NullableMoneyModel.objects.filter(price__isnull=True).count(), 1) null_instance = NullableMoneyModel.objects.filter(price__isnull=True)[0] - self.assertEquals(null_instance.name, name + "_null") + self.assertEqual(null_instance.name, name + "_null") null_instance = NullableMoneyModel.objects.filter(price_currency='')[0] - self.assertEquals(null_instance.name, name + "_null") + self.assertEqual(null_instance.name, name + "_null") - self.assertEquals(NullableMoneyModel.objects.filter(price__isnull=False).count(), 1) + self.assertEqual(NullableMoneyModel.objects.filter(price__isnull=False).count(), 1) undefined_instance = NullableMoneyModel.objects.filter(price__isnull=False)[0] - self.assertEquals(undefined_instance.name, name+"_undefined") + self.assertEqual(undefined_instance.name, name + "_undefined") undefined_instance = NullableMoneyModel.objects.filter(price_currency='XXX')[0] - self.assertEquals(undefined_instance.name, name + "_undefined") + self.assertEqual(undefined_instance.name, name + "_undefined") @pytest.mark.django_db diff --git a/money/tests/test_django_rendering.py b/money/tests/test_django_rendering.py index ed93020..18a8a2d 100644 --- a/money/tests/test_django_rendering.py +++ b/money/tests/test_django_rendering.py @@ -11,7 +11,12 @@ SimpleMoneyModel, ) -from money.tests.views import * +from money.tests.views import ( + instance_view, + model_form_view, + model_from_db_view, + model_view, +) class TestView(TestCase): @@ -65,7 +70,6 @@ class TestEditView(TestCase): def setUp(self): self.client = Client() - def test_form_GET(self): url = reverse(model_form_view, kwargs={'amount': '987.00', 'currency': 'JPY'}) response = self.client.get(url) diff --git a/money/tests/views.py b/money/tests/views.py index 55a6c0a..b2add26 100644 --- a/money/tests/views.py +++ b/money/tests/views.py @@ -16,6 +16,11 @@ class TestModelForm(forms.ModelForm): class Meta: model = SimpleMoneyModel + fields = ( + 'name', + 'price', + ) + def instance_view(request): money = Money('0.0', 'JPY') @@ -33,8 +38,6 @@ def model_from_db_view(request, amount='0', currency='XXX'): instance = SimpleMoneyModel.objects.create(price=Money(amount, currency)) instance = SimpleMoneyModel.objects.get(pk=instance.pk) - print(instance, instance.pk) - money = instance.price return render_to_response('view.html', {'money': money}) @@ -56,37 +59,38 @@ def model_form_view(request, amount='0', currency='XXX'): def regular_form(request): if request.method == 'POST': form = TestForm(request.POST) - print(form.is_valid()) + if form.is_valid(): price = form.cleaned_data['price'] - return render_to_response('form.html', {'price':price} ) + return render_to_response('form.html', {'price': price}) else: form = TestForm() - return render_to_response('form.html', {'form':form} ) + return render_to_response('form.html', {'form': form}) + def regular_form_edit(request, id): instance = get_object_or_404(SimpleMoneyModel, pk=id) if request.method == 'POST': - form = TestForm(request.POST, initial={'price':instance.price}) - print(form.is_valid()) + form = TestForm(request.POST, initial={'price': instance.price}) + form = TestForm(request.POST, initial={'price': instance.price}) + if form.is_valid(): price = form.cleaned_data['price'] - return render_to_response('form.html', {'price':price} ) + return render_to_response('form.html', {'price': price}) else: - form = TestForm(initial={'price':instance.price}) - return render_to_response('form.html', {'form':form} ) - + form = TestForm(initial={'price': instance.price}) + return render_to_response('form.html', {'form': form}) def model_form_edit(request, id): instance = get_object_or_404(SimpleMoneyModel, pk=id) if request.method == 'POST': form = TestModelForm(request.POST, instance=instance) - print(form.is_valid()) + if form.is_valid(): price = form.cleaned_data['price'] form.save() - return render_to_response('form.html', {'price':price} ) + return render_to_response('form.html', {'price': price}) else: form = TestModelForm(instance=instance) - return render_to_response('form.html', {'form':form} ) + return render_to_response('form.html', {'form': form}) diff --git a/setup.py b/setup.py index ff9e338..fcd777f 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ def run_tests(self): tests_require = [ 'pytest-django', 'pytest-cov', - 'django<1.8', + 'django<1.9', 'psycopg2', 'six', ] diff --git a/version.py b/version.py index caab2a6..f75cef5 100644 --- a/version.py +++ b/version.py @@ -46,7 +46,7 @@ # first number: major business changes/milestones # second number: database changes # third number: code changes/patches -from __future__ import unicode_literals +from __future__ import print_function, unicode_literals from subprocess import Popen, PIPE From ac7a5806add0606b1a7b18c5922bbb6a447530e1 Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sun, 1 May 2016 18:53:40 +0900 Subject: [PATCH 07/11] Clean up the README --- README.md | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 629b7d2..6b5b80a 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,8 @@ - python-money ============ Primitives for working with money and currencies in Python - Compatibility ============= @@ -19,7 +17,6 @@ postgres specific field, and a `py.test` based test suite among other changes. You are free to use this version but please look at other forks as well as they may better suit your use case. - Installation ============ @@ -29,7 +26,6 @@ You can install this project directly from the git repository using pip: You do not have to specify the version number but it might be a good idea. - Usage ===== @@ -44,7 +40,7 @@ For example: Currency(code='BZD', numeric='084', name='Belize Dollar', countries=['BELIZE']) -There is a dict of all ISO-4217 currencies: +There is a dictionary of all ISO-4217 currencies: >>> from money.money import CURRENCY >>> print CURRENCY['GBP'].name @@ -53,7 +49,7 @@ There is a dict of all ISO-4217 currencies: ### Money Class The Money class is available for doing arithmetic on values in defined -currencies. It wraps the python Decimal type and gives you several convienience +currencies. It wraps the python Decimal type and gives you several convenience methods. Using this prevents you from making mistakes like adding Pounds and Dollars together, multiplying two money values or comparing different currencies. For example: @@ -106,19 +102,12 @@ If you don't you will get a non-specified 'XXX' currency: >>> print Money(amount=23.45) XXX 23.45 -There is also an exchange rate that may be set: - -This default currency and exchange rate is used for arithmetic addition. If you -add two monetary values that are in differing currency, they will first be -converted into the default currency, and then added together. - - A Note About Equality and Math Operations ----------------------------------------- -The way equlity is currently implemented, `USD 0` is not equal to `EUR 0` however, +The way equality is currently implemented, `USD 0` is not equal to `EUR 0` however, `USD 0` is considered equal to `0`. This means you can only compare similar -currencies to each other, but it is safe to compare a currancy to the value `0`. +currencies to each other, but it is safe to compare a currency to the value `0`. Comparing two differing currencies is undefined and will raise a `money.CurrencyMismatchException`. Prior versions of this project would do an @@ -132,7 +121,7 @@ example, `Money(10, 'USD') - Money(3, 'JPY')` is not allowed due to differing currencies. Both `Money(3, 'USD') * Money(3, 'USD')` and `Money(9, 'USD') / Money(3, 'USD')` -are undefined. There are 3 conceiveable ways to handle division: +are undefined. There are 3 conceivable ways to handle division: Money(9, 'USD') / Money(3, 'USD') # Money(3, 'XXX') # where 'XXX' denotes undefined currency Money(9, 'USD') / Money(3, 'USD') # Decimal('3') @@ -164,12 +153,11 @@ python `Decimal` class: bool(Money('0.01', 'USD')) # True bool(Money('1')) # True -To test for the existance of the objects, compare the value to `None`: +To test for the existence of the objects, compare the value to `None`: if amount is None: amount = Money(0) - Django ====== @@ -188,9 +176,9 @@ the Django DecimalField: price = MoneyField(default=0, max_digits=12, decimal_places=2) ... -Now run ./manage.py dbsync or South migrate. Your database table will contain a +Now run `./manage.py dbsync` or South migrate. Your database table will contain a field for holding the value and a second field for the currency type. In -postgresql it might look like this: +PostgreSQL it might look like this: price | numeric(12,2) | not null default NULL::numeric price_currency | character varying(3) | not null @@ -205,22 +193,22 @@ The value you get from your model will be a `Money` class: ### User Defined Precision of Decimals in Postgres It can be difficult to represent decimals exactly as the user entered them with -django. If you use postgres, you can preserve the user's entered precision by -using the Postgresql `numeric` type. Simply use the `InfiniteDecimalField` +Django. If you use postgres, you can preserve the user's entered precision by +using the PostgreSQL `numeric` type. Simply use the `InfiniteDecimalField` class and the value will be stored as entered by the user without having to define the precision in the model class. InfiniteDecimalField -This allows you to store and later retreive a values like `3`, `3.0`, and +This allows you to store and later retrieve a values like `3`, `3.0`, and `3.000` without losing the precision. The `MoneyField` class already extends this by default. ### Fixtures -When loading from or searializing to fixtures, the field class expects the values -to be specified separately: +When loading from or serializing to fixtures, the field class expects the +values to be specified separately: ... { @@ -243,7 +231,7 @@ The form field used by the `models.MoneyField` is also called `MoneyField` ### Running Tests -The test suite requires `py.test`, `django` and several other libaries to be +The test suite requires `py.test`, `django` and several other libraries to be installed. They will be downloaded and installed automatically when run. Tests can be run via the `setup.py` script: From d12f0a9ed268edbddee5252fcdc837c831060fa8 Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sun, 1 May 2016 19:29:18 +0900 Subject: [PATCH 08/11] Use PostgreSQL for tests --- .travis.yml | 6 ++++-- money/tests/settings.py | 28 +++++++++++++++++++++------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index e910ea5..58896d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ language: python python: - - "2.7" - - "3.5" + - "2.7" + - "3.5" script: python setup.py test +services: + - postgresql diff --git a/money/tests/settings.py b/money/tests/settings.py index 784e277..42ac032 100644 --- a/money/tests/settings.py +++ b/money/tests/settings.py @@ -9,16 +9,30 @@ STATIC_ROOT = os.path.join(TEST_DIR, 'static') DATABASES = { + #'default': { + # 'ENGINE': 'django.db.backends.sqlite3', + # 'NAME': ':memory:', + #}, 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': ':memory:', - }, - # 'default': { - # 'ENGINE': 'django.db.backends.postgresql_psycopg2', - # 'NAME': 'money', - # } + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'money', + 'USER': '', + 'PASSWORD': '', + } } + +if os.environ.get('CIRCLECI'): + DATABASES['default']['USER'] = 'ubuntu' +elif os.environ.get('TRAVIS'): + DATABASES['default']['USER'] = 'postgres' +elif os.environ.get('SNAP_CI'): + DATABASES['default']['USER'] = os.environ['SNAP_DB_PG_USER'] + DATABASES['default']['PASSWORD'] = os.environ['SNAP_DB_PG_PASSWORD'] + DATABASES['default']['HOST'] = os.environ['SNAP_DB_PG_HOST'] + DATABASES['default']['PORT'] = os.environ['SNAP_DB_PG_PORT'] + + INSTALLED_APPS = ( 'money', 'money.tests', From 869bf7718e524f80d82bc1dafd9b8d0a9dd5b6a2 Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sun, 1 May 2016 19:44:06 +0900 Subject: [PATCH 09/11] Clean up warnings --- MANIFEST.in | 3 --- money/tests/views.py | 22 +++++++++++----------- setup.py | 1 - 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index f99c169..1aedc82 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,10 +1,7 @@ include MANIFEST.in include RELEASE-VERSION -include *.txt include *.md include *.py recursive-include money * -recursive-include tests * -recursive-exclude * __pycache__ recursive-exclude * *.py[co] diff --git a/money/tests/views.py b/money/tests/views.py index b2add26..4bc8f29 100644 --- a/money/tests/views.py +++ b/money/tests/views.py @@ -8,11 +8,11 @@ from money.tests.models import SimpleMoneyModel -class TestForm(forms.Form): +class SampleForm(forms.Form): price = MoneyField() -class TestModelForm(forms.ModelForm): +class SampleModelForm(forms.ModelForm): class Meta: model = SimpleMoneyModel @@ -45,52 +45,52 @@ def model_from_db_view(request, amount='0', currency='XXX'): def model_form_view(request, amount='0', currency='XXX'): cleaned_data = {} if request.method == 'POST': - form = TestModelForm(request.POST) + form = SampleModelForm(request.POST) if form.is_valid(): cleaned_data = form.cleaned_data form.save() # Most views would redirect here but we continue so we can render the data else: - form = TestModelForm(initial={'price': Money(amount, currency)}) + form = SampleModelForm(initial={'price': Money(amount, currency)}) return render_to_response('form.html', {'form': form, 'cleaned_data': cleaned_data}) def regular_form(request): if request.method == 'POST': - form = TestForm(request.POST) + form = SampleForm(request.POST) if form.is_valid(): price = form.cleaned_data['price'] return render_to_response('form.html', {'price': price}) else: - form = TestForm() + form = SampleForm() return render_to_response('form.html', {'form': form}) def regular_form_edit(request, id): instance = get_object_or_404(SimpleMoneyModel, pk=id) if request.method == 'POST': - form = TestForm(request.POST, initial={'price': instance.price}) - form = TestForm(request.POST, initial={'price': instance.price}) + form = SampleForm(request.POST, initial={'price': instance.price}) + form = SampleForm(request.POST, initial={'price': instance.price}) if form.is_valid(): price = form.cleaned_data['price'] return render_to_response('form.html', {'price': price}) else: - form = TestForm(initial={'price': instance.price}) + form = SampleForm(initial={'price': instance.price}) return render_to_response('form.html', {'form': form}) def model_form_edit(request, id): instance = get_object_or_404(SimpleMoneyModel, pk=id) if request.method == 'POST': - form = TestModelForm(request.POST, instance=instance) + form = SampleModelForm(request.POST, instance=instance) if form.is_valid(): price = form.cleaned_data['price'] form.save() return render_to_response('form.html', {'price': price}) else: - form = TestModelForm(instance=instance) + form = SampleModelForm(instance=instance) return render_to_response('form.html', {'form': form}) diff --git a/setup.py b/setup.py index fcd777f..2e28d95 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,6 @@ def run_tests(self): setup( name='python-money', version=get_git_version(), - source_label=get_git_hash(), description='Primitives for working with money and currencies in Python', url='http://github.com/poswald/python-money', maintainer='Paul Oswald', From 2c3eb142e921e3f8e6854859bd4d4f384a0d3192 Mon Sep 17 00:00:00 2001 From: Daniel Izquierdo Date: Sun, 1 May 2016 19:54:56 +0900 Subject: [PATCH 10/11] Clean up some pep8 and pylint warnings --- money/contrib/django/models/fields.py | 16 ++++++++-------- money/money.py | 27 ++++++++++++--------------- money/tests/settings.py | 8 ++++---- money/tests/test_django.py | 16 ++++++++-------- setup.py | 3 +-- 5 files changed, 33 insertions(+), 37 deletions(-) diff --git a/money/contrib/django/models/fields.py b/money/contrib/django/models/fields.py index 055268d..2ec2f41 100644 --- a/money/contrib/django/models/fields.py +++ b/money/contrib/django/models/fields.py @@ -64,24 +64,24 @@ def __get__(self, obj, *args): return Money(amount, currency) def __set__(self, obj, value): - if value is None: # Money(0) is False + if value is None: # Money(0) is False self._set_values(obj, None, '') elif isinstance(value, Money): self._set_values(obj, value.amount, value.currency) elif isinstance(value, Decimal): - _, currency = self._get_values(obj) # use what is currently set + _, currency = self._get_values(obj) # use what is currently set self._set_values(obj, value, currency) else: # It could be an int, or some other python native type try: amount = Decimal(str(value)) - _, currency = self._get_values(obj) # use what is currently set + _, currency = self._get_values(obj) # use what is currently set self._set_values(obj, amount, currency) except TypeError: # Lastly, assume string type 'XXX 123' or something Money can # handle. try: - _, currency = self._get_values(obj) # use what is currently set + _, currency = self._get_values(obj) # use what is currently set m = Money.from_string(str(value)) self._set_values(obj, m.amount, m.currency) except TypeError: @@ -135,7 +135,7 @@ class MoneyField(InfiniteDecimalField): # Don't extend SubfieldBase since we need to have access to both fields when # to_python is called. We need our code there instead of subfieldBase - #__metaclass__ = models.SubfieldBase + # __metaclass__ = models.SubfieldBase def __init__(self, *args, **kwargs): # We add the currency field except when using frozen south orm. See introspection rules below. @@ -146,10 +146,10 @@ def __init__(self, *args, **kwargs): self.blankable = kwargs.get('blank', False) if isinstance(default, Money): - self.default_currency = default.currency # use the default's currency + self.default_currency = default.currency # use the default's currency kwargs['default'] = default.amount else: - self.default_currency = default_currency or '' # use the kwarg passed in + self.default_currency = default_currency or '' # use the kwarg passed in super(MoneyField, self).__init__(*args, **kwargs) @@ -185,7 +185,7 @@ def contribute_to_class(self, cls, name): max_length=3, default=self.default_currency, editable=False, - null=False, # empty char fields should be '' + null=False, # empty char fields should be '' blank=self.blankable, db_column=currency_field_db_column(self.db_column), ) diff --git a/money/money.py b/money/money.py index 1357824..b91f53d 100644 --- a/money/money.py +++ b/money/money.py @@ -111,7 +111,7 @@ def from_string(cls, value): def _currency_check(self, other): """ Compare the currencies matches and raise if not """ if self._currency != other.currency: - raise CurrencyMismatchException(u"Currency mismatch: %s != %s" % (self._currency, other.currency,)) + raise CurrencyMismatchException("Currency mismatch: %s != %s" % (self._currency, other.currency,)) def __init__(self, amount=None, currency=None): if isinstance(amount, Decimal): @@ -187,11 +187,11 @@ def __rsub__(self, other): # In the case where both values are Money, the left hand one will be # called. In the case where we are subtracting Money from another # value, we want to disallow it - raise TypeError("Can not subtact Money from %r" % other) + raise TypeError("Cannot subtract Money from %r" % other) def __mul__(self, other): if isinstance(other, Money): - raise InvalidOperationException(u'Cannot multiply monetary quantities') + raise InvalidOperationException("Cannot multiply monetary quantities") return Money(amount=self._amount*Decimal(str(other)), currency=self._currency) def __truediv__(self, other): @@ -200,29 +200,26 @@ def __truediv__(self, other): another Money value is undefined """ if isinstance(other, Money): - raise InvalidOperationException(u'Cannot divide two monetary quantities') + raise InvalidOperationException("Cannot divide two monetary quantities") return Money(amount=self._amount / other, currency=self._currency) __div__ = __truediv__ def __floordiv__(self, other): - raise InvalidOperationException(u'Floor division not supported for monetary quantities') + raise InvalidOperationException("Floor division not supported for monetary quantities") def __rtruediv__(self, other): - raise InvalidOperationException(u'Cannot divide by monetary quantities') + raise InvalidOperationException("Cannot divide by monetary quantities") __rdiv__ = __rtruediv__ - # Communative operations + # Commutative operations __radd__ = __add__ __rmul__ = __mul__ # Boolean def __bool__(self): - if self._amount != 0: - return True - else: - return False + return self._amount != 0 __nonzero__ = __bool__ @@ -241,16 +238,16 @@ def __ne__(self, other): def __lt__(self, other): if isinstance(other, Money): self._currency_check(other) - return (self._amount < other.amount) + return self._amount < other.amount else: - return (self._amount < Decimal(str(other))) + return self._amount < Decimal(str(other)) def __gt__(self, other): if isinstance(other, Money): self._currency_check(other) - return (self._amount > other.amount) + return self._amount > other.amount else: - return (self._amount > Decimal(str(other))) + return self._amount > Decimal(str(other)) def __le__(self, other): return self < other or self == other diff --git a/money/tests/settings.py b/money/tests/settings.py index 42ac032..68d2ead 100644 --- a/money/tests/settings.py +++ b/money/tests/settings.py @@ -9,10 +9,10 @@ STATIC_ROOT = os.path.join(TEST_DIR, 'static') DATABASES = { - #'default': { - # 'ENGINE': 'django.db.backends.sqlite3', - # 'NAME': ':memory:', - #}, + # 'default': { + # 'ENGINE': 'django.db.backends.sqlite3', + # 'NAME': ':memory:', + # }, 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'money', diff --git a/money/tests/test_django.py b/money/tests/test_django.py index 3f2aa9e..c2f751b 100644 --- a/money/tests/test_django.py +++ b/money/tests/test_django.py @@ -53,16 +53,16 @@ def test_retrive(self): price = Money(100, "USD") SimpleMoneyModel.objects.create(name="one hundred dollars", price=price) - #Filter + # Filter qset = SimpleMoneyModel.objects.filter(price=price) self.assertEqual(qset.count(), 1) self.assertEqual(qset[0].price, price) - #Get + # Get entry = SimpleMoneyModel.objects.get(price=price) self.assertEqual(entry.price, price) - #test retrieving without currency + # test retrieving without currency entry = SimpleMoneyModel.objects.get(price=100) self.assertEqual(entry.price, price) @@ -124,7 +124,7 @@ def test_lookup(self): SimpleMoneyModel.objects.create(name="one hundred and one hrivnyas", price=UAH100 + 1) SimpleMoneyModel.objects.create(name="ninety nine hrivnyas", price=UAH100 - 1) - #Exact: + # Exact: qset = SimpleMoneyModel.objects.filter(price__exact=USD100) self.assertEqual(qset.count(), 1) qset = SimpleMoneyModel.objects.filter(price__exact=EUR100) @@ -132,7 +132,7 @@ def test_lookup(self): qset = SimpleMoneyModel.objects.filter(price__exact=UAH100) self.assertEqual(qset.count(), 1) - #Less than: + # Less than: qset = SimpleMoneyModel.objects.filter(price__lt=USD100) self.assertEqual(qset.count(), 1) self.assertEqual(qset[0].price, USD100 - 1) @@ -145,7 +145,7 @@ def test_lookup(self): self.assertEqual(qset.count(), 1) self.assertEqual(qset[0].price, UAH100 - 1) - #Greater than: + # Greater than: qset = SimpleMoneyModel.objects.filter(price__gt=USD100) self.assertEqual(qset.count(), 1) self.assertEqual(qset[0].price, USD100 + 1) @@ -158,7 +158,7 @@ def test_lookup(self): self.assertEqual(qset.count(), 1) self.assertEqual(qset[0].price, UAH100 + 1) - #Less than or equal: + # Less than or equal: qset = SimpleMoneyModel.objects.filter(price__lte=USD100) self.assertEqual(qset.count(), 2) self.assertSameCurrency([ent.price for ent in qset], "USD") @@ -177,7 +177,7 @@ def test_lookup(self): for ent in qset: self.assertTrue(ent.price.amount <= 100) - #Greater than or equal: + # Greater than or equal: qset = SimpleMoneyModel.objects.filter(price__gte=USD100) self.assertEqual(qset.count(), 2) self.assertSameCurrency([ent.price for ent in qset], "USD") diff --git a/setup.py b/setup.py index 2e28d95..e746c2c 100644 --- a/setup.py +++ b/setup.py @@ -27,7 +27,7 @@ def finalize_options(self): self.test_suite = True def run_tests(self): - #import here, cause outside the eggs aren't loaded + # import here, cause outside the eggs aren't loaded import pytest errno = pytest.main(self.test_args) sys.exit(errno) @@ -64,7 +64,6 @@ def run_tests(self): platforms=["any"], keywords=keywords, long_description=README, - #test_suite='tests', packages=[ 'money', ], From 2398f78dc6fa3af95632b7faf77129264044c897 Mon Sep 17 00:00:00 2001 From: Paul Oswald Date: Mon, 2 May 2016 13:20:58 +0900 Subject: [PATCH 11/11] Update for version 1.1 --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b5b80a..b29fd2f 100644 --- a/README.md +++ b/README.md @@ -265,7 +265,16 @@ TODO CHANGELOG === -* Version 1.0.0 +* Version 1.1 + + - Python 3 compatibility + - Fix queryset returning the wrong value when running in Django 1.8 + +* Version 1.0.1 (tagged 0.3.3) + + - Add support or the `db_column` parameter + +* Version 1.0.0 (tagged 0.3.2) Note: This fork of the project is now going to be version-managed separate from other forks. This is the first release that we consider to be fully