1.. _contributing: 2 3Contributing to Trio and related projects 4========================================= 5 6So you're interested in contributing to Trio or `one of our associated 7projects <https://github.com/python-trio>`__? That's awesome! Trio is 8an open-source project maintained by an informal group of 9volunteers. Our goal is to make async I/O in Python more fun, easy, 10and reliable, and we can't do it without help from people like you. We 11welcome contributions from anyone willing to work in good faith with 12other contributors and the community (see also our 13:ref:`code-of-conduct`). 14 15There are many ways to contribute, no contribution is too small, and 16all contributions are valued. For example, you could: 17 18- Hang out in our `chatroom <https://gitter.im/python-trio/general>`__ 19 and help people with questions. 20- Sign up for our `forum <https://trio.discourse.group>`__, set up 21 your notifications so you notice interesting conversations, and join 22 in. 23- Answer questions on StackOverflow (`recent questions 24 <https://stackexchange.com/filters/289914/trio-project-tags-on-stackoverflow-filter>`__). 25- Use Trio in a project, and give us feedback on what worked and what 26 didn't. 27- Write a blog post about your experiences with Trio, good or bad. 28- Release open-source programs and libraries that use Trio. 29- Improve documentation. 30- Comment on issues. 31- Add tests. 32- Fix bugs. 33- Add features. 34 35We want contributing to be enjoyable and mutually beneficial; this 36document tries to give you some tips to help that happen, and applies 37to all of the projects under the `python-trio organization on Github 38<https://github.com/python-trio>`__. If you have thoughts on how it 39can be improved then please let us know. 40 41 42Getting started 43--------------- 44 45If you're new to open source in general, you might find it useful to 46check out `opensource.guide's How to Contribute to Open Source 47tutorial <https://opensource.guide/how-to-contribute/>`__, or if 48video's more your thing, `egghead.io has a short free video course 49<https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github>`__. 50 51Trio and associated projects are developed on GitHub, under the 52`python-trio <https://github.com/python-trio>`__ organization. Code 53and documentation changes are made through pull requests (see 54:ref:`preparing-pull-requests` below). 55 56We also have an unusual policy for managing commit rights: anyone 57whose pull request is merged is automatically invited to join the 58GitHub organization, and gets commit rights to all of our 59repositories. See :ref:`joining-the-team` below for more details. 60 61If you're looking for a good place to start, then check out our issues 62labeled `good first issue 63<https://github.com/search?utf8=%E2%9C%93&q=user%3Apython-trio+label%3A%22good+first+issue%22+state%3Aopen&type=Issues&ref=advsearch&l=&l=>`__, 64or feel free to ask `on the forum <https://trio.discourse.group>`__ or 65`in chat <https://gitter.im/python-trio/general>`__. 66 67 68Providing support 69----------------- 70 71When helping others use Trio, please remember that you are 72representing our community, and we want this to be a friendly and 73welcoming place. 74 75Concurrency is *really confusing* when you're first learning. When 76talking to beginners, remember that you were a beginner once too, and 77the whole goal here is to make a top-tier concurrency library that's 78accessible to everyone and a joy to use. If people are showing up with 79beginner questions, *that means we're succeeding*. How we respond to 80questions is part of that developer experience, just as much as our 81API, documentation, or testing tools. And as a bonus, helping 82beginners is often the best way to discover ideas for improvements. If 83you start getting burned out and cranky, we've all been there, and 84it's OK to take a break until you feel better. But it's not OK to take 85that out on random users. 86 87Please remember that the authors and users of competing projects are 88smart, thoughtful people doing their best to balance complicated and 89conflicting requirements, just like us. Of course it's totally fine to 90make specific technical critiques ("In project X, this is handled by 91doing Y, Trio does Z instead, which I prefer because...") or talk 92about your personal experience ("I tried using X but I got super 93frustrated and confused"), but refrain from generic statements like "X 94sucks" or "I can't believe anyone uses X". 95 96Please try not to make assumptions about people's gender, and in 97particular remember that we're not all dudes. If you don't have a 98specific reason to assume otherwise, then `singular they 99<https://en.wikipedia.org/wiki/Third-person_pronoun#Singular_they>`__ 100makes a fine pronoun, and there are plenty of gender-neutral 101collective terms: "Hey folks", "Hi all", ... 102 103We also like the Recurse Center's `social rules 104<https://www.recurse.com/manual#sub-sec-social-rules>`__: 105 106* no feigning surprise (also available in a `sweet comic version 107 <https://jvns.ca/blog/2017/04/27/no-feigning-surprise/>`__) 108* no well-actually's 109* no subtle -isms (`more details <https://www.recurse.com/blog/38-subtle-isms-at-hacker-school>`__) 110 111 112.. _preparing-pull-requests: 113 114Preparing pull requests 115----------------------- 116 117If you want to submit a documentation or code change to one of the 118Trio projects, then that's done by preparing a Github pull request (or 119"PR" for short). We'll do our best to review your PR quickly. If it's 120been a week or two and you're still waiting for a response, feel free 121to post a comment poking us. (This can just be a comment with the 122single word "ping"; it's not rude at all.) 123 124Here's a quick checklist for putting together a good PR, with details 125in separate sections below: 126 127* :ref:`pull-request-scope`: Does your PR address a single, 128 self-contained issue? 129 130* :ref:`pull-request-tests`: Are your tests passing? Did you add any 131 necessary tests? Code changes pretty much always require test 132 changes, because if it's worth fixing the code then it's worth 133 adding a test to make sure it stays fixed. 134 135* :ref:`pull-request-formatting`: If you changed Python code, then did 136 you run ``black setup.py trio``? (Or for other packages, replace 137 ``trio`` with the package name.) 138 139* :ref:`pull-request-release-notes`: If your change affects 140 user-visible functionality, then did you add a release note to the 141 ``newsfragments/`` directory? 142 143* :ref:`pull-request-docs`: Did you make any necessary documentation 144 updates? 145 146* License: by submitting a PR to a Trio project, you're offering your 147 changes under that project's license. For most projects, that's dual 148 MIT/Apache 2, except for cookiecutter-trio, which is CC0. 149 150 151.. _pull-request-scope: 152 153What to put in a PR 154~~~~~~~~~~~~~~~~~~~ 155 156Each PR should, as much as possible, address just one issue and be 157self-contained. If you have ten small, unrelated changes, then go 158ahead and submit ten PRs – it's much easier to review ten small 159changes than one big change with them all mixed together, and this way 160if there's some problem with one of the changes it won't hold up all 161the others. 162 163If you're uncertain about whether a change is a good idea and want 164some feedback before putting time into it, feel free to ask in an 165issue or in the chat room. If you have a partial change that you want 166to get feedback on, feel free to submit it as a PR. (In this case it's 167traditional to start the PR title with ``[WIP]``, for "work in 168progress".) 169 170When you are submitting your PR, you can include ``Closes #123``, 171``Fixes: #123`` or 172`some variation <https://help.github.com/en/articles/closing-issues-using-keywords>`__ 173in either your commit message or the PR description, in order to 174automatically close the referenced issue when the PR is merged. 175This keeps us closer to the desired state where each open issue reflects some 176work that still needs to be done. 177 178 179.. _pull-request-tests: 180 181Tests 182~~~~~ 183 184We use `pytest <https://pytest.org/>`__ for testing. To run the tests 185locally, you should run: 186 187.. code-block:: shell 188 189 cd path/to/trio/checkout/ 190 pip install -r test-requirements.txt # possibly using a virtualenv 191 pytest trio 192 193This doesn't try to be completely exhaustive – it only checks that 194things work on your machine, and it may skip some slow tests. But it's 195a good way to quickly check that things seem to be working, and we'll 196automatically run the full test suite when your PR is submitted, so 197you'll have a chance to see and fix any remaining issues then. 198 199Every change should have 100% coverage for both code and tests. But, 200you can use ``# pragma: no cover`` to mark lines where 201lack-of-coverage isn't something that we'd want to fix (as opposed to 202it being merely hard to fix). For example:: 203 204 else: # pragma: no cover 205 raise AssertionError("this can't happen!") 206 207We use Codecov to track coverage, because it makes it easy to combine 208coverage from running in different configurations. Running coverage 209locally can be useful 210(``pytest --cov=PACKAGENAME --cov-report=html``), but don't be 211surprised if you get lower coverage than when looking at Codecov 212reports, because there are some lines that are only executed on 213Windows, or macOS, or PyPy, or CPython, or... you get the idea. After 214you create a PR, Codecov will automatically report back with the 215coverage, so you can check how you're really doing. (But note that the 216results can be inaccurate until all the tests are passing. If the 217tests failed, then fix that before worrying about coverage.) 218 219Some rules for writing good tests: 220 221* `Tests MUST pass deterministically 222 <https://github.com/python-trio/trio/issues/200>`__. Flakey tests 223 make for miserable developers. One common source of indeterminism is 224 scheduler ordering; if you're having trouble with this, then 225 :mod:`trio.testing` provides powerful tools to help control 226 ordering, like :func:`trio.testing.wait_all_tasks_blocked`, 227 :class:`trio.testing.Sequencer`, and :class:`trio.testing.MockClock` 228 (usually used as a fixture: ``async def 229 test_whatever(autojump_clock): ...``). And if you need more tools 230 than this then we should add them. 231 232* (Trio package only) Slow tests – anything that takes more than about 233 0.25 seconds – should be marked with ``@slow``. This makes it so they 234 only run if you do ``pytest trio --run-slow``. Our CI scripts do 235 run slow tests, so you can be sure that the code will still be 236 thoroughly tested, and this way you don't have to sit around waiting 237 for a few irrelevant multi-second tests to run while you're iterating 238 on a change locally. 239 240 You can check for slow tests by passing ``--durations=10`` to 241 pytest. Most tests should take 0.01 seconds or less. 242 243* Speaking of waiting around for tests: Tests should never sleep 244 unless *absolutely* necessary. However, calling :func:`trio.sleep` 245 when using ``autojump_clock`` is fine, because that's not really 246 sleeping, and doesn't waste developers time waiting for the test to 247 run. 248 249* We like tests to exercise real functionality. For example, if you're 250 adding subprocess spawning functionality, then your tests should 251 spawn at least one process! Sometimes this is tricky – for example, 252 Trio's :class:`KeyboardInterrupt` tests have to jump through quite 253 some hoops to generate real SIGINT signals at the right times to 254 exercise different paths. But it's almost always worth it. 255 256* For cases where real testing isn't relevant or sufficient, then we 257 strongly prefer fakes or stubs over mocks. Useful articles: 258 259 * `Test Doubles - Fakes, Mocks and Stubs 260 <https://dev.to/milipski/test-doubles---fakes-mocks-and-stubs>`__ 261 262 * `Mocks aren't stubs 263 <https://martinfowler.com/articles/mocksArentStubs.html>`__ 264 265 * `Write test doubles you can trust using verified fakes 266 <https://codewithoutrules.com/2016/07/31/verified-fakes/>`__ 267 268 Most major features have both real tests and tests using fakes or 269 stubs. For example, :class:`~trio.SSLStream` has some tests that 270 use Trio to make a real socket connection to real SSL server 271 implemented using blocking I/O, because it sure would be 272 embarrassing if that didn't work. And then there are also a bunch of 273 tests that use a fake in-memory transport stream where we have 274 complete control over timing and can make sure all the subtle edge 275 cases work correctly. 276 277Writing reliable tests for obscure corner cases is often harder than 278implementing a feature in the first place, but stick with it: it's 279worth it! And don't be afraid to ask for help. Sometimes a fresh pair 280of eyes can be helpful when trying to come up with devious tricks. 281 282 283.. _pull-request-formatting: 284 285Code formatting 286~~~~~~~~~~~~~~~ 287 288Instead of wasting time arguing about code formatting, we use `black 289<https://github.com/psf/black>`__ to automatically format all our 290code to a standard style. While you're editing code you can be as 291sloppy as you like about whitespace; and then before you commit, just 292run:: 293 294 pip install -U black 295 black setup.py trio 296 297to fix it up. (And don't worry if you forget – when you submit a pull 298request then we'll automatically check and remind you.) Hopefully this 299will let you focus on more important style issues like choosing good 300names, writing useful comments, and making sure your docstrings are 301nicely formatted. (black doesn't reformat comments or docstrings.) 302 303Very occasionally, you'll want to override black formatting. To do so, 304you can can add ``# fmt: off`` and ``# fmt: on`` comments. 305 306If you want to see what changes black will make, you can use:: 307 308 black --diff setup.py trio 309 310(``--diff`` displays a diff, versus the default mode which fixes files 311in-place.) 312 313 314.. _pull-request-release-notes: 315 316Release notes 317~~~~~~~~~~~~~ 318 319We use `towncrier <https://github.com/hawkowl/towncrier>`__ to manage 320our `release notes <https://trio.readthedocs.io/en/latest/history.html>`__. 321Basically, every pull request that has a user 322visible effect should add a short file to the ``newsfragments/`` 323directory describing the change, with a name like ``<ISSUE 324NUMBER>.<TYPE>.rst``. See `newsfragments/README.rst 325<https://github.com/python-trio/trio/blob/master/newsfragments/README.rst>`__ 326for details. This way we can keep a good list of changes as we go, 327which makes the release manager happy, which means we get more 328frequent releases, which means your change gets into users' hands 329faster. 330 331 332.. _pull-request-commit-messages: 333 334Commit messages 335~~~~~~~~~~~~~~~ 336 337We don't enforce any particular format on commit messages. In your 338commit messages, try to give the context to explain *why* a change was 339made. 340 341The target audience for release notes is users, who want to find out 342about changes that might affect how they use the library, or who are 343trying to figure out why something changed after they upgraded. 344 345The target audience for commit messages is some hapless developer 346(think: you in six months... or five years) who is trying to figure 347out why some code looks the way it does. Including links to issues and 348any other discussion that led up to the commit is *strongly* 349recommended. 350 351 352.. _pull-request-docs: 353 354Documentation 355~~~~~~~~~~~~~ 356 357We take pride in providing friendly and comprehensive documentation. 358Documentation is stored in ``docs/source/*.rst`` and is rendered using 359`Sphinx <http://www.sphinx-doc.org/>`__ with the `sphinxcontrib-trio 360<https://sphinxcontrib-trio.readthedocs.io/en/latest/>`__ extension. 361Documentation is hosted at `Read the Docs 362<https://readthedocs.org/>`__, who take care of automatically 363rebuilding it after every commit. 364 365For docstrings, we use `the Google docstring format 366<https://www.sphinx-doc.org/en/3.x/usage/extensions/example_google.html#example-google-style-python-docstrings>`__. 367If you add a new function or class, there's no mechanism for 368automatically adding that to the docs: you'll have to at least add a 369line like ``.. autofunction:: <your function>`` in the appropriate 370place. In many cases it's also nice to add some longer-form narrative 371documentation around that. 372 373We enable Sphinx's "nitpick mode", which turns dangling references 374into an error – this helps catch typos. (This will be automatically 375checked when your PR is submitted.) If you intentionally want to allow 376a dangling reference, you can add it to the `nitpick_ignore 377<http://www.sphinx-doc.org/en/stable/config.html#confval-nitpick_ignore>`__ 378whitelist in ``docs/source/conf.py``. 379 380To build the docs locally, use our handy ``docs-requirements.txt`` 381file to install all of the required packages (possibly using a 382virtualenv). After that, build the docs using ``make html`` in the 383docs directory. The whole process might look something like this:: 384 385 cd path/to/project/checkout/ 386 pip install -r docs-requirements.txt 387 cd docs 388 make html 389 390You can then browse the docs using Python's builtin http server: 391``python -m http.server 8000 --bind 127.0.0.1 --directory build/html`` 392and then opening ``http://127.0.0.1:8000/`` in your web browser. 393 394.. _joining-the-team: 395 396Joining the team 397---------------- 398 399After your first PR is merged, you should receive a Github invitation 400to join the ``python-trio`` organization. If you don't, that's not 401your fault, it's because we made a mistake on our end. Give us a 402nudge on chat or `send @njsmith an email <mailto:njs@pobox.com>`__ and 403we'll fix it. 404 405It's totally up to you whether you accept or not, and if you do 406accept, you're welcome to participate as much or as little as you 407want. We're offering the invitation because we'd love for you to join 408us in making Python concurrency more friendly and robust, but there's 409no pressure: life is too short to spend volunteer time on things that 410you don't find fulfilling. 411 412At this point people tend to have questions. 413 414**How can you trust me with this kind of power? What if I mess 415everything up?!?** 416 417Relax, you got this! And we've got your back. Remember, it's just 418software, and everything's in version control: worst case we'll just 419roll things back and brainstorm ways to avoid the issue happening 420again. We think it's more important to welcome people and help them 421grow than to worry about the occasional minor mishap. 422 423**I don't think I really deserve this.** 424 425It's up to you, but we wouldn't be offering if we didn't think 426you did. 427 428**What exactly happens if I accept? Does it mean I'll break everything 429if I click the wrong button?** 430 431Concretely, if you accept the invitation, this does three things: 432 433* It lets you manage incoming issues on all of the ``python-trio`` 434 projects by labelling them, closing them, etc. 435 436* It lets you merge pull requests on all of the ``python-trio`` 437 projects by clicking Github's big green "Merge" button, but only if 438 all their tests have passed. 439 440* It automatically subscribes you to notifications on the 441 ``python-trio`` repositories (but you can unsubscribe again if you 442 want through the Github interface) 443 444Note that it does *not* allow you to push changes directly to Github 445without submitting a PR, and it doesn't let you merge broken PRs – 446this is enforced through Github's "branch protection" feature, and it 447applies to everyone from the newest contributor up to the project 448founder. 449 450**Okay, that's what I CAN do, but what SHOULD I do?** 451 452Short answer: whatever you feel comfortable with. 453 454We do have one rule, which is the same one most F/OSS projects use: 455don't merge your own PRs. We find that having another person look at 456each PR leads to better quality. 457 458Beyond that, it all comes down to what you feel up to. If you don't 459feel like you know enough to review a complex code change, then you 460don't have to – you can just look it over and make some comments, even 461if you don't feel up to making the final merge/no-merge decision. Or 462you can just stick to merging trivial doc fixes and adding tags to 463issues, that's helpful too. If after hanging around for a while you 464start to feel like you have better handle on how things work and want 465to start doing more, that's excellent; if it doesn't happen, that's 466fine too. 467 468If at any point you're unsure about whether doing something would be 469appropriate, feel free to ask. For example, it's *totally OK* if the 470first time you review a PR, you want someone else to check over your 471work before you hit the merge button. 472 473The best essay I know about reviewing pull request's is Sage Sharp's 474`The gentle art of patch review 475<http://sage.thesharps.us/2014/09/01/the-gentle-art-of-patch-review/>`__. 476The `node.js guide 477<https://github.com/nodejs/node/blob/master/doc/guides/contributing/pull-requests.md#reviewing-pull-requests>`__ 478also has some good suggestions, and `so does this blog post 479<http://verraes.net/2013/10/pre-merge-code-reviews/>`__. 480 481 482Managing issues 483--------------- 484 485As issues come in, they need to be responded to, tracked, and – 486hopefully! – eventually closed. 487 488As a general rule, each open issue should represent some kind of task 489that we need to do. Sometimes that task might be "figure out what to 490do here", or even "figure out whether we want to address this issue"; 491sometimes it will be "answer this person's question". But if there's 492no followup to be done, then the issue should be closed. 493 494 495Issue labels 496~~~~~~~~~~~~ 497 498The Trio repository in particular uses a number of labels to try and 499keep track of issues. The current list is somewhat ad hoc, and may or 500may not remain useful over time – if you think of a new label that 501would be useful, a better name for an existing label, or think a label 502has outlived its usefulness, then speak up. 503 504* `good first issue 505 <https://github.com/python-trio/trio/labels/good%20first%20issue>`__: 506 Used to mark issues that are relatively straightforward, and could 507 be good places for a new contributor to start. 508 509* `todo soon 510 <https://github.com/python-trio/trio/labels/todo%20soon>`__: This 511 marks issues where there aren't questions left about whether or how 512 to do it, it's just waiting for someone to dig in and do the work. 513 514* `missing piece 515 <https://github.com/python-trio/trio/labels/missing%20piece>`__: 516 This generally marks significant self-contained chunks of missing 517 functionality. If you're looking for a more ambitious project to 518 work on, this might be useful. 519 520* `potential API breaker 521 <https://github.com/python-trio/trio/labels/potential%20API%20breaker>`__: 522 What it says. This is useful because these are issues that we'll 523 want to make sure to review aggressively as Trio starts to 524 stabilize, and certainly before we reach 1.0. 525 526* `design discussion 527 <https://github.com/python-trio/trio/labels/design%20discussion>`__: 528 This marks issues where there's significant design questions to be 529 discussed; if you like meaty theoretical debates and discussions of 530 API design, then browsing this might be interesting. 531 532* `polish <https://github.com/python-trio/trio/labels/polish>`__: 533 Marks issues that it'd be nice to resolve eventually, because it's 534 the Right Thing To Do, but it's addressing a kind of edge case thing 535 that isn't necessary for a minimum viable product. Sometimes 536 overlaps with "user happiness". 537 538* `user happiness 539 <https://github.com/python-trio/trio/labels/user%20happiness>`__: 540 From the name alone, this could apply to any bug (users certainly 541 are happier when you fix bugs!), but that's not what we mean. This 542 label is used for issues involving places where users stub their 543 toes, or for the kinds of quality-of-life features that leave users 544 surprised and excited – e.g. fancy testing tools that Just Work. 545 546 547Governance 548---------- 549 550`Nathaniel J. Smith <https://github.com/njsmith>`__ is the Trio `BDFL 551<https://en.wikipedia.org/wiki/Benevolent_dictator_for_life>`__. If 552the project grows to the point where we'd benefit from more structure, 553then we'll figure something out. 554 555 556.. Possible references for future additions: 557 558 """ 559 Jumping into an unfamiliar codebase (or any for that matter) for the first time can be scary. Plus, if it’s your first time contributing to open source, it can even be scarier! 560 561 But, we at webpack believe: 562 563 Any (even non-technical) individual should feel welcome to contribute. 564 However you decide to contribute, it should be fun and enjoyable for you! 565 Even after your first commit, you will walk away understanding more about webpack or JavaScript. 566 Consequently, you could become a better developer, writer, 567 designer, etc. along the way, and we are committed to helping 568 foster this growth. 569 """ 570 571 imposter syndrome disclaimer 572 https://github.com/Unidata/MetPy#contributing 573 574 checklist 575 https://github.com/nayafia/contributing-template/blob/master/CONTRIBUTING-template.md 576 577 https://medium.com/the-node-js-collection/healthy-open-source-967fa8be7951 578 579 http://sweng.the-davies.net/Home/rustys-api-design-manifesto 580