Skip to content

Instantly share code, notes, and snippets.

@SethMMorton
Created May 19, 2015 03:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SethMMorton/dff367d7258107d4bd23 to your computer and use it in GitHub Desktop.
Save SethMMorton/dff367d7258107d4bd23 to your computer and use it in GitHub Desktop.
Script to patch the doctest standard library module to be able to work on C extension modules.
"""\
Copies doctest.py from the stdlib to the current directory,
and modifies it so that
a) It will load "*.so" files as modules just like a "*.py" file
b) It recognizes functions defined in "*.so" files
c) Remove the configuration extension from the "*.so" files (on Python3)
With these enhancements, doctest can be run on a C python extension module.
"""
from __future__ import print_function
import sys
import inspect
import doctest
# Get the source file location
dt_location = inspect.getsourcefile(doctest)
# Read the module into memory
with open(dt_location) as fl:
doctest_str = fl.read()
# Add a search for the .so extension when inspecting the input files
# so that extension modules will be loaded properly.
doctest_str = doctest_str.replace(
'if filename.endswith(".py"):',
'if filename.endswith(".py") or filename.endswith(".so"):'
)
# inspect.isfunction does not work for functions written in C,
# so we have to replace that with an inspect.isbuiltin check when
# looking for functions with docstrings.
doctest_str = doctest_str.replace(
'if ((inspect.isfunction(val) or inspect.isclass(val)) and',
'if ((inspect.isfunction(val) or inspect.isbuiltin(val) or inspect.isclass(val)) and'
)
# Replace the configuration extension with nothing on Python3
if sys.version[0] == '3':
doctest_str = doctest_str.replace(
'm = __import__(filename[:-3])',
'm = __import__(filename[:-3] if filename.endswith(".py") else filename.replace(get_config_var("EXT_SUFFIX"), ""))'
)
# We need to import the get_config_var variable.
doctest_str = doctest_str.replace(
'def _test():',
'from sysconfig import get_config_var\ndef _test():'
)
# Open up the new output file and write the modified input to it.
with open('doctest.py', 'w') as fl:
print(doctest_str, file=fl, end='')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment