0

I'm having trouble using twisted together with doctest. I'm trying to open a file like so:

from __future__ import print_function

from twisted.internet.defer import Deferred
from twisted.internet.fdesc import readFromFD, setNonBlocking
from twisted.internet.task import react


def asyncFunc(filename):
    """Description.

    Examples:
        >>> def run(reactor, filename):
        ...     d = asyncFunc(filename)
        ...     return d.addCallback(print)
        >>>
        >>> try:
        ...     react(run, ['hello.txt'])
        ... except SystemExit:
        ...     pass
        hello world
        <BLANKLINE>
    """
    with open(filename) as f:
        d = Deferred()
        fd = f.fileno()
        setNonBlocking(fd)
        readFromFD(fd, d.callback)
        return d

It works fine with just one test, but for more than one I get a ReactorNotRestartable error.

def anotherAsyncFunc(filename):
    """Description.

    Examples:
        >>> def run(reactor, filename):
        ...     d = anotherAsyncFunc(filename)
        ...     return d.addCallback(print)
        >>>
        >>> try:
        ...     react(run, ['hello.txt'])
        ... except SystemExit:
        ...     pass
        hello world
        <BLANKLINE>
    """
    with open(filename) as f:
        d = Deferred()
        fd = f.fileno()
        setNonBlocking(fd)
        readFromFD(fd, d.callback)
        return d

I then read about MemoryReactor and tried this:

def anotherAsyncFunc(filename):
    """Description.

    Examples:
        >>> from twisted.test.proto_helpers import MemoryReactor
        >>> reactor = MemoryReactor()
        >>>
        >>> def run(reactor, filename):
        ...     d = anotherAsyncFunc(filename)
        ...     return d.addCallback(print)
        >>>
        >>> try:
        ...     react(run, ['hello.txt'], reactor)
        ... except SystemExit:
        ...     pass
        hello world
        <BLANKLINE>
    """
    with open(filename) as f:
        d = Deferred()
        fd = f.fileno()
        setNonBlocking(fd)
        readFromFD(fd, d.callback)
        return d

But that gives me an 'MemoryReactor' object has no attribute 'addSystemEventTrigger' AttributeError. Any idea on the proper way to do this?

Community
  • 1
  • 1
reubano
  • 5,087
  • 1
  • 42
  • 41

1 Answers1

0

You have correctly identified that MemoryReactor does not provide the interface IReactorCore. The proper thing to do would be to contribute an implementation of IReactorCore to MemoryReactor so that the second example would work as desired. Please open a ticket and do that :).

Glyph
  • 31,152
  • 11
  • 87
  • 129
  • Thanks for the help @glyph. I'm new to the whole interface concept so could you please point me to an existing ticket or example I could follow as a guide? – reubano Nov 17 '15 at 13:11
  • I can't think of a specific ticket, but it's not complicated; [`IReactorCore`](https://twistedmatrix.com/documents/15.4.0/api/twisted.internet.interfaces.IReactorCore.html) has a bunch of methods and attributes, just add those attributes to `MemoryReactor` (and then add `IReactorCore` to its `@implements` line). Interfaces are just a documented description of what features a particular object has to have. – Glyph Nov 18 '15 at 20:05
  • gotcha.... do they actually need to do anything or can I just use `pass` for all of them? – reubano Nov 19 '15 at 11:14
  • Well, [patch submitted](https://twistedmatrix.com/trac/ticket/8113) and the tests pass so I guess all is ok :). – reubano Nov 19 '15 at 12:43
  • Thanks very much for your contribution, we'll discuss further on the ticket! – Glyph Nov 20 '15 at 08:33