Uploaded image for project: 'Motor'
  1. Motor
  2. MOTOR-338

Don't obfuscate full module name when generating framework-specific API classes

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: 2.0
    • Component/s: asyncio
    • None

      Currently, we shorten/obfuscate the module name when dynamically generating our framework-specific public API classes. E.g. when we create AsyncIOMotorClient we do:

      def create_asyncio_class(cls):
          return create_class_with_framework(cls, asyncio_framework, 'motor_asyncio')
      
      AsyncIOMotorClient = create_asyncio_class(core.AgnosticClient)
      

      with the factory function defined as:

      def create_class_with_framework(cls, framework, module_name):
          motor_class_name = framework.CLASS_PREFIX + cls.__motor_class_name__
          cache_key = (cls, motor_class_name, framework)
          cached_class = _class_cache.get(cache_key)
          if cached_class:
              return cached_class
      
          new_class = type(str(motor_class_name), cls.__bases__, cls.__dict__.copy())
          new_class.__module__ = module_name
          new_class._framework = framework
          ...
          ...
      

      Consequently, AsyncIOMotorClient appears to belong (as per its _module_ value) to the motor_asyncio module, even though it actually resides in motor.motor_asyncio. This creates problems when we attempt to use intersphinx to link to the MOTOR documentation as seen in MOTOR-338.

      Unless there is a good rationale for fudging the _module_ of these classes, we should change the code so that it reflects the actual path.


      ORIGINAL DESCRIPTION


      In my conf.py I have:

      extensions = [
          'sphinx.ext.autodoc',
          'sphinx.ext.autosummary',
          'sphinx.ext.intersphinx',
          'sphinx.ext.extlinks',
      ]
      
      intersphinx_mapping = {
          'python': ('https://docs.python.org/3/', None),
          'motor': ('https://motor.readthedocs.io/en/stable/', None),
      }
      

      code.rst:

      .. automodule:: code
          :members:
          :undoc-members:
          :show-inheritance:
      

      code.py:

      from asyncio.motor_asyncio import (    AsyncIOMotorClient, AsyncIOMotorDatabase, AsyncIOMotorCollection)
      
      class MyClient(AsyncIOMotorClient):
          pass
      
      class MyDatabase(AsyncIOMotorDatabase):
          pass
       
      class MyCollection(AsyncIOMotorCollection):
          pass
      

      Sphinx output:

      code.py:docstring of code.MyClient:1: WARNING: py:class reference target not found: motor_asyncio.AsyncIOMotorClient
      code.py:docstring of code.MyDatabase:1: WARNING: py:class reference target not found: motor_asyncio.AsyncIOMotorDatabase
      code.py:docstring of code.MyCollection:1: WARNING: py:class reference target not found: motor_asyncio.AsyncIOMotorCollection

      Adding a top-level module 'motor_asyncio' to the intersphinx configuration does not help.
      References in the docstrings and .rst files to :class:`motor.motor_asyncio.AsyncIOMotorClient` work fine.

        1. example.tar
          14 kB
          Prashant Mital

            Assignee:
            prashant.mital Prashant Mital (Inactive)
            Reporter:
            gimperiale Guido Imperiale
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: