Repository: joke2k/faker
Pull request #707 (2018-02-24 18:55:23)

Added hexify
### What does this changes

In the same spirit than lexify, I added hexify, to format strings with hexadecimal numbers.

I could be useful in many case, especially to develop providers.


Patch:
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index a3d45120..4521e0a8 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 0.8.12
+current_version = 0.8.11
 files = setup.py faker/__init__.py docs/conf.py
 commit = True
 tag = True
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 8fb9717e..4c79a08e 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,22 +1,6 @@
 Changelog
 =========
 
-`0.8.12 - 12-March-2018 <https://github.com/joke2k/faker/compare/v0.8.11...v0.8.12>`__
---------------------------------------------------------------------------------------
-
-* Fix issue with ``cx_Freeze``. Thanks @sedominik.
-* Add dutch ``nl_NL`` bank provider. Thanks @PatSousa.
-* Add ``distrito`` and ``freguesia`` to ``pt_PT`` ``address`` provider. Thanks @ZuluPro.
-* Fix  unicode issues with the ``person`` provider. Thanks @karthikarul20.
-* Add ``en_SG`` ``person`` provider. Thanks @karthikarul20.
-* Add street names to the Ukrainian address provider. Thanks @cadmi.
-* Add ``de_AT`` address provider. Thanks @bessl.
-* Fix credit card prefixes. Thanks @jphalip.
-* Fix capitalization in ``no_NO`` address provider. Thanks @cloveras.
-* Fix deprecated syntax for raw strings. Thanks @dchudz.
-* Add ``latitude`` and ``longitude`` to ``de_AT`` ``address`` provider. Thanks @bessl.
-* Fix incorrect value in list of middle name for locale ``ru_RU``. Thanks @damirazo.
-
 `0.8.11 - 12-February-2018 <https://github.com/joke2k/faker/compare/v0.8.10...v0.8.11>`__
 -----------------------------------------------------------------------------------------
 
diff --git a/docs/conf.py b/docs/conf.py
index def75da4..6574486d 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.8.12'
+version = '0.8.11'
 # The full version, including alpha/beta/rc tags.
-release = '0.8.12'
+release = '0.8.11'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/docs/index.rst b/docs/index.rst
index 87139ee1..c5cfa531 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -6,7 +6,399 @@
 Welcome to Faker's documentation!
 =================================
 
