Esempio n. 1
0
 def test_get_return_type(self):
     """Make sure we can get the return type described."""
     root = google.parse(
         Peaker(lex('\n'.join([
             'Ferment potato.',
             '',
             'Returns:',
             '    Alcohol: Vodka.',
             '\n',
         ])),
                lookahead=3))
     docstring = Docstring.from_google(root)
     self.assertEqual(
         docstring.get_types(Sections.RETURNS_SECTION),
         'Alcohol',
     )
Esempio n. 2
0
 def test_parse_library_exception(self):
     tokens = condense(
         lex('\n'.join([
             'Use custom handlers for error conditions.', '', 'Raises:',
             '    aiohttp.web.HTTPException: Reraises any HTTPExceptions we don\'t have an override for.',
             ''
         ])))
     node = parse(tokens)
     self.assertTrue(CykNodeUtils.contains(node, 'raises-section'))
     exceptions = CykNodeUtils.get_annotated(node, ExceptionIdentifier)
     self.assertEqual(len(exceptions), 1)
     exception = list(exceptions)[0]
     self.assertEqual(
         ExceptionIdentifier.extract(exception),
         'aiohttp.web.HTTPException',
     )
Esempio n. 3
0
 def test_crazy_argument_type_signatures(self):
     possible_types = [
         # '(int)',
         # '(:obj:`str`, optional)',
         '(:obj:`str`, optional)',
         '(:obj:`str`,\n    optional)',
     ]
     for type_ in possible_types:
         docstring = '\n'.join([
             'A short summary,',
             '',
             'Args:',
             '    x {}: y.'.format(type_),
         ])
         node = parse(condense(lex(docstring)))
         self.assertTrue(CykNodeUtils.contains(node, 'type-section-parens'))
Esempio n. 4
0
 def test_parse_star_arguments(self):
     docstring = '\n'.join([
         'Negate a function which returns a boolean.',
         '',
         'Args:',
         '    *fns (int): Functions which returns a boolean.',
         '',
         'Returns:',
         '    int: A function which returns fallse when any of the'
         '        callables return true, and true will all of the ',
         '        callables return false.',
     ])
     tokens = condense(lex(docstring))
     tree = parse(tokens)
     self.assertTrue(tree is not None)
     self.assertContains(tree, 'arguments')
Esempio n. 5
0
 def test_get_return_section(self):
     """Make sure we can get the returns description."""
     root = google.parse(
         Peaker(lex('\n'.join([
             'Ferment corn.',
             '',
             'Returns:',
             '    Bourbon.',
             '\n',
         ])),
                lookahead=3))
     docstring = Docstring.from_google(root)
     self.assertEqual(
         docstring.get_section(Sections.RETURNS_SECTION),
         'Returns:\n    Bourbon.',
     )
Esempio n. 6
0
 def test_get_yields_type(self):
     """Make sure we can get the yields type."""
     root = google.parse(
         Peaker(lex('\n'.join([
             'Get slavic cats.',
             '',
             'Yields:',
             '    Cat: The slavic ones.',
             '\n',
         ])),
                lookahead=3))
     docstring = Docstring.from_google(root)
     self.assertEqual(
         docstring.get_types(Sections.YIELDS_SECTION),
         'Cat',
     )
Esempio n. 7
0
 def test_parse_args_section_with_newline_after_type_in_context(self):
     tokens = condense(lex('\n'.join([
         'Args:',
         '    unbroken (int): without breaks.',
         '    points (:class:`numpy.ndarray`):',
         '        The points to test.',
         '    other (:class: `numpy.ndarray`):',
         '        Something.',
         '    nonbroken (int): without extra break',
     ])))
     node = parse(tokens)
     self.assertEqual(
         node.symbol,
         'arguments-section',
         str(node),
     )
Esempio n. 8
0
 def test_long_description_with_noqa(self):
     tokens = condense(lex('\n'.join([
         'A docstring with noqas in it.',
         '',
         '# noqa: I203',
         '',
         '# noqa',
         '',
     ])))
     node = parse(tokens)
     self.assertTrue(
         CykNodeUtils.contains(node, 'short-description')
     )
     self.assertTrue(
         CykNodeUtils.contains(node, 'long-description')
     )
