Opened 22 months ago

Last modified 14 months ago

#6318 enhancement new

Document when to use L{} and when to use C{}

Reported by: tom.prince Owned by:
Priority: normal Milestone:
Component: core Keywords: documentation policy
Cc: staceysern@… Branch:
Author: Launchpad Bug:

Description

L{} should be used for global names, C{} should be used for local names, particularly parameter names and code-snippets.

In particular, L{} can and should be used for things in the standard library.

Also, L{} should have either a absolute path (i.e. something suitable for twisted.python.reflect.namedAny) or a locally usable name. For example if mod is imported, then L{mod.SomeClass}, or if import mod as m, then L{m.SomeCalss} or if from mod import SomeClass then L{SomeClass}.

Change History (9)

comment:1 Changed 22 months ago by glyph

Also, to make the generated documentation more readable in cases where things are referred to, but not used – for example, if you want to mention that one of your parameters must implement an interface, but there's no call to use that interface itself in the function and therefore no reason to import it – L{Z <x.y.Z>}. may be used.

comment:2 Changed 22 months ago by tom.prince

Some experimation should that sibling methods can use 'L{}'.

comment:3 Changed 20 months ago by rwall

I've never understood why it's necessary to use L{} C{} etc in test docstrings given that tests are not included in the API docs. It would be useful to write a note about that either here or in #6301.

comment:4 Changed 19 months ago by tom.prince

  • Keywords policy added

comment:5 follow-up: Changed 16 months ago by shira

  • Cc staceysern@… added

It seems to me that using L{} for built-in types does not add value to the API documentation and in some cases makes it less readable.

int, bytes, list, tuple, file and others all link to the top of same page in the Python documentation for built-in-types (http://docs.python.org/2/library/stdtypes.html). dict and set also link to information on this same page. They link to the constructor for the class, not to the general discussion of their type. Having a link to this page for these types isn't really useful especially since they are basic Python types that users are probably familiar with. If a user needed to look something up about one of these types, they would probably not think that the Twisted API documentation should have linked to information about basic Python types. On the other hand, if they clicked the link and ended up in a place that didn't easily provide the information about the type, they might think that the link was misleading.

More problematic is the treatment of None. Currently when specifying that a variable or parameter can hold the value of None, the documentation contains C{NoneType}. That would need to change to L{types.NoneType}. That's less readable and the link (http://docs.python.org/2/library/types.html#types.NoneType) offers little information. No one would ever be tempted to click on a NoneType link more than once.

This policy might be a good idea for more complicated types especially those that have direct links to useful information in the Python documentation but perhaps some of the basic types should excluded from the L{} policy.

In experimenting with links to types in the standard library, I found that the current tools for building the API docs don't resolve all standard library references. Some examples are collections.Counter, fraction.Fractions, rfc822.Message. StringIO presents another problem for a link because in some files there is an attempt to import from cStringIO followed by an import from StringIO if there is an error.

The suggestions that an absolute path or locally usable name should be used also negatively affects readability of the API documentation. It is often much easier to "get" what is being talked about when the reference is IReactorTCP than twisted.internet.interfaces.IReactorTCP or even internet.interfaces.IReactorTCP, for example. The eye has to pass over most of the name to get to the last part which is what is important. And if the reader needs to know the full path of the class, they could just click the link in the API. There is less information for someone just reading the docstring in the code but they an always go to the API documentation and click the link for more info.

The way pydoctor works seems to suggest this behavior is normal. It links to classes in Twisted which are not in imported modules. So, L{DNSProtocol} links to twisted.names.dns.DNSProtocol even if nothing in that path has been imported. If there are two classes in Twisted that have the same name, pydoctor will warn about an ambiguous reference and will not generate a link. The pitfall is when trying to link to a class in another module that has the same name as a class in the current package, pydoctor will automatically link to the class in the current package without raising an ambiguous reference warning.

comment:6 Changed 16 months ago by exarkun

Having a link to this page for these types isn't really useful especially since they are basic Python types that users are probably familiar with. If a user needed to look something up about one of these types, they would probably not think that the Twisted API documentation should have linked to information about basic Python types.

I think this is probably true. I think that it's a problem to fix in pydoctor, though - not in the API documentation source (ie, the docstrings). That is, this is a rendering problem. It's better to keep all the metadata we can in the model (ie, the docstrings).

pydoctor should give us a toggle to say which builtin types have links generated for them and which don't.

If we stop using L{} then we essentially lose the ability to generate any of these links. We also have to make developers and reviews think harder. "Oh, is this a type that we agreed is simple enough to not link to it? I forget...". The most likely outcome is a confusing mix of inconsistently linked and not linked types.

comment:7 Changed 16 months ago by glyph

(This is somewhat redundant with exarkun's response, since I composed it at the same time :-).)

Thanks, Stacy. This information would all be very useful in a pydoctor bug report. However, I still think we should prefer L{}. L{} provides more information to the documentation generator. Maybe all the generator should do with that information would be to highlight the word differently (like, "blue and in a bold monospaced font" as many popular editors will do with builtins). Maybe there's a better stdlib thing that could be linked to. But if we start documenting things with C{None} and C{int}, then it's ambiguous to the documentation generator whether we're referring to the built-in Python type, or the name of an argument, or maybe just a meta-syntactic variable.

So let's stick to L{} and then perhaps file some presentation bugs on pydoctor's side of things, or some documentation bugs on Python's side of things. (NoneType's documentation should clearly be better, I think.)

comment:8 in reply to: ↑ 5 Changed 16 months ago by tom.prince

Replying to shira:

The suggestions that an absolute path or locally usable name should be used also negatively affects readability of the API documentation. It is often much easier to "get" what is being talked about when the reference is IReactorTCP than twisted.internet.interfaces.IReactorTCP or even internet.interfaces.IReactorTCP, for example.

It is possible to get the behavior by writing L{IReactorTCP<twisted.internet.interface.IReactorTCP>} for example.

comment:9 Changed 14 months ago by tom.prince

`
<exarkun> L{} is for references to things
<exarkun> Here is what L{} is *not*: L{} is not a way to make some words render as blue with an underline in a web browser.
<exarkun> L{} means "Look, if you interpret this as a Python name, then you'll find an object and you can use that to assign some semantic significance to this text
<exarkun> (For completeness, C{} means "if you tried to run this using a Python unterpreter in the right context then some coherent result would probably come out")
`

Note: See TracTickets for help on using tickets.