You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

519 lines
22 KiB

4 years ago
  1. =====================
  2. Contributing to SciPy
  3. =====================
  4. This document aims to give an overview of how to contribute to SciPy. It
  5. tries to answer commonly asked questions, and provide some insight into how the
  6. community process works in practice. Readers who are familiar with the SciPy
  7. community and are experienced Python coders may want to jump straight to the
  8. `git workflow`_ documentation.
  9. There are a lot of ways you can contribute:
  10. - Contributing new code
  11. - Fixing bugs and other maintenance work
  12. - Improving the documentation
  13. - Reviewing open pull requests
  14. - Triaging issues
  15. - Working on the `scipy.org`_ website
  16. - Answering questions and participating on the scipy-dev and scipy-user
  17. `mailing lists`_.
  18. Contributing new code
  19. =====================
  20. If you have been working with the scientific Python toolstack for a while, you
  21. probably have some code lying around of which you think "this could be useful
  22. for others too". Perhaps it's a good idea then to contribute it to SciPy or
  23. another open source project. The first question to ask is then, where does
  24. this code belong? That question is hard to answer here, so we start with a
  25. more specific one: *what code is suitable for putting into SciPy?*
  26. Almost all of the new code added to scipy has in common that it's potentially
  27. useful in multiple scientific domains and it fits in the scope of existing
  28. scipy submodules. In principle new submodules can be added too, but this is
  29. far less common. For code that is specific to a single application, there may
  30. be an existing project that can use the code. Some scikits (`scikit-learn`_,
  31. `scikit-image`_, `statsmodels`_, etc.) are good examples here; they have a
  32. narrower focus and because of that more domain-specific code than SciPy.
  33. Now if you have code that you would like to see included in SciPy, how do you
  34. go about it? After checking that your code can be distributed in SciPy under a
  35. compatible license (see FAQ for details), the first step is to discuss on the
  36. scipy-dev mailing list. All new features, as well as changes to existing code,
  37. are discussed and decided on there. You can, and probably should, already
  38. start this discussion before your code is finished.
  39. Assuming the outcome of the discussion on the mailing list is positive and you
  40. have a function or piece of code that does what you need it to do, what next?
  41. Before code is added to SciPy, it at least has to have good documentation, unit
  42. tests and correct code style.
  43. 1. Unit tests
  44. In principle you should aim to create unit tests that exercise all the code
  45. that you are adding. This gives some degree of confidence that your code
  46. runs correctly, also on Python versions and hardware or OSes that you don't
  47. have available yourself. An extensive description of how to write unit
  48. tests is given in the NumPy `testing guidelines`_.
  49. 2. Documentation
  50. Clear and complete documentation is essential in order for users to be able
  51. to find and understand the code. Documentation for individual functions
  52. and classes -- which includes at least a basic description, type and
  53. meaning of all parameters and returns values, and usage examples in
  54. `doctest`_ format -- is put in docstrings. Those docstrings can be read
  55. within the interpreter, and are compiled into a reference guide in html and
  56. pdf format. Higher-level documentation for key (areas of) functionality is
  57. provided in tutorial format and/or in module docstrings. A guide on how to
  58. write documentation is given in `how to document`_.
  59. 3. Code style
  60. Uniformity of style in which code is written is important to others trying
  61. to understand the code. SciPy follows the standard Python guidelines for
  62. code style, `PEP8`_. In order to check that your code conforms to PEP8,
  63. you can use the `pep8 package`_ style checker. Most IDEs and text editors
  64. have settings that can help you follow PEP8, for example by translating
  65. tabs by four spaces. Using `pyflakes`_ to check your code is also a good
  66. idea.
  67. At the end of this document a checklist is given that may help to check if your
  68. code fulfills all requirements for inclusion in SciPy.
  69. Another question you may have is: *where exactly do I put my code*? To answer
  70. this, it is useful to understand how the SciPy public API (application
  71. programming interface) is defined. For most modules the API is two levels
  72. deep, which means your new function should appear as
  73. ``scipy.submodule.my_new_func``. ``my_new_func`` can be put in an existing or
  74. new file under ``/scipy/<submodule>/``, its name is added to the ``__all__``
  75. list in that file (which lists all public functions in the file), and those
  76. public functions are then imported in ``/scipy/<submodule>/__init__.py``. Any
  77. private functions/classes should have a leading underscore (``_``) in their
  78. name. A more detailed description of what the public API of SciPy is, is given
  79. in `SciPy API`_.
  80. Once you think your code is ready for inclusion in SciPy, you can send a pull
  81. request (PR) on Github. We won't go into the details of how to work with git
  82. here, this is described well in the `git workflow`_ section of the NumPy
  83. documentation and on the `Github help pages`_. When you send the PR for a new
  84. feature, be sure to also mention this on the scipy-dev mailing list. This can
  85. prompt interested people to help review your PR. Assuming that you already got
  86. positive feedback before on the general idea of your code/feature, the purpose
  87. of the code review is to ensure that the code is correct, efficient and meets
  88. the requirements outlined above. In many cases the code review happens
  89. relatively quickly, but it's possible that it stalls. If you have addressed
  90. all feedback already given, it's perfectly fine to ask on the mailing list
  91. again for review (after a reasonable amount of time, say a couple of weeks, has
  92. passed). Once the review is completed, the PR is merged into the "master"
  93. branch of SciPy.
  94. The above describes the requirements and process for adding code to SciPy. It
  95. doesn't yet answer the question though how decisions are made exactly. The
  96. basic answer is: decisions are made by consensus, by everyone who chooses to
  97. participate in the discussion on the mailing list. This includes developers,
  98. other users and yourself. Aiming for consensus in the discussion is important
  99. -- SciPy is a project by and for the scientific Python community. In those
  100. rare cases that agreement cannot be reached, the maintainers of the module
  101. in question can decide the issue.
  102. Contributing by helping maintain existing code
  103. ==============================================
  104. The previous section talked specifically about adding new functionality to
  105. SciPy. A large part of that discussion also applies to maintenance of existing
  106. code. Maintenance means fixing bugs, improving code quality or style,
  107. documenting existing functionality better, adding missing unit tests, keeping
  108. build scripts up-to-date, etc. The SciPy `issue list`_ contains all
  109. reported bugs, build/documentation issues, etc. Fixing issues
  110. helps improve the overall quality of SciPy, and is also a good way
  111. of getting familiar with the project. You may also want to fix a bug because
  112. you ran into it and need the function in question to work correctly.
  113. The discussion on code style and unit testing above applies equally to bug
  114. fixes. It is usually best to start by writing a unit test that shows the
  115. problem, i.e. it should pass but doesn't. Once you have that, you can fix the
  116. code so that the test does pass. That should be enough to send a PR for this
  117. issue. Unlike when adding new code, discussing this on the mailing list may
  118. not be necessary - if the old behavior of the code is clearly incorrect, no one
  119. will object to having it fixed. It may be necessary to add some warning or
  120. deprecation message for the changed behavior. This should be part of the
  121. review process.
  122. Reviewing pull requests
  123. =======================
  124. Reviewing open pull requests (PRs) is very welcome, and a valuable way to help
  125. increase the speed at which the project moves forward. If you have specific
  126. knowledge/experience in a particular area (say "optimization algorithms" or
  127. "special functions") then reviewing PRs in that area is especially valuable -
  128. sometimes PRs with technical code have to wait for a long time to get merged
  129. due to a shortage of appropriate reviewers.
  130. We encourage everyone to get involved in the review process; it's also a
  131. great way to get familiar with the code base. Reviewers should ask
  132. themselves some or all of the following questions:
  133. - Was this change adequately discussed (relevant for new features and changes
  134. in existing behavior)?
  135. - Is the feature scientifically sound? Algorithms may be known to work based on
  136. literature; otherwise, closer look at correctness is valuable.
  137. - Is the intended behavior clear under all conditions (e.g. unexpected inputs
  138. like empty arrays or nan/inf values)?
  139. - Does the code meet the quality, test and documentation expectation outline
  140. under `Contributing new code`_?
  141. If we do not know you yet, consider introducing yourself.
  142. Other ways to contribute
  143. ========================
  144. There are many ways to contribute other than contributing code.
  145. Triaging issues (investigating bug reports for validity and possible actions to
  146. take) is also a useful activity. SciPy has many hundreds of open issues;
  147. closing invalid ones and correctly labeling valid ones (ideally with some first
  148. thoughts in a comment) allows prioritizing maintenance work and finding related
  149. issues easily when working on an existing function or submodule.
  150. Participating in discussions on the scipy-user and scipy-dev `mailing lists`_ is
  151. a contribution in itself. Everyone who writes to those lists with a problem or
  152. an idea would like to get responses, and writing such responses makes the
  153. project and community function better and appear more welcoming.
  154. The `scipy.org`_ website contains a lot of information on both SciPy the
  155. project and SciPy the community, and it can always use a new pair of hands.
  156. The sources for the website live in their own separate repo:
  157. https://github.com/scipy/scipy.org
  158. Recommended development setup
  159. =============================
  160. Since Scipy contains parts written in C, C++, and Fortran that need to be
  161. compiled before use, make sure you have the necessary compilers and Python
  162. development headers installed. Having compiled code also means that importing
  163. Scipy from the development sources needs some additional steps, which are
  164. explained below.
  165. First fork a copy of the main Scipy repository in Github onto your own
  166. account and then create your local repository via::
  167. $ git clone git@github.com:YOURUSERNAME/scipy.git scipy
  168. $ cd scipy
  169. $ git remote add upstream git://github.com/scipy/scipy.git
  170. To build the development version of Scipy and run tests, spawn
  171. interactive shells with the Python import paths properly set up etc.,
  172. do one of::
  173. $ python runtests.py -v
  174. $ python runtests.py -v -s optimize
  175. $ python runtests.py -v -t scipy.special.tests.test_basic::test_xlogy
  176. $ python runtests.py --ipython
  177. $ python runtests.py --python somescript.py
  178. $ python runtests.py --bench
  179. This builds Scipy first, so the first time it may take some time. If
  180. you specify ``-n``, the tests are run against the version of Scipy (if
  181. any) found on current PYTHONPATH. *Note: if you run into a build issue,
  182. more detailed build documentation can be found in :doc:`building/index` and at
  183. https://github.com/scipy/scipy/tree/master/doc/source/building*
  184. Using ``runtests.py`` is the recommended approach to running tests.
  185. There are also a number of alternatives to it, for example in-place
  186. build or installing to a virtualenv. See the FAQ below for details.
  187. Some of the tests in Scipy are very slow and need to be separately
  188. enabled. See the FAQ below for details.
  189. SciPy structure
  190. ===============
  191. All SciPy modules should follow the following conventions. In the
  192. following, a *SciPy module* is defined as a Python package, say
  193. ``yyy``, that is located in the scipy/ directory.
  194. * Ideally, each SciPy module should be as self-contained as possible.
  195. That is, it should have minimal dependencies on other packages or
  196. modules. Even dependencies on other SciPy modules should be kept to
  197. a minimum. A dependency on NumPy is of course assumed.
  198. * Directory ``yyy/`` contains:
  199. - A file ``setup.py`` that defines
  200. ``configuration(parent_package='',top_path=None)`` function
  201. for `numpy.distutils`.
  202. - A directory ``tests/`` that contains files ``test_<name>.py``
  203. corresponding to modules ``yyy/<name>{.py,.so,/}``.
  204. * Private modules should be prefixed with an underscore ``_``,
  205. for instance ``yyy/_somemodule.py``.
  206. * User-visible functions should have good documentation following
  207. the Numpy documentation style, see `how to document`_
  208. * The ``__init__.py`` of the module should contain the main reference
  209. documentation in its docstring. This is connected to the Sphinx
  210. documentation under ``doc/`` via Sphinx's automodule directive.
  211. The reference documentation should first give a categorized list of
  212. the contents of the module using ``autosummary::`` directives, and
  213. after that explain points essential for understanding the use of the
  214. module.
  215. Tutorial-style documentation with extensive examples should be
  216. separate, and put under ``doc/source/tutorial/``
  217. See the existing Scipy submodules for guidance.
  218. For further details on Numpy distutils, see:
  219. https://github.com/numpy/numpy/blob/master/doc/DISTUTILS.rst.txt
  220. Useful links, FAQ, checklist
  221. ============================
  222. Checklist before submitting a PR
  223. --------------------------------
  224. - Are there unit tests with good code coverage?
  225. - Do all public function have docstrings including examples?
  226. - Is the code style correct (PEP8, pyflakes)
  227. - Is the commit message `formatted correctly`_?
  228. - Is the new functionality tagged with ``.. versionadded:: X.Y.Z`` (with
  229. X.Y.Z the version number of the next release - can be found in setup.py)?
  230. - Is the new functionality mentioned in the release notes of the next
  231. release?
  232. - Is the new functionality added to the reference guide?
  233. - In case of larger additions, is there a tutorial or more extensive
  234. module-level description?
  235. - In case compiled code is added, is it integrated correctly via setup.py
  236. (and preferably also Bento configuration files - bento.info and bscript)?
  237. - If you are a first-time contributor, did you add yourself to THANKS.txt?
  238. Please note that this is perfectly normal and desirable - the aim is to
  239. give every single contributor credit, and if you don't add yourself it's
  240. simply extra work for the reviewer (or worse, the reviewer may forget).
  241. - Did you check that the code can be distributed under a BSD license?
  242. Useful SciPy documents
  243. ----------------------
  244. - The `how to document`_ guidelines
  245. - NumPy/SciPy `testing guidelines`_
  246. - `SciPy API`_
  247. - The `SciPy Roadmap`_
  248. - NumPy/SciPy `git workflow`_
  249. - How to submit a good `bug report`_
  250. FAQ
  251. ---
  252. *I based my code on existing Matlab/R/... code I found online, is this OK?*
  253. It depends. SciPy is distributed under a BSD license, so if the code that you
  254. based your code on is also BSD licensed or has a BSD-compatible license (e.g.
  255. MIT, PSF) then it's OK. Code which is GPL or Apache licensed, has no
  256. clear license, requires citation or is free for academic use only can't be
  257. included in SciPy. Therefore if you copied existing code with such a license
  258. or made a direct translation to Python of it, your code can't be included.
  259. If you're unsure, please ask on the scipy-dev mailing list.
  260. *Why is SciPy under the BSD license and not, say, the GPL?*
  261. Like Python, SciPy uses a "permissive" open source license, which allows
  262. proprietary re-use. While this allows companies to use and modify the software
  263. without giving anything back, it is felt that the larger user base results in
  264. more contributions overall, and companies often publish their modifications
  265. anyway, without being required to. See John Hunter's `BSD pitch`_.
  266. *How do I set up a development version of SciPy in parallel to a released
  267. version that I use to do my job/research?*
  268. One simple way to achieve this is to install the released version in
  269. site-packages, by using a binary installer or pip for example, and set
  270. up the development version in a virtualenv. First install
  271. `virtualenv`_ (optionally use `virtualenvwrapper`_), then create your
  272. virtualenv (named scipy-dev here) with::
  273. $ virtualenv scipy-dev
  274. Now, whenever you want to switch to the virtual environment, you can use the
  275. command ``source scipy-dev/bin/activate``, and ``deactivate`` to exit from the
  276. virtual environment and back to your previous shell. With scipy-dev
  277. activated, install first Scipy's dependencies::
  278. $ pip install Numpy pytest Cython
  279. After that, you can install a development version of Scipy, for example via::
  280. $ python setup.py install
  281. The installation goes to the virtual environment.
  282. *How do I set up an in-place build for development*
  283. For development, you can set up an in-place build so that changes made to
  284. ``.py`` files have effect without rebuild. First, run::
  285. $ python setup.py build_ext -i
  286. Then you need to point your PYTHONPATH environment variable to this directory.
  287. Some IDEs (Spyder for example) have utilities to manage PYTHONPATH. On Linux
  288. and OSX, you can run the command::
  289. $ export PYTHONPATH=$PWD
  290. and on Windows
  291. $ set PYTHONPATH=/path/to/scipy
  292. Now editing a Python source file in SciPy allows you to immediately
  293. test and use your changes (in ``.py`` files), by simply restarting the
  294. interpreter.
  295. *Are there any video examples for installing from source, setting up a
  296. development environment, etc...?*
  297. Currently, there are two video demonstrations for Anaconda Python on macOS:
  298. `Anaconda SciPy Dev Part I (macOS)`_ is a four-minute
  299. overview of installing Anaconda, building SciPy from source, and testing
  300. changes made to SciPy from the Spyder IDE.
  301. `Anaconda SciPy Dev Part II (macOS)`_ shows how to use
  302. a virtual environment to easily switch between the "pre-built version" of SciPy
  303. installed with Anaconda and your "source-built version" of SciPy created
  304. according to Part I.
  305. *Are there any video examples of the basic development workflow?*
  306. `SciPy Development Workflow`_ is a five-minute example of fixing a bug and
  307. submitting a pull request. While it's intended as a followup to
  308. `Anaconda SciPy Dev Part I (macOS)`_ and `Anaconda SciPy Dev Part II (macOS)`_,
  309. the process is similar for other development setups.
  310. *Can I use a programming language other than Python to speed up my code?*
  311. Yes. The languages used in SciPy are Python, Cython, C, C++ and Fortran. All
  312. of these have their pros and cons. If Python really doesn't offer enough
  313. performance, one of those languages can be used. Important concerns when
  314. using compiled languages are maintainability and portability. For
  315. maintainability, Cython is clearly preferred over C/C++/Fortran. Cython and C
  316. are more portable than C++/Fortran. A lot of the existing C and Fortran code
  317. in SciPy is older, battle-tested code that was only wrapped in (but not
  318. specifically written for) Python/SciPy. Therefore the basic advice is: use
  319. Cython. If there's specific reasons why C/C++/Fortran should be preferred,
  320. please discuss those reasons first.
  321. *How do I debug code written in C/C++/Fortran inside Scipy?*
  322. The easiest way to do this is to first write a Python script that
  323. invokes the C code whose execution you want to debug. For instance
  324. ``mytest.py``::
  325. from scipy.special import hyp2f1
  326. print(hyp2f1(5.0, 1.0, -1.8, 0.95))
  327. Now, you can run::
  328. gdb --args python runtests.py -g --python mytest.py
  329. If you didn't compile with debug symbols enabled before, remove the
  330. ``build`` directory first. While in the debugger::
  331. (gdb) break cephes_hyp2f1
  332. (gdb) run
  333. The execution will now stop at the corresponding C function and you
  334. can step through it as usual. Instead of plain ``gdb`` you can of
  335. course use your favourite alternative debugger; run it on the
  336. ``python`` binary with arguments ``runtests.py -g --python mytest.py``.
  337. *How do I enable additional tests in Scipy?*
  338. Some of the tests in Scipy's test suite are very slow and not enabled
  339. by default. You can run the full suite via::
  340. $ python runtests.py -g -m full
  341. This invokes the test suite ``import scipy; scipy.test("full")``,
  342. enabling also slow tests.
  343. There is an additional level of very slow tests (several minutes),
  344. which are disabled also in this case. They can be enabled by setting
  345. the environment variable ``SCIPY_XSLOW=1`` before running the test
  346. suite.
  347. .. _scikit-learn: http://scikit-learn.org
  348. .. _scikit-image: http://scikit-image.org/
  349. .. _statsmodels: http://statsmodels.sourceforge.net/
  350. .. _testing guidelines: https://github.com/numpy/numpy/blob/master/doc/TESTS.rst.txt
  351. .. _formatted correctly: http://docs.scipy.org/doc/numpy/dev/gitwash/development_workflow.html#writing-the-commit-message
  352. .. _how to document: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
  353. .. _bug report: http://scipy.org/bug-report.html
  354. .. _PEP8: http://www.python.org/dev/peps/pep-0008/
  355. .. _pep8 package: http://pypi.python.org/pypi/pep8
  356. .. _pyflakes: http://pypi.python.org/pypi/pyflakes
  357. .. _SciPy API: https://docs.scipy.org/doc/scipy/reference/api.html
  358. .. _SciPy Roadmap: https://scipy.github.io/devdocs/roadmap.html
  359. .. _git workflow: http://docs.scipy.org/doc/numpy/dev/gitwash/index.html
  360. .. _Github help pages: https://help.github.com/articles/set-up-git/
  361. .. _issue list: https://github.com/scipy/scipy/issues
  362. .. _Github: https://github.com/scipy/scipy
  363. .. _scipy.org: https://scipy.org/
  364. .. _scipy.github.com: http://scipy.github.com/
  365. .. _scipy.org-new: https://github.com/scipy/scipy.org-new
  366. .. _documentation wiki: https://docs.scipy.org/scipy/Front%20Page/
  367. .. _SciPy Central: http://scipy-central.org/
  368. .. _doctest: http://www.doughellmann.com/PyMOTW/doctest/
  369. .. _virtualenv: http://www.virtualenv.org/
  370. .. _virtualenvwrapper: http://www.doughellmann.com/projects/virtualenvwrapper/
  371. .. _bsd pitch: http://nipy.sourceforge.net/nipy/stable/faq/johns_bsd_pitch.html
  372. .. _Pytest: https://pytest.org/
  373. .. _mailing lists: https://www.scipy.org/scipylib/mailing-lists.html
  374. .. _Anaconda SciPy Dev Part I (macOS): https://youtu.be/1rPOSNd0ULI
  375. .. _Anaconda SciPy Dev Part II (macOS): https://youtu.be/Faz29u5xIZc
  376. .. _SciPy Development Workflow: https://youtu.be/HgU01gJbzMY