generator.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. # coding=utf-8
  2. from __future__ import unicode_literals
  3. import re
  4. import random as random_module
  5. _re_token = re.compile(r'\{\{(\s?)(\w+)(\s?)\}\}')
  6. random = random_module.Random()
  7. mod_random = random # compat with name released in 0.8
  8. class Generator(object):
  9. __config = {}
  10. def __init__(self, **config):
  11. self.providers = []
  12. self.__config = dict(
  13. list(self.__config.items()) + list(config.items()))
  14. self.__random = random
  15. def add_provider(self, provider):
  16. if isinstance(provider, type):
  17. provider = provider(self)
  18. self.providers.insert(0, provider)
  19. for method_name in dir(provider):
  20. # skip 'private' method
  21. if method_name.startswith('_'):
  22. continue
  23. faker_function = getattr(provider, method_name)
  24. if hasattr(faker_function, '__call__') or \
  25. isinstance(faker_function, (classmethod, staticmethod)):
  26. # add all faker method to generator
  27. self.set_formatter(method_name, faker_function)
  28. def provider(self, name):
  29. try:
  30. lst = [p for p in self.get_providers()
  31. if p.__provider__ == name.lower()]
  32. return lst[0]
  33. except IndexError:
  34. return None
  35. def get_providers(self):
  36. """Returns added providers."""
  37. return self.providers
  38. @property
  39. def random(self):
  40. return self.__random
  41. def seed_instance(self, seed=None):
  42. """Calls random.seed"""
  43. if self.__random == random:
  44. # create per-instance random obj when first time seed_instance() is
  45. # called
  46. self.__random = random_module.Random()
  47. self.__random.seed(seed)
  48. return self
  49. @classmethod
  50. def seed(cls, seed=None):
  51. random.seed(seed)
  52. def format(self, formatter, *args, **kwargs):
  53. """
  54. This is a secure way to make a fake from another Provider.
  55. """
  56. # TODO: data export?
  57. return self.get_formatter(formatter)(*args, **kwargs)
  58. def get_formatter(self, formatter):
  59. try:
  60. return getattr(self, formatter)
  61. except AttributeError:
  62. if 'locale' in self.__config:
  63. msg = 'Unknown formatter "{0}" with locale "{1}"'.format(
  64. formatter, self.__config['locale']
  65. )
  66. else:
  67. raise AttributeError('Unknown formatter "{0}"'.format(
  68. formatter
  69. ))
  70. raise AttributeError(msg)
  71. def set_formatter(self, name, method):
  72. """
  73. This method adds a provider method to generator.
  74. Override this method to add some decoration or logging stuff.
  75. """
  76. setattr(self, name, method)
  77. def parse(self, text):
  78. """
  79. Replaces tokens (like '{{ tokenName }}' or '{{tokenName}}')
  80. with the result from the token method call.
  81. """
  82. return _re_token.sub(self.__format_token, text)
  83. def __format_token(self, matches):
  84. formatter = list(matches.groups())
  85. formatter[1] = self.format(formatter[1])
  86. return ''.join(formatter)