Referring to 'self' in the documentation

183 views
Skip to first unread message

Eric Gourgoulhon

unread,
Apr 3, 2015, 9:49:53 AM4/3/15
to sage-...@googlegroups.com
Hi,

I would like some advice about the mention of the Python (conventional pseudo-)keyword self when writing docstrings of new class methods: shall we mention self or not ? Of course, from a technical point of view, this is perfectly valid and clear. But for a Sage user not familiar with Python, this might be confusing.

It seems that the current documentation is not homogeneous in this respect:

sage: n=2
sage: n.is_prime?
  Test whether "self" is prime.

sage: n.is_unit?
   Returns "true" if this integer is a unit, i.e., 1 or -1.

Thank you for your advice.

Eric.

Daniel Krenn

unread,
Apr 3, 2015, 9:58:53 AM4/3/15
to sage-...@googlegroups.com
Am 2015-04-03 um 15:49 schrieb Eric Gourgoulhon:
> I would like some advice about the mention of the Python (conventional
> pseudo-)keyword *self* when writing docstrings of new class methods:
> shall we mention *self *or not ? Of course, from a technical point of
> view, this is perfectly valid and clear. But for a Sage user not
> familiar with Python, this might be confusing.

In the html-documentation "self" is not shown for methods. Therefore I
always try to avoid it.

Daniel

Eric Gourgoulhon

unread,
Apr 3, 2015, 10:11:36 AM4/3/15
to sage-...@googlegroups.com

Yes it is: see the example is_prime above; another random example is the method algebra() of
SymmetricGroup.

Eric.

Daniel Krenn

unread,
Apr 3, 2015, 10:18:21 AM4/3/15
to sage-...@googlegroups.com
> <http://www.sagemath.org/doc/reference/groups/sage/groups/perm_gps/permgroup_named.html#sage.groups.perm_gps.permgroup_named.SymmetricGroup>

What I meant is, that in the html documentation in the headline
announcing this function, "self" is not included:

E.g. "algebra(base_ring)" in your example. Therefore *I* avoid it in the
docstring. (But among the existing documentation, this is not consistent).

Daniel

Volker Braun

unread,
Apr 3, 2015, 10:21:02 AM4/3/15
to sage-...@googlegroups.com
See also: https://groups.google.com/d/msg/sage-devel/zMWMBU7CNAo/nLRLgd0BYfcJ

In general, try to avoid "self". We know already that the docstring refers to the object being documented, no need to repeat that all the time. Shorter is better:

sage: n.is_prime?
  Test primality.

Definitely do not document self as one of the INPUT: arguments

Simon King

unread,
Apr 3, 2015, 10:24:26 AM4/3/15
to sage-...@googlegroups.com
Hi Eric,

On 2015-04-03, Eric Gourgoulhon <egourg...@gmail.com> wrote:
>> In the html-documentation "self" is not shown for methods.=20
>
>
> Yes it is:

I think Daniel was referring to the fact that self is not shown in
the documentation in the list of arguments of a method. Of course
it is mentioned in doc strings.

I am not very consistent here, myself. Sometimes I write "self",
sometimes I write "this element" (or whatever is appropriate).

Best regards,
Simon

Eric Gourgoulhon

unread,
Apr 4, 2015, 3:11:58 AM4/4/15
to sage-...@googlegroups.com
Thank you all for your answers.

Eric.


Nicolas M. Thiery

unread,
Apr 4, 2015, 9:12:15 AM4/4/15
to sage-...@googlegroups.com
On Fri, Apr 03, 2015 at 07:21:02AM -0700, Volker Braun wrote:
> Definitely do not document self as one of the INPUT: arguments

I occasionally do, when there are some specific preconditions about
``self``, or when I want to use the occasion to introduce some
mathematical notation that will be used later on in the documentation:

- ``self`` -- an element `w` of a Coxeter group `W`

- ``self`` -- a non-zero element

Cheers,
Nicolas
--
Nicolas M. Thiéry "Isil" <nth...@users.sf.net>
http://Nicolas.Thiery.name/

Volker Braun

unread,
Apr 4, 2015, 9:40:26 AM4/4/15
to sage-...@googlegroups.com, Nicolas...@u-psud.fr
Besides violating every Python docstring guide that I know, its also inconsistent: You can't just sometimes list self as input and sometimes not. IMHO the right thing to do is to either

