Skip to content

Reduce amount of RFC copy in functions, properties, modules and class docstrings #1244

@niccokunzmann

Description

@niccokunzmann

At the start, I thought it was good to copy in information of the RFC into different locations. That addresses the following problems.

  • It is hard for developers to construct valid calendars when it comes to details. Putting the context into the places informs them.
  • Sometimes, attributes influence other attributes or parameters. It is good to know about the side effects.
  • Code affected by several RFC has parts of those copied together, so there is an overview.
  • Having RFC text examples, we can more easily create code examples.

However, this approach does not solve all problems, and creates other problems.

  • It duplicates existing documentation from the RFC.
  • It doesn't document the implementation of the RFC in Python.
  • It doesn't document what the class does, which is the purpose of Python docstrings.

General guidance

  • Follow the Python docstrings style guide, especially Docstring structure.
  • Sometimes you'll need to escape docstrings.
  • See Docstring examples.
  • It's strongly recommended that you build the documentation locally, and not attempt this through only the GitHub web editor. It will save you and the pull request reviewers a lot of time, effort, and frustration. Building locally gives you a live preview of the documentation while you edit it. You can also test usage examples automatically. See Build and check documentation for details.

Docstring sections

  • The docstring's Summary should be a brief sentence. It shouldn't have a section heading.
  • The docstring's Description should do the following. It shouldn't have a section heading.
    • Discuss RFCs that are implemented in the Python class or property.
    • Include links to the specific sections in the original RFC. See General cross-references for an example.
    • Highlight special cases, if any, for example, float can be one or many.
    • Refer to any related classes or properties. Examples:
      • vFloat is a single float, and vGeo is multiple floats.
      • RECURRENCE_ID is usually a DATE-TIME and must use the same value type as the DTSTART property in the same component.
    • Explicitly describe any constraints or requirements for classes or properties.
  • The docstring's Attributes, Parameters, Returns, and Raises section headings might be automatically generated. If you build the documentation locally, you'll see how your edits affect the appearance of how it renders to HTML.
  • The docstring's Example section should have either text examples from the RFC or usage examples of icalendar, such as instantiating an object from the class, and how to add, edit, or remove properties. Usage examples are tested automatically.

Property example

The following code is an example of a property declaration with a docstring for component categories.

categories_property = property(
    _get_categories,
    _set_categories,
    _del_categories,
    """This property defines the categories for a component.

IANA, non-standard, and language property parameters can be specified on
this property.

The property can be specified within "VEVENT", "VTODO", or "VJOURNAL"
calendar components. Since :rfc:`7986#section-5.6`, it can also be defined
on a "VCALENDAR" component.

This property can be used in icalendar through its Python attributes of :attr:`Event.categories <icalendar.cal.event.Event.categories>`, :attr:`Todo.categories <icalendar.cal.todo.Todo.categories>`, :attr:`Journal.categories <icalendar.cal.journal.Journal.categories>`, and :attr:`Calendar.categories <icalendar.cal.calendar.Calendar.categories>`.

This property is used to specify categories or subtypes of the calendar
component. The categories are useful to search for a calendar component of
a particular type and category. Within the "VEVENT", "VTODO", or "VJOURNAL"
calendar components, more than one category can be specified as a
COMMA-separated list of categories.

Note:
    At present, icalendar doesn't take the LANGUAGE parameter into account.

Parameters:
    categories(list[str]): A list of categories as strings.

Example:
    Create an event, add categories to it, print its ical representation,
    append another category, and finally compare the result
    against its expected value.

    ..  code-block:: pycon

        >>> from icalendar import Event
        >>> event = Event()
        >>> event.categories = ["Work", "Meeting"]
        >>> print(event.to_ical())
        BEGIN:VEVENT
        CATEGORIES:Work,Meeting
        END:VEVENT
        >>> event.categories.append("Lecture")
        >>> event.categories == ["Work", "Meeting", "Lecture"]
        True

See also:
    :attr:`Component.concepts <icalendar.cal.component.Component.concepts>`

""",
)

Result

Image

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions