classification
Title: Put “deprecated” warnings first
Type: enhancement Stage: needs patch
Components: Documentation Versions:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Tony R., brett.cannon, docs@python, eric.araujo, ezio.melotti, georg.brandl, r.david.murray
Priority: normal Keywords: patch

Created on 2015-10-23 17:23 by Tony R., last changed 2015-10-27 15:32 by ezio.melotti.

Files
File name Uploaded Description Edit
0001-Move-deprecated-blocks-to-the-beginning-of-their-doc.patch Tony R., 2015-10-23 17:23 Patch. In documentation, moves “deprecated” warnings to the beginning of their context. review
Messages (11)
msg253391 - (view) Author: Tony R. (Tony R.) * Date: 2015-10-23 17:23
Python has wonderful, detailed documentation.  I love it!

Unfortunately, I have often found myself reading the otherwise-excellent documentation on a class/function/whatever, only to find out at the END of my reading that it is deprecated.

This is frustrating, and counter-intuitive.  If something is deprecated, I want to know it before I read any further.  

I have attached a patch with the relevant changes.  I hope it helps!
msg253467 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2015-10-26 11:31
Thanks for the report and the patch.

I think a better way to handle this would be to add a "tag" next to the function name for both deprecations and "new in", and leave the actual deprecation/new-in notes at the bottom, something like:

funcname(args)  [new in 3.2] [deprecated in 3.5]
  Func description here.

  New in 3.2: the funcname() function was added.
  Deprecated in 3.5: funcname() has been deprecated.  Use anotherfunc() instead.

I've seen other docs doing it, however I'm not sure how easy it would be to implement something similar for Sphinx (maybe it's necessary to redefine the func/meth/class roles).
msg253470 - (view) Author: Tony R. (Tony R.) * Date: 2015-10-26 12:40
> Thanks for the report and the patch.

Thank you for the review!

> I think a better way to handle this would be to add a "tag" next to the function name for both deprecations and "new in", and leave the actual deprecation/new-in notes at the bottom, something like:
> 
> funcname(args)  [new in 3.2] [deprecated in 3.5]
>  Func description here.
> 
>  New in 3.2: the funcname() function was added.
>  Deprecated in 3.5: funcname() has been deprecated.  Use anotherfunc() instead.

I’m not sure I understand what you mean by “tag”.

(ASIDE: I’m only marginally familiar with Sphinx, so I don’t know if “tag” has a specific meaning here.  I dabble across lots of markup-to-full-docs generation tools; Sphinx is just one that I happen to know the least.)

Are you saying that the source documentation would remain as-is, but something during the Sphinx _transformation_ would generate the new/deprecated tags?  

As long as those tags are clearly visible at-or-near the start, then I’m all for it.  If that is what you propose, then I can think of several possible ways to structure the generated HTML & CSS—and from there I would just need to dive into the Sphinx transformations and figure out where to sprinkle the “tags”.
msg253472 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2015-10-26 13:11
> I’m not sure I understand what you mean by “tag”.

>> funcname(args)  [new in 3.2] [deprecated in 3.5]
>>   Func description here.

I mean some kind of tag/label next to the name of the function in the documentation (red/orange for deprecations, green for new-in)  -- it's not a Sphinx-specific term.
I saw it in some other documentation but I can't find it anymore, however if you look at the [task] and [assigned] tags/labels at the top of https://twistedmatrix.com/trac/ticket/5000 you can get a pretty close idea of what I'm thinking about.

> Are you saying that the source documentation would remain as-is,
> but something during the Sphinx _transformation_ would generate
> the new/deprecated tags?  

That's the idea.  Ideally the func/meth/class directives [0] would add the tags/labels if they contain version-added/version-changed/deprecated/deprecated-remove directives.

[0]: directives look like ".. function:: foo(args)", whereas roles look like :func:`foo`.  Functions are defined using directives.  In the previous message I mistakenly said "roles".  See also https://docs.python.org/devguide/documenting.html#directives
msg253483 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-10-26 17:33
I think Ezio's idea is great.  I would not want to see the notices at the top, but a label would make things clear (and the label could be hyperlinked to the note, since sometimes they are a bit of a distance away).

Someone has to figure out the Sphinx programming, though.

Note that the 'new' label should only appear for stuff that is new in that release.  It's not clear to me if it should appear at all in the docs for maintenance releases...that should be discussed.
msg253486 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2015-10-26 17:49
> Note that the 'new' label should only appear for stuff that is new
> in that release.

This is not a problem if it says [new in x.y] explicitly.  This way for each version-added/version-changed/deprecated/deprecated-remove directive we will also have a label.

As for the implementation, I'm pretty sure it can be done by changing/redefining all the function/method/class directives.  The directives should then be able to inspect the nodes they contain and see if there are any of the aforementioned directives and turn them into labels.  Not sure if there's a clever way to do it though (maybe a CSS class can be added to the directives and the labels can be added with CSS :after).
msg253487 - (view) Author: Tony R. (Tony R.) * Date: 2015-10-26 17:52
> On Oct 26, 2015, at 1:49 PM, Ezio Melotti <report@bugs.python.org> wrote:
> 
> Not sure if there's a clever way to do it though (maybe a CSS class can be added to the directives and the labels can be added with CSS :after).

I was thinking something along these lines.  Other possibilities come to mind, also.
msg253490 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-10-26 18:22
Insert "in my opinion" into that sentence.  I don't want to be distracted by "new in 3.1" tags when reading the 3.6 documentation.  It isn't new from my POV :)
msg253498 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2015-10-26 20:28
> I don't want to be distracted by "new in 3.1" tags when reading
> the 3.6 documentation.

This is true, but on the other hand you might want to see the [new in 3.4] while looking at 3.6 docs and working on a program that must support Python 3.3+.  Anyway we can discuss this again once we have a patch -- depending on how it is implemented, it might be easy enough to include the tag only for functions added in the last 2 releases, or perhaps the tag won't be particularly distracting and can be used for all versions.
msg253536 - (view) Author: Tony R. (Tony R.) * Date: 2015-10-27 13:17
> On Oct 26, 2015, at 4:28 PM, Ezio Melotti <report@bugs.python.org> wrote:
> 
> This is true, but on the other hand you might want to see the [new in 3.4] while looking at 3.6 docs and working on a program that must support Python 3.3+.  Anyway we can discuss this again once we have a patch -- depending on how it is implemented, it might be easy enough to include the tag only for functions added in the last 2 releases, or perhaps the tag won't be particularly distracting and can be used for all versions.

Smart use of CSS and a sprinkle of JavaScript could solve this.  

- Add all versions in the markup
- By default, use CSS to hide all except latest version
- Using JavaScript and a simple `localStorage` variable, save a preference to “lower the version threshold” if desired

I tend to prefer non-JS solutions when possible, but this would only take a few lines of code.  (And of course, one `localStorage` variable along the lines of `minimumAddedInPythonVersion = ‘3.2’`, or whatever.)

—Tony
msg253546 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2015-10-27 15:32
I would rather avoid a JS-based solution.

It should be possible to create a mixin that adds the checks for deprecated/versionadded directives among the children of the node, and then define new directives for functions/methods/classes that inherit from the existing one and the mixin.
These directives can be added to https://hg.python.org/cpython/file/tip/Doc/tools/extensions/pyspecific.py
History
Date User Action Args
2015-10-27 15:32:17ezio.melottisetmessages: + msg253546
2015-10-27 13:17:21Tony R.setmessages: + msg253536
2015-10-26 20:28:49ezio.melottisetmessages: + msg253498
stage: needs patch
2015-10-26 18:22:28r.david.murraysetmessages: + msg253490
2015-10-26 17:52:51Tony R.setmessages: + msg253487
2015-10-26 17:49:46ezio.melottisetmessages: + msg253486
2015-10-26 17:33:45r.david.murraysetnosy: + r.david.murray
messages: + msg253483
2015-10-26 16:14:02brett.cannonsetnosy: + brett.cannon
2015-10-26 13:11:00ezio.melottisetmessages: + msg253472
2015-10-26 12:40:28Tony R.setmessages: + msg253470
2015-10-26 11:31:07ezio.melottisetnosy: + georg.brandl, ezio.melotti, eric.araujo
messages: + msg253467
2015-10-23 17:23:23Tony R.create