Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

string_formatting.py 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. """test for Python 3 string formatting error
  2. """
  3. # pylint: disable=too-few-public-methods, import-error, unused-argument, line-too-long, no-absolute-import
  4. import os
  5. from missing import Missing
  6. __revision__ = 1
  7. class Custom(object):
  8. """ Has a __getattr__ """
  9. def __getattr__(self, _):
  10. return self
  11. class Test(object):
  12. """ test format attribute access """
  13. custom = Custom()
  14. ids = [1, 2, 3, [4, 5, 6]]
  15. class Getitem(object):
  16. """ test custom getitem for lookup access """
  17. def __getitem__(self, index):
  18. return 42
  19. class ReturnYes(object):
  20. """ can't be properly infered """
  21. missing = Missing()
  22. def log(message, message_type="error"):
  23. """ Test """
  24. return message
  25. def print_good():
  26. """ Good format strings """
  27. "{0} {1}".format(1, 2)
  28. "{0!r:20}".format("Hello")
  29. "{!r:20}".format("Hello")
  30. "{a!r:20}".format(a="Hello")
  31. "{pid}".format(pid=os.getpid())
  32. str("{}").format(2)
  33. "{0.missing.length}".format(ReturnYes())
  34. "{1.missing.length}".format(ReturnYes())
  35. "{a.ids[3][1]}".format(a=Test())
  36. "{a[0][0]}".format(a=[[1]])
  37. "{[0][0]}".format({0: {0: 1}})
  38. "{a.test}".format(a=Custom())
  39. "{a.__len__}".format(a=[])
  40. "{a.ids.__len__}".format(a=Test())
  41. "{a[0]}".format(a=Getitem())
  42. "{a[0][0]}".format(a=[Getitem()])
  43. "{[0][0]}".format(["test"])
  44. # these are skipped
  45. "{0} {1}".format(*[1, 2])
  46. "{a} {b}".format(**{'a': 1, 'b': 2})
  47. "{a}".format(a=Missing())
  48. def pprint_bad():
  49. """Test string format """
  50. "{{}}".format(1) # [too-many-format-args]
  51. "{} {".format() # [bad-format-string]
  52. "{} }".format() # [bad-format-string]
  53. "{0} {}".format(1, 2) # [format-combined-specification]
  54. # +1: [missing-format-argument-key, unused-format-string-argument]
  55. "{a} {b}".format(a=1, c=2)
  56. "{} {a}".format(1, 2) # [missing-format-argument-key]
  57. "{} {}".format(1) # [too-few-format-args]
  58. "{} {}".format(1, 2, 3) # [too-many-format-args]
  59. # +1: [missing-format-argument-key,missing-format-argument-key,missing-format-argument-key]
  60. "{a} {b} {c}".format()
  61. "{} {}".format(a=1, b=2) # [too-few-format-args]
  62. # +1: [missing-format-argument-key, missing-format-argument-key]
  63. "{a} {b}".format(1, 2)
  64. "{0} {1} {a}".format(1, 2, 3) # [missing-format-argument-key]
  65. # +1: [missing-format-attribute]
  66. "{a.ids.__len__.length}".format(a=Test())
  67. "{a.ids[3][400]}".format(a=Test()) # [invalid-format-index]
  68. "{a.ids[3]['string']}".format(a=Test()) # [invalid-format-index]
  69. "{[0][1]}".format(["a"]) # [invalid-format-index]
  70. "{[0][0]}".format(((1, ))) # [invalid-format-index]
  71. # +1: [missing-format-argument-key, unused-format-string-argument]
  72. "{b[0]}".format(a=23)
  73. "{a[0]}".format(a=object) # [invalid-format-index]
  74. log("{}".format(2, "info")) # [too-many-format-args]
  75. "{0.missing}".format(2) # [missing-format-attribute]
  76. "{0} {1} {2}".format(1, 2) # [too-few-format-args]
  77. "{0} {1}".format(1, 2, 3) # [too-many-format-args]
  78. "{0} {a}".format(a=4) # [too-few-format-args]
  79. "{[0]} {}".format([4]) # [too-few-format-args]
  80. "{[0]} {}".format([4], 5, 6) # [too-many-format-args]
  81. def good_issue288(*args, **kwargs):
  82. """ Test that using kwargs does not emit a false
  83. positive.
  84. """
  85. 'Hello John Doe {0[0]}'.format(args)
  86. 'Hello {0[name]}'.format(kwargs)
  87. def good_issue287():
  88. """ Test that the string format checker skips
  89. format nodes which don't have a string as a parent
  90. (but a subscript, name etc).
  91. """
  92. name = 'qwerty'
  93. ret = {'comment': ''}
  94. ret['comment'] = 'MySQL grant {0} is set to be revoked'
  95. ret['comment'] = ret['comment'].format(name)
  96. return ret, name
  97. def nested_issue294():
  98. """ Test nested format fields. """
  99. '{0:>{1}}'.format(42, 24)
  100. '{0:{a[1]}} {a}'.format(1, a=[1, 2])
  101. '{:>{}}'.format(42, 24)
  102. '{0:>{1}}'.format(42) # [too-few-format-args]
  103. '{0:>{1}}'.format(42, 24, 54) # [too-many-format-args]
  104. '{0:{a[1]}}'.format(1) # [missing-format-argument-key]
  105. '{0:{a.x}}'.format(1, a=2) # [missing-format-attribute]
  106. def issue310():
  107. """ Test a regression using duplicate manual position arguments. """
  108. '{0} {1} {0}'.format(1, 2)
  109. '{0} {1} {0}'.format(1) # [too-few-format-args]
  110. def issue322():
  111. """ Test a regression using mixed manual position arguments
  112. and attribute access arguments.
  113. """
  114. '{0}{1[FOO]}'.format(123, {'FOO': 456})
  115. '{0}{1[FOO]}'.format(123, {'FOO': 456}, 321) # [too-many-format-args]
  116. '{0}{1[FOO]}'.format(123) # [too-few-format-args]
  117. def issue338():
  118. """
  119. Check that using a namedtuple subclass doesn't crash when
  120. trying to infer EmptyNodes (resulted after mocking the
  121. members of namedtuples).
  122. """
  123. from collections import namedtuple
  124. class Crash(namedtuple("C", "foo bar")):
  125. """ Looking for attributes in __str__ will crash,
  126. because EmptyNodes can't be infered.
  127. """
  128. def __str__(self):
  129. return "{0.foo}: {0.bar}".format(self)
  130. return Crash
  131. def issue351():
  132. """
  133. Check that the format method can be assigned to a variable, ie:
  134. """
  135. fmt = 'test {} {}'.format
  136. fmt('arg1') # [too-few-format-args]
  137. fmt('arg1', 'arg2')
  138. fmt('arg1', 'arg2', 'arg3') # [too-many-format-args]
  139. def issue373():
  140. """
  141. Ignore any object coming from an argument.
  142. """
  143. class SomeClass(object):
  144. """ empty docstring. """
  145. def __init__(self, opts=None):
  146. self.opts = opts
  147. def dunc(self, arg):
  148. """Don't try to analyze this."""
  149. return "A{0}{1}".format(arg, self.opts)
  150. def func(self):
  151. """Don't try to analyze the following string."""
  152. return 'AAA{0[iface]}BBB{0[port]}'.format(self.opts)
  153. return SomeClass
  154. def issue_463():
  155. """
  156. Mix positional arguments, `{0}`, with positional
  157. arguments with attribute access, `{0.__x__}`.
  158. """
  159. data = "{0.__class__.__name__}: {0}".format(42)
  160. data2 = "{0[0]}: {0}".format([1])
  161. return (data, data2)
  162. def avoid_empty_attribute():
  163. """The following string is invalid, avoid crashing."""
  164. return "There are {.:2f} undiscovered errors.".format(1) # [bad-format-string]