Repository: joke2k/faker
Pull request #259 (2015-06-17 19:18:29)

seed a Random instance instead of the module
Seeding the random module will seed that module globally --
this affects calls to random outside the faker package.
Seeding an instance of the Random class will not affect
other calls to the random module.
This addresses one concern in issue #14.

Let me know if you want me to change anything!


Patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 3f8bb0da..f8baf4e0 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,4 +1,4 @@
 [bumpversion]
-current_version = 0.5.2
+current_version = 0.5.1
 files = setup.py faker/__init__.py docs/conf.py
 
diff --git a/.travis.yml b/.travis.yml
index 1a4348bc..23e71cbb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,6 +11,7 @@ python:
   - "pypy3"
 install:
   - pip install -e .
+  - pip install -r faker/tests/requirements.txt
   - pip install coveralls
 script:
   - coverage run --source=faker setup.py test
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 147b840b..13c5dee4 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -8,7 +8,6 @@ Changelog
 * Fixed `jcb15` and `jcb16` in `credit_card` provider. Thanks Rodrigo Braz.
 * Fixed CVV and CID code generation in `credit_card` provider. Thanks Kevin Stone.
 * Added `--include` flag to command line tool. Thanks Flavio Curella.
-* Added `country_code` to `address` provider. Thanks @elad101 and Tobin Brown.
 
 
 `0.5.1 - 21-May-2015 <http://github.com/joke2k/faker/compare/v0.5...v0.5.1>`__
diff --git a/README.rst b/README.rst
index 7143d166..3e6b6e86 100644
--- a/README.rst
+++ b/README.rst
@@ -280,6 +280,11 @@ same results.
 
 Tests
 -----
+Installing dependencies:
+
+.. code:: bash
+
+    $ pip install -r faker/tests/requirements.txt
 
 Run tests:
 
diff --git a/appveyor.yml b/appveyor.yml
index d9fa6ed4..a7a20237 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -12,6 +12,7 @@ install:
   - ps: (new-object net.webclient).DownloadFile('https://raw.github.com/pypa/pip/master/contrib/get-pip.py', 'C:/get-pip.py')
   - "%PYTHON%/python.exe C:/get-pip.py"
   - "%PYTHON%/Scripts/pip.exe install -e ."
+  - "%PYTHON%/Scripts/pip.exe install -r faker/tests/requirements.txt"
 test_script:
   - "%PYTHON%/Scripts/pip.exe --version"
   - "%PYTHON%/python.exe setup.py test"
diff --git a/circle.yml b/circle.yml
new file mode 100644
index 00000000..d6005267
--- /dev/null
+++ b/circle.yml
@@ -0,0 +1,3 @@
+dependencies:
+  pre:
+    - pip install -r faker/tests/requirements.txt
diff --git a/docs/conf.py b/docs/conf.py
index a929e5ab..c4b20a97 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -54,9 +54,9 @@ copyright = u'2014, Daniele Faraglia'
 # built documents.
 #
 # The short X.Y version.
-version = '0.5.2'
+version = '0.5.1'
 # The full version, including alpha/beta/rc tags.
-release = '0.5.2'
+release = '0.5.1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/faker/__init__.py b/faker/__init__.py
index 9bff28f1..5c34d5fa 100644
--- a/faker/__init__.py
+++ b/faker/__init__.py
@@ -1,4 +1,4 @@
-VERSION = '0.5.2'
+VERSION = '0.5.1'
 
 from faker.generator import Generator
 from faker.factory import Factory
diff --git a/faker/generator.py b/faker/generator.py
index 7b383be2..95dfac2a 100644
--- a/faker/generator.py
+++ b/faker/generator.py
@@ -7,6 +7,7 @@ import random
 
 
 _re_token = re.compile(r'\{\{(\s?)(\w+)(\s?)\}\}')
+random = random.Random()
 
 
 class Generator(object):
diff --git a/faker/providers/__init__.py b/faker/providers/__init__.py
index a876d2f9..d46cfbf5 100644
--- a/faker/providers/__init__.py
+++ b/faker/providers/__init__.py
@@ -1,8 +1,9 @@
 # coding=utf-8
 
 import re
-import random
 import string
