Check if Sphinx doc called the script
Asked Answered
C

4

5

I am currently trying to generate sphinx documentation for scripts which use the ArcGIS arcpy library.

I am running into an issue when sphinx tries to run the scripts while generating the documentation, as arcpy scripts take input parameters from the arcgis gui. Since sphinx is calling the scripts without the gui, these parameters are empty and are causing Tracebacks such as:

C:\VersionControl\PythonScripts\Source\src\_build\script_export_pdf.rst:4: WARNING:     autodoc: failed to import module u'gis.scripts.script_export_pdf'; the following exception was raised:
Traceback (most recent call last):
  File "C:\VersionControl\PythonScripts\Source\src\lib\Python27\ArcGIS10.1\lib\site-packages\sphinx\ext\autodoc.py", line 335, in import_object
    __import__(self.modname)
  File "C:\VersionControl\PythonScripts\Source\src\gis\scripts\script_export_pdf.py", line 76, in <module>
    mxd.ExportToPDF(in_mxds, out_folder, overwrite, current)
  File "C:\VersionControl\PythonScripts\Source\src\gis\mapping\mxd.py", line 315, in ExportToPDF
    _ExportToPDF(arcpy.mapping.MapDocument(m), out_folder, overwrite)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.1\arcpy\arcpy\arcobjects\mixins.py", line 609, in __init__
    assert (os.path.isfile(mxd) or (mxd.lower() == "current")), gp.getIDMessage(89004, "Invalid MXD filename")
AssertionError: Invalid MXD filename.

I get around this issue in unittests by setting a variable when the test begins which the script checks for and sets test values in the parameters, I am wondering if there is a similar workaround with sphinx?

Concessive answered 30/12, 2013 at 16:43 Comment(0)
C
4

The solution I came up with, while probably no-where near ideal, is to simply check

if 'sphinx' in sys.modules:
    in_mxds = [r"C:/test.mxd"]
else:
    in_mxds = arcpy.GetParameterAsText(1)

This will ensure the script is not trying to get a parameter from the GUI which isn't set when generating sphinx documents.

Concessive answered 6/1, 2014 at 22:59 Comment(1)
An excellent hack for most projects! Unfortunately, if you're documenting a sphinx extension, it won't work :/Hump
F
4

I do something like this. In my conf.py I add a new variable to the builtins module like:

# anywhere in conf.py before any of your modules are imported
import builtins
builtins.__sphinx_build__ = True

Then in my module code I can write a check like:

try:
    from some_dependency import SomeClass
except ImportError:
    try:
        if __sphinx_build__:
            class SomeClass:
                """Mock the class"""
    except NameError:
        raise ImportError('some_dependency')
Forfeit answered 4/12, 2020 at 17:3 Comment(1)
In a similar spirit, it's possible to set an environment variable like os.environ['SPHINX_BUILD'] = '1' (suggested by GitHub copilot...)Effrontery
H
2

If your project is importing sphinx (in my case a sphinx extension), the following may also work for you

import os
import sys
if os.path.basename(sys.argv[0]) == "sphinx-build":
    # code for when sphinx is running
else:
    # code for regular application

I'm not sure if that will work on Windows or if it should be something like

if os.path.basename(sys.argv[0]) in ["sphinx-build", "sphinx-build.exe"]:
Hump answered 12/4, 2018 at 5:4 Comment(0)
M
1

Since Sphinx 1.3 there is a simple solution for this issue. Just add

autodoc_mock_imports = ['arcpy']

to your conf.py. This can be used when some external dependencies are not met at build time and break the building process. See Sphinx: how to exclude imports in automodule?.

It's unfortunate that Esri has very poor arcpy documentation and mostly ignores Python standards.

Manteau answered 17/7, 2020 at 10:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.