How to contribute to the NumPy documentation#

This guide will help you decide what to contribute and how to submit it to theofficial NumPy documentation.

Documentation team meetings#

The NumPy community has set a firm goal of improving its documentation. Wehold regular documentation meetings on Zoom (dates are announced on thenumpy-discussion mailing list), and everyoneis welcome. Reach out if you have questions or needsomeone to guide you through your first steps – we’re happy to help.Minutes are takenon hackmd.ioand stored in theNumPy Archive repository.

What’s needed#

TheNumPy Documentation has the details covered.API reference documentation is generated directly fromdocstrings in the code when thedocumentation isbuilt. Although we have mostlycomplete reference documentation for each function and class exposed to users,there is a lack of usage examples for some of them.

What we lack are docs with broader scope – tutorials, how-tos, andexplanations. Reporting defects is another way to contribute. We discuss both.

Contributing fixes#

We’re eager to hear about and fix doc defects. But to attack the biggestproblems we end up having to defer or overlook some bug reports. Here are thebest defects to go after.

Top priority goes totechnical inaccuracies – a docstring missing aparameter, a faulty description of a function/parameter/method, and so on.Other “structural” defects like broken links also get priority. All these fixesare easy to confirm and put in place. You can submitapull request (PR)with the fix, if you know how to do that; otherwise pleaseopen an issue.

Typos and misspellings fall on a lower rung; we welcome hearing about thembut may not be able to fix them promptly. These too can be handled as pullrequests or issues.

Obviouswording mistakes (like leaving out a “not”) fall into the typocategory, but other rewordings – even for grammar – require a judgment call,which raises the bar. Test the waters by first presenting the fix as an issue.

Some functions/objects like numpy.ndarray.transpose, numpy.array etc. defined inC-extension modules have their docstrings defined separately in_add_newdocs.py

Contributing new pages#

Your frustrations using our documents are our best guide to what needs fixing.

If you write a missing doc you join the front line of open source, but it’sa meaningful contribution just to let us know what’s missing. If you want tocompose a doc, run your thoughts by themailing list for furtherideas and feedback. If you want to alert us to a gap,open an issue. Seethis issue for an example.

If you’re looking for subjects, our formal roadmap for documentation is aNumPy Enhancement Proposal (NEP),NEP 44 — Restructuring the NumPy documentation.It identifies areas where our docs need help and lists severaladditions we’d like to see, includingJupyter notebooks.

Documentation framework#

There are formulas for writing useful documents, and four formulascover nearly everything. There are four formulas because there are fourcategories of document –tutorial,how-toguide,explanation,andreference. The insight that docs divide up this way belongs toDaniele Procida and hisDiátaxis Framework. When youbegin a document or propose one, have in mind which of these types it will be.

NumPy tutorials#

In addition to the documentation that is part of the NumPy source tree, you cansubmit content in Jupyter Notebook format to theNumPy Tutorials page. Thisset of tutorials and educational materials is meant to provide high-qualityresources by the NumPy project, both for self-learning and for teaching classeswith. These resources are developed in a separate GitHub repository,numpy-tutorials, where you cancheck out existing notebooks, open issues to suggest new topics or submit yourown tutorials as pull requests.

More on contributing#

Don’t worry if English is not your first language, or if you can only come upwith a rough draft. Open source is a community effort. Do your best – we’llhelp fix issues.

Images and real-life data make text more engaging and powerful, but be surewhat you use is appropriately licensed and available. Here again, even a roughidea for artwork can be polished by others.

For now, the only data formats accepted by NumPy are those also used by otherPython scientific libraries like pandas, SciPy, or Matplotlib. We’redeveloping a package to accept more formats; contact us for details.

NumPy documentation is kept in the source code tree. To get your documentinto the docbase you must download the tree,build it, and submit a pull request. If GitHub and pull requestsare new to you, check ourContributor Guide.

Our markup language is reStructuredText (rST), which is more elaborate thanMarkdown. Sphinx, the tool many Python projects use to build and link projectdocumentation, converts the rST into HTML and other formats. For more onrST, see theQuick reStructuredText Guide or thereStructuredText Primer

Contributing indirectly#

If you run across outside material that would be a useful addition to theNumPy docs, let us know byopening an issue.

You don’t have to contribute here to contribute to NumPy. You’ve contributedif you write a tutorial on your blog, create a YouTube video, or answer questionson Stack Overflow and other sites.

Documentation style#

User documentation#

  • In general, we follow theGoogle developer documentation style guidefor the User Guide.

  • NumPy style governs cases where:

    • Google has no guidance, or

    • We prefer not to use the Google style

    Our current rules:

    • We pluralizeindex asindices rather thanindexes,following the precedent ofnumpy.indices.

    • For consistency we also pluralizematrix asmatrices.

  • Grammatical issues inadequately addressed by the NumPy or Google rules aredecided by the section on “Grammar and Usage” in the most recent edition oftheChicago Manual of Style.

  • We welcome beingalerted to caseswe should add to the NumPy style rules.

Docstrings#

When usingSphinx in combination with theNumPy conventions, you should use thenumpydoc extension so that yourdocstrings will be handled correctly. For example, Sphinx will extract theParameters section from your docstring and convert it into a fieldlist. Usingnumpydoc will also avoid the reStructuredText errors producedby plain Sphinx when it encounters NumPy docstring conventions likesection headers (e.g.-------------) that sphinx does not expect tofind in docstrings.

It is available from:

Note that for documentation within NumPy, it is not necessary to doimportnumpyasnp at the beginning of an example.

Please use thenumpydocformatting standard asshown in theirexample.

Documenting C/C++ code#

NumPy usesDoxygen to parse specially-formatted C/C++ comment blocks. This generatesXML files, which are converted byBreathe into RST, which is used by Sphinx.

It takes three steps to complete the documentation process:

1. Writing the comment blocks#

Although there is still no commenting style set to follow, the Javadocis more preferable than the others due to the similarities with the currentexisting non-indexed comment blocks.

This is what Javadoc style looks like:

/***Thisasimplebrief.**Andthedetailsgoeshere.*Multilinesarewelcome.**@paramnumleaveacommentforparameternum.*@paramstrleaveacommentforthesecondparameter.*@returnleaveacommentforthereturnedvalue.*/intdoxy_javadoc_example(intnum,constchar*str);

And here is how it is rendered:

intdoxy_javadoc_example(intnum,constchar*str)#

This a simple brief.

And the details goes here. Multi lines are welcome.

Parameters:
  • num – leave a comment for parameter num.

  • str – leave a comment for the second parameter.

Returns:

leave a comment for the returned value.

For line comment, you can use a triple forward slash. For example:

