docstr: Try to find the source code for a module.
  
  Returns ('filename', 'source'). One of it can be None if
  no filename or source found
docstr_tok: ["Try","to","find","the","source","code","for","a","module",".","Returns","(","'filename","'",",","'source","'",")",".","One","of","it","can","be","None","if","no","filename","or","source","found"]
code: def get_module_source(modname: str) -> tuple[str | None, str | None]:
      """Try to find the source code for a module.
  
      Returns ('filename', 'source'). One of it can be None if
      no filename or source found
      """
      try:
          mod = import_module(modname)
      except Exception as err:
          raise PycodeError(
              "error importing %r" % modname, err
          ) from err
      loader = getattr(mod, "__loader__", None)
      filename = getattr(mod, "__file__", None)
      if loader and getattr(loader, "get_source", None):
          # prefer Native loader, as it respects #coding directive
          try:
              source = loader.get_source(modname)
              if source:
                  # no exception and not None - it must be module source
                  return filename, source
          except ImportError:
              pass  # Try other "source-mining" methods
      if (
          filename is None
          and loader
          and getattr(loader, "get_filename", None)
      ):
          # have loader, but no filename
          try:
              filename = loader.get_filename(modname)
          except ImportError as err:
              raise PycodeError(
                  "error getting filename for %r" % modname, err
              ) from err
      if filename is None:
          # all methods for getting filename failed, so raise...
          raise PycodeError("no source found for module %r" % modname)
      filename = path.normpath(path.abspath(filename))
      if filename.lower().endswith((".pyo", ".pyc")):
          filename = filename[:-1]
          if not path.isfile(filename) and path.isfile(filename + "w"):
              filename += "w"
      elif not filename.lower().endswith((".py", ".pyw")):
          raise PycodeError("source is not a .py file: %r" % filename)
  
      if not path.isfile(filename):
          raise PycodeError("source file is not present: %r" % filename)
      return filename, None
  
file_path: sphinx/sphinx/pycode/__init__.py
imports: from __future__ import annotations
  import tokenize
  from importlib import import_module
  from os import path
  from typing import TYPE_CHECKING, Any
  from sphinx.errors import PycodeError
  from sphinx.pycode.parser import Parser
label_desc: Use image node_id 1 for calling the ModuleAnalyzer obj's underlying member method code with example usage: obj.get_module_source(modname) and returns: filename,  None, filename,  source