Ticket #11817: trac11817_question_mark_using_sage_getdoc.patch

File trac11817_question_mark_using_sage_getdoc.patch, 11.7 KB (added by SimonKing, 8 years ago)

Use sage_getdoc for interactively reading documentation. Improve docstring formatting

  • sage/misc/interpreter.py

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1316514289 -7200
    # Node ID cc3079ebdad462065d8662ec8a131de74c5953d7
    # Parent  3c6b828cfbe0ba15255bd97f663034734ca23421
    #11817: Improve formatting of sage docstrings, and use sage_getdoc, so that embedding info is not printed.
    
    diff --git a/sage/misc/interpreter.py b/sage/misc/interpreter.py
    a b  
    2222  -- the R.<x,y,z> = ... notation
    2323
    2424TODO:
     25
    2526  I have no plans for anything further, except to improve the
    2627  robustness of the above.  Preparsing may work incorrectly for
    2728  multi-line input lines in some cases; this will be fixed.
     
    4748Finally, I added back the M.n notation for the n-th generator
    4849of object M, again like in MAGMA.
    4950
    50 EXAMPLE:
     51EXAMPLE::
     52
    5153    sage: 2/3
    5254    2/3
    5355    sage: type(2/3)
     
    6668A fix would be to only not make what's in the brackets an
    6769Integer if what's before the bracket is a valid identifier,
    6870so the w = [5] above would work right.
     71::
    6972
    7073    sage: s = "x^3 + x + 1"
    7174    sage: s
     
    137140
    138141    INPUT:
    139142   
    140         - ``line`` -- a single line; must *not* have any newlines in it
    141         - ``continuation`` -- whether the input line is really part
    142           of the previous line, because of open parens or backslash.
     143    - ``line`` -- a single line; must *not* have any newlines in it
     144    - ``continuation`` -- whether the input line is really part
     145      of the previous line, because of open parens or backslash.
    143146    """
    144147    if '\n' in line:
    145148        raise RuntimeError, "bug in function that calls do_prefilter_paste -- there can be no newlines in the input"
     
    269272        # -*- coding: utf-8 -*-
    270273        'import os, sys\n...'
    271274
    272     TESTS::
     275    TESTS:
    273276
    274     These are some of the tests listed in PEP 263.
     277    These are some of the tests listed in PEP 263::
    275278
    276279        sage: contents = '#!/usr/bin/python\n# -*- coding: latin-1 -*-\nimport os, sys'
    277280        sage: handle_encoding_declaration(contents, sys.stdout)
     
    320323        '#!/usr/local/bin/python\nimport os, sys'
    321324
    322325
    323     NOTES::
     326    NOTES:
    324327
    325         PEP 263: http://www.python.org/dev/peps/pep-0263/
     328    - PEP 263: http://www.python.org/dev/peps/pep-0263/
     329    - PEP 263 says that Python will interpret a UTF-8 byte order mark
     330      as a declaration of UTF-8 encoding, but I don't think we do
     331      that; this function only sees a Python string so it can't
     332      account for a BOM.
     333    - We default to UTF-8 encoding even though PEP 263 says that
     334      Python files should default to ASCII.
     335    - Also see http://docs.python.org/ref/encodings.html.
    326336
    327         PEP 263 says that Python will interpret a UTF-8 byte order mark
    328         as a declaration of UTF-8 encoding, but I don't think we do
    329         that; this function only sees a Python string so it can't
    330         account for a BOM.
     337    AUTHORS:
    331338
    332         We default to UTF-8 encoding even though PEP 263 says that
    333         Python files should default to ASCII.
    334 
    335         Also see http://docs.python.org/ref/encodings.html.
    336 
    337     AUTHORS::
    338 
    339         - Lars Fischer
    340         - Dan Drake (2010-12-08, rewrite for ticket #10440)
     339    - Lars Fischer
     340    - Dan Drake (2010-12-08, rewrite for ticket #10440)
    341341    """
    342342    lines = contents.splitlines()
    343343    for num, line in enumerate(lines[:2]):
     
    389389    line), return the preparsed version of it. 
    390390
    391391    INPUT:
    392         block -- string (usually a single line, but not always)
    393         continuation -- whether or not this line is a continuation.
     392
     393    - block -- string (usually a single line, but not always)
     394    - continuation -- whether or not this line is a continuation.
    394395    """
    395396    try:
    396397        block2 = ''
     
    432433    Turn on or off the Sage preparser.
    433434
    434435    INPUT:
    435         - ``on`` -- bool (default: True) if True turn on preparsing; if False, turn it off.
    436436
    437     EXAMPLES:
     437    - ``on`` -- bool (default: True) if True turn on preparsing; if False, turn it off.
     438
     439    EXAMPLES::
     440
    438441        sage: 2/3
    439442        2/3
    440443        sage: preparser(False)
     
    456459import sagedoc
    457460import sageinspect
    458461import IPython.OInspect
    459 IPython.OInspect.getdoc = sagedoc.my_getdoc
     462IPython.OInspect.getdoc = sageinspect.sage_getdoc #sagedoc.my_getdoc
    460463IPython.OInspect.getsource = sagedoc.my_getsource
    461464IPython.OInspect.getargspec = sageinspect.sage_getargspec
    462465
  • sage/misc/sagedoc.py

    diff --git a/sage/misc/sagedoc.py b/sage/misc/sagedoc.py
    a b  
    1010- John Palmieri (2009-04-11): fix for #5754 plus doctests
    1111- Dan Drake (2009-05-21): refactor search_* functions, use system 'find' instead of sage -grep
    1212- John Palmieri (2009-06-28): don't use 'find' -- use Python (os.walk, re.search) instead.
    13 - Simon King (2011-09-19): use os.linesep, avoid destruction of embedding information,
    14   enable nodetex in a docstring.
     13- Simon King (2011-09): Use os.linesep, avoid destruction of embedding information,
     14  enable nodetex in a docstring. Consequently use sage_getdoc.
    1515"""
    1616#*****************************************************************************
    1717#       Copyright (C) 2005 William Stein <wstein@gmail.com>
     
    151151    ``math_substitutes`` and ``nonmath_substitutes``.  If True, then
    152152    only do ``nonmath_substitutes``.
    153153
    154     OUTPUT: string
     154    OUTPUT:
     155
     156    string
    155157
    156158    EXAMPLES::
    157159
     
    320322    return s
    321323
    322324def format(s, embedded=False):
    323     r"""
     325    r"""noreplace
    324326    Format Sage documentation ``s`` for viewing with IPython.
    325327
    326328    This calls ``detex`` on ``s`` to convert LaTeX commands to plain
    327     text, and if ``s`` contains a string of the form "<<<obj>>>",
    328     then it replaces it with the docstring for "obj".
     329    text, unless the directive ``nodetex`` is given in the first line
     330    of the string.
     331
     332    Also, if ``s`` contains a string of the form ``<<<obj>>>``, then
     333    it replaces it with the docstring for ``obj``, unless the
     334    directive ``noreplace`` is given in the first line. If an error
     335    occurs under the attempt to find the docstring for ``obj``, then
     336    the substring ``<<<obj>>>`` is preserved.
     337
     338    Directives must be separated by a comma.
    329339
    330340    NOTE:
    331341
     
    355365    don't modify any TeX commands::
    356366   
    357367        sage: format("nodetex\n`x \\geq y`")
    358         '\n`x \\geq y`'
     368        '`x \\geq y`'
    359369
    360370    Testing a string enclosed in triple angle brackets::
    361371
     
    378388    a ``nodetex`` directive in the first "essential" line of the doc string
    379389    is recognised. That has been implemented in trac ticket #11815::
    380390
    381         sage: r = 'File: _local_user_with_a_very_long_name_that_would_normally_be_wrapped_sage_temp_machine_name_1234_tmp_1_spyx_0.pyx (starting at line 6)\nnodetex\nsome doc for a cython method\n`x \\geq y`'
     391        sage: r = 'File: _local_user_with_a_very_long_name_that_would_normally_be_wrapped_sage_temp_machine_name_1234_tmp_1_spyx_0.pyx (starting at line 6)\nnodetex\nsome doc for a cython method\n`x \geq y`'
    382392        sage: print format(r)
    383393        File: _local_user_with_a_very_long_name_that_would_normally_be_wrapped_sage_temp_machine_name_1234_tmp_1_spyx_0.pyx (starting at line 6)
    384394        <BLANKLINE>
     
    405415            `x \geq y`
    406416        <BLANKLINE>
    407417
     418    We check that the ``noreplace`` directive works, even combined with ``nodetex`` and
     419    an embedding information (see trac ticket #11817)::
     420
     421        sage: print format('File: bla.py (starting at line 1)\nnodetex, noreplace\n<<<identity_matrix>>>`\\not= 0`')
     422        File: bla.py (starting at line 1)
     423        <<<identity_matrix>>>`\not= 0`
     424
     425    If replacement is impossible, then no error is raised::
     426
     427        sage: print format('<<<bla\n<<<bla>>>\n<<<identity_matrix>>>')
     428        <<<bla <<<bla>>>
     429        <BLANKLINE>
     430        Definition: identity_matrix(ring, n=0, sparse=False)
     431        <BLANKLINE>
     432           Return the n x n identity matrix over the given ring.
     433        ...
     434
    408435    """
    409436    if not isinstance(s, str):
    410437        raise TypeError, "s must be a string"
     
    420447        from sage.misc.sageinspect import _extract_embedded_position
    421448        if _extract_embedded_position(first_line) is not None:
    422449            embedding_info = first_line + os.linesep
    423             s = s[first_newline+1:]
     450            s = s[first_newline+len(os.linesep):]
    424451            # Hence, by now, s starts with the second line.
    425452    else:
    426453        from sage.misc.sageinspect import _extract_embedded_position
     
    432459    s = s.lstrip(os.linesep)
    433460
    434461    # parse directives at beginning of docstring
    435     # currently, only 'nodetex' is supported.
     462    # currently, only 'nodetex' and 'noreplace' are supported.
    436463    # 'no' + 'doctest' may be supported eventually (don't type that as
    437464    # one word, or the whole file will not be doctested).
    438465    first_newline = s.find(os.linesep)
     
    443470    # Moreover, we must strip blank space in order to get the directives
    444471    directives = [ d.strip().lower() for d in first_line.split(',') ]
    445472
     473    if 'noreplace' in directives or 'nodetex' in directives:
     474        s = s[first_newline+len(os.linesep):]
     475
    446476    import sage.all
    447477    import sage.server.support
    448478    docs = set([])
    449     while True:
    450         i = s.find("<<<")
    451         if i == -1: break
    452         j = s[i+3:].find('>>>')
    453         if j == -1: break
    454         obj = s[i+3:i+3+j]
    455         if obj in docs:
    456             t = ''
    457         else:
    458             x = eval('sage.all.%s'%obj, locals())
    459             t0 = sage.misc.sageinspect.sage_getdef(x, obj)
    460             t1 = my_getdoc(x)
    461             t = 'Definition: ' + t0 + '\n\n' + t1
    462             docs.add(obj)
    463         s = s[:i] + '\n' + t + s[i+6+j:]
     479    if 'noreplace' not in directives:
     480        i_0 = 0
     481        while True:
     482            i = s[i_0:].find("<<<")
     483            if i == -1: break
     484            j = s[i_0+i+3:].find('>>>')
     485            if j == -1: break
     486            obj = s[i_0+i+3 : i_0+i+3+j]
     487            if obj in docs:
     488                t = ''
     489            else:
     490                try:
     491                    x = eval('sage.all.%s'%obj, locals())
     492                except AttributeError:
     493                    # A pair <<<...>>> has been found, but the object not.
     494                    i_0 += i+6+j
     495                    continue
     496                except SyntaxError:
     497                    # This is a simple heuristics to cover the case of
     498                    # a non-matching set of <<< and >>>
     499                    i_0 += i+3
     500                    continue
     501                t0 = sage.misc.sageinspect.sage_getdef(x, obj)
     502                t1 = sage.misc.sageinspect.sage_getdoc(x)
     503                t = 'Definition: ' + t0 + '\n\n' + t1
     504                docs.add(obj)
     505            s = s[:i_0+i] + '\n' + t + s[i_0+i+6+j:]
     506            i_0 += i
    464507
    465508    if 'nodetex' not in directives:
    466509        s = process_dollars(s)
    467510        s = process_mathtt(s, embedded=embedded)
    468511        s = detex(s, embedded=embedded)
    469     else:
    470         # strip the 'nodetex' directive from s
    471         s = s.replace('nodetex', '', 1)
    472512    return embedding_info+s
    473513
    474514def format_src(s):
     
    10671107#######################################
    10681108import sageinspect
    10691109
    1070 def my_getdoc(obj):
    1071     """
    1072     Retrieve the documentation for ``obj``.
    1073 
    1074     INPUT: ``obj`` - a Sage object, function, etc.
    1075 
    1076     OUTPUT: its documentation (string)
    1077    
    1078     EXAMPLES::
    1079 
    1080         sage: from sage.misc.sagedoc import my_getdoc
    1081         sage: s = my_getdoc(identity_matrix)
    1082         sage: type(s)
    1083         <type 'str'>
    1084     """
    1085     try:
    1086         ds = obj._sage_doc_()
    1087     except (AttributeError, TypeError):  # TypeError for interfaces
    1088         try:
    1089             ds = sageinspect.sage_getdoc(obj)
    1090         except:
    1091             return None
    1092     if ds is None:
    1093         return None
    1094     return ds
    1095 
    10961110def my_getsource(obj, is_binary):
    10971111    """
    10981112    Retrieve the source code for ``obj``.