strings.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. # coding=utf-8
  2. #
  3. # This file is part of Hypothesis, which may be found at
  4. # https://github.com/HypothesisWorks/hypothesis-python
  5. #
  6. # Most of this work is copyright (C) 2013-2018 David R. MacIver
  7. # (david@drmaciver.com), but it contains contributions by others. See
  8. # CONTRIBUTING.rst for a full list of people who may hold copyright, and
  9. # consult the git log if you need to determine who owns an individual
  10. # contribution.
  11. #
  12. # This Source Code Form is subject to the terms of the Mozilla Public License,
  13. # v. 2.0. If a copy of the MPL was not distributed with this file, You can
  14. # obtain one at http://mozilla.org/MPL/2.0/.
  15. #
  16. # END HEADER
  17. from __future__ import division, print_function, absolute_import
  18. from hypothesis.errors import InvalidArgument
  19. from hypothesis.internal import charmap
  20. from hypothesis.internal.compat import hunichr, text_type, binary_type
  21. from hypothesis.internal.intervalsets import IntervalSet
  22. from hypothesis.internal.conjecture.utils import integer_range
  23. from hypothesis.searchstrategy.strategies import SearchStrategy, \
  24. MappedSearchStrategy
  25. class OneCharStringStrategy(SearchStrategy):
  26. """A strategy which generates single character strings of text type."""
  27. specifier = text_type
  28. zero_point = ord('0')
  29. def __init__(self,
  30. whitelist_categories=None,
  31. blacklist_categories=None,
  32. blacklist_characters=None,
  33. min_codepoint=None,
  34. max_codepoint=None,
  35. whitelist_characters=None):
  36. intervals = charmap.query(
  37. include_categories=whitelist_categories,
  38. exclude_categories=blacklist_categories,
  39. min_codepoint=min_codepoint,
  40. max_codepoint=max_codepoint,
  41. include_characters=whitelist_characters,
  42. exclude_characters=blacklist_characters,
  43. )
  44. if not intervals:
  45. raise InvalidArgument(
  46. 'No valid characters in set'
  47. )
  48. self.intervals = IntervalSet(intervals)
  49. if whitelist_characters:
  50. self.whitelist_characters = set(whitelist_characters)
  51. else:
  52. self.whitelist_characters = set()
  53. self.zero_point = self.intervals.index_above(ord('0'))
  54. def do_draw(self, data):
  55. i = integer_range(
  56. data, 0, len(self.intervals) - 1,
  57. center=self.zero_point,
  58. )
  59. return hunichr(self.intervals[i])
  60. class StringStrategy(MappedSearchStrategy):
  61. """A strategy for text strings, defined in terms of a strategy for lists of
  62. single character text strings."""
  63. def __init__(self, list_of_one_char_strings_strategy):
  64. super(StringStrategy, self).__init__(
  65. strategy=list_of_one_char_strings_strategy
  66. )
  67. def __repr__(self):
  68. return 'StringStrategy()'
  69. def pack(self, ls):
  70. return u''.join(ls)
  71. class BinaryStringStrategy(MappedSearchStrategy):
  72. """A strategy for strings of bytes, defined in terms of a strategy for
  73. lists of bytes."""
  74. def __repr__(self):
  75. return 'BinaryStringStrategy()'
  76. def pack(self, x):
  77. assert isinstance(x, list), repr(x)
  78. ba = bytearray(x)
  79. return binary_type(ba)
  80. class FixedSizeBytes(SearchStrategy):
  81. def __init__(self, size):
  82. self.size = size
  83. def do_draw(self, data):
  84. return binary_type(data.draw_bytes(self.size))