4

I'm attempting to use sphinx-doc :automodule: in conjunction with Mock-ed out modules as per this answer. Specifically I'm using Mock for PyQt5 module imports which are not available on ReadTheDocs.

Strangely, I'm finding that any class that inherits from a Mock-ed module's class is not included in the resulting documentation. It appears as though sphinx-doc can't see them for some reason.

My slightly-custom Mock is as follows:

from mock import Mock as MagicMock


class Mock(MagicMock):
    __all__ = ['QApplication','pyqtSignal','pyqtSlot','QObject','QAbstractItemModel','QModelIndex','QTabWidget',
        'QWebPage','QTableView','QWebView','QAbstractTableModel','Qt','QWidget','QPushButton','QDoubleSpinBox',
        'QListWidget','QDialog','QSize','QTableWidget','QMainWindow','QTreeWidget',
        'QAbstractItemDelegate','QColor','QGraphicsItemGroup','QGraphicsItem','QGraphicsPathItem',
        'QGraphicsTextItem','QGraphicsRectItem','QGraphicsScene','QGraphicsView',]

    def __init__(self, *args, **kwargs):
        super(Mock, self).__init__()


    @classmethod
    def __getattr__(cls, name):
        if name in ('__file__', '__path__'):
            return os.devnull
        else:
            return Mock

    @classmethod
    def __setattr__(*args, **kwargs):
        pass

    def __setitem__(self, *args, **kwargs):
        return

    def __getitem__(self, *args, **kwargs):
        return Mock

The __all__ is required to allow from x import * style imports for the PyQt5 classes.

I can confirm that changing the superclass to object results in the classes being correctly documented, as does remove the Mock (generating locally). Forcing the documentation by using :autoclass: results in a single line saying that the class inherits from Mock.

Community
  • 1
  • 1
mfitzp
  • 15,275
  • 7
  • 50
  • 70

1 Answers1

0

I resolved this in the end by not using Mock for Qt objects. In my application there is a qt.py wrapper file that handles differences between PyQt4 and PyQt5 and allows them to be subsequently imported for use (while ignoring the Qt namespace rearrangement).

In this file I wrapped the actual import code in a test for ReadTheDocs and then if detected returned a series of dummy classes inheriting directly from object. Additions were required where objects have attributes, but this is only used once in the code base. It'll need to be kept up to date, but it solves the problem.

# ReadTheDocs
ON_RTD = os.environ.get('READTHEDOCS', None) == 'True'
if not ON_RTD:

    #... do the normal import here ...

else:

    class QMockObject(object):
        def __init__(self, *args, **kwargs):
            super(QMockObject, self).__init__()

        def __call__(self, *args, **kwargs):
            return None

    class QApplication(QMockObject):
        pass

    class pyqtSignal(QMockObject):
        pass

    class pyqtSlot(QMockObject):
        pass

    class QObject(QMockObject):
        pass

    class QAbstractItemModel(QMockObject):
        pass

    class QModelIndex(QMockObject):
        pass

    class QTabWidget(QMockObject):
        pass

    class QWebPage(QMockObject):
        pass

    class QTableView(QMockObject):
        pass

    class QWebView(QMockObject):
        pass

    class QAbstractTableModel(QMockObject):
        pass

    class Qt(QMockObject):
        DisplayRole = None

    class QWidget(QMockObject):
        pass

    class QPushButton(QMockObject):
        pass

    class QDoubleSpinBox(QMockObject):
        pass

    class QListWidget(QMockObject):
        pass

    class QDialog(QMockObject):
        pass

    class QSize(QMockObject):
        pass

    class QTableWidget(QMockObject):
        pass

    class QMainWindow(QMockObject):
        pass

    class QTreeWidget(QMockObject):
        pass

    class QAbstractItemDelegate(QMockObject):
        pass

    class QColor(QMockObject):
        pass

    class QGraphicsItemGroup(QMockObject):
        pass

    class QGraphicsItem(QMockObject):
        pass

    class QGraphicsPathItem(QMockObject):
        pass

    class QGraphicsTextItem(QMockObject):
        pass

    class QGraphicsRectItem(QMockObject):
        pass

    class QGraphicsScene(QMockObject):
        pass

    class QGraphicsView(QMockObject):
        pass

    app = None
mfitzp
  • 15,275
  • 7
  • 50
  • 70