Documenting Scripts .... part 2

1967
0
05-09-2015 06:38 AM
Labels (1)
DanPatterson_Retired
MVP Emeritus
0 0 1,967

A thread on GeoNet caused me to revisit an earlier post where I showed one option for documenting scripts as they were run.  I didn’t include the generating script in that post since it was quite unwieldy.  A slightly different and simpler, example is given here. 

The scripts below show the generation of namespace within python as modules are imported. Also of equal importance, is how to cleanup after yourself when you are done a run and have no need for the variables generated.

The first script ... calling_script.py ... does just that.  It is used to import a series of python modules including one user-created script ... import_this.py ... which contains a few useless functions.

"""
Script:   calling_script.py
Author:   
Dan.Patterson@carleton.ca
Requires: import_this.py script/module in the same path as this script
Returns:  Some information about the imported module and this script
Reference:  https://www.python.org/dev/peps/pep-0257/
  https://community.esri.com/blogs/dan_patterson/2014/11/30
         /documenting-python-scripts-and-outputs-as-they-are-run
  https://community.esri.com/thread/158590
"""

locals_in = set(locals().keys())  # namespace at the beginning
print('\nMains script start... locals().keys ...\n{}'.format(locals_in))

import sys
import numpy as np
import arcpy

import import_this                # import the module in question

script = sys.argv[0]
frmt = "\nBack to main script...{}"
frmt += "\nimported module info:\n__doc__...{}__help__...\n{}"

print(frmt.format(script, import_this.__doc__, import_this.__help__))
print("\n-----------------------")
print("Calling script doc...{}".format( __doc__ ))

locals_out = set(locals().keys())
diff = sorted(list(locals_out.difference(locals_in)))
print('Namespace change...\n{}'.format(diff))

#clean up
for i in diff:
    del locals()[i]

del locals_out, i, diff
print('\nNamespace after cleanup...\n{}'.format(locals().keys()))‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

In lines 13 and 14, the local namespace is obtained and printed prior performing the imports. Most of the imports are common ones used people programming for ArcMap.  The ... import_this ... module is nothing more than a user written script which contains a few useless functions.  That script can also be run in standalone mode so that you can see the difference in outputs. 

The remainder of the calling_script, obtains the local namespace after imports, performs a difference in the before and after, then cleans out the namespace.  Those lines can be commented out should you chose to keep access to the variables for command line use.

The module/script being imported is as follows:

"""
Script:   import_this.py
Author:   Dan.Patterson@carleton.ca
Requires: absolutely nothing
Returns:  see Requirements
Purpose:  imports, namespace and doc strings
          (and recursion in Returns-Requires)
"""
import sys

def do_squat():
    """"Hello...I am 'do_squat' the function in import_this.py"
    """
    print(do_squat.__doc__)

def do_stuff():
    """Hi... I am 'do_stuff' a function in 'import_this.py'\n"""   
    done = do_stuff.__doc__ + __help__
    return done

if __name__ == '__main__':
    do_squat()
else:
    __help__ = " I am being imported"
    done = do_stuff()
    print("\nimport_this.py ... says...\n{}".format(done))
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The output after a run of the calling script records the document information for the modules and the functions contained within the imported module.

Mains script start... locals().keys ...
    set(['__builtins__', '__file__', 'pywin', '__package__', '__name__', '__doc__'])

import_this.py ... says...
    Hi... I am 'do_stuff' a function in 'import_this.py'
    I am being imported

Back to main script...D:\Temp\calling_script.py

imported module info:

__doc__...
Script:   import_this.py
Author:   
Dan.Patterson@carleton.ca
Requires: absolutely nothing
Returns:  see Requirements
Purpose:  imports, namespace and doc strings
          (and recursion in Returns-Requires)

__help__...
 I am being imported

-----------------------

Calling script doc...

Script:   calling_script.py

Author:   
Dan.Patterson@carleton.ca
Requires: import_this.py script/module in the same path as this script
Returns:  Some information about the imported module and this script
Reference:
  https://www.python.org/dev/peps/pep-0257/
  https://community.esri.com/blogs/dan_patterson/2014/11/30
         /documenting-python-scripts-and-outputs-as-they-are-run
https://community.esri.com/thread/158590


Namespace change...
    ['arcgis', 'arcpy', 'datetime', 'frmt', 'import_this', 'locals_in', 'math', 'np',
     'script', 'sys', 'time']

Namespace after cleanup...
    ['__builtins__', '__file__', 'pywin', '__package__', '__name__', '__doc__']‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

If you follow the sequences within the scripts and the outputs you can get a sense where you might want to include such information.

About the Author
Retired Geomatics Instructor at Carleton University. I am a forum MVP and Moderator. Current interests focus on python-based integration in GIS. See... Py... blog, my GeoNet blog...
Labels