Repository: joke2k/faker
Pull request #235 (2015-04-28 21:35:42)

added inlcude flag


Patch:
diff --git a/README.rst b/README.rst
index e06981ef..00f958df 100644
--- a/README.rst
+++ b/README.rst
@@ -163,6 +163,7 @@ When installed, you can invoke faker from the command-line:
     faker [-h] [--version] [-o output]
           [-l {bg_BG,cs_CZ,...,zh_CN,zh_TW}]
           [-r REPEAT] [-s SEP]
+          [-i {module.containing.custom_provider othermodule.containing.custom_provider}]
           [fake [fake ...]]
 
 Where:
@@ -184,6 +185,9 @@ Where:
 -  ``-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 module 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``
 
diff --git a/faker/cli.py b/faker/cli.py
index adf19949..0062574e 100644
--- a/faker/cli.py
+++ b/faker/cli.py
@@ -9,7 +9,7 @@ import argparse
 
 from faker import Faker, Factory, documentor
 from faker import VERSION
-from faker.config import AVAILABLE_LOCALES, DEFAULT_LOCALE
+from faker.config import AVAILABLE_LOCALES, DEFAULT_LOCALE, META_PROVIDERS_MODULES
 
 
 if sys.version < '3':
@@ -56,10 +56,10 @@ def print_provider(doc, provider, formatters, excludes=None, output=None):
 
 
 def print_doc(provider_or_field=None,
-              args=None, lang=DEFAULT_LOCALE, output=None):
+              args=None, lang=DEFAULT_LOCALE, output=None, includes=None):
     args = args or []
     output = output or sys.stdout
-    fake = Faker(locale=lang)
+    fake = Faker(locale=lang, includes=includes)
 
     from faker.providers import BaseProvider
     base_provider_formatters = [f for f in dir(BaseProvider)]
