Process doctest scope directly under the module scope

Explicitly place the doctest directly under the module scope,
instead of processing it while within the scope where the
docstring was encountered.
Also do not process doctest which are not processed by default
according to the doctest documentation.

The primary benefit of moving the doctest scope directly under
the module scope is that it may be efficiently identified,
as it may only appear second in the stack.

However it also ensures that the doctest scope can not access
names in scopes between the module scope and the object where the
docstring was encountered.  As it was, class scope rules prevented
the doctest scope from accessing names in a class scope, however
the doctest scope was able to access names in an outer function,
if the doctest appeared in a nested function.
Note that there was no real bug there, as the doctest module does
not process doctest in nested functions (Python issue #1650090),
so doctest appearing in nested functions are informational only.
pyflakes previously inspected doctest in nested functions,
and now these are ignored.
diff --git a/pyflakes/checker.py b/pyflakes/checker.py
index e693f20..f8c8df8 100644
--- a/pyflakes/checker.py
+++ b/pyflakes/checker.py
@@ -254,11 +254,11 @@
 
 
 class ModuleScope(Scope):
-    pass
+    """Scope for a module."""
 
 
 class DoctestScope(ModuleScope):
-    pass
+    """Scope for a doctest."""
 
 
 # Globally defined names which are not attributes of the builtins module, or
@@ -352,6 +352,10 @@
             self.offset = offset
             handler()
 
+    def _in_doctest(self):
+        return (len(self.scopeStack) >= 2 and
+                isinstance(self.scopeStack[1], DoctestScope))
+
     @property
     def scope(self):
         return self.scopeStack[-1]
@@ -681,6 +685,10 @@
             return
         if not examples:
             return
+
+        # Place doctest in module scope
+        saved_stack = self.scopeStack
+        self.scopeStack = [self.scopeStack[0]]
         node_offset = self.offset or (0, 0)
         self.pushScope(DoctestScope)
         underscore_in_builtins = '_' in self.builtIns
@@ -704,6 +712,7 @@
         if not underscore_in_builtins:
             self.builtIns.remove('_')
         self.popScope()
+        self.scopeStack = saved_stack
 
     def ignore(self, node):
         pass
@@ -745,14 +754,8 @@
         """
         Keep track of globals declarations.
         """
-        for i, scope in enumerate(self.scopeStack):
-            if isinstance(scope, DoctestScope):
-                global_scope_index = i
-                global_scope = scope
-                break
-        else:
-            global_scope_index = 0
-            global_scope = self.scopeStack[0]
+        global_scope_index = 1 if self._in_doctest() else 0
+        global_scope = self.scopeStack[global_scope_index]
 
         # Ignore 'global' statement in global scope.
         if self.scope is not global_scope:
@@ -861,9 +864,11 @@
             self.handleNode(deco, node)
         self.LAMBDA(node)
         self.addBinding(node, FunctionDefinition(node.name, node))
-        # doctest does not process doctest within a doctest
-        if self.withDoctest and not any(
-                isinstance(scope, DoctestScope) for scope in self.scopeStack):
+        # doctest does not process doctest within a doctest,
+        # or in nested functions.
+        if (self.withDoctest and
+                not self._in_doctest() and
+                not isinstance(self.scope, FunctionScope)):
             self.deferFunction(lambda: self.handleDoctests(node))
 
     ASYNCFUNCTIONDEF = FUNCTIONDEF
@@ -963,7 +968,11 @@
             for keywordNode in node.keywords:
                 self.handleNode(keywordNode, node)
         self.pushScope(ClassScope)
-        if self.withDoctest:
+        # doctest does not process doctest within a doctest
+        # classes within classes are processed.
+        if (self.withDoctest and
+                not self._in_doctest() and
+                not isinstance(self.scope, FunctionScope)):
             self.deferFunction(lambda: self.handleDoctests(node))
         for stmt in node.body:
             self.handleNode(stmt, node)
diff --git a/pyflakes/test/test_doctests.py b/pyflakes/test/test_doctests.py
index 6793da9..9dd4278 100644
--- a/pyflakes/test/test_doctests.py
+++ b/pyflakes/test/test_doctests.py
@@ -190,6 +190,54 @@
             '''
         """, m.UndefinedName)
 
+    def test_nested_class(self):
+        """Doctest within nested class are processed."""
+        self.flakes("""
+        class C:
+            class D:
+                '''
+                    >>> m
+                '''
+                def doctest_stuff(self):
+                    '''
+                        >>> m
+                    '''
+                    return 1
+        """, m.UndefinedName, m.UndefinedName)
+
+    def test_ignore_nested_function(self):
+        """Doctest module does not process doctest in nested functions."""
+        # 'syntax error' would cause a SyntaxError if the doctest was processed.
+        # However doctest does not find doctest in nested functions
+        # (https://bugs.python.org/issue1650090). If nested functions were
+        # processed, this use of m should cause UndefinedName, and the
+        # name inner_function should probably exist in the doctest scope.
+        self.flakes("""
+        def doctest_stuff():
+            def inner_function():
+                '''
+                    >>> syntax error
+                    >>> inner_function()
+                    1
+                    >>> m
+                '''
+                return 1
+            m = inner_function()
+            return m
+        """)
+
+    def test_inaccessible_scope_class(self):
+        """Doctest may not access class scope."""
+        self.flakes("""
+        class C:
+            def doctest_stuff(self):
+                '''
+                    >>> m
+                '''
+                return 1
+            m = 1
+        """, m.UndefinedName)
+
     def test_importBeforeDoctest(self):
         self.flakes("""
         import foo