-.. include:: ../README.rst
+::
+
+    _|_|_|_|          _|
+    _|        _|_|_|  _|  _|      _|_|    _|  _|_|
+    _|_|_|  _|    _|  _|_|      _|_|_|_|  _|_|
+    _|      _|    _|  _|  _|    _|        _|
+    _|        _|_|_|  _|    _|    _|_|_|  _|
+
+*Faker* is a Python package that generates fake data for you. Whether
+you need to bootstrap your database, create good-looking XML documents,
+fill-in your persistence to stress test it, or anonymize data taken from
+a production service, Faker is for you.
+
+Faker is heavily inspired by `PHP Faker`_, `Perl Faker`_, and by `Ruby Faker`_.
+
+----
+
+|pypi| |unix_build| |windows_build| |coverage| |license|
+
+----
+
+Basic Usage
+-----------
+
+Install with pip:
+
+.. code:: bash
+
+    pip install Faker
+
+
+Use ``faker.Faker()`` to create and initialize a faker
+generator, which can generate data by accessing properties named after
+the type of data you want.
+
+.. code:: python
+
+    from faker import Faker
+    fake = Faker()
+
+    fake.name()
+    # 'Lucy Cechtelar'
+
+    fake.address()
+    # "426 Jordy Lodge
+    #  Cartwrightshire, SC 88120-6700"
+
+    fake.text()
+    # Sint velit eveniet. Rerum atque repellat voluptatem quia rerum. Numquam excepturi
+    # beatae sint laudantium consequatur. Magni occaecati itaque sint et sit tempore. Nesciunt
+    # amet quidem. Iusto deleniti cum autem ad quia aperiam.
+    # A consectetur quos aliquam. In iste aliquid et aut similique suscipit. Consequatur qui
+    # quaerat iste minus hic expedita. Consequuntur error magni et laboriosam. Aut aspernatur
+    # voluptatem sit aliquam. Dolores voluptatum est.
+    # Aut molestias et maxime. Fugit autem facilis quos vero. Eius quibusdam possimus est.
+    # Ea quaerat et quisquam. Deleniti sunt quam. Adipisci consequatur id in occaecati.
+    # Et sint et. Ut ducimus quod nemo ab voluptatum.
+
+Each call to method ``fake.name()`` yields a different (random) result.
+This is because faker forwards ``faker.Generator.method_name()`` calls
+to ``faker.Generator.format(method_name)``.
+
+.. code:: python
+
+    for _ in range(0, 10):
+      print fake.name()
+
+    # Adaline Reichel
+    # Dr. Santa Prosacco DVM
+    # Noemy Vandervort V
+    # Lexi O'Conner
+    # Gracie Weber
+    # Roscoe Johns
+    # Emmett Lebsack
+    # Keegan Thiel
+    # Wellington Koelpin II
+    # Ms. Karley Kiehn V
+
+Providers
+---------
+
+Each of the generator properties (like ``name``, ``address``, and
+``lorem``) are called "fake". A faker generator has many of them,
+packaged in "providers". For a list of the bundled providers, see
+:doc:`providers`.
+
+For a list of third-party providers, see :doc:`communityproviders`.
+
+Localization
+------------
+
+``faker.Factory`` can take a locale as an argument, to return localized
+data. If no localized provider is found, the factory falls back to the
+default en\_US locale.
+
+.. code:: python
+
+    from faker import Faker
+    fake = Faker('it_IT')
+    for _ in range(0, 10):
+        print fake.name()
+
+    > Elda Palumbo
+    > Pacifico Giordano
+    > Sig. Avide Guerra
+    > Yago Amato
+    > Eustachio Messina
+    > Dott. Violante Lombardo
+    > Sig. Alighieri Monti
+    > Costanzo Costa
+    > Nazzareno Barbieri
+    > Max Coppola
+
+You can check available Faker locales in the source code, under the
+providers package. The localization of Faker is an ongoing process, for
+which we need your help. Please don't hesitate to create a localized
+provider for your own locale and submit a Pull Request (PR).
+
+Included localized providers:
+
+-  `ar\_EG <https://faker.readthedocs.io/en/master/locales/ar_EG.html>`__ - Arabic (Egypt)
+-  `ar\_PS <https://faker.readthedocs.io/en/master/locales/ar_PS.html>`__ - Arabic (Palestine)
+-  `ar\_SA <https://faker.readthedocs.io/en/master/locales/ar_SA.html>`__ - Arabic (Saudi Arabia)
+-  `bg\_BG <https://faker.readthedocs.io/en/master/locales/bg_BG.html>`__ - Bulgarian
+-  `cs\_CZ <https://faker.readthedocs.io/en/master/locales/cs_CZ.html>`__ - Czech
+-  `de\_DE <https://faker.readthedocs.io/en/master/locales/de_DE.html>`__ - German
+-  `dk\_DK <https://faker.readthedocs.io/en/master/locales/dk_DK.html>`__ - Danish
+-  `el\_GR <https://faker.readthedocs.io/en/master/locales/el_GR.html>`__ - Greek
+-  `en\_AU <https://faker.readthedocs.io/en/master/locales/en_AU.html>`__ - English (Australia)
+-  `en\_CA <https://faker.readthedocs.io/en/master/locales/en_CA.html>`__ - English (Canada)
+-  `en\_GB <https://faker.readthedocs.io/en/master/locales/en_GB.html>`__ - English (Great Britain)
+-  `en\_US <https://faker.readthedocs.io/en/master/locales/en_US.html>`__ - English (United States)
+-  `es\_ES <https://faker.readthedocs.io/en/master/locales/es_ES.html>`__ - Spanish (Spain)
+-  `es\_MX <https://faker.readthedocs.io/en/master/locales/es_MX.html>`__ - Spanish (Mexico)
+-  `et\_EE <https://faker.readthedocs.io/en/master/locales/et_EE.html>`__ - Estonian
+-  `fa\_IR <https://faker.readthedocs.io/en/master/locales/fa_IR.html>`__ - Persian (Iran)
+-  `fi\_FI <https://faker.readthedocs.io/en/master/locales/fi_FI.html>`__ - Finnish
+-  `fr\_FR <https://faker.readthedocs.io/en/master/locales/fr_FR.html>`__ - French
+-  `hi\_IN <https://faker.readthedocs.io/en/master/locales/hi_IN.html>`__ - Hindi
+-  `hr\_HR <https://faker.readthedocs.io/en/master/locales/hr_HR.html>`__ - Croatian
+-  `hu\_HU <https://faker.readthedocs.io/en/master/locales/hu_HU.html>`__ - Hungarian
+-  `it\_IT <https://faker.readthedocs.io/en/master/locales/it_IT.html>`__ - Italian
+-  `ja\_JP <https://faker.readthedocs.io/en/master/locales/ja_JP.html>`__ - Japanese
+-  `ko\_KR <https://faker.readthedocs.io/en/master/locales/ko_KR.html>`__ - Korean
+-  `lt\_LT <https://faker.readthedocs.io/en/master/locales/lt_LT.html>`__ - Lithuanian
+-  `lv\_LV <https://faker.readthedocs.io/en/master/locales/lv_LV.html>`__ - Latvian
+-  `ne\_NP <https://faker.readthedocs.io/en/master/locales/ne_NP.html>`__ - Nepali
+-  `nl\_NL <https://faker.readthedocs.io/en/master/locales/nl_NL.html>`__ - Dutch (Netherlands)
+-  `no\_NO <https://faker.readthedocs.io/en/master/locales/no_NO.html>`__ - Norwegian
+-  `pl\_PL <https://faker.readthedocs.io/en/master/locales/pl_PL.html>`__ - Polish
+-  `pt\_BR <https://faker.readthedocs.io/en/master/locales/pt_BR.html>`__ - Portuguese (Brazil)
+-  `pt\_PT <https://faker.readthedocs.io/en/master/locales/pt_PT.html>`__ - Portuguese (Portugal)
+-  `ro\_RO <https://faker.readthedocs.io/en/master/locales/ro_RO.html>`__ - Romanian
+-  `ru\_RU <https://faker.readthedocs.io/en/master/locales/ru_RU.html>`__ - Russian
+-  `sl\_SI <https://faker.readthedocs.io/en/master/locales/sl_SI.html>`__ - Slovene
+-  `sv\_SE <https://faker.readthedocs.io/en/master/locales/sv_SE.html>`__ - Swedish
+-  `tr\_TR <https://faker.readthedocs.io/en/master/locales/tr_TR.html>`__ - Turkish
+-  `uk\_UA <https://faker.readthedocs.io/en/master/locales/uk_UA.html>`__ - Ukrainian
+-  `zh\_CN <https://faker.readthedocs.io/en/master/locales/zh_CN.html>`__ - Chinese (China)
+-  `zh\_TW <https://faker.readthedocs.io/en/master/locales/zh_TW.html>`__ - Chinese (Taiwan)
+
+Command line usage
+------------------
+
+When installed, you can invoke faker from the command-line:
+
+.. code:: bash
+
+    faker [-h] [--version] [-o output]
+          [-l {bg_BG,cs_CZ,...,zh_CN,zh_TW}]
+          [-r REPEAT] [-s SEP]
+          [-i {package.containing.custom_provider otherpkg.containing.custom_provider}]
+          [fake] [fake argument [fake argument ...]]
+
+Where:
+
+-  ``faker``: is the script when installed in your environment, in
+   development you could use ``python -m faker`` instead
+
+-  ``-h``, ``--help``: shows a help message
+
+-  ``--version``: shows the program's version number
+
+-  ``-o FILENAME``: redirects the output to the specified filename
+
+-  ``-l {bg_BG,cs_CZ,...,zh_CN,zh_TW}``: allows use of a localized
+   provider
+
+-  ``-r REPEAT``: will generate a specified number of outputs
+
+-  ``-s SEP``: will generate the specified separator after each
+   generated output
+
+-  ``-i {my.custom_provider other.custom_provider}`` list of additional custom providers to use.
+   Note that is the import path of the package containing your Provider class, not the custom Provider class itself.
+
+-  ``fake``: is the name of the fake to generate an output for, such as
+   ``name``, ``address``, or ``text``
+
+-  ``[fake argument ...]``: optional arguments to pass to the fake (e.g. the profile fake takes an optional list of comma separated field names as the first argument)
+
+Examples:
+
+.. code:: bash
+
+    $ faker address
+    968 Bahringer Garden Apt. 722
+    Kristinaland, NJ 09890
+
+    $ faker -l de_DE address
+    Samira-Niemeier-Allee 56
+    94812 Biedenkopf
+
+    $ faker profile ssn,birthdate
+    {'ssn': u'628-10-1085', 'birthdate': '2008-03-29'}
+
+    $ faker -r=3 -s=";" name
+    Willam Kertzmann;
+    Josiah Maggio;
+    Gayla Schmitt;
+
+How to create a Provider
+------------------------
+
+.. code:: python
+
+    from faker import Faker
+    fake = Faker()
+
+    # first, import a similar Provider or use the default one
+    from faker.providers import BaseProvider
+
+    # create new provider class
+    class MyProvider(BaseProvider):
+        def foo(self):
+            return 'bar'
+
+    # then add new provider to faker instance
+    fake.add_provider(MyProvider)
+
+    # now you can use:
+    fake.foo()
+    > 'bar'
+
+How to use with Factory Boy
+---------------------------
+
+`Factory Boy`_ already ships with integration with ``Faker``. Simply use the
+``factory.Faker`` method of ``factory_boy``:
+
+.. code:: python
+
+    import factory
+    from myapp.models import Book
+
+    class BookFactory(factory.Factory):
+        class Meta:
+            model = Book
+
+        title = factory.Faker('sentence', nb_words=4)
+        author_name = factory.Faker('name')
+
+Accessing the `random` instance
+-------------------------------
+
+The ``.random`` property on the generator returns the instance of ``random.Random``
+used to generate the values:
+
+.. code:: python
+
+    from faker import Faker
+    fake = Faker()
+    fake.random
+    fake.random.getstate()
+
+By default all generators share the same instance of ``random.Random``, which
+can be accessed with ``from faker.generator import random``. Using this may
+be useful for plugins that want to affect all faker instances.
+
+Seeding the Generator
+---------------------
+
+When using Faker for unit testing, you will often want to generate the same
+data set. For convenience, the generator also provide a ``seed()`` method, which
+seeds the shared random number generator. Calling the same methods with the
+same version of faker and seed produces the same results.
+
+.. code:: python
+
+    from faker import Faker
+    fake = Faker()
+    fake.seed(4321)
+
+    print(fake.name())
+    > Jason Brown
+
+Each generator can also be switched to its own instance of ``random.Random``,
+separate to the shared one, by using the ``seed_instance()`` method, which acts
+the same way. For example:
+
+.. code-block:: python
+
+    from faker import Faker
+    fake = Faker()
+    fake.seed_instance(4321)
+
+    print(fake.name())
+    > Margaret Boehm
+
+Please note that as we keep updating datasets, results are not guaranteed to be
+consistent across patch versions. If you hardcode results in your test, make sure
+you pinned the version of ``Faker`` down to the patch number.
+
+Tests
+-----
+
+Installing dependencies:
+
+.. code:: bash
+
+    $ pip install -r tests/requirements.txt
+
+Run tests:
+
+.. code:: bash
+
+    $ python setup.py test
+
+or
+
+.. code:: bash
+
+    $ python -m unittest -v tests
+
+Write documentation for providers:
+
+.. code:: bash
+
+    $ python -m faker > docs.txt
+
+
+Contribute
+----------
+
+Please see `CONTRIBUTING`_.
+
+License
+-------
+
+Faker is released under the MIT License. See the bundled `LICENSE`_ file for details.
+
+Credits
+-------
+
+-  `FZaninotto`_ / `PHP Faker`_
+-  `Distribute`_
+-  `Buildout`_
+-  `modern-package-template`_
+
+
+.. _FZaninotto: https://github.com/fzaninotto
+.. _PHP Faker: https://github.com/fzaninotto/Faker
+.. _Perl Faker: http://search.cpan.org/~jasonk/Data-Faker-0.07/
+.. _Ruby Faker: http://faker.rubyforge.org/
+.. _Distribute: https://pypi.python.org/pypi/distribute
+.. _Buildout: http://www.buildout.org/
+.. _modern-package-template: https://pypi.python.org/pypi/modern-package-template
+.. _extended docs: https://faker.readthedocs.io/en/latest/
+.. _bundled providers: https://faker.readthedocs.io/en/latest/providers.html
+.. _community providers: https://faker.readthedocs.io/en/latest/communityproviders.html
+.. _LICENSE: https://github.com/joke2k/faker/blob/master/LICENSE.txt
+.. _CONTRIBUTING: https://github.com/joke2k/faker/blob/master/CONTRIBUTING.rst
+.. _Factory Boy: https://github.com/FactoryBoy/factory_boy
+
+.. |pypi| image:: https://img.shields.io/pypi/v/Faker.svg?style=flat-square&label=version
+    :target: https://pypi.python.org/pypi/Faker
+    :alt: Latest version released on PyPi
+
+.. |coverage| image:: https://img.shields.io/coveralls/joke2k/faker/master.svg?style=flat-square
+    :target: https://coveralls.io/r/joke2k/faker?branch=master
+    :alt: Test coverage
+
+.. |unix_build| image:: https://img.shields.io/travis/joke2k/faker/master.svg?style=flat-square&label=unix%20build
+    :target: http://travis-ci.org/joke2k/faker
+    :alt: Build status of the master branch on Mac/Linux
+
+.. |windows_build|  image:: https://img.shields.io/appveyor/ci/joke2k/faker/master.svg?style=flat-square&label=windows%20build
+    :target: https://ci.appveyor.com/project/joke2k/faker
+    :alt: Build status of the master branch on Windows
+
+.. |license| image:: https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square
+    :target: https://raw.githubusercontent.com/joke2k/faker/master/LICENSE.txt
+    :alt: Package license
 
 
 Contents