Esempio n. 9
0
 def test_get_yields_description(self):
     """Make sure we can get the yields description."""
     root = google.parse(
         Peaker(lex('\n'.join([
             'To pedestrians.',
             '',
             'Yields:',
             '    To pedestrians.',
             '\n',
         ])),
                lookahead=3))
     docstring = Docstring.from_google(root)
     self.assertEqual(
         docstring.get_section(Sections.YIELDS_SECTION),
         'Yields:\n    To pedestrians.',
     )
Esempio n. 10
0
 def test_parse_args_section_with_quotation(self):
     tokens = condense(lex('\n'.join([
         'Args:',
         '    x: Some description with "quotes"',
         '    y: The next item, which should appear.',
     ])))
     node = parse(tokens)
     self.assertEqual(
         node.symbol,
         'arguments-section',
         str(node),
     )
     args = CykNodeUtils.get_annotated(node, ArgumentIdentifier)
     self.assertEqual(
         {ArgumentIdentifier.extract(x) for x in args},
         {'x', 'y'},
     )
Esempio n. 11
0
 def test_only_indents_treated_newlines_within_simple_section(self):
     """Make sure indent-only lines are treated as newlines in simple."""
     root = parse(
         Peaker(lex('\n'.join([
             'Get the value of pi.',
             '',
             'Returns:',
             '    A value that is an approximation of pi.  This approximation',
             '    is actually just the quotient,',
             '    ',
             'Raises:',
             '    Exception: Seemingly at random.',
             '',
         ])),
                lookahead=3))
     raises = root.first_instance(NodeType.RAISES_SECTION)
     self.assertTrue(raises is not None, )
Esempio n. 12
0
 def test_parse_raises_section_with_newline_after_item_name(self):
     tokens = condense(lex('\n'.join([
         'Raises:',
         '    SyntaxError:',
         '        There\'s basically a 50% chance of this.',
         '    IOError:',
         '    There\'s also a 90% chance of this.',
         '    Exception:',
         '            Overindented.',
         '',
     ])))
     node = parse(tokens)
     self.assertEqual(
         node.symbol,
         'raises-section',
         str(node),
     )
Esempio n. 13
0
 def test_parses_long_description(self):
     func = '\n'.join([
         'def this_function_has_a_long_description(arg1):',
         '    """Return the arg, unchanged.',
         '',
         '    This function returns the arg, unchanged.  There is',
         '    no particular reason, but this is a good place to check to ',
         '    see that long descriptions are being parsed correctly. ',
         '    If they are, I\'m not sure why.  There is some magic ',
         '    going on here, in fact.',
         '',
         '    """',
         '    return arg1',
     ])
     doc = ast.get_docstring(ast.parse(func).body[0])
     tokens = list(lex(doc))
     node = parse(tokens)
     self.assertTrue(node is not None)
Esempio n. 14
0
 def test_parse_long_description_multiple_sections(self):
     func = '\n'.join([
         'def this_function_has_multiple_long_descriptions():',
         '    """Do some math.',
         '',
         '    This is the first part of the long description.',
         '    it can be multiple lines, but doesn\'t have to be',
         '',
         '    This is the second half of the long description.',
         '',
         '    And the final part of it.',
         '',
         '    """',
         '    pass',
     ])
     doc = ast.get_docstring(ast.parse(func).body[0])
     tokens = list(lex(doc))
     node = parse(tokens)
     self.assertTrue(node is not None)
Esempio n. 15
0
    def test_only_indents_treated_as_newlines_in_compound(self):
        """Make sure that erroneous indentation is treated like newlines.

        This is okay to do, since other tools should pick up and handle
        erroneous newlines.  (Flake8, for example raises the W293 error.)

        """
        node = parse(
            condense(
                lex('\n'.join([
                    'Maintains the heap invariant.',
                    '',
                    'Args:',
                    '    heap: A something close to a heap.',
                    '    ',
                    'Returns:',
                    '    That self-same heap.',
                ]))))
        self.assertTrue(CykNodeUtils.contains(node, 'returns-section'))
Esempio n. 16
0
 def test_get_noqas(self):
     """Make sure we can get all of the noqas in the docstring."""
     root = parse(Peaker(lex('\n'.join([
         'Full of noqas.',
         '',
         '# noqa: I200',
         '# noqa: I201 y',
         '',
         'Args:',
         '    x: Something. # noqa: I201',
         '\n',
     ])), lookahead=3))
     docstring = Docstring.from_google(root)
     self.assertEqual(
         docstring.get_noqas(),
         {
             'I200': [],
             'I201': ['x', 'y'],
         },
     )