+
+from faker.generator import random
 from faker.utils.distribution import choice_distribution
 
 
diff --git a/faker/providers/address/__init__.py b/faker/providers/address/__init__.py
index 875ac355..6e25cb65 100644
--- a/faker/providers/address/__init__.py
+++ b/faker/providers/address/__init__.py
@@ -1,10 +1,10 @@
 # coding=utf-8
 from __future__ import unicode_literals
 from decimal import Decimal
-import random
 
 from .. import BaseProvider
 from .. import date_time
+from faker.generator import random
 
 localized = True
 
@@ -19,7 +19,6 @@ class Provider(BaseProvider):
     building_number_formats = ('##', )
     postcode_formats = ('#####', )
     countries = [tz['name'] for tz in date_time.Provider.countries]
-    country_codes = [tz['code'] for tz in date_time.Provider.countries]
 
     @classmethod
     def city_suffix(cls):
@@ -81,10 +80,6 @@ class Provider(BaseProvider):
     def country(cls):
         return cls.random_element(cls.countries)
 
-    @classmethod
-    def country_code(cls):
-        return cls.random_element(cls.country_codes)
-
     @classmethod
     def geo_coordinate(cls, center=None, radius=0.001):
         """
diff --git a/faker/providers/address/el_GR/__init__.py b/faker/providers/address/el_GR/__init__.py
index 50d40afa..1afc29fd 100644
--- a/faker/providers/address/el_GR/__init__.py
+++ b/faker/providers/address/el_GR/__init__.py
@@ -1,8 +1,9 @@
 # coding=utf-8
 from __future__ import unicode_literals
 from decimal import Decimal
-import random
+
 from .. import Provider as AddressProvider
+from faker.generator import random
 
 
 def contains_point(poly, point):
diff --git a/faker/providers/address/en_US/__init__.py b/faker/providers/address/en_US/__init__.py
index 9b4ce8ff..c8750433 100644
--- a/faker/providers/address/en_US/__init__.py
+++ b/faker/providers/address/en_US/__init__.py
@@ -1,7 +1,7 @@
 from __future__ import unicode_literals
-import random
 
 from ..en import Provider as AddressProvider
+from faker.generator import random
 
 
 class Provider(AddressProvider):
diff --git a/faker/providers/address/ja_JP/__init__.py b/faker/providers/address/ja_JP/__init__.py
index f268df50..a212f09c 100644
--- a/faker/providers/address/ja_JP/__init__.py
+++ b/faker/providers/address/ja_JP/__init__.py
@@ -1,7 +1,8 @@
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
-import random
+
 from .. import Provider as AddressProvider
+from faker.generator import random
 
 
 class Provider(AddressProvider):
diff --git a/faker/providers/company/fi_FI/__init__.py b/faker/providers/company/fi_FI/__init__.py
index d2e38878..0a5cb4c0 100644
--- a/faker/providers/company/fi_FI/__init__.py
+++ b/faker/providers/company/fi_FI/__init__.py
@@ -13,41 +13,3 @@ class Provider(CompanyProvider):
     company_suffixes = (
         'As Oy', 'Tmi', 'Oy', 'Oyj', 'Ky', 'Osk', 'ry'
     )
-
-    def company_business_id(self):
-        """
-        Returns Finnish company Business Identity Code (y-tunnus).
-        Format is 8 digits - e.g. FI99999999,[8] last digit is a check
-        digit utilizing MOD 11-2. The first digit is zero for some old
-        organizations. This function provides current codes starting with
-        non-zero.
-        """
-        def calculate_checksum(number):
-            """Calculate the checksum using mod 11,2 method"""
-            factors = [7, 9, 10, 5, 8, 4, 2]
-            sum = 0
-            for x, y in zip(number, factors):
-                sum = sum + int(x) * y
-            if sum % 11 == 0:
-                return '0'
-            else:
-                return str(11 - sum % 11)
-
-        first_digit = str(self.random_digit_not_null())
-        body = first_digit + self.bothify(self.random_element(('######',)))
-        cs = calculate_checksum(body)
-        return (body + '-' + str(cs))
-
-    def company_vat(self):
-        """
-        Returns Finnish VAT identification number (Arvonlisaveronumero).
-        This can be calculated from company business identity code by
-        adding prefix "FI" and removing dash before checksum.
-        """
-        def convert_to_vat(business_id):
-            """
-            Convert business id to VATIN
-            """
-            return 'FI' + business_id.replace('-', '')
-
-        return convert_to_vat(self.company_business_id())
diff --git a/faker/providers/date_time/__init__.py b/faker/providers/date_time/__init__.py
index 146ae89d..f2e93e5c 100644
--- a/faker/providers/date_time/__init__.py
+++ b/faker/providers/date_time/__init__.py
@@ -2,12 +2,12 @@
 
 from __future__ import unicode_literals
 
-import random
 import re
 from time import time, mktime
 
 from datetime import timedelta
 
+from faker.generator import random
 from faker.utils.datetime_safe import date, datetime, real_date, real_datetime
 from faker.utils import is_string
 
diff --git a/faker/providers/internet/__init__.py b/faker/providers/internet/__init__.py
index 6e517426..3deff04d 100644
--- a/faker/providers/internet/__init__.py
+++ b/faker/providers/internet/__init__.py
@@ -2,10 +2,10 @@
 
 from __future__ import unicode_literals
 from .. import BaseProvider
-import random
 import re
 import unicodedata
 
+from faker.generator import random
 from faker.providers.lorem.la import Provider as Lorem
 from faker.utils.decorators import slugify, slugify_domain
 
diff --git a/faker/providers/misc/__init__.py b/faker/providers/misc/__init__.py
index a3544620..32531a60 100644
--- a/faker/providers/misc/__init__.py
+++ b/faker/providers/misc/__init__.py
@@ -2,10 +2,10 @@
 
 from __future__ import unicode_literals
 import hashlib
-import random
 import string
 import uuid
 
+from faker.generator import random
 from faker.providers.date_time import Provider as DatetimeProvider
 
 from .. import BaseProvider
diff --git a/faker/providers/ssn/en_CA/__init__.py b/faker/providers/ssn/en_CA/__init__.py
index b84f886e..7bc6cd1e 100644
--- a/faker/providers/ssn/en_CA/__init__.py
+++ b/faker/providers/ssn/en_CA/__init__.py
@@ -1,7 +1,7 @@
 # coding=utf-8
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-import random
+from faker.generator import random
 
 
 class Provider(SsnProvider):
diff --git a/faker/providers/ssn/fi_FI/__init__.py b/faker/providers/ssn/fi_FI/__init__.py
index 4461e0f9..44d9ff36 100644
--- a/faker/providers/ssn/fi_FI/__init__.py
+++ b/faker/providers/ssn/fi_FI/__init__.py
@@ -2,8 +2,8 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
+from faker.generator import random
 import datetime
-import random
 
 
 class Provider(SsnProvider):
diff --git a/faker/providers/ssn/nl_NL/__init__.py b/faker/providers/ssn/nl_NL/__init__.py
index 41756f1d..087a5509 100644
--- a/faker/providers/ssn/nl_NL/__init__.py
+++ b/faker/providers/ssn/nl_NL/__init__.py
@@ -2,7 +2,7 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
-import random
+from faker.generator import random
 
 
 class Provider(SsnProvider):
diff --git a/faker/providers/ssn/sv_SE/__init__.py b/faker/providers/ssn/sv_SE/__init__.py
index f9af55d3..ff6a8e0b 100644
--- a/faker/providers/ssn/sv_SE/__init__.py
+++ b/faker/providers/ssn/sv_SE/__init__.py
@@ -2,8 +2,8 @@
 
 from __future__ import unicode_literals
 from .. import Provider as SsnProvider
+from faker.generator import random
 import datetime
-import random
 
 
 class Provider(SsnProvider):
diff --git a/faker/providers/user_agent/__init__.py b/faker/providers/user_agent/__init__.py
index ed5c952d..511ccdb0 100644
--- a/faker/providers/user_agent/__init__.py
+++ b/faker/providers/user_agent/__init__.py
@@ -3,8 +3,8 @@
 from __future__ import unicode_literals
 
 from datetime import datetime
-import random
 
+from faker.generator import random
 from faker.providers.date_time import Provider as DatetimeProvider
 
 from .. import BaseProvider
diff --git a/faker/utils/distribution.py b/faker/utils/distribution.py
index e562f64c..9182a86a 100644
--- a/faker/utils/distribution.py
+++ b/faker/utils/distribution.py
@@ -1,8 +1,7 @@
 # coding=utf-8
 
 import bisect
-import random
-
+from faker.generator import random
 
 def random_sample():
     return random.uniform(0.0, 1.0)
diff --git a/setup.py b/setup.py
index 9097f402..f033ae63 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@ README = io.open(os.path.join(here, 'README.rst'), encoding="utf8").read()
 NEWS = io.open(os.path.join(here, 'CHANGELOG.rst'), encoding="utf8").read()
 
 
-version = '0.5.2'
+version = '0.5.1'
 
 install_requires = []
 if ((sys.version_info[0] == 2 and sys.version_info[1] < 7) or


Test patch:
diff --git a/faker/tests/__init__.py b/faker/tests/__init__.py
index b10c7d92..e49bd598 100644
--- a/faker/tests/__init__.py
+++ b/faker/tests/__init__.py
@@ -7,17 +7,22 @@ __loader__ = None
 import datetime
 import json
 import os
-import random
 import time
 import unittest
 import sys
 
+try:
+    from mock import patch
+except ImportError:
+    from unittest.mock import patch
+
 try:
     from StringIO import StringIO
 except ImportError:
     from io import StringIO
 
 from faker import Generator, Factory
+from faker.generator import random
 from faker.utils import text, decorators
 
 try:
@@ -324,20 +329,20 @@ class FactoryTestCase(unittest.TestCase):
         provider = Provider
         # test century
         self.assertTrue(self._datetime_to_time(provider.date_time_this_century(after_now=False)) <= self._datetime_to_time(datetime.datetime.now()))
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_century(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.datetime.now()))
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_century(before_now=False)) >= self._datetime_to_time(datetime.datetime.now()))
         # test decade
         self.assertTrue(self._datetime_to_time(provider.date_time_this_decade(after_now=False)) <= self._datetime_to_time(datetime.datetime.now()))
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_decade(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.datetime.now()))
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_decade(before_now=False)) >= self._datetime_to_time(datetime.datetime.now()))
         self.assertEqual(self._datetime_to_time(provider.date_time_this_decade(before_now=False, after_now=False)),
                                self._datetime_to_time(datetime.datetime.now()))
         # test year
         self.assertTrue(self._datetime_to_time(provider.date_time_this_year(after_now=False)) <= self._datetime_to_time(datetime.datetime.now()))
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_year(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.datetime.now()))
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_year(before_now=False)) >= self._datetime_to_time(datetime.datetime.now()))
         self.assertEqual(self._datetime_to_time(provider.date_time_this_year(before_now=False, after_now=False)),
                                self._datetime_to_time(datetime.datetime.now()))
         # test month
         self.assertTrue(self._datetime_to_time(provider.date_time_this_month(after_now=False)) <= self._datetime_to_time(datetime.datetime.now()))
-        self.assertTrue(self._datetime_to_time(provider.date_time_this_month(before_now=False, after_now=True)) >= self._datetime_to_time(datetime.datetime.now()))
+        self.assertTrue(self._datetime_to_time(provider.date_time_this_month(before_now=False)) >= self._datetime_to_time(datetime.datetime.now()))
         self.assertEqual(self._datetime_to_time(provider.date_time_this_month(before_now=False, after_now=False)),
                                self._datetime_to_time(datetime.datetime.now()))
 
@@ -366,5 +371,16 @@ class FactoryTestCase(unittest.TestCase):
         self.assertEqual(sentence, '')
 
 
+class GeneratorTestCase(unittest.TestCase):
+
+    def setUp(self):
+        self.generator = Generator()
+
+    @patch('random.seed')
+    def test_random_seed_doesnt_seed_system_random(self, mock_system_random):
+        self.generator.seed(0)
+        self.assertFalse(mock_system_random.called)
+
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/faker/tests/requirements.txt b/faker/tests/requirements.txt
new file mode 100644
index 00000000..c78278b6
--- /dev/null
+++ b/faker/tests/requirements.txt
@@ -0,0 +1,1 @@
+mock==1.0.1