Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

have pytest run code examples in docs + have travis build docs #59

Merged
merged 3 commits into from
Jun 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ python: 3.5
sudo: false

install:
- python3 setup.py install
- travis_retry pip install -e .[test]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the use of travis_retry?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw it in another project's .travis.yml (which seemed like it knew what it was doing), and it seemed like a zero-cost line of defense against e.g. transient network failures and other things that shouldn't cause the build to fail. Any reason not to?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly don't know, hence the question. 😄


script:
- python3 -m pytest
- sphinx-build -nq -b html -b linkcheck -d docs/_build/doctrees docs docs/_build/html
2 changes: 1 addition & 1 deletion curio/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# Task class and task related functions.

__all__ = [ 'sleep', 'current_task', 'spawn', 'gather', 'timeout_after', 'ignore_after', 'wait' ]
__all__ = [ 'Task', 'sleep', 'current_task', 'spawn', 'gather', 'timeout_after', 'ignore_after', 'wait' ]

from .errors import TaskTimeout, TaskError
from .traps import *
Expand Down
44 changes: 22 additions & 22 deletions docs/devel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,16 @@ Defining a Coroutine

A coroutine is a function defined using ``async def`` such as this::

async def greeting(name):
return 'Hello ' + name
>>> async def greeting(name):
... return 'Hello ' + name

Unlike a normal function, a coroutine never executes independently.
It has to be driven by some other code. It's low-level, but you can
drive a coroutine manually if you want::

>>> g = greeting('Dave')
>>> g
<coroutine object greeting at 0x10ded14c0>
<coroutine object greeting at ...>
>>> g.send(None)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Expand All @@ -115,13 +115,16 @@ Coroutines Calling Coroutines
Coroutines can call other coroutines as long as you preface the call
with the ``await`` keyword. For example::

async def main():
names = ['Dave', 'Paula', 'Thomas', 'Lewis']
for name in names:
print(await greeting(name))

from curio import run
run(main())
>>> async def main():
... names = ['Dave', 'Paula', 'Thomas', 'Lewis']
... for name in names:
... print(await greeting(name))
>>> from curio import run
>>> run(main())
Hello Dave
Hello Paula
Hello Thomas
Hello Lewis

For the most part, you can write async functions, methods, and do everything that you
would do with normal Python functions. The use of the ``await`` in calls is important
Expand Down Expand Up @@ -149,31 +152,29 @@ completes the request and reschedules the process.
Now, what does all of this have to do with coroutines? Let's define
a very special kind of coroutine::

from types import coroutine

@coroutine
def sleep(seconds):
yield ('sleep', seconds)
>>> from types import coroutine
>>> @coroutine
... def sleep(seconds):
... yield ('sleep', seconds)

This coroutine is different than the rest--it doesn't use the
``async`` syntax and it makes direct use of the ``yield`` statement
(which is not normally allowed in ``async`` functions). The ``@coroutine``
decorator is there so that it can be called with ``await``.
Now, let's write a coroutine that uses this::

async def main():
print('Yawn. Getting sleepy.')
await sleep(10)
print('Awake at last!')
>>> async def main():
... print('Yawn. Getting sleepy.')
... await sleep(10)
... print('Awake at last!')

Let's manually drive it using the same technique as before::

>>> c = main()
>>> request = c.send(None)
Yawn! Getting sleepy.
Yawn. Getting sleepy.
>>> request
('sleep', 10)
>>>

The output from the first ``print()`` function appears, but the
coroutine is now suspended. The return value of the
Expand All @@ -192,7 +193,6 @@ return result if any). For example::
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>

All of this might seem very low-level, but this is precisely what
Curio is doing. Coroutines execute statements under the
Expand Down
9 changes: 5 additions & 4 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ Contents:
.. toctree::
:maxdepth: 2

* :doc:`tutorial`
* :doc:`reference`
* :doc:`howto`
tutorial
reference
howto
devel
Copy link
Contributor Author

@jab jab Jun 15, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, I moved these under the .. toctree:: here assuming that was the intention. Also added devel because otherwise sphinx generates a warning that it's not part of any toctree. The resulting built docs are the same, except the bulleted list in the "Contents" section of index.html is now generated automatically, including 2nd-level topics as per the :maxdepth: 2 (which I didn't change). Could change that to :maxdepth: 1 to make it condensed, as it was with the manually-generated bulleted list before.


Installation:
-------------
Expand Down Expand Up @@ -91,7 +92,7 @@ of the code::
run(tcp_server('', 25000, echo_client))

This is only a small sample of what's possible. The `tutorial
<https://curio.readthedocs.org/en/latest/tutorial.html>`_ is a good starting point
<https://curio.readthedocs.io/en/latest/tutorial.html>`_ is a good starting point
for more information.

Additional Features
Expand Down
6 changes: 3 additions & 3 deletions docs/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ run a top-level coroutine using the following function:
crash. If *with_monitor* is ``True``, then the monitor debugging
task executes in the background. If *selector* is given, it should
be an instance of a selector from the :mod:`selectors
<python:selector>` module.
<python:selectors>` module.

If you are going to repeatedly run coroutines one after the other, it
will be more efficient to create a ``Kernel`` instance and submit
Expand Down Expand Up @@ -76,8 +76,8 @@ The following functions are defined to help manage the execution of tasks.

Create a new task that runs the coroutine *coro*. Does not
return to the caller until the new task has been scheduled and
executed for at least one cycle. Returns a :class:`Task` instance
as a result. The *daemon* option, if supplied, specifies that the
executed for at least one cycle. Returns a :class:`Task <curio.task.Task>`
instance as a result. The *daemon* option, if supplied, specifies that the
new task will run indefinitely in the background. Curio only runs
as long as there are non-daemonic tasks to execute. Note: a
daemonic task will still be cancelled if the underlying kernel is
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ More Information
The official Github page at https://github.com/dabeaz/curio should be used for bug reports,
pull requests, and other activities.

A reference manual can be found at https://curio.readthedocs.org/en/latest/reference.html.
A reference manual can be found at https://curio.readthedocs.io/en/latest/reference.html.



Expand Down
9 changes: 9 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[pytest]
; uncomment when ready to test code samples in docs:
;testpaths = tests docs
testpaths = tests
addopts = --verbose
--ignore=setup.py --ignore=docs/conf.py
; --doctest-modules --doctest-glob=docs/*.rst
; uncomment ^^^ when ready to test code samples in docs
doctest_optionflags = IGNORE_EXCEPTION_DETAIL ELLIPSIS
6 changes: 6 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
except ImportError:
from distutils.core import setup

tests_require = ['pytest', 'Sphinx']

setup(name = "curio",
description="Curio - Concurrent I/O",
long_description = """
Expand All @@ -16,6 +18,10 @@
maintainer_email = "dave@dabeaz.com",
url = "https://github.com/dabeaz/curio",
packages = ['curio'],
tests_require = tests_require,
extras_require = {
'test': tests_require,
},
classifiers = [
'Programming Language :: Python :: 3',
]
Expand Down