Esempio n. 17
0
 def test_get_argument_types(self):
     """Make sure we can get a dictionary of arguments to types."""
     root = parse(Peaker(lex('\n'.join([
         'Something.',
         '',
         'Args:',
         '    x (int): The first.',
         '    y (List[int], optional): The second.',
         '\n',
     ])), lookahead=3))
     docstring = Docstring.from_google(root)
     argtypes = docstring.get_argument_types()
     self.assertEqual(
         argtypes['x'],
         'int',
     )
     self.assertEqual(
         argtypes['y'],
         'List[int], optional',
     )
Esempio n. 18
0
 def test_parse_noqa_for_argument(self):
     func = '\n'.join([
         'def my_function():',
         '    """Has an extra argument, but thats okay.',
         '',
         '    Args:',
         '        arg1: This will be defined very soon.  # noqa: I102',
         '',
         '    """',
         '    print("Not done yet!")',
     ])
     doc = ast.get_docstring(ast.parse(func).body[0])
     self.assertTrue(doc.startswith('Has an extra'))
     node = parse(condense(lex(doc)))
     self.assertTrue(CykNodeUtils.contains(node, 'noqa'), )
     noqa = self.get_identifier(node, NoqaIdentifier)
     self.assertTrue(noqa is not None, )
     self.assertEqual(
         NoqaIdentifier.extract(noqa),
         'I102',
     )
Esempio n. 19
0
 def test_arguments_are_last(self):
     """Make sure arguments can be parsed as the last section."""
     docstring = '\n'.join([
         'Example of docstring on the __init__ method.',
         '',
         'The __init__ method may be documented in either the class level',
         'docstring, or as a docstring on the __init__ method itself.',
         '',
         'Either form is acceptable, but the two should not be mixed. Choose one',  # noqa: E501
         'convention to document the __init__ method and be consistent with it.',  # noqa: E501
         '',
         'Note:',
         '    Do not include the `self` parameter in the ``Args`` section.',
         '',
         'Args:',
         '    param1: Description of `param1`.',
         '    param2: Description of `param2`. Multiple',  # noqa: E501
         '        lines are supported.',
         '    param3: Description of `param3`.',
     ])
     node = parse(condense(lex(docstring)))
     self.assertTrue(CykNodeUtils.contains(node, 'arguments-section'))
Esempio n. 20
0
    def test_only_indents_treated_as_newlines_in_compound(self):
        """Make sure that erroneous indentation is treated like newlines.

        This is okay to do, since other tools should pick up and handle
        erroneous newlines.  (Flake8, for example raises the W293 error.)

        """
        root = parse(
            Peaker(lex('\n'.join([
                'Maintains the heap invariant.',
                '',
                'Args:',
                '    heap: A something close to a heap.',
                '    ',
                'Returns:',
                '    That self-same heap.',
            ])),
                   lookahead=3))
        self.assertTrue(
            root.first_instance(NodeType.RETURNS_SECTION) is not None,
            'The return section should not have been swallowed.',
        )
Esempio n. 21
0
    def test_parse_type_with_line_continuation(self):
        """Make sure we allow for line continuation in types.

        See Issue 19.

        """
        # Should raise exception if not valid.  The ast module
        # handles line continuation in docstrings, surprisingly.
        # So, it just ends up looking like indents in random places.
        # Probably, indents shouldn't have been lexed except
        # immediately after newlines.
        docstring = '\n'.join([
            'Do something with complex array types.',
            '',
            'Args:',
            '    item (AVeryLongTypeDefinitionWhichMustBeSplit,',
            '       AcrossMultipleLines): Actually quite simple.',
        ])
        tokens = condense(lex(docstring))
        tree = parse(tokens)
        self.assertTrue(tree is not None)
        self.assertContains(tree, 'type-section-parens')
Esempio n. 22
0
 def test_long_description_can_come_between_sections(self):
     """Make sure non-standard parts are treated as descriptions."""
     node = parse(
         Peaker(lex('\n'.join([
             'Double the number.',
             '',
             'Args:',
             '    x: The only argument..',
             '',
             'Requires:',
             '    Some kind of setup.',
             '',
         ])),
                lookahead=3))
     self.assertEqual(
         node.node_type,
         NodeType.DOCSTRING,
     )
     self.assertEqual(
         node.children[2].node_type,
         NodeType.LONG_DESCRIPTION,
     )
Esempio n. 23
0
 def test_single_word_sections_parse_correctly(self):
     """Make sure we can have a minimal amount of words in each section."""
     contents = '\n'.join([
         'def f(foo):',
         '    """foobar',
         '',
         '    Args:',
         '        foo: foobar',
         '',
         '    Returns:',
         '        bar',
         '',
         '    """',
         '    return "bar"',
     ])
     function = ast.parse(contents).body[0]
     docstring = ast.get_docstring(function)
     tokens = condense(lex(docstring))
     node = parse(tokens)
     self.assertTrue(CykNodeUtils.contains(node, 'short-description'))
     self.assertTrue(CykNodeUtils.contains(node, 'returns-section'))
     self.assertTrue(CykNodeUtils.contains(node, 'arguments-section'))
Esempio n. 24
0
 def test_parse_sole_argument_with_two_lines(self):
     docstring = '\n'.join([
         'Short.',
         '',
         'Args:',
         '    x: Something something something.',
         '        Something something.',
         '        Something, something, something.',
         '',
         'Returns:',
         '    A value.',
     ])
     tokens = condense(lex(docstring))
     node = parse(tokens)
     self.assertTrue(CykNodeUtils.contains(node, 'arguments-section'))
     annotation_lookup = self.get_annotation_lookup(node)
     values = {
         ArgumentIdentifier.extract(x)
         for x in annotation_lookup[ArgumentIdentifier]
     }
     self.assertEqual(
         values,
         {'x'},
     )
Esempio n. 25
0
 def test_parse_raises_multiple_lines(self):
     docstring = '\n'.join([
         'Iterates through the records.',
         '',
         'Args:',
         '    address: The address of the database.',
         '',
         'Raises:',
         '    StopIteration:  Once there are no more records,',
         '        or possible if there were never any records.',
         '    ConnectionError: If we were unable to establish a',
         '        connection.',
     ])
     tokens = condense(lex(docstring))
     tree = parse(tokens)
     annotation_lookup = self.get_annotation_lookup(tree)
     values = {
         ExceptionIdentifier.extract(x)
         for x in annotation_lookup[ExceptionIdentifier]
     }
     self.assertEqual(
         values,
         {'StopIteration', 'ConnectionError'},
     )
Esempio n. 26
0
 def test_parse_underindented_raises_section(self):
     docstring = '\n'.join([
         'Iterates through the records.',
         '',
         'Args:',
         '    address: The address of the database.',
         '',
         'Raises:',
         '    StopIteration:  Once there are no more records,',
         '    or possible if there were never any records.',
         '',
     ])
     tokens = condense(lex(docstring))
     tree = parse(tokens)
     annotation_lookup = self.get_annotation_lookup(tree)
     self.assertEqual(len(annotation_lookup[IndentError]), 1)
     values = {
         ExceptionIdentifier.extract(x)
         for x in annotation_lookup[ExceptionIdentifier]
     }
     self.assertEqual(
         values,
         {'StopIteration'},
     )
Esempio n. 27
0
 def test_parse_inline_noqa_statements(self):
     """Make sure we can parse noqa statements."""
     node = parse(condense(lex('Something something.  # noqa: I201\n')))
     self.assertTrue(CykNodeUtils.contains(node, 'noqa'))
Esempio n. 28
0
 def test_parse_noqa_with_target_and_argument(self):
     """Make sure we can target specific args in a noqa."""
     node = parse(condense(lex('# noqa: I101 arg1, arg2\n')))
     self.assertTrue(CykNodeUtils.contains(node, 'noqa'), str(node))
Esempio n. 29
0
 def test_parse_noqa_with_target(self):
     """Make sure we can target a specific error message."""
     node = parse(condense(lex('# noqa: I203\n')))
     self.assertTrue(CykNodeUtils.contains(node, 'noqa'))
Esempio n. 30
0
 def test_parse_bare_noqa_statement(self):
     """Make sure we can parse noqa statements."""
     node = parse(condense(lex('# noqa\n')))
     self.assertTrue(CykNodeUtils.contains(node, 'noqa'))