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.

test_check_return_docs.py 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. # -*- coding: utf-8 -*-
  2. # Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com>
  3. # Copyright (c) 2016 Derek Gustafson <degustaf@gmail.com>
  4. # Copyright (c) 2016 Glenn Matthews <glenn@e-dad.net>
  5. # Copyright (c) 2016 Ashley Whetter <ashley@awhetter.co.uk>
  6. # Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com>
  7. # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  8. # For details: https://github.com/PyCQA/pylint/blob/master/COPYING
  9. """Unit tests for the return documentation checking in the
  10. `DocstringChecker` in :mod:`pylint.extensions.check_docs`
  11. """
  12. from __future__ import division, print_function, absolute_import
  13. import astroid
  14. from pylint.testutils import CheckerTestCase, Message, set_config
  15. from pylint.extensions.docparams import DocstringParameterChecker
  16. class TestDocstringCheckerReturn(CheckerTestCase):
  17. """Tests for pylint_plugin.RaiseDocChecker"""
  18. CHECKER_CLASS = DocstringParameterChecker
  19. def test_ignores_no_docstring(self):
  20. return_node = astroid.extract_node('''
  21. def my_func(self):
  22. return False #@
  23. ''')
  24. with self.assertNoMessages():
  25. self.checker.visit_return(return_node)
  26. @set_config(accept_no_return_doc=False)
  27. def test_warns_no_docstring(self):
  28. node = astroid.extract_node('''
  29. def my_func(self):
  30. return False
  31. ''')
  32. return_node = node.body[0]
  33. with self.assertAddsMessages(
  34. Message(msg_id='missing-return-doc', node=node),
  35. Message(msg_id='missing-return-type-doc', node=node)):
  36. self.checker.visit_return(return_node)
  37. def test_ignores_unknown_style(self):
  38. return_node = astroid.extract_node('''
  39. def my_func(self):
  40. """This is a docstring."""
  41. return False #@
  42. ''')
  43. with self.assertNoMessages():
  44. self.checker.visit_return(return_node)
  45. def test_warn_partial_sphinx_returns(self):
  46. node = astroid.extract_node('''
  47. def my_func(self):
  48. """This is a docstring.
  49. :returns: Always False
  50. """
  51. return False
  52. ''')
  53. return_node = node.body[0]
  54. with self.assertAddsMessages(
  55. Message(msg_id='missing-return-type-doc', node=node)):
  56. self.checker.visit_return(return_node)
  57. def test_warn_partial_sphinx_returns_type(self):
  58. node = astroid.extract_node('''
  59. def my_func(self):
  60. """This is a docstring.
  61. :rtype: bool
  62. """
  63. return False
  64. ''')
  65. return_node = node.body[0]
  66. with self.assertAddsMessages(
  67. Message(msg_id='missing-return-doc', node=node)):
  68. self.checker.visit_return(return_node)
  69. def test_warn_missing_sphinx_returns(self):
  70. node = astroid.extract_node('''
  71. def my_func(self, doc_type):
  72. """This is a docstring.
  73. :param doc_type: Sphinx
  74. :type doc_type: str
  75. """
  76. return False
  77. ''')
  78. return_node = node.body[0]
  79. with self.assertAddsMessages(
  80. Message(msg_id='missing-return-doc', node=node),
  81. Message(msg_id='missing-return-type-doc', node=node)):
  82. self.checker.visit_return(return_node)
  83. def test_warn_partial_google_returns(self):
  84. node = astroid.extract_node('''
  85. def my_func(self):
  86. """This is a docstring.
  87. Returns:
  88. Always False
  89. """
  90. return False
  91. ''')
  92. return_node = node.body[0]
  93. with self.assertAddsMessages(
  94. Message(msg_id='missing-return-type-doc', node=node)):
  95. self.checker.visit_return(return_node)
  96. def test_warn_partial_google_returns_type(self):
  97. node = astroid.extract_node('''
  98. def my_func(self):
  99. """This is a docstring.
  100. Returns:
  101. bool:
  102. """
  103. return False
  104. ''')
  105. return_node = node.body[0]
  106. with self.assertAddsMessages(
  107. Message(msg_id='missing-return-doc', node=node)):
  108. self.checker.visit_return(return_node)
  109. def test_warn_missing_google_returns(self):
  110. node = astroid.extract_node('''
  111. def my_func(self, doc_type):
  112. """This is a docstring.
  113. Parameters:
  114. doc_type (str): Google
  115. """
  116. return False
  117. ''')
  118. return_node = node.body[0]
  119. with self.assertAddsMessages(
  120. Message(msg_id='missing-return-doc', node=node),
  121. Message(msg_id='missing-return-type-doc', node=node)):
  122. self.checker.visit_return(return_node)
  123. def test_warn_partial_numpy_returns_type(self):
  124. node = astroid.extract_node('''
  125. def my_func(self, doc_type):
  126. """This is a docstring.
  127. Arguments
  128. ---------
  129. doc_type : str
  130. Numpy
  131. Returns
  132. -------
  133. bool
  134. """
  135. return False
  136. ''')
  137. return_node = node.body[0]
  138. with self.assertAddsMessages(
  139. Message(msg_id='missing-return-doc', node=node)):
  140. self.checker.visit_return(return_node)
  141. def test_warn_missing_numpy_returns(self):
  142. node = astroid.extract_node('''
  143. def my_func(self, doc_type):
  144. """This is a docstring.
  145. Arguments
  146. ---------
  147. doc_type : str
  148. Numpy
  149. """
  150. return False
  151. ''')
  152. return_node = node.body[0]
  153. with self.assertAddsMessages(
  154. Message(msg_id='missing-return-doc', node=node),
  155. Message(msg_id='missing-return-type-doc', node=node)):
  156. self.checker.visit_return(return_node)
  157. def test_find_sphinx_returns(self):
  158. return_node = astroid.extract_node('''
  159. def my_func(self):
  160. """This is a docstring.
  161. :return: Always False
  162. :rtype: bool
  163. """
  164. return False #@
  165. ''')
  166. with self.assertNoMessages():
  167. self.checker.visit_return(return_node)
  168. def test_find_google_returns(self):
  169. return_node = astroid.extract_node('''
  170. def my_func(self):
  171. """This is a docstring.
  172. Returns:
  173. bool: Always False
  174. """
  175. return False #@
  176. ''')
  177. with self.assertNoMessages():
  178. self.checker.visit_return(return_node)
  179. def test_find_numpy_returns(self):
  180. return_node = astroid.extract_node('''
  181. def my_func(self):
  182. """This is a docstring.
  183. Returns
  184. -------
  185. bool
  186. Always False
  187. """
  188. return False #@
  189. ''')
  190. with self.assertNoMessages():
  191. self.checker.visit_return(return_node)
  192. def test_ignores_sphinx_return_none(self):
  193. return_node = astroid.extract_node('''
  194. def my_func(self, doc_type):
  195. """This is a docstring.
  196. :param doc_type: Sphinx
  197. :type doc_type: str
  198. """
  199. return #@
  200. ''')
  201. with self.assertNoMessages():
  202. self.checker.visit_return(return_node)
  203. def test_ignores_google_return_none(self):
  204. return_node = astroid.extract_node('''
  205. def my_func(self, doc_type):
  206. """This is a docstring.
  207. Args:
  208. doc_type (str): Google
  209. """
  210. return #@
  211. ''')
  212. with self.assertNoMessages():
  213. self.checker.visit_return(return_node)
  214. def test_ignores_numpy_return_none(self):
  215. return_node = astroid.extract_node('''
  216. def my_func(self, doc_type):
  217. """This is a docstring.
  218. Arguments
  219. ---------
  220. doc_type : str
  221. Numpy
  222. """
  223. return #@
  224. ''')
  225. with self.assertNoMessages():
  226. self.checker.visit_return(return_node)
  227. def test_finds_sphinx_return_custom_class(self):
  228. return_node = astroid.extract_node('''
  229. def my_func(self):
  230. """This is a docstring.
  231. :returns: An object
  232. :rtype: :class:`mymodule.Class`
  233. """
  234. return mymodule.Class() #@
  235. ''')
  236. with self.assertNoMessages():
  237. self.checker.visit_return(return_node)
  238. def test_finds_google_return_custom_class(self):
  239. return_node = astroid.extract_node('''
  240. def my_func(self):
  241. """This is a docstring.
  242. Returns:
  243. mymodule.Class: An object
  244. """
  245. return mymodule.Class() #@
  246. ''')
  247. with self.assertNoMessages():
  248. self.checker.visit_return(return_node)
  249. def test_finds_numpy_return_custom_class(self):
  250. return_node = astroid.extract_node('''
  251. def my_func(self):
  252. """This is a docstring.
  253. Returns
  254. -------
  255. mymodule.Class
  256. An object
  257. """
  258. return mymodule.Class() #@
  259. ''')
  260. with self.assertNoMessages():
  261. self.checker.visit_return(return_node)
  262. def test_finds_sphinx_return_list_of_custom_class(self):
  263. return_node = astroid.extract_node('''
  264. def my_func(self):
  265. """This is a docstring.
  266. :returns: An object
  267. :rtype: list(:class:`mymodule.Class`)
  268. """
  269. return [mymodule.Class()] #@
  270. ''')
  271. with self.assertNoMessages():
  272. self.checker.visit_return(return_node)
  273. def test_finds_google_return_list_of_custom_class(self):
  274. return_node = astroid.extract_node('''
  275. def my_func(self):
  276. """This is a docstring.
  277. Returns:
  278. list(:class:`mymodule.Class`): An object
  279. """
  280. return [mymodule.Class()] #@
  281. ''')
  282. with self.assertNoMessages():
  283. self.checker.visit_return(return_node)
  284. def test_finds_numpy_return_list_of_custom_class(self):
  285. return_node = astroid.extract_node('''
  286. def my_func(self):
  287. """This is a docstring.
  288. Returns
  289. -------
  290. list(:class:`mymodule.Class`)
  291. An object
  292. """
  293. return [mymodule.Class()] #@
  294. ''')
  295. with self.assertNoMessages():
  296. self.checker.visit_return(return_node)
  297. def test_warns_sphinx_return_list_of_custom_class_without_description(self):
  298. node = astroid.extract_node('''
  299. def my_func(self):
  300. """This is a docstring.
  301. :rtype: list(:class:`mymodule.Class`)
  302. """
  303. return [mymodule.Class()]
  304. ''')
  305. return_node = node.body[0]
  306. with self.assertAddsMessages(
  307. Message(msg_id='missing-return-doc', node=node)):
  308. self.checker.visit_return(return_node)
  309. def test_warns_google_return_list_of_custom_class_without_description(self):
  310. node = astroid.extract_node('''
  311. def my_func(self):
  312. """This is a docstring.
  313. Returns:
  314. list(:class:`mymodule.Class`):
  315. """
  316. return [mymodule.Class()]
  317. ''')
  318. return_node = node.body[0]
  319. with self.assertAddsMessages(
  320. Message(msg_id='missing-return-doc', node=node)):
  321. self.checker.visit_return(return_node)
  322. def test_warns_numpy_return_list_of_custom_class_without_description(self):
  323. node = astroid.extract_node('''
  324. def my_func(self):
  325. """This is a docstring.
  326. Returns
  327. -------
  328. list(:class:`mymodule.Class`)
  329. """
  330. return [mymodule.Class()]
  331. ''')
  332. return_node = node.body[0]
  333. with self.assertAddsMessages(
  334. Message(msg_id='missing-return-doc', node=node)):
  335. self.checker.visit_return(return_node)
  336. def test_warns_sphinx_redundant_return_doc(self):
  337. node = astroid.extract_node('''
  338. def my_func(self):
  339. """This is a docstring.
  340. :returns: One
  341. """
  342. return None
  343. ''')
  344. with self.assertAddsMessages(
  345. Message(msg_id='redundant-returns-doc', node=node)):
  346. self.checker.visit_functiondef(node)
  347. def test_warns_sphinx_redundant_rtype_doc(self):
  348. node = astroid.extract_node('''
  349. def my_func(self):
  350. """This is a docstring.
  351. :rtype: int
  352. """
  353. return None
  354. ''')
  355. with self.assertAddsMessages(
  356. Message(msg_id='redundant-returns-doc', node=node)):
  357. self.checker.visit_functiondef(node)
  358. def test_warns_google_redundant_return_doc(self):
  359. node = astroid.extract_node('''
  360. def my_func(self):
  361. """This is a docstring.
  362. Returns:
  363. One
  364. """
  365. return None
  366. ''')
  367. with self.assertAddsMessages(
  368. Message(msg_id='redundant-returns-doc', node=node)):
  369. self.checker.visit_functiondef(node)
  370. def test_warns_google_redundant_rtype_doc(self):
  371. node = astroid.extract_node('''
  372. def my_func(self):
  373. """This is a docstring.
  374. Returns:
  375. int:
  376. """
  377. return None
  378. ''')
  379. with self.assertAddsMessages(
  380. Message(msg_id='redundant-returns-doc', node=node)):
  381. self.checker.visit_functiondef(node)
  382. def test_warns_numpy_redundant_return_doc(self):
  383. node = astroid.extract_node('''
  384. def my_func(self):
  385. """This is a docstring.
  386. Returns
  387. -------
  388. int
  389. One
  390. """
  391. return None
  392. ''')
  393. with self.assertAddsMessages(
  394. Message(msg_id='redundant-returns-doc', node=node)):
  395. self.checker.visit_functiondef(node)
  396. def test_warns_numpy_redundant_rtype_doc(self):
  397. node = astroid.extract_node('''
  398. def my_func(self):
  399. """This is a docstring.
  400. Returns
  401. -------
  402. int
  403. """
  404. return None
  405. ''')
  406. with self.assertAddsMessages(
  407. Message(msg_id='redundant-returns-doc', node=node)):
  408. self.checker.visit_functiondef(node)
  409. def test_ignores_sphinx_redundant_return_doc_multiple_returns(self):
  410. node = astroid.extract_node('''
  411. def my_func(self):
  412. """This is a docstring.
  413. :returns: One
  414. :rtype: int
  415. :returns: None sometimes
  416. :rtype: None
  417. """
  418. if a_func():
  419. return None
  420. return 1
  421. ''')
  422. with self.assertNoMessages():
  423. self.checker.visit_functiondef(node)
  424. def test_ignores_google_redundant_return_doc_multiple_returns(self):
  425. node = astroid.extract_node('''
  426. def my_func(self):
  427. """This is a docstring.
  428. Returns:
  429. int or None: One, or sometimes None.
  430. """
  431. if a_func():
  432. return None
  433. return 1
  434. ''')
  435. with self.assertNoMessages():
  436. self.checker.visit_functiondef(node)
  437. def test_ignores_numpy_redundant_return_doc_multiple_returns(self):
  438. node = astroid.extract_node('''
  439. def my_func(self):
  440. """This is a docstring.
  441. Returns
  442. -------
  443. int
  444. One
  445. None
  446. Sometimes
  447. """
  448. if a_func():
  449. return None
  450. return 1
  451. ''')
  452. with self.assertNoMessages():
  453. self.checker.visit_functiondef(node)
  454. def test_ignore_sphinx_redundant_return_doc_yield(self):
  455. node = astroid.extract_node('''
  456. def my_func_with_yield(self):
  457. """This is a docstring.
  458. :returns: One
  459. :rtype: generator
  460. """
  461. for value in range(3):
  462. yield value
  463. ''')
  464. with self.assertNoMessages():
  465. self.checker.visit_functiondef(node)
  466. def test_warns_google_redundant_return_doc_yield(self):
  467. node = astroid.extract_node('''
  468. def my_func(self):
  469. """This is a docstring.
  470. Returns:
  471. int: One
  472. """
  473. yield 1
  474. ''')
  475. with self.assertAddsMessages(
  476. Message(msg_id='redundant-returns-doc', node=node)):
  477. self.checker.visit_functiondef(node)
  478. def test_warns_numpy_redundant_return_doc_yield(self):
  479. node = astroid.extract_node('''
  480. def my_func(self):
  481. """This is a docstring.
  482. Returns
  483. -------
  484. int
  485. One
  486. """
  487. yield 1
  488. ''')
  489. with self.assertAddsMessages(
  490. Message(msg_id='redundant-returns-doc', node=node)):
  491. self.checker.visit_functiondef(node)