@@ -68,7 +68,7 @@ def print_doc(provider_or_field=None,
         if '.' in provider_or_field:
             parts = provider_or_field.split('.')
             locale = parts[-2] if parts[-2] in AVAILABLE_LOCALES else lang
-            fake = Factory.create(locale, providers=[provider_or_field])
+            fake = Factory.create(locale, providers=[provider_or_field], includes=includes)
             doc = documentor.Documentor(fake)
             doc.already_generated = base_provider_formatters
             print_provider(
@@ -80,8 +80,8 @@ def print_doc(provider_or_field=None,
             try:
                 print(fake.format(provider_or_field, *args), end='', file=output)
             except AttributeError:
-                print('No faker found for "{0}({1})"'.format(
-                    provider_or_field, args), file=output)
+                raise ValueError('No faker found for "{0}({1})"'.format(
+                    provider_or_field, args))
 
     else:
         doc = documentor.Documentor(fake)
@@ -145,6 +145,8 @@ class Command(object):
         parser.add_argument('-s', '--sep',
                             default='\n')
 
+        parser.add_argument('-i', '--include', default=META_PROVIDERS_MODULES, nargs='*')
+
         parser.add_argument('fake', action='store', nargs='*')
 
         arguments = parser.parse_args(self.argv[1:])
@@ -156,7 +158,9 @@ class Command(object):
             print_doc(fake,
                       arguments.fake[1:],
                       lang=arguments.lang,
-                      output=arguments.o)
+                      output=arguments.o,
+                      includes=arguments.include
+                      )
             print(arguments.sep, file=arguments.o)
 
             if not fake:
diff --git a/faker/config.py b/faker/config.py
index a9a1431b..3796de84 100644
--- a/faker/config.py
+++ b/faker/config.py
@@ -4,10 +4,10 @@ from faker.utils.loading import find_available_locales, find_available_providers
 
 DEFAULT_LOCALE = 'en_US'
 
-DEFAULT_PROVIDERS_MODULES = (
+META_PROVIDERS_MODULES = [
     'faker.providers',
-)
+]
 
-DEFAULT_PROVIDERS = find_available_providers([import_module(path) for path in DEFAULT_PROVIDERS_MODULES])
+PROVIDERS = find_available_providers([import_module(path) for path in META_PROVIDERS_MODULES])
 
-AVAILABLE_LOCALES = find_available_locales(DEFAULT_PROVIDERS)
+AVAILABLE_LOCALES = find_available_locales(PROVIDERS)
diff --git a/faker/factory.py b/faker/factory.py
index 9eb0106d..4f172c07 100644
--- a/faker/factory.py
+++ b/faker/factory.py
@@ -7,14 +7,16 @@ from importlib import import_module
 import locale as pylocale
 
 from faker import Generator
-from faker.config import DEFAULT_LOCALE, DEFAULT_PROVIDERS, AVAILABLE_LOCALES
+from faker.config import DEFAULT_LOCALE, PROVIDERS, AVAILABLE_LOCALES
 from faker.utils.loading import list_module
 
 
 class Factory(object):
 
     @classmethod
-    def create(cls, locale=None, providers=None, generator=None, **config):
+    def create(cls, locale=None, providers=None, generator=None, includes=None, **config):
+        if includes is None:
+            includes = []
 
         # fix locale to package name
         locale = locale.replace('-', '_') if locale else DEFAULT_LOCALE
@@ -23,11 +25,16 @@ class Factory(object):
             msg = 'Invalid configuration for faker locale "{0}"'.format(locale)
             raise AttributeError(msg)
 
-        providers = providers or DEFAULT_PROVIDERS
+        providers = providers or PROVIDERS
+
+        providers += includes
 
         faker = generator or Generator(**config)
 
         for prov_name in providers:
+            if prov_name == 'faker.providers':
+                continue
+
             prov_cls, lang_found = cls._get_provider_class(prov_name, locale)
             provider = prov_cls(faker)
             provider.__provider__ = prov_name


Test patch:
diff --git a/faker/tests/__init__.py b/faker/tests/__init__.py
index 163958b4..82e7a7f6 100644
--- a/faker/tests/__init__.py
+++ b/faker/tests/__init__.py
@@ -106,17 +106,17 @@ class UtilsTestCase(unittest.TestCase):
 
     def test_find_available_locales(self):
         from faker.utils.loading import find_available_locales
-        from faker.config import DEFAULT_PROVIDERS
+        from faker.config import PROVIDERS
 
-        result = find_available_locales(DEFAULT_PROVIDERS)
+        result = find_available_locales(PROVIDERS)
         self.assertNotEqual(len(result), 0)
 
     def test_find_available_providers(self):
         from faker.utils.loading import find_available_providers
-        from faker.config import DEFAULT_PROVIDERS_MODULES
+        from faker.config import META_PROVIDERS_MODULES
         from importlib import import_module
 
-        modules = [import_module(path) for path in DEFAULT_PROVIDERS_MODULES]
+        modules = [import_module(path) for path in META_PROVIDERS_MODULES]
         providers = find_available_providers(modules)
 
         expected_providers = list(map(str, [
@@ -217,6 +217,17 @@ class FactoryTestCase(unittest.TestCase):
         finally:
             sys.stdout = orig_stdout
 
+    def test_command_custom_provider(self):
+        from faker.cli import Command
+        orig_stdout = sys.stdout
+        try:
+            sys.stdout = StringIO()
+            command = Command(['faker', 'foo', '-i', 'faker.tests.mymodule.en_US'])
+            command.execute()
+            assert sys.stdout.getvalue()
+        finally:
+            sys.stdout = orig_stdout
+
     def test_slugify(self):
         slug = text.slugify("a'b/c")
         self.assertEqual(slug, 'abc')
diff --git a/faker/tests/mymodule/__init__.py b/faker/tests/mymodule/__init__.py
new file mode 100644
index 00000000..ed10b7f5
--- /dev/null
+++ b/faker/tests/mymodule/__init__.py
@@ -0,0 +1,1 @@
+localized = True
diff --git a/faker/tests/mymodule/en_US/__init__.py b/faker/tests/mymodule/en_US/__init__.py
new file mode 100644
index 00000000..1ddb0970
--- /dev/null
+++ b/faker/tests/mymodule/en_US/__init__.py
@@ -0,0 +1,7 @@
+from __future__ import unicode_literals
+from faker.providers import BaseProvider
+
+
+class Provider(BaseProvider):
+    def foo(self):
+        return 'bar'