diff --git a/faker/__init__.py b/faker/__init__.py
index c8c69280..55c47351 100644
--- a/faker/__init__.py
+++ b/faker/__init__.py
@@ -1,4 +1,4 @@
-VERSION = '0.8.12'
+VERSION = '0.8.11'
 
 from faker.generator import Generator
 from faker.factory import Factory
diff --git a/faker/providers/__init__.py b/faker/providers/__init__.py
index b7418fc1..417a033e 100644
--- a/faker/providers/__init__.py
+++ b/faker/providers/__init__.py
@@ -12,6 +12,7 @@ _re_perc = re.compile(r'%')
 _re_excl = re.compile(r'!')
 _re_at = re.compile(r'@')
 _re_qm = re.compile(r'\?')
+_re_cir = re.compile(r'\^')
 
 
 class BaseProvider(object):
@@ -213,3 +214,17 @@ class BaseProvider(object):
         :returns: string with all numerical and letter placeholders filled in
         """
         return self.lexify(self.numerify(text), letters=letters)
+
+    def hexify(self, text='^^^^', upper=False):
+        """
+        Replaces all circumflex ('^') occurrences with a random
+        hexadecimal character.
+
+        :param text: string to be parsed
+        :param upper: Format as uppercase hexadecimal
+        :returns: string with all letter placeholders filled in
+        """
+        letters = string.hexdigits[:-6]
+        if upper:
+            letters = letters.upper()
+        return _re_cir.sub(lambda x: self.random_element(letters), text)
diff --git a/faker/providers/address/de_AT/__init__.py b/faker/providers/address/de_AT/__init__.py
deleted file mode 100644
index e27f7641..00000000
--- a/faker/providers/address/de_AT/__init__.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# coding=utf-8
-
-from __future__ import unicode_literals
-from .. import Provider as AddressProvider
-
-
-class Provider(AddressProvider):
-
-    city_formats = ('{{city_name}}', )
-
-    street_name_formats = (
-        '{{first_name}}-{{last_name}}-{{street_suffix_long}}',
-        '{{last_name}}{{street_suffix_short}}',
-    )
-    street_address_formats = ('{{street_name}} {{building_number}}', )
-    address_formats = ('{{street_address}}\n{{postcode}} {{city}}', )
-
-    building_number_formats = ('###', '##', '#', '#/#', )
-
-    street_suffixes_long = (
-        'Gasse', 'Platz', 'Ring', 'Straße', 'Weg'
-    )
-    street_suffixes_short = (
-        'gasse', 'platz', 'ring', 'straße', 'str.', 'weg'
-    )
-
-    # https://en.wikipedia.org/wiki/List_of_postal_codes_in_Austria
-    postcode_formats = (
-        '1###',
-        '2###',
-        '3###',
-        '4###',
-        '5###',
-        '6###',
-        '7###',
-        '8###',
-        '9###'
-    )
-
-    # https://en.wikipedia.org/wiki/List_of_cities_and_towns_in_Austria
-    cities = (
-        'Allentsteig', 'Altheim', 'Althofen', 'Amstetten', 'Ansfelden', 'Attnang-Puchheim',
-        'Bad Aussee', 'Bad Hall', 'Bad Ischl', 'Bad Leonfelden', 'Bad Radkersburg',
-        'Bad Sankt Leonhard im Lavanttal', 'Bad Vöslau', 'Baden', 'Bärnbach', 'Berndorf',
-        'Bischofshofen', 'Bleiburg', 'Bludenz', 'Braunau am Inn', 'Bregenz',
-        'Bruck an der Leitha', 'Bruck an der Mur', 'Deutsch-Wagram', 'Deutschlandsberg',
-        'Dornbirn', 'Drosendorf-Zissersdorf 1', 'Dürnstein', 'Ebenfurth', 'Ebreichsdorf',
-        'Eferding', 'Eggenburg', 'Eisenerz', 'Eisenstadt', 'Enns', 'Fehring', 'Feldbach',
-        'Feldkirch', 'Feldkirchen', 'Ferlach', 'Fischamend', 'Frauenkirchen', 'Freistadt',
-        'Friedberg', 'Friesach', 'Frohnleiten', 'Fürstenfeld', 'Gallneukirchen', 'Gänserndorf',
-        'Geras', 'Gerasdorf bei Wien', 'Gföhl', 'Gleisdorf', 'Gloggnitz', 'Gmünd',
-        'Gmünd in Kärnten', 'Gmunden', 'Graz', 'Grein', 'Grieskirchen', 'Groß-Enzersdorf',
-        'Groß-Gerungs', 'Groß-Siegharts', 'Güssing', 'Haag', 'Hainburg an der Donau', 'Hainfeld',
-        'Hall in Tirol', 'Hallein', 'Hardegg', 'Hartberg', 'Heidenreichstein', 'Herzogenburg',
-        'Imst', 'Innsbruck', 'Jennersdorf', 'Judenburg', 'Kapfenberg', 'Kindberg', 'Klagenfurt',
-        'Klosterneuburg', 'Knittelfeld', 'Köflach', 'Korneuburg', 'Krems an der Donau', 'Kufstein',
-        'Laa an der Thaya', 'Laakirchen', 'Landeck', 'Langenlois', 'Leibnitz', 'Leoben', 'Lienz',
-        'Liezen', 'Lilienfeld', 'Linz', 'Litschau', 'Maissau', 'Mank', 'Mannersdorf am Leithagebirge',
-        'Marchegg', 'Marchtrenk', 'Mariazell', 'Mattersburg', 'Mattighofen', 'Mautern an der Donau',
-        'Melk', 'Mistelbach an der Zaya', 'Mödling', 'Murau', 'Mureck', 'Mürzzuschlag', 'Neulengbach',
-        'Neumarkt am Wallersee', 'Neunkirchen', 'Neusiedl am See', 'Oberndorf bei Salzburg',
-        'Oberpullendorf', 'Oberwart', 'Oberwälz', 'Perg', 'Peuerbach', 'Pinkafeld', 'Pöchlarn',
-        'Poysdorf', 'Pregarten', 'Pulkau', 'Purbach am Neusiedler See', 'Purkersdorf',
-        'Raabs an der Thaya', 'Radenthein', 'Radstadt', 'Rattenberg', 'Retz', 'Ried im Innkreis',
-        'Rohrbach in Oberösterreich', 'Rottenmann', 'Rust', 'Saalfelden am Steinernen Meer',
-        'Salzburg', 'Sankt Andrä im Lavanttal', 'Sankt Johann im Pongau', 'Sankt Pölten',
-        'Sankt Valentin', 'Sankt Veit an der Glan', 'Schärding', 'Scheibbs', 'Schladming',
-        'Schrattenthal', 'Schrems', 'Schwanenstadt', 'Schwaz', 'Schwechat', 'Spittal an der Drau',
-        'Stadtschlaining', 'Steyr', 'Steyregg', 'Stockerau', 'Straßburg', 'Ternitz', 'Traiskirchen',
-        'Traismauer', 'Traun', 'Trieben', 'Trofaiach', 'Tulln an der Donau', 'Villach', 'Vils',
-        'Vöcklabruck', 'Voitsberg', 'Völkermarkt', 'Waidhofen an der Thaya', 'Waidhofen an der Ybbs',
-        'Weitra', 'Weiz', 'Wels', 'Wien', 'Wiener Neustadt', 'Wieselburg', 'Wilhelmsburg', 'Wolfsberg',
-        'Wolkersdorf', 'Wörgl', 'Ybbs an der Donau', 'Zell am See', 'Zeltweg', 'Zistersdorf', 'Zwettl'
-    )
-
-    # https://en.wikipedia.org/wiki/States_of_Austria
-    states = (
-        'Wien', 'Steiermark', 'Burgenland', 'Tirol', 'Niederösterreich',
-        'Oberösterreich', 'Salzburg', 'Kärnten', 'Vorarlberg'
-    )
-
-    countries = (
-        'Afghanistan', 'Alandinseln', 'Albanien', 'Algerien',
-        'Amerikanisch-Ozeanien', 'Amerikanisch-Samoa',
-        'Amerikanische Jungferninseln', 'Andorra', 'Angola', 'Anguilla',
-        'Antarktis', 'Antigua und Barbuda', 'Argentinien', 'Armenien', 'Aruba',
-        'Aserbaidschan', 'Australien', 'Bahamas', 'Bahrain', 'Bangladesch',
-        'Barbados', 'Belarus', 'Belgien', 'Belize', 'Benin', 'Bermuda',
-        'Bhutan', 'Bolivien', 'Bosnien und Herzegowina', 'Botsuana',
-        'Bouvetinsel', 'Brasilien', 'Britische Jungferninseln',
-        'Britisches Territorium im Indischen Ozean', 'Brunei Darussalam',
-        'Bulgarien', 'Burkina Faso', 'Burundi', 'Chile', 'China', 'Cookinseln',
-        'Costa Rica', 'Côte d’Ivoire', 'Demokratische Republik Kongo',
-        'Demokratische Volksrepublik Korea', 'Deutschland', 'Dominica',
-        'Dominikanische Republik', 'Dschibuti', 'Dänemark', 'Ecuador',
-        'El Salvador', 'Eritrea', 'Estland', 'Falklandinseln', 'Fidschi',
-        'Finnland', 'Frankreich', 'Französisch-Guayana',
-        'Französisch-Polynesien', 'Färöer', 'Gabun', 'Gambia', 'Georgien',
-        'Ghana', 'Gibraltar', 'Grenada', 'Griechenland', 'Grönland',
-        'Guadeloupe', 'Guam', 'Guatemala', 'Guernsey', 'Guinea',
-        'Guinea-Bissau', 'Guyana', 'Haiti', 'Heard- und McDonald-Inseln',
-        'Honduras', 'Indien', 'Indonesien', 'Irak', 'Iran', 'Irland', 'Island',
-        'Isle of Man', 'Israel', 'Italien', 'Jamaika', 'Japan', 'Jemen',
-        'Jersey', 'Jordanien', 'Kaimaninseln', 'Kambodscha', 'Kamerun',
-        'Kanada', 'Kap Verde', 'Kasachstan', 'Katar', 'Kenia', 'Kirgisistan',
-        'Kiribati', 'Kokosinseln', 'Kolumbien', 'Komoren', 'Kongo', 'Kroatien',
-        'Kuba', 'Kuwait', 'Laos', 'Lesotho', 'Lettland', 'Libanon', 'Liberia',
-        'Libyen', 'Liechtenstein', 'Litauen', 'Luxemburg', 'Madagaskar',
-        'Malawi', 'Malaysia', 'Malediven', 'Mali', 'Malta', 'Marokko',
-        'Marshallinseln', 'Martinique', 'Mauretanien', 'Mauritius', 'Mayotte',
-        'Mazedonien', 'Mexiko', 'Mikronesien', 'Monaco', 'Mongolei',
-        'Montenegro', 'Montserrat', 'Mosambik', 'Myanmar', 'Namibia', 'Nauru',
-        'Nepal', 'Neukaledonien', 'Neuseeland', 'Nicaragua', 'Niederlande',
-        'Niederländische Antillen', 'Niger', 'Nigeria', 'Niue', 'Norfolkinsel',
-        'Norwegen', 'Nördliche Marianen', 'Oman', 'Osttimor', 'Pakistan',
-        'Palau', 'Palästinensische Gebiete', 'Panama', 'Papua-Neuguinea',
-        'Paraguay', 'Peru', 'Philippinen', 'Pitcairn', 'Polen', 'Portugal',
-        'Puerto Rico', 'Republik Korea', 'Republik Moldau', 'Ruanda',
-        'Rumänien', 'Russische Föderation', 'Réunion', 'Salomonen', 'Sambia',
-        'Samoa', 'San Marino', 'Saudi-Arabien', 'Schweden', 'Schweiz',
-        'Senegal', 'Serbien', 'Serbien und Montenegro', 'Seychellen',
-        'Sierra Leone', 'Simbabwe', 'Singapur', 'Slowakei', 'Slowenien',
-        'Somalia', 'Sonderverwaltungszone Hongkong',
-        'Sonderverwaltungszone Macao', 'Spanien', 'Sri Lanka',
-        'St. Barthélemy', 'St. Helena', 'St. Kitts und Nevis', 'St. Lucia',
-        'St. Martin', 'St. Pierre und Miquelon',
-        'St. Vincent und die Grenadinen', 'Sudan', 'Suriname',
-        'Svalbard und Jan Mayen', 'Swasiland', 'Syrien',
-        'São Tomé und Príncipe', 'Südafrika',
-        'Südgeorgien und die Südlichen Sandwichinseln', 'Tadschikistan',
-        'Taiwan', 'Tansania', 'Thailand', 'Togo', 'Tokelau', 'Tonga',
-        'Trinidad und Tobago', 'Tschad', 'Tschechische Republik', 'Tunesien',
-        'Turkmenistan', 'Turks- und Caicosinseln', 'Tuvalu', 'Türkei',
-        'Uganda', 'Ukraine', 'Ungarn', 'Uruguay', 'Usbekistan', 'Vanuatu',
-        'Vatikanstadt', 'Venezuela', 'Vereinigte Arabische Emirate',
-        'Vereinigte Staaten', 'Vereinigtes Königreich', 'Vietnam',
-        'Wallis und Futuna', 'Weihnachtsinsel', 'Westsahara',
-        'Zentralafrikanische Republik', 'Zypern', 'Ägypten',
-        'Äquatorialguinea', 'Äthiopien', 'Äußeres Ozeanien', 'Österreich',
-    )
-
-    def street_suffix_short(self):
-        return self.random_element(self.street_suffixes_short)
-
-    def street_suffix_long(self):
-        return self.random_element(self.street_suffixes_long)
-
-    def city_name(self):
-        return self.random_element(self.cities)
-
-    def state(self):
-        return self.random_element(self.states)
-
-    def latitude(self):
-        return self.geo_coordinate(center=47.60707, radius=1)
-
-    def longitude(self):
-        return self.geo_coordinate(center=13.37208, radius=2)
diff --git a/faker/providers/credit_card/__init__.py b/faker/providers/credit_card/__init__.py
index 4bcb499a..25767c19 100644
--- a/faker/providers/credit_card/__init__.py
+++ b/faker/providers/credit_card/__init__.py
@@ -23,19 +23,16 @@ class CreditCard(object):
 
 class Provider(BaseProvider):
 
-    # Prefixes from:
-    # * https://en.wikipedia.org/wiki/Payment_card_number#Issuer_identification_number_.28IIN.29
-    # * https://www.regular-expressions.info/creditcard.html
-    # * https://creditcardjs.com/credit-card-type-detection
-    prefix_maestro = ['5018', '5020', '5038', '56##', '57##', '58##',
+    prefix_maestro = ['5018', '5020', '5038', '5612', '5893',
                       '6304', '6759', '6761', '6762', '6763', '0604', '6390']
-    prefix_mastercard = ['51', '52', '53', '54', '55', '222%']
+    prefix_mastercard = ['51', '52', '53', '54', '55']
     prefix_visa = ['4']
     prefix_amex = ['34', '37']
-    prefix_discover = ['6011', '65']
-    prefix_diners = ['300', '301', '302', '303', '304', '305', '36', '38']
-    prefix_jcb16 = ['35']
-    prefix_jcb15 = ['2131', '1800']
+    prefix_discover = ['6011']
+    prefix_diners = ['300', '301', '302', '303', '304', '305']
+    prefix_jcb16 = ['3088', '3096', '3112', '3158', '3337', '3528']
+    prefix_jcb15 = ['2100', '1800']
+    prefix_voyager = ['8699']
 
     credit_card_types = OrderedDict((
         ('maestro', CreditCard('Maestro',
@@ -50,6 +47,7 @@ class Provider(BaseProvider):
         ('diners', CreditCard('Diners Club / Carte Blanche', prefix_diners, 14)),
         ('jcb15', CreditCard('JCB 15 digit', prefix_jcb15, 15)),
         ('jcb16', CreditCard('JCB 16 digit', prefix_jcb16)),
+        ('voyager', CreditCard('Voyager', prefix_voyager, 15)),
     ))
     credit_card_types['visa'] = credit_card_types['visa16']
     credit_card_types['jcb'] = credit_card_types['jcb16']
@@ -67,7 +65,7 @@ class Provider(BaseProvider):
         """ Returns a valid credit card number. """
         card = self._credit_card_type(card_type)
         prefix = self.random_element(card.prefixes)
-        number = self._generate_number(self.numerify(prefix), card.length)
+        number = self._generate_number(prefix, card.length)
         return number
 
     def credit_card_expire(self, start='now', end='+10y', date_format='%m/%y'):
diff --git a/faker/providers/person/no_NO/__init__.py b/faker/providers/person/no_NO/__init__.py
index 5444dba7..e597eb11 100644
--- a/faker/providers/person/no_NO/__init__.py
+++ b/faker/providers/person/no_NO/__init__.py
@@ -268,6 +268,7 @@ class Provider(PersonProvider):
         'Christensen',
         'Dahl',
         'Danielsen',
+        'ødegård',
         'Edvardsen',
         'Eide',
         'Eliassen',
@@ -345,7 +346,6 @@ class Provider(PersonProvider):
         'Thorsen',
         'Tveit',
         'Vik',
-        'Ødegård',
     )
 
     prefixes = (
diff --git a/faker/providers/person/ru_RU/__init__.py b/faker/providers/person/ru_RU/__init__.py
index c7873b19..e66a2bf7 100644
--- a/faker/providers/person/ru_RU/__init__.py
+++ b/faker/providers/person/ru_RU/__init__.py
@@ -241,7 +241,7 @@ class Provider(PersonProvider):
         'Вадимовна', 'Васильевна', 'Владимировна', 'Валентиновна',
         'Вениаминовна', 'Владиславовна', 'Валериевна', 'Викторовна',
         'Вячеславовна', 'Геннадиевна', 'Георгиевна', 'Геннадьевна',
-        'Григорьевна', 'Даниловна', 'Дмитриевна', 'Евгеньевна',
+        'Григорьевна', 'Даниловна', 'Дмитриевна', 'Евгеньевна', 'Егоровны',
         'Егоровна', 'Ефимовна', 'Ждановна', 'Захаровна', 'Ивановна', 'Игоревна',
         'Ильинична', 'Кирилловна', 'Кузминична', 'Константиновна',
         'Кузьминична', 'Леонидовна', 'Леоновна', 'Львовна', 'Макаровна',
diff --git a/faker/providers/ssn/no_NO/__init__.py b/faker/providers/ssn/no_NO/__init__.py
deleted file mode 100644
index 0e384276..00000000
--- a/faker/providers/ssn/no_NO/__init__.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# coding=utf-8
-
-from __future__ import unicode_literals
-from .. import Provider as SsnProvider
-import datetime
-import operator
-
-
-def checksum(digits, scale):
-    """
-    Calculate checksum of Norwegian personal identity code.
-
-    Checksum is calculated with "Module 11" method using a scale.
-    The digits of the personal code are multiplied by the corresponding
-    number in the scale and summed;
-    if remainder of module 11 of the sum is less than 10, checksum is the
-    remainder.
-    If remainder is 0, the checksum is 0.
-
-    https://no.wikipedia.org/wiki/F%C3%B8dselsnummer
-    """
-    chk_nbr = 11 - (sum(map(operator.mul, digits, scale)) % 11)
-    if chk_nbr == 11:
-        return 0
-    return chk_nbr
-
-
-class Provider(SsnProvider):
-    scale1 = (3, 7, 6, 1, 8, 9, 4, 5, 2)
-    scale2 = (5, 4, 3, 2, 7, 6, 5, 4, 3, 2)
-
-    def ssn(self, dob=None, gender=None):
-        """
-        Returns 11 character Norwegian personal identity code (Fødselsnummer).
-
-        A Norwegian personal identity code consists of 11 digits, without any
-        whitespace or other delimiters. The form is DDMMYYIIICC, where III is
-        a serial number separating persons born oh the same date with different
-        intervals depending on the year they are born. CC is two checksums.
-        https://en.wikipedia.org/wiki/National_identification_number#Norway
-
-        :param dob: date of birth as a "YYYYMMDD" string
-        :type dob: str
-        :param gender: gender of the person - "F" for female, M for male.
-        :type gender: str
-        :return: Fødselsnummer in str format (11 digs)
-        :rtype: str
-        """
-
-        if dob:
-            birthday = datetime.datetime.strptime(dob, '%Y%m%d')
-        else:
-            age = datetime.timedelta(
-                days=self.generator.random.randrange(18 * 365, 90 * 365))
-            birthday = datetime.datetime.now() - age
-        if not gender:
-            gender = self.generator.random.choice(('F', 'M'))
-        elif gender not in ('F', 'M'):
-            raise ValueError('Gender must be one of F or M.')
-
-        while True:
-            if birthday.year >= 1900 and birthday.year <= 1999:
-                suffix = str(self.generator.random.randrange(0, 49))
-            elif birthday.year >= 1854 and birthday.year <= 1899:
-                suffix = str(self.generator.random.randrange(50, 74))
-            elif birthday.year >= 2000 and birthday.year <= 2039:
-                suffix = str(self.generator.random.randrange(50, 99))
-            elif birthday.year >= 1940 and birthday.year <= 1999:
-                suffix = str(self.generator.random.randrange(90, 99))
-            if gender == 'F':
-                gender_num = self.generator.random.choice((0, 2, 4, 6, 8))
-            elif gender == 'M':
-                gender_num = self.generator.random.choice((1, 3, 5, 7, 9))
-            pnr = birthday.strftime('%y%m%d') + suffix.zfill(2) + str(gender_num)
-            pnr_nums = [int(ch) for ch in pnr]
-            k1 = checksum(Provider.scale1, pnr_nums)
-            k2 = checksum(Provider.scale2, pnr_nums + [k1])
-            # Checksums with a value of 10 is rejected.
-            # https://no.wikipedia.org/wiki/F%C3%B8dselsnummer
-            if k1 == 10 or k2 == 10:
-                continue
-            pnr += '{}{}'.format(k1, k2)
-            return pnr
diff --git a/faker/utils/text.py b/faker/utils/text.py
index 00d57b37..41b4a347 100644
--- a/faker/utils/text.py
+++ b/faker/utils/text.py
@@ -8,9 +8,9 @@ import six
 import unicodedata
 
 
-_re_pattern = re.compile(r'[^\w\s-]', flags=re.U)
-_re_pattern_allow_dots = re.compile(r'[^\.\w\s-]', flags=re.U)
-_re_spaces = re.compile(r'[-\s]+', flags=re.U)
+_re_pattern = re.compile('[^\w\s-]', flags=re.U)
+_re_pattern_allow_dots = re.compile('[^\.\w\s-]', flags=re.U)
+_re_spaces = re.compile('[-\s]+', flags=re.U)
 
 
 _PROTECTED_TYPES = six.integer_types + (
diff --git a/setup.py b/setup.py
index 852aa81c..46946823 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,7 @@ with io.open(os.path.join(here, 'README.rst'), encoding='utf-8') as fp:
     README = fp.read()
 
 
-version = '0.8.12'
+version = '0.8.11'
 
 # this module can be zip-safe if the zipimporter implements iter_modules or if
 # pkgutil.iter_importer_modules has registered a dispatch for the zipimporter.


Test patch:
diff --git a/tests/providers/test_address.py b/tests/providers/test_address.py
index 5286cd36..b22444b8 100644
--- a/tests/providers/test_address.py
+++ b/tests/providers/test_address.py
@@ -9,7 +9,6 @@ from decimal import Decimal
 from ukpostcodeparser.parser import parse_uk_postcode
 
 from faker import Faker
-from faker.providers.address.de_AT import Provider as DeAtProvider
 from faker.providers.address.de_DE import Provider as DeProvider
 from faker.providers.address.el_GR import Provider as GrProvider
 from faker.providers.address.en_AU import Provider as EnAuProvider
@@ -22,50 +21,6 @@ from faker.providers.address.ne_NP import Provider as NeProvider
 from six import string_types
 
 
-class TestDeAT(unittest.TestCase):
-    """ Tests in addresses in the de_AT locale """
-
-    def setUp(self):
-        self.factory = Faker('de_AT')
-
-    def test_city(self):
-        city = self.factory.city()
-        assert isinstance(city, string_types)
-        assert city in DeAtProvider.cities
-
-    def test_state(self):
-        state = self.factory.state()
-        assert isinstance(state, string_types)
-        assert state in DeAtProvider.states
-
-    def test_street_suffix_short(self):
-        street_suffix_short = self.factory.street_suffix_short()
-        assert isinstance(street_suffix_short, string_types)
-        assert street_suffix_short in DeAtProvider.street_suffixes_short
-
-    def test_street_suffix_long(self):
-        street_suffix_long = self.factory.street_suffix_long()
-        assert isinstance(street_suffix_long, string_types)
-        assert street_suffix_long in DeAtProvider.street_suffixes_long
-
-    def test_country(self):
-        country = self.factory.country()
-        assert isinstance(country, string_types)
-        assert country in DeAtProvider.countries
-
-    def test_postcode(self):
-        postcode = self.factory.postcode()
-        assert re.match("\d{4}", postcode)
-
-    def test_latitude(self):
-        latitude = self.factory.latitude()
-        assert re.match("4[6-8]\.\d+", str(latitude))
-
-    def test_longitude(self):
-        longitude = self.factory.longitude()
-        assert re.match("1[1-5]\.\d+", str(longitude))
-
-
 class TestDeDE(unittest.TestCase):
     """ Tests in addresses in the de_DE locale """
 
diff --git a/tests/providers/test_automotive.py b/tests/providers/test_automotive.py
index 10604e2e..ddabaa2b 100644
--- a/tests/providers/test_automotive.py
+++ b/tests/providers/test_automotive.py
@@ -12,7 +12,7 @@ class TestPtBR(unittest.TestCase):
 
     def setUp(self):
         self.factory = Faker('pt_BR')
-        self.format = re.compile(r'[\w]{3}-[\d]{4}')
+        self.format = re.compile('[\w]{3}-[\d]{4}')
 
     def test_plate_has_been_generated(self):
         plate = self.factory.license_plate()
diff --git a/tests/providers/test_ssn.py b/tests/providers/test_ssn.py
index ab5db852..dddcd44d 100644
--- a/tests/providers/test_ssn.py
+++ b/tests/providers/test_ssn.py
@@ -11,7 +11,6 @@ from faker.providers.ssn.et_EE import checksum as et_checksum
 from faker.providers.ssn.hr_HR import checksum as hr_checksum
 from faker.providers.ssn.pt_BR import checksum as pt_checksum
 from faker.providers.ssn.pl_PL import checksum as pl_checksum, calculate_month as pl_calculate_mouth
-from faker.providers.ssn.no_NO import checksum as no_checksum, Provider
 
 
 class TestEtEE(unittest.TestCase):
@@ -128,43 +127,3 @@ class TestPlPL(unittest.TestCase):
     def test_ssn(self):
         for _ in range(100):
             self.assertTrue(re.search(r'^\d{11}$', self.factory.ssn()))
-
-
-class TestNoNO(unittest.TestCase):
-    def setUp(self):
-        self.factory = Faker('no_NO')
-
-    def test_no_NO_ssn_checksum(self):
-        self.assertEqual(no_checksum([0, 1, 0, 2, 0, 3, 9, 8, 7], Provider.scale1), 6)
-        self.assertEqual(no_checksum([0, 1, 0, 2, 0, 3, 9, 8, 7, 6], Provider.scale2), 7)
-
-    def test_no_NO_ssn(self):
-        for _ in range(100):
-            ssn = self.factory.ssn()
-            self.assertTrue(ssn.isdigit())
-            self.assertEqual(len(ssn), 11)
-
-    def test_no_NO_ssn_dob_passed(self):
-        date_of_birth = '20010203'
-        ssn = self.factory.ssn(dob=date_of_birth)
-        self.assertEqual(ssn[:6], date_of_birth[2:])
-
-    def test_no_NO_ssn_invalid_dob_passed(self):
-        with self.assertRaises(ValueError):
-            self.factory.ssn(dob='010401')
-        with self.assertRaises(ValueError):
-            self.factory.ssn(dob='hello_world')
-        with self.assertRaises(ValueError):
-            self.factory.ssn(dob='001301')
-
-    def test_no_NO_ssn_gender_passed(self):
-        # Females have even number at index 8
-        ssn = self.factory.ssn(gender='F')
-        self.assertTrue(int(ssn[8]) % 2 == 0)
-        # Males have odd number at index 8
-        ssn = self.factory.ssn(gender='M')
-        self.assertTrue(int(ssn[8]) % 2 == 1)
-
-    def test_no_NO_ssn_invalid_gender_passed(self):
-        with self.assertRaises(ValueError):
-            self.factory.ssn(gender='A')
diff --git a/tests/test_base_provider.py b/tests/test_base_provider.py
index 299ae362..e45c6692 100644
--- a/tests/test_base_provider.py
+++ b/tests/test_base_provider.py
@@ -1,4 +1,5 @@
 import unittest
+import string
 
 from faker import Generator
 from faker.providers import BaseProvider
@@ -89,3 +90,18 @@ class TestBaseProvider(unittest.TestCase):
         self.assertFalse(bothified)
         bothified = self.provider.lexify(text, letters='someletters')
         self.assertFalse(bothified)
+
+    def test_hexify(self):
+        text = '^^^'
+
+        for i in range(1000):
+            hexified = self.provider.hexify(text)
+            for c in hexified:
+                self.assertIn(c, string.hexdigits[:-6])
+                self.assertNotIn(c, string.hexdigits[-6:])
+
+        for i in range(1000):
+            hexified = self.provider.hexify(text, upper=True)
+            for c in hexified:
+                self.assertIn(c, string.hexdigits[:-6].upper())
+                self.assertNotIn(c, string.hexdigits[-6:].lower())