/***Templatetorepresentlimbonumbers.**Specializationsforintegertypesthatarepartofnowhere.*Itdoesn't support with any real types.**@paramTpTypeoftheinteger.Requiredtobeanintegertype.*@paramNNumberofelements.*/template<typenameTp,std::size_tN>classDoxyLimbo{public:///Defaultconstructor.Initializenothing.DoxyLimbo();///SetDefaultbehaviorforcopythelimbo.DoxyLimbo(constDoxyLimbo<Tp,N>&l);///Returnstherawdataforthelimbo.constTp*data();protected:Tpp_data[N];///<Exampleforinlinecomment.};

And here is how it is rendered:

template<typenameTp,std::size_tN>
classDoxyLimbo#

Template to represent limbo numbers.

Specializations for integer types that are part of nowhere. It doesn’t support with any real types.

Param Tp:

Type of the integer. Required to be an integer type.

Param N:

Number of elements.

Public Functions

DoxyLimbo()#

Default constructor. Initialize nothing.

DoxyLimbo(constDoxyLimbo<Tp,N>&l)#

Set Default behavior for copy the limbo.

constTp*data()#

Returns the raw data for the limbo.

Protected Attributes

Tpp_data[N]#

Example for inline comment.

Common Doxygen Tags:#

Note

For more tags/commands, please take a look athttps://www.doxygen.nl/manual/commands.html

@brief

Starts a paragraph that serves as a brief description. By default the first sentenceof the documentation block is automatically treated as a brief description, sinceoptionJAVADOC_AUTOBRIEFis enabled within doxygen configurations.

@details

Just like@brief starts a brief description,@details starts the detailed description.You can also start a new paragraph (blank line) then the@details command is not needed.

@param

Starts a parameter description for a function parameter with name <parameter-name>,followed by a description of the parameter. The existence of the parameter is checkedand a warning is given if the documentation of this (or any other) parameter is missingor not present in the function declaration or definition.

@return

Starts a return value description for a function.Multiple adjacent@return commands will be joined into a single paragraph.The@return description ends when a blank line or some other sectioning command is encountered.

@code/@endcode

Starts/Ends a block of code. A code block is treated differently from ordinary text.It is interpreted as source code.

@rst/@endrst

Starts/Ends a block of reST markup.

Example#

Take a look at the following example:

/***AcommentblockcontainsreSTmarkup.*@rst*..note::**ThankstoBreathe_,wewereabletobringittoDoxygen_**Somecodeexample::**intexample(intx){*returnx*2;*}*@endrst*/voiddoxy_reST_example(void);

And here is how it is rendered:

voiddoxy_reST_example(void)#

A comment block contains reST markup.

Some code example:

intexample(intx){returnx*2;}

Note

Thanks toBreathe, we were able to bring it toDoxygen

2. Feeding Doxygen#

Not all headers files are collected automatically. You have to add the desiredC/C++ header paths within the sub-config files of Doxygen.

Sub-config files have the unique name.doxyfile, which you can usually find neardirectories that contain documented headers. You need to create a new config file ifthere’s not one located in a path close(2-depth) to the headers you want to add.

Sub-config files can accept any ofDoxygenconfiguration options,but do not override or re-initialize any configuration option,rather only use the concatenation operator “+=”. For example:

# to specify certain headersINPUT+=@CUR_DIR/header1.h \@CUR_DIR/header2.h# to add all headers in certain pathINPUT+=@CUR_DIR/to/headers# to define certain macrosPREDEFINED+=C_MACRO(X)=X# to enable certain branchesPREDEFINED+=NPY_HAVE_FEATURE \NPY_HAVE_FEATURE2

Note

@CUR_DIR is a template constant returns the currentdir path of the sub-config file.

3. Inclusion directives#

Breathe provides a wide range of custom directives to allowconverting the documents generated byDoxygen into reST files.

Note

For more information, please check out “Directives & Config Variables

Common directives:#

doxygenfunction

This directive generates the appropriate output for a single function.The function name is required to be unique in the project.

..doxygenfunction::<functionname>:outline::no-link:

Checkout theexampleto see it in action.

doxygenclass

This directive generates the appropriate output for a single class.It takes the standard project, path, outline and no-link options andadditionally the members, protected-members, private-members, undoc-members,membergroups and members-only options:

..doxygenclass::<classname>:members:[...]:protected-members::private-members::undoc-members::membergroups:...:members-only::outline::no-link:

Checkout thedoxygenclass documentationfor more details and to see it in action.

doxygennamespace

This directive generates the appropriate output for the contents of a namespace.It takes the standard project, path, outline and no-link options and additionally the content-only,members, protected-members, private-members and undoc-members options.To reference a nested namespace, the full namespaced path must be provided,e.g. foo::bar for the bar namespace inside the foo namespace.

..doxygennamespace::<namespace>:content-only::outline::members::protected-members::private-members::undoc-members::no-link:

Checkout thedoxygennamespace documentationfor more details and to see it in action.

doxygengroup

This directive generates the appropriate output for the contents of a doxygen group.A doxygen group can be declared with specific doxygen markup in the source commentsas covered in the doxygengrouping documentation.

It takes the standard project, path, outline and no-link options and additionally thecontent-only, members, protected-members, private-members and undoc-members options.

..doxygengroup::<groupname>:content-only::outline::members::protected-members::private-members::undoc-members::no-link::inner:

Checkout thedoxygengroup documentationfor more details and to see it in action.

Legacy directive#

If a function, module or API is inlegacy mode, meaning that it is kept aroundfor backwards compatibility reasons, but is not recommended to use in new code,you can use the..legacy:: directive.

By default, if used with no arguments, the legacy directive will generate thefollowing output:

Legacy

This submodule is considered legacy and will no longer receive updates. This could also mean it will be removed in future NumPy versions.

We strongly recommend that you also add a custom message, such as a new API toreplace the old one:

.. legacy::   For more details, see :ref:`distutils-status-migration`.

This message will be appended to the default message and will create thefollowing output:

Legacy

This submodule is considered legacy and will no longer receive updates. This could also mean it will be removed in future NumPy versions. For more details, seeStatus of numpy.distutils and migration advice.

Finally, if you want to mention a function, method (or any custom object)instead of asubmodule, you can use an optional argument:

..legacy::function

This will create the following output:

Legacy

This function is considered legacy and will no longer receive updates. This could also mean it will be removed in future NumPy versions.

Documentation reading#

  • The leading organization of technical writers,Write the Docs,holds conferences, hosts learning resources, and runs a Slack channel.

  • “Every engineer is also a writer,” says Google’scollection of technical writing resources,which includes free online courses for developers in planning and writingdocuments.

  • Software Carpentry’s mission isteaching software to researchers. In addition to hosting the curriculum, thewebsite explains how to present ideas effectively.