code: def test_study1(self):
      eq = self.assertEqual
      p = self.parser
      setcode = p.set_code
      study = p._study1
  
      (NONE, BACKSLASH, FIRST, NEXT, BRACKET) = range(5)
      TestInfo = namedtuple(
          "TestInfo", ["string", "goodlines", "continuation"]
      )
      tests = (
          TestInfo("", [0], NONE),
          # Docstrings.
          TestInfo(
              '"""This is a complete docstring."""\n', [0, 1], NONE
          ),
          TestInfo(
              "'''This is a complete docstring.'''\n", [0, 1], NONE
          ),
          TestInfo(
              '"""This is a continued docstring.\n', [0, 1], FIRST
          ),
          TestInfo(
              "'''This is a continued docstring.\n", [0, 1], FIRST
          ),
          TestInfo(
              '"""Closing quote does not match."\n', [0, 1], FIRST
          ),
          TestInfo('"""Bracket in docstring [\n', [0, 1], FIRST),
          TestInfo(
              "'''Incomplete two line docstring.\n\n", [0, 2], NEXT
          ),
          # Single-quoted strings.
          TestInfo('"This is a complete string."\n', [0, 1], NONE),
          TestInfo('"This is an incomplete string.\n', [0, 1], NONE),
          TestInfo("'This is more incomplete.\n\n", [0, 1, 2], NONE),
          # Comment (backslash does not continue comments).
          TestInfo("# Comment\\\n", [0, 1], NONE),
          # Brackets.
          TestInfo(
              '("""Complete string in bracket"""\n', [0, 1], BRACKET
          ),
          TestInfo('("""Open string in bracket\n', [0, 1], FIRST),
          TestInfo(
              "a = (1 + 2) - 5 *\\\n", [0, 1], BACKSLASH
          ),  # No bracket.
          TestInfo(
              "\n   def function1(self, a,\n                 b):\n",
              [0, 1, 3],
              NONE,
          ),
          TestInfo(
              "\n   def function1(self, a,\\\n", [0, 1, 2], BRACKET
          ),
          TestInfo("\n   def function1(self, a,\n", [0, 1, 2], BRACKET),
          TestInfo("())\n", [0, 1], NONE),  # Extra closer.
          TestInfo(")(\n", [0, 1], BRACKET),  # Extra closer.
          # For the mismatched example, it doesn't look like continuation.
          TestInfo("{)(]\n", [0, 1], NONE),  # Mismatched.
      )
  
      for test in tests:
          with self.subTest(string=test.string):
              setcode(test.string)  # resets study_level
              study()
              eq(p.study_level, 1)
              eq(p.goodlines, test.goodlines)
              eq(p.continuation, test.continuation)
  
      # Called again, just returns without reprocessing.
      self.assertIsNone(study())
  
imports: from idlelib import pyparse
  import unittest
  from collections import namedtuple
label_desc: Use image node_id 7 for calling the PyParseTest obj's underlying member method code with example usage: obj.test_study1() without return types