A) structure the code such that methods are always applicable, eg. why have a method on coxeter group elements that doesn't apply to coxeter group elements? Or

B) document what happens under OUTPUT (though ideally we'd have a RAISES section like the google docstring style). Which also gives you a chance to say what kind of exception is being raised since caller code might want to catch that:

class Number():

    def invert(self):
        """
        Return the reciprocal number

        OUTPUT:

        The reciprocal. Raises a ``ZeroDivisionError`` if the number is zero.
        """

    def invert_proposal(self):
        """
        Return the reciprocal number

        OUTPUT:

        The reciprocal.

        RAISES:

        - ``ZeroDivisionError`` -- the number is zero.
        """

Nicolas M. Thiery

unread,
Apr 5, 2015, 4:24:17 AM4/5/15
to Volker Braun, sage-...@googlegroups.com
On Sat, Apr 04, 2015 at 06:40:26AM -0700, Volker Braun wrote:
> Besides violating every Python docstring guide that I know,

Reference please.

> its also inconsistent: You can't just sometimes list self as
> input and sometimes not.

Why not? There are other chunks of our docstrings that are optional,
and only included if they are non trivial.

> IMHO the right thing to do is to either
> A) structure the code such that methods are always applicable,
> eg. why have a method on coxeter group elements that doesn't
> apply to coxeter group elements? Or

That's certainly the ideal situation. Sometimes it's
possible. Sometimes it's overdesign. We don't have a separate class
for non negative integers or for prime integers. Usually people
complain that I tend to overdesign with too many classes :-).

> B) document what happens under OUTPUT (though ideally we'd have a
> RAISES section like the google docstring style). Which also gives you a
> chance to say what kind of exception is being raised since caller code
> might want to catch that:

The INPUT section is the natural place for specifying simple
preconditions on the individual arguments (e.g. `l` -- a list of non
negative integer). I don't see why we should make a special case for
``self``. And why we should prevent ourselves from using a natural
concise idiom for doing so.

I agree that it's nice to be specific about the behavior when the
preconditions are violated (introducing a standardized RAISES section
would definitely make sense). But only if it's not obvious (e.g.,
depending on the context, a TypeError or a ValueError). Besides, more
often than not, this information is best explained (and tested!) on an
example.

Volker Braun

unread,
Apr 5, 2015, 7:32:49 AM4/5/15
to sage-...@googlegroups.com, vbrau...@gmail.com, Nicolas...@u-psud.fr
On Sunday, April 5, 2015 at 10:24:17 AM UTC+2, Nicolas M. Thiéry wrote:
On Sat, Apr 04, 2015 at 06:40:26AM -0700, Volker Braun wrote:
>    Besides violating every Python docstring guide that I know,
Reference please. 

We talked about that in the thread that I linked, but for reference here is the relevant part of the Google docstring guide once more: 


class ExampleError(Exception):
    """Exceptions are documented in the same way as classes.

    The __init__ method may be documented in either the class level
    docstring, or as a docstring on the __init__ method itself.

    Either form is acceptable, but the two should not be mixed. Choose one
    convention to document the __init__ method and be consistent with it.

    Note:
      Do not include the `self` parameter in the ``Args`` section.

    Args:
      msg (str): Human readable string describing the exception.
      code (int, optional): Error code, defaults to 2.

    Attributes:
      msg (str): Human readable string describing the exception.
      code (int): Exception error code.

    """
    def __init__(self, msg, code=2):
        self.msg = msg
        self.code = code


>    its also inconsistent: You can't just sometimes list self as
>    input and sometimes not.
Why not? There are other chunks of our docstrings that are optional,
and only included if they are non trivial.

I don't think I understand what you are referring to. It is mandatory to document every INPUT argument, not just the ones that you feel like documenting. 
 

>    B) document what happens under OUTPUT (though ideally we'd have a
>    RAISES section like the google docstring style). Which also gives you a
>    chance to say what kind of exception is being raised since caller code
>    might want to catch that:

The INPUT section is the natural place for specifying simple
preconditions on the individual arguments (e.g. `l` -- a list of non
negative integer).  I don't see why we should make a special case for
``self``. And why we should prevent ourselves from using a natural
concise idiom for doing so.

You don't specify self as part of the arguments when you call a method, so its not part of the INPUT section. You shouldn't have to know about the details of Python OOP just to call a method after reading the docstring.

Nicolas M. Thiery

unread,
May 12, 2015, 4:29:49 AM5/12/15
to Volker Braun, sage-...@googlegroups.com
Dear Volker,

Ooops, I let this thread drop out of my view ... sorry to get back to
it so much later.

> You don't specify self as part of the arguments when you call a method,
> so its not part of the INPUT section. You shouldn't have to know about
> the details of Python OOP just to call a method after reading the
> docstring.

Be it in Java, Python or other OOP programing language, the instance
(this, self, ...) is definitely part of the input of the method; of
course the method call and declaration syntax makes it more or less
explicit depending on the language.


> We talked about that in the thread that I linked, but for reference
> here is the relevant part of the Google docstring guide once more:
> http://sphinx-doc.org/latest/ext/example_google.html
> class ExampleError(Exception):
> """Exceptions are documented in the same way as classes.
> The __init__ method may be documented in either the class level
> docstring, or as a docstring on the __init__ method itself.
> Either form is acceptable, but the two should not be mixed. Choose
> one
> convention to document the __init__ method and be consistent with
> it.
> Note:
> Do not include the `self` parameter in the ``Args`` section.
> ...

Thanks for the specific ref!

As every programming rule, I take it as "don't do it, unless you
master the rationale and potential consequences, and have a better
reason to do it". In most situations, the consequences can be hard to
foresee, and I totally agree with the general position of "in doubt,
take advantage of the community experience, and follow the
recommendations".

Here, the rationale is clear (don't be redundant: we know `self` is
part of the input), and the consequences seem straightforward to
evaluate. And we are anyway using a custom syntax. So I maintain my
preference for customizing the above rule to:

``Don't include the `self` parameter in the ``Args`` section,
unless there is a good reason for it, like specifying certain
precondition `self` should satisfy, or using the occasion to
define a notation''

> > its also inconsistent: You can't just sometimes list self as
> > input and sometimes not.
> Why not? There are other chunks of our docstrings that are optional,
> and only included if they are non trivial.
>
> I don't think I understand what you are referring to. It is mandatory
> to document every INPUT argument, not just the ones that you feel like
> documenting.

Certainly. Sorry, I was ambiguous. By chunks of the documentation, I
meant things like the ALGORITHM or REFERENCES sections. So the
situation would be similar: don't document `self` unless it's non trivial.

Volker Braun

unread,
May 12, 2015, 7:47:27 AM5/12/15
to sage-...@googlegroups.com, Nicolas...@u-psud.fr, vbrau...@gmail.com
On Tuesday, May 12, 2015 at 10:29:49 AM UTC+2, Nicolas M. Thiéry wrote:
>          Do not include the `self` parameter in the ``Args`` section.
As every programming rule, I take it as "don't do it, unless you
master the rationale and potential consequences, and have a better
reason to do it".

Which part of "Do not include the `self` parameter in the ``Args`` section" did you not understand? ;-)

Really, this is about presenting a consistent documentation to end users. They shouldn't have to know how Python scopes the object state, and they most certainly shouldn't have to guess whether Nicolas thought it would be a good idea to add 'self' to the INPUT section in this particular case. In that sense the need for consistency is much higher in the documentation than in the code.

leif

unread,
May 12, 2015, 9:46:44 AM5/12/15
to sage-...@googlegroups.com
How about a '.. note::' in the INPUT section in case (properties of /
restrictions on) 'self' need(s) to be documented?


-leif


Simon King

unread,
May 12, 2015, 5:39:18 PM5/12/15
to sage-...@googlegroups.com
Hi Nicolas and Volker,

On 2015-05-12, Volker Braun <vbrau...@gmail.com> wrote:
> On Tuesday, May 12, 2015 at 10:29:49 AM UTC+2, Nicolas M. Thiéry wrote:
>>
>> > Do not include the `self` parameter in the ``Args`` section.
>> As every programming rule, I take it as "don't do it, unless you
>> master the rationale and potential consequences, and have a better
>> reason to do it".
>
>
> Which part of "Do not include the `self` parameter in the ``Args`` section"
> did you not understand? ;-)
>
> Really, this is about presenting a consistent documentation to end users.
> They shouldn't have to know how Python scopes the object state, and they
> most certainly shouldn't have to guess whether Nicolas thought it would be
> a good idea to add 'self' to the INPUT section in this particular case.

I agree that the INPUT section is not the place for elaborating on
"self".

In his previous post, Nicolas mentioned that sometimes one needs to
formulate preconditions that self needs to provide, or one needs to fix
a notation involving self. I believe that preconditions should be
formulated in an ASSUMPTIONS section, and notations should belong to an
ALGORITHM or THEORY section. If I recall correctly, all these sections
are used in sage's documentation (or at least I have used them...).

Best regards,
Simon


Jori Mäntysalo

unread,
May 13, 2015, 2:07:56 AM5/13/15
to sage-...@googlegroups.com
On Tue, 12 May 2015, Simon King wrote:

> - - sometimes one needs to formulate preconditions that self needs to
> provide, or one needs to fix a notation involving self. I believe that
> preconditions should be formulated in an ASSUMPTIONS section, and
> notations should belong to an ALGORITHM or THEORY section.

How explicit should this be? For example see
http://www.sagemath.org/doc/reference/combinat/sage/combinat/posets/posets.html
Is it enought to say "Return the flag f-polynomial of a bounded and ranked
poset self." just rephrased as "Return the flag f-polynomial of the poset,
which is assumed to be bounded and ranked."?

There is also a difference between something not defined mathematically
and something not (yet) implemented in Sage.

--
Jori Mäntysalo

leif

unread,
May 13, 2015, 5:26:29 AM5/13/15
to sage-...@googlegroups.com
Simon King wrote:
>> Really, this is about presenting a consistent documentation to end users.
>> They shouldn't have to know how Python scopes the object state, and they
>> most certainly shouldn't have to guess whether Nicolas thought it would be
>> a good idea to add 'self' to the INPUT section in this particular case.
>
> I agree that the INPUT section is not the place for elaborating on
> "self".
>
> In his previous post, Nicolas mentioned that sometimes one needs to
> formulate preconditions that self needs to provide, or one needs to fix
> a notation involving self. I believe that preconditions should be
> formulated in an ASSUMPTIONS section, and notations should belong to an
> ALGORITHM or THEORY section. If I recall correctly, all these sections
> are used in sage's documentation (or at least I have used them...).

Ahem, maybe I misunderstood you, but (most) assumptions or preconditions
are formulated in the INPUT section, namely the ("simple") ones on the
"types" and/or values of the parameters (except 'self').

Do you intend to move anything beyond "- ``s`` -- a string" and "-
``proof`` -- bool (default: False)", say, into another section?

(The meaning or influence of parameters is often also part of the
"Return[s] ..." or "OUTPUT" section.)


-leif


Simon King

unread,
May 13, 2015, 6:39:39 AM5/13/15
to sage-...@googlegroups.com
Hi Leif,

On 2015-05-13, leif <not.r...@online.de> wrote:
> Simon King wrote:
>> In his previous post, Nicolas mentioned that sometimes one needs to
>> formulate preconditions that self needs to provide, or one needs to fix
>> a notation involving self. I believe that preconditions should be
>> formulated in an ASSUMPTIONS section, and notations should belong to an
>> ALGORITHM or THEORY section. If I recall correctly, all these sections
>> are used in sage's documentation (or at least I have used them...).
>
> Ahem, maybe I misunderstood you, but (most) assumptions or preconditions
> are formulated in the INPUT section, namely the ("simple") ones on the
> "types" and/or values of the parameters (except 'self').

Yes, you misunderstood me.

Or I misunderstood Nicolas. I understood Nicolas that sometimes it is
needed to state prerequisites that *self* (not the other arguments) have
to provide for the method to make sense. And that does not belong to an
INPUT section but to an ASSUMPTIONS section, IMHO.

> Do you intend to move anything beyond "- ``s`` -- a string" and "-
> ``proof`` -- bool (default: False)", say, into another section?

No. I think that
(1) "self" should not be documented in the INPUT section,
(2) types/prerequisites/etc of the other arguments should be documented
in the INPUT section, and
(3) there should only be an ASSUMPTIONS section if self needs to be
somehow special for the method to work, and in that case the ASSUMPTIONS
section should refer only to self and not to prerequisites for the other
parameters.

Clearer now?

> (The meaning or influence of parameters is often also part of the
> "Return[s] ..." or "OUTPUT" section.)

Yes.

Best regards,
Simon


Volker Braun

unread,
May 13, 2015, 7:37:47 AM5/13/15
to sage-...@googlegroups.com
I would prefer a RAISES section that also defines what happens if preconditions are violated, but calling it ASSUMPTIONS would be fine with me too. In any case, it ought to be documented at

http://www.sagemath.org/doc/developer/coding_basics.html#the-docstring-of-a-function-content

Huayi Wei

unread,
Jun 1, 2015, 6:10:13 AM6/1/15
to sage-...@googlegroups.com
Hi, there,

I met the following error when I install sage from ppa. My system is
Ubuntu 14.04 LTS 64bit.

I need your help. Thanks very much.

Best

Huayi

```
:~$ sudo apt-get install sagemath-upstream-binary
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
sagemath-upstream-binary
0 upgraded, 1 newly installed, 0 to remove and 10 not upgraded.
Need to get 270 MB of archives.
After this operation, 2,055 MB of additional disk space will be used.
Get:1 http://ppa.launchpad.net/aims/sagemath/ubuntu/ trusty/main
sagemath-upstream-binary amd64 6.7ppa8revert6.6 [270 MB]
Fetched 270 MB in 8min 44s (514 kB/s)
Selecting previously unselected package sagemath-upstream-binary.
(Reading database ... 819671 files and directories currently installed.)
Preparing to unpack
.../sagemath-upstream-binary_6.7ppa8revert6.6_amd64.deb ...
Unpacking sagemath-upstream-binary (6.7ppa8revert6.6) ...
Processing triggers for mime-support (3.54ubuntu1.1) ...
Processing triggers for gnome-menus (3.10.1-0ubuntu2) ...
Processing triggers for desktop-file-utils (0.22-1ubuntu1) ...
Processing triggers for bamfdaemon (0.5.1+14.04.20140409-0ubuntu1) ...
Rebuilding /usr/share/applications/bamf-2.index...
Setting up sagemath-upstream-binary (6.7ppa8revert6.6) ...
Running Sage once as root to set paths
┌────────────────────────────────────────────────────────────────────┐
│ SageMath Version 6.6, Release Date: 2015-04-14 │
│ Type "notebook()" for the browser-based notebook interface. │
│ Type "help()" for help. │
└────────────────────────────────────────────────────────────────────┘
The Sage installation tree has moved
from /home/buildbot/build/sage/snapperkob/sage_git/build
to /usr/lib/sagemath
Updating various hardcoded paths...
(Please wait at most a few minutes.)
DO NOT INTERRUPT THIS.
Done updating paths.
Traceback (most recent call last):
File "/usr/lib/sagemath/src/bin/sage-ipython", line 7, in <module>
from sage.repl.interpreter import SageTerminalApp
File
"/usr/lib/sagemath/local/lib/python2.7/site-packages/sage/__init__.py",
line 3, in <module>
from sage.repl.ipython_extension import load_ipython_extension
File
"/usr/lib/sagemath/local/lib/python2.7/site-packages/sage/repl/ipython_extension.py",
line 59, in <module>
from IPython.core.magic import Magics, magics_class, line_magic
File
"/usr/lib/sagemath/local/lib/python2.7/site-packages/IPython/__init__.py",
line 45, in <module>
from .config.loader import Config
File
"/usr/lib/sagemath/local/lib/python2.7/site-packages/IPython/config/__init__.py",
line 6, in <module>
from .application import *
File
"/usr/lib/sagemath/local/lib/python2.7/site-packages/IPython/config/application.py",
line 9, in <module>
import json
File "/usr/lib/sagemath/local/lib/python/json/__init__.py", line 108,
in <module>
from .decoder import JSONDecoder
File "/usr/lib/sagemath/local/lib/python/json/decoder.py", line 5, in
<module>
import struct
File "/usr/lib/sagemath/local/lib/python/struct.py", line 1, in <module>
from _struct import *
ImportError: No module named _struct
dpkg: error processing package sagemath-upstream-binary (--configure):
subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
sagemath-upstream-binary
E: Sub-process /usr/bin/dpkg returned an error code (1)

```


Reply all
Reply to author
Forward
0 new messages