Ticket #4568: utilities.xhtml.patch

File utilities.xhtml.patch, 17.9 KB (added by jdb, 5 years ago)

Patch for the articles in the section 'Utilities' of the core howto

  • doc/core/howto/dirdbm.xhtml

    diff --git a/doc/core/howto/dirdbm.xhtml b/doc/core/howto/dirdbm.xhtml
    index 25f0b64..d1b7bbf 100644
    a b Python's built-in DBM modules.</p> 
    4040
    4141<h2>dirdbm.Shelf</h2>
    4242
    43 <p>Sometimes it is neccessary to persist more complicated objects than strings.
    44 With some care, <code base="twisted.persisted" class="API">dirdbm.Shelf</code>
    45 can transparently persist
    46 them. <code>Shelf</code> works exactly like <code>DirDBM</code>, except that
    47 the values (but not the keys) can be arbitrary picklable objects. However,
    48 notice that mutating an object after it has been stored in the
    49 <code>Shelf</code> has no effect on the Shelf.
    50 When mutating objects, it is neccessary to explictly store them back in the <code>Shelf</code>
    51 afterwards:</p>
     43<p>Sometimes it is neccessary to persist more complicated objects than
     44strings.  With some care, <code base="twisted.persisted"
     45class="API">dirdbm.Shelf</code> can transparently persist
     46them. <code>Shelf</code> works exactly like <code>DirDBM</code>,
     47except that the values (but not the keys) can be arbitrary picklable
     48objects. However, notice that mutating an object after it has been
     49stored in the <code>Shelf</code> has no effect on the Shelf.  When
     50mutating objects, it is neccessary to explictly store them back in
     51the <code>Shelf</code> afterwards:</p>
    5252
    5353<pre class="python-interpreter">
    5454&gt;&gt;&gt; from twisted.persisted import dirdbm
  • doc/core/howto/telnet.xhtml

    diff --git a/doc/core/howto/telnet.xhtml b/doc/core/howto/telnet.xhtml
    index 933dd84..f7e687e 100644
    a b be on port 4040, and it will start listening for connections on this port. Try 
    1616connecting with your favorite telnet utility to 127.0.0.1 port 4040.</p>
    1717
    1818<pre class="shell">
    19 $ <em>telnet localhost 4040</em>
     19$ telnet localhost 4040
    2020Trying 127.0.0.1...
    2121Connected to localhost.
    2222Escape character is '^]'.
    2323
    2424twisted.manhole.telnet.ShellFactory
    2525Twisted 1.1.0
    26 username: <em>admin</em>
    27 password: <em>admin</em>
     26username: admin
     27password: admin
    2828&gt;&gt;&gt;
    2929</pre>
    3030
    password: <em>admin</em> 
    3333here. Let's try looking around.</p>
    3434
    3535<pre class="python-interpreter">
    36 &gt;&gt;&gt; <em>dir()</em>
     36&gt;&gt;&gt; dir()
    3737['__builtins__']
    3838</pre>
    3939
    4040<p>Ok, not much. let's play a little more:</p>
    4141<pre class="python-interpreter">
    42 &gt;&gt;&gt; <em>import __main__</em>
    43 &gt;&gt;&gt; <em>dir(__main__)</em>
     42&gt;&gt;&gt; import __main__
     43&gt;&gt;&gt; dir(__main__)
    4444['__builtins__', '__doc__', '__name__', 'os', 'run', 'string', 'sys']
    4545
    46 &gt;&gt;&gt; <em>service</em>
     46&gt;&gt;&gt; service
    4747&lt;twisted.application.internet.TCPServer instance at 0x10270f48&gt;
    48 &gt;&gt;&gt; <em>service._port</em>
     48&gt;&gt;&gt; service._port
    4949&lt;twisted.manhole.telnet.ShellFactory on 4040&gt;
    50 &gt;&gt;&gt; <em>service.parent</em>
     50&gt;&gt;&gt; service.parent
    5151&lt;twisted.application.service.MultiService instance at 0x1024d7a8&gt;
    5252</pre>
    5353
    5454<p>The service object is the service used to serve the telnet shell,
    55 and that it is listening on port 4040 with something called a
    56 <code class="API" base="twisted.manhole.telnet">ShellFactory</code>.
    57 Its parent is a <code class="python">twisted.application.service.MultiService</code>,
    58 a collection of services. We can keep getting the parent attribute
    59 of services until we hit the root of all services.</p>
     55and that it is listening on port 4040 with something called
     56a <code class="API" base="twisted.manhole.telnet">ShellFactory</code>.
     57Its parent is
     58a <code class="python">twisted.application.service.MultiService</code>,
     59a collection of services. We can keep getting the parent attribute of
     60services until we hit the root of all services.</p>
    6061
    61 <p>As you can see, this is quite useful - we can introspect a
    62 running process, see the internal objects, and even change
    63 their attributes. The telnet server can of course be used from straight
    64 Python code; you can see how to do this by reading the code for
    65 <code class="API">twisted.tap.telnet</code>.</p>
     62<p>As you can see, this is quite useful - we can introspect a running
     63process, see the internal objects, and even change their
     64attributes. The telnet server can of course be used from straight
     65Python code; you can see how to do this by reading the code
     66for <code class="API">twisted.tap.telnet</code>.</p>
    6667
    6768<p>A final note - if you want access to be more secure, you can even
    6869have the telnet server use SSL. Assuming you have the appropriate
  • doc/core/howto/testing.xhtml

    diff --git a/doc/core/howto/testing.xhtml b/doc/core/howto/testing.xhtml
    index e83e8d2..0b60709 100644
    a b may complete (and fail) during a later test. These lead to intermittent 
    6868failures that wander from test to test and are very time-consuming to track
    6969down.</p>
    7070
    71 <p>If your test leaves event sources in the reactor, Trial will fail the test.
    72 The <code>tearDown</code> method is a good place to put cleanup code: it is
    73 always run regardless of whether your test passes or fails (like a bare <code>
    74 except</code> clause in a try-except construct). Exceptions in <code>tearDown
    75 </code> are flagged as errors and flunk the test.
    76 <code class="API" base="twisted.trial.unittest">TestCase.addCleanup</code> is
    77 another useful tool for cleaning up.  With it, you can register callables to
    78 clean up resources as the test allocates them.  Generally, code should be
    79 written so that only resources allocated in the tests need to be cleaned up in
    80 the tests.  Resources which are allocated internally by the implementation
    81 should be cleaned up by the implementation.</p>
    82 
    83 <p>If your code uses Deferreds or depends on the reactor running, you can
    84 return a Deferred from your test method, setUp, or tearDown and Trial will
    85 do the right thing. That is, it will run the reactor for you until the
    86 Deferred has triggered and its callbacks have been run. Don't use
    87 <code>reactor.run()</code>, <code>reactor.stop()</code>, <code>reactor.crash()
    88 </code>or <code>reactor.iterate()</code> in your tests.</p>
     71<p>If your test leaves event sources in the reactor, Trial will fail
     72the test.  The <code>tearDown</code> method is a good place to put
     73cleanup code: it is always run regardless of whether your test passes
     74or fails (like a bare <code> except</code> clause in a try-except
     75construct). Exceptions in <code>tearDown</code> are flagged as errors
     76and flunk the test. <code class="API"
     77base="twisted.trial.unittest">TestCase.addCleanup</code> is another
     78useful tool for cleaning up.  With it, you can register callables to
     79clean up resources as the test allocates them.  Generally, code should
     80be written so that only resources allocated in the tests need to be
     81cleaned up in the tests.  Resources which are allocated internally by
     82the implementation should be cleaned up by the implementation.</p>
     83
     84<p>If your code uses Deferreds or depends on the reactor running, you
     85can return a Deferred from your test method, setUp, or tearDown and
     86Trial will do the right thing. That is, it will run the reactor for
     87you until the Deferred has triggered and its callbacks have been
     88run. Don't
     89use <code>reactor.run()</code>, <code>reactor.stop()</code>, <code>reactor.crash() </code>or <code>reactor.iterate()</code>
     90in your tests.</p>
    8991
    9092<p>Calls to <code>reactor.callLater</code> create <code class="API"
    9193base="twisted.internet.interfaces">IDelayedCall</code>s.  These need to be run
    in unusual cases.</p> 
    132134
    133135<h3>Interacting with warnings in tests</h3>
    134136
    135 <p>Trial includes specific support for interacting with Python's
    136 <code>warnings</code> module.  This support allows warning-emitting code to
    137 be written test-driven, just as any other code would be.  It also improves
    138 the way in which warnings reporting when a test suite is running.</p>
     137<p>Trial includes specific support for interacting with
     138Python's <code>warnings</code> module.  This support allows
     139warning-emitting code to be written test-driven, just as any other
     140code would be.  It also improves the way in which warnings reporting
     141when a test suite is running.</p>
    139142
    140143<p><code class="API"
    141 base="twisted.trial.unittest">TestCase.assertWarns</code> and <code
    142 class="API" base="twisted.trial.unittest">TestCase.flushWarnings</code>
    143 allow tests to be written which make assertions about what warnings have
    144 been emitted during a particular test method.  <code>flushWarnings</code> is
    145 the new method and has a simpler and more flexible API and should be
    146 preferred when writing new code.  In order to test a warning with
    147 <code>flushWarnings</code>, write a test which first invokes the code which
    148 will emit a warning and then calls <code>flushWarnings</code> and makes
    149 assertions about the result.  For example:</p>
     144base="twisted.trial.unittest">TestCase.assertWarns</code>
     145and <code class="API"
     146base="twisted.trial.unittest">TestCase.flushWarnings</code> allow
     147tests to be written which make assertions about what warnings have
     148been emitted during a particular test
     149method.  <code>flushWarnings</code> is the new method and has a
     150simpler and more flexible API and should be preferred when writing new
     151code.  In order to test a warning with <code>flushWarnings</code>,
     152write a test which first invokes the code which will emit a warning
     153and then calls <code>flushWarnings</code> and makes assertions about
     154the result.  For example:</p>
    150155
    151156<pre class="python">
    152157def test_warning(self):
    def test_warning(self): 
    154159    self.assertEqual(len(self.flushWarnings()), 1)
    155160</pre>
    156161
    157 <p>Warnings emitted in tests which are not flushed will be included by the
    158 default reporter in its output after the result of the test.  If Python's
    159 warnings filter system (see <a
    160 href="http://docs.python.org/using/cmdline.html#cmdoption-W">the -W command
    161 line option to Python</a>) is configured to treat a warning as an error,
    162 then unflushed warnings will causes tests to fail and will be included in
    163 the summary section of the default reporter.  Note that unlike usual
    164 operation, when <code>warnings.warn</code> is called as part of a test
    165 method, it will not raise an exception when warnings have been configured as
    166 errors.  However, if called outside of a test method (for example, at module
    167 scope in a test module or a module imported by a test module) then it
    168 <em>will</em> raise an exception.</p>
     162<p>Warnings emitted in tests which are not flushed will be included by
     163the default reporter in its output after the result of the test.  If
     164Python's warnings filter system
     165(see <a href="http://docs.python.org/using/cmdline.html#cmdoption-W">the
     166-W command line option to Python</a>) is configured to treat a warning
     167as an error, then unflushed warnings will causes tests to fail and
     168will be included in the summary section of the default reporter.  Note
     169that unlike usual operation, when <code>warnings.warn</code> is called
     170as part of a test method, it will not raise an exception when warnings
     171have been configured as errors.  However, if called outside of a test
     172method (for example, at module scope in a test module or a module
     173imported by a test module) then it <em>will</em> raise an
     174exception.</p>
    169175
    170176  </body>
    171177</html>
  • doc/core/howto/upgrading.xhtml

    diff --git a/doc/core/howto/upgrading.xhtml b/doc/core/howto/upgrading.xhtml
    index 2a50e4f..f994ee8 100644
    a b structures. </p> 
    2121
    2222<h2>Basic Persistence: Application and .tap files</h2>
    2323
    24 <p>Simple object persistence (using <code>pickle</code> or
    25 <code>jelly</code>) provides the fundamental <q>save the object to disk</q>
    26 functionality at application shutdown. If you use the <code class="API"
    27 base="twisted.application.service">Application</code> object, every object
    28 referenced by your Application will be saved into the
    29 <code>-shutdown.tap</code> file when the program terminates. When you use
    30 <code>twistd</code> to launch that new .tap file, the Application object
    31 will be restored along with all of its referenced data.</p>
    32 
    33 <p>This provides a simple way to have data outlive any particular invocation
    34 of your program: simply store it as an attribute of the Application. Note
    35 that all Services are referenced by the Application, so their attributes
    36 will be stored as well. Ports that have been bound with listenTCP (and the
    37 like) are also remembered, and the sockets are created at startup time (when
    38 <code>Application.run</code> is called).</p>
     24<p>Simple object persistence (using <code>pickle</code>
     25or <code>jelly</code>) provides the fundamental <q>save the object to
     26disk</q> functionality at application shutdown. If you use
     27the <code class="API"
     28base="twisted.application.service">Application</code> object, every
     29object referenced by your Application will be saved into
     30the <code>-shutdown.tap</code> file when the program terminates. When
     31you use <code>twistd</code> to launch that new .tap file, the
     32Application object will be restored along with all of its referenced
     33data.</p>
     34
     35<p>This provides a simple way to have data outlive any particular
     36invocation of your program: simply store it as an attribute of the
     37Application. Note that all Services are referenced by the Application,
     38so their attributes will be stored as well. Ports that have been bound
     39with listenTCP (and the like) are also remembered, and the sockets are
     40created at startup time (when <code>Application.run</code> is
     41called).</p>
    3942
    4043<p>To influence the way that the <code class="API"
    4144base="twisted.application.service">Application</code> is persisted, you can adapt
    a string like <q>pickle</q> or <q>source</q>. These use different serializers (a 
    4548extensions: <q>.tap</q> and <q>.tas</q> respectively) for the
    4649saved Application.</p>
    4750
    48 <p>You can manually cause the application to be saved by calling its
    49 <code>.save</code> method (on the <code class="API">twisted.persisted.sob.IPersistable</code>
     51<p>You can manually cause the application to be saved by calling
     52its <code>.save</code> method (on
     53the <code class="API">twisted.persisted.sob.IPersistable</code>
    5054adapted object).</p>
    5155
    5256
    those data attributes: for example, if you use a string in one version and 
    7680an integer in another, those versions must have different version numbers.
    7781</p>
    7882
    79 <p>The version number is defined in a class attribute named
    80 <code>persistenceVersion</code>. This is an integer which will be stored in
    81 the .tap file along with the rest of the instance state. When the object is
    82 unserialized, the saved persistenceVersion is compared against the current
    83 class's value, and if they differ, special upgrade methods are called. These
    84 methods are named <code>upgradeToVersionNN</code>, and there must be one for
    85 each intermediate version. These methods are expected to manipulate the
    86 instance's state from the previous version's format into that of the new
    87 version.</p>
     83<p>The version number is defined in a class attribute
     84named <code>persistenceVersion</code>. This is an integer which will
     85be stored in the .tap file along with the rest of the instance
     86state. When the object is unserialized, the saved persistenceVersion
     87is compared against the current class's value, and if they differ,
     88special upgrade methods are called. These methods are
     89named <code>upgradeToVersionNN</code>, and there must be one for each
     90intermediate version. These methods are expected to manipulate the
     91instance's state from the previous version's format into that of the
     92new version.</p>
    8893
    8994<p>To use this, simply have your class inherit from <code class="API"
    9095base="twisted.persisted.styles">Versioned</code>. You don't have to do this
    class Thing(Versioned): 
    137142      self.length = (length, units)
    138143</pre>
    139144
    140 <p>Note that we must provide both <code>upgradeToVersion1</code>
    141 <em>and</em> <code>upgradeToVersion2</code>. We have to assume that the
    142 saved .tap files which will be provided to this class come from a random
    143 assortment of old versions: we must be prepared to accept anything ever
    144 saved by a released version of our application.</p>
     145<p>Note that we must provide
     146both <code>upgradeToVersion1</code> <em>and</em> <code>upgradeToVersion2</code>. We
     147have to assume that the saved .tap files which will be provided to
     148this class come from a random assortment of old versions: we must be
     149prepared to accept anything ever saved by a released version of our
     150application.</p>
    145151
    146152<p>Finally, version 2.0 adds multiple dimensions. Instead of merely
    147153recording the length of a line, it records the size of an N-dimensional
    editing the code).</p> 
    294300</ul>
    295301
    296302<p>Finally, note that <code class="API"
    297 base="twisted.python.rebuild">rebuild</code> <em>cannot</em> currently be
    298 mixed with <code class="API"
    299 base="twisted.persisted.styles">Versioned</code>. <code>rebuild</code> does
    300 not run any of the classes' methods, whereas <code>Versioned</code> works by
    301 running <code>__setstate__</code> during the load process and
    302 <code>doUpgrade</code> afterwards. This means <code>rebuild</code> can only
    303 be used to process upgrades that do not change the data attributes of any of
    304 the involved classes. Any time attributes are added or removed, the program
    305 must be shut down, persisted, and restarted, with upgradeToVersionNN methods
    306 used to handle the attributes. (this may change in the future, but for now
    307 the implementation is easier and more reliable with this restriction).</p>
     303base="twisted.python.rebuild">rebuild</code> <em>cannot</em> currently
     304be mixed with <code class="API"
     305base="twisted.persisted.styles">Versioned</code>. <code>rebuild</code>
     306does not run any of the classes' methods,
     307whereas <code>Versioned</code> works by
     308running <code>__setstate__</code> during the load process
     309and <code>doUpgrade</code> afterwards. This means <code>rebuild</code>
     310can only be used to process upgrades that do not change the data
     311attributes of any of the involved classes. Any time attributes are
     312added or removed, the program must be shut down, persisted, and
     313restarted, with upgradeToVersionNN methods used to handle the
     314attributes. (this may change in the future, but for now the
     315implementation is easier and more reliable with this restriction).</p>
    308316
    309317</body> </html>