Ticket #4568: utilities.xhtml.patch

File utilities.xhtml.patch, 17.9 KB (added by jdb, 4 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>