Ticket #4568: high-level.xhtml.patch
| File high-level.xhtml.patch, 22.9 KB (added by jdb, 3 years ago) |
|---|
-
doc/core/howto/application.xhtml
diff --git a/doc/core/howto/application.xhtml b/doc/core/howto/application.xhtml index 79f19db..3b6601a 100644
a b 95 95 96 96 <h3>twistd and tac</h3><a name="twistd" /> 97 97 98 <p>To handle start-up and configuration of your Twisted application, the 99 Twisted Application infrastructure uses <code>.tac</code> files. 100 <code>.tac</code> are Python files which configure an <code class="API" 101 base="twisted.application.service">Application</code> object and assign this 102 object to the top-level variable <q><code>application</code></q>.</p> 98 <p>To handle start-up and configuration of your Twisted application, 99 the Twisted Application infrastructure uses <code>.tac</code> 100 files. <code>.tac</code> are Python files which configure 101 an <code class="API" 102 base="twisted.application.service">Application</code> object and 103 assign this object to the top-level 104 variable <q><code>application</code></q>.</p> 103 105 104 106 <p>The following is a simple example of a <code>.tac</code> file:</p> 105 107 106 108 <a href="listings/application/service.tac" class="py-listing">service.tac</a> 107 109 108 <p><code>twistd</code> is a program that runs Twisted applications using a 109 <code>.tac</code> file. In its most simple form, it takes a single argument 110 <code>-y</code> and a tac file name. For example, you can run the above server 111 with the command <code class="shell">twistd -y service.tac</code>.</p> 110 <p><code>twistd</code> is a program that runs Twisted applications 111 using a <code>.tac</code> file. In its most simple form, it takes a 112 single argument <code>-y</code> and a tac file name. For example, you 113 can run the above server with the command <code class="shell">twistd 114 -y service.tac</code>.</p> 112 115 113 <p>By default, <code>twistd</code> daemonizes and logs to a file called114 <code>twistd.log</code>. More usually, when debugging, you will want your 115 application to run in the foreground and log to the command line. To run the 116 above file like this, use the command <code class="shell">twistd -noy 117 service.tac</code></p>116 <p>By default, <code>twistd</code> daemonizes and logs to a file 117 called <code>twistd.log</code>. More usually, when debugging, you will 118 want your application to run in the foreground and log to the command 119 line. To run the above file like this, use the 120 command <code class="shell">twistd -noy service.tac</code></p> 118 121 119 122 <p>For more information, see the <code>twistd</code> man page.</p> 120 123 121 124 <h3>Customizing <code>twistd</code> logging in a .tac application</h3> 122 125 123 126 <p> 124 The logging behavior can be customized through an API 125 accessiblefrom <code>.tac</code> files. The <code class="API"126 base="twisted.python.log">ILogObserver</code> component can be 127 set on an Application in order to customize the default log observer that 128 <code>twistd</code> will use.127 The logging behavior can be customized through an API accessible 128 from <code>.tac</code> files. The <code class="API" 129 base="twisted.python.log">ILogObserver</code> component can be set on 130 an Application in order to customize the default log observer 131 that <code>twistd</code> will use. 129 132 </p> 130 133 131 134 <p> … … 146 149 147 150 <p> 148 151 invoking <code class="shell">twistd -y my.tac</code> will create a log file 149 at <code>/tmp/my.log</code>.152 at <code>/tmp/my.log</code>. 150 153 </p> 151 154 152 155 <h3>Services provided by Twisted</h3> … … 253 256 <h3>Service Collection</h3> 254 257 255 258 <p><code class="API" 256 base="twisted.application.service">IServiceCollection</code> objects contain 257 <code class="API" base="twisted.application.service">IService</code> objects. 258 IService objects can be added to IServiceCollection by calling <code class="API" 259 base="twisted.application.service.IService">setServiceParent</code> and detached 260 by using <code class="API" 259 base="twisted.application.service">IServiceCollection</code> objects 260 contain <code class="API" 261 base="twisted.application.service">IService</code> objects. IService 262 objects can be added to IServiceCollection by 263 calling <code class="API" 264 base="twisted.application.service.IService">setServiceParent</code> 265 and detached by using <code class="API" 261 266 base="twisted.application.service.IService">disownServiceParent</code>.</p> 262 267 263 268 <p>The standard implementation of IServiceCollection is <code class="API" -
doc/core/howto/basics.xhtml
diff --git a/doc/core/howto/basics.xhtml b/doc/core/howto/basics.xhtml index df27fba..20b00ed 100644
a b 12 12 13 13 <h2>Application</h2> 14 14 15 <p>Twisted programs usually work with16 <code class="API">twisted.application.service.Application</code>.17 This class usually holds all persistent configuration of 18 a running server -- ports to bind to, places where connections 19 to must be kept or attempted, periodic actions to do and almost 20 everything else. It is the root object in a tree of services implementing 21 <code class="API"base="twisted.application.service">IService</code>.</p>15 <p>Twisted programs usually work 16 with <code class="API">twisted.application.service.Application</code>. 17 This class usually holds all persistent configuration of a running 18 server -- ports to bind to, places where connections to must be kept 19 or attempted, periodic actions to do and almost everything else. It is 20 the root object in a tree of services implementing <code class="API" 21 base="twisted.application.service">IService</code>.</p> 22 22 23 23 <p>Other HOWTOs describe how to write custom code for Applications, 24 24 but this one describes how to use already written code (which can be … … 52 52 object called <code>application</code> is used, use the <code class="shell">-y</code> 53 53 option.</p> 54 54 55 <p>When <code class="shell">twistd</code> runs, it records its process id in a 56 <code>twistd.pid</code> file (this can be configured via a command line 57 switch). In order to shutdown the <code class="shell">twistd</code> process, kill that 58 pid (usually you would do <code class="shell">kill `cat twistd.pid`</code>). 55 <p>When <code class="shell">twistd</code> runs, it records its process 56 id in a <code>twistd.pid</code> file (this can be configured via a 57 command line switch). In order to shutdown 58 the <code class="shell">twistd</code> process, kill that pid (usually 59 you would do <code class="shell">kill `cat twistd.pid`</code>). 59 60 </p> 60 61 61 62 <p>As always, the gory details are in the manual page.</p> … … 63 64 <h2>OS Integration</h2> 64 65 65 66 <p> 66 If you have an Application that runs with <code class="shell">twistd</code>, 67 you can easily deploy it on RedHat Linux or Debian GNU/Linux based systems 68 using the <code class="shell">tap2deb</code> or <code 69 class="shell">tap2rpm</code> tools. These take a Twisted Application file (of 70 any of the supported formats — Python source, XML or pickle), and build a 71 Debian or RPM package (respectively) that installs the Application as a system 72 service. The package includes the Application file, a default 73 <code>/etc/init.d/</code> script that starts and stops the process with twistd, 74 and post-installation scripts that configure the Application to be run in the 75 appropriate init levels. 67 If you have an Application that runs 68 with <code class="shell">twistd</code>, you can easily deploy it on 69 RedHat Linux or Debian GNU/Linux based systems using 70 the <code class="shell">tap2deb</code> 71 or <code class="shell">tap2rpm</code> tools. These take a Twisted 72 Application file (of any of the supported formats — Python source, XML 73 or pickle), and build a Debian or RPM package (respectively) that 74 installs the Application as a system service. The package includes the 75 Application file, a default <code>/etc/init.d/</code> script that 76 starts and stops the process with twistd, and post-installation 77 scripts that configure the Application to be run in the appropriate 78 init levels. 76 79 </p> 77 80 78 81 <!-- Is "note" really the right class to be using here? --> 79 <div class="note"> 80 <code class="shell">tap2rpm</code> and <code class="shell">tap2deb</code> do 81 not package your entire application and dependent code, just the Twisted 82 Application file. You will need to find some other way to package your Python 83 code, such as <code class="API">distutils</code>' <code>bdist_rpm</code> 84 command. 82 <div class="note"> <code class="shell">tap2rpm</code> 83 and <code class="shell">tap2deb</code> do not package your entire 84 application and dependent code, just the Twisted Application file. You 85 will need to find some other way to package your Python code, such 86 as <code class="API">distutils</code>' <code>bdist_rpm</code> command. 85 87 </div> 86 88 87 89 <p> -
doc/core/howto/components.xhtml
diff --git a/doc/core/howto/components.xhtml b/doc/core/howto/components.xhtml index 3567d6e..135e4ef 100644
a b 8 8 <body> 9 9 <h1>Components: Interfaces and Adapters</h1> 10 10 11 <p>Object oriented programming languages allow programmers to reuse portions of 12 existing code by creating new <q>classes</q> of objects which subclass another 13 class. When a class subclasses another, it is said to <em>inherit</em> all of its 14 behaviour. The subclass can then <q>override</q> and <q>extend</q> the behavior 15 provided to it by the superclass. Inheritance is very useful in many situations, 16 but because it is so convenient to use, often becomes abused in large software 17 systems, especially when multiple inheritance is involved. One solution is to 18 use <em>delegation</em> instead of <q>inheritance</q> where appropriate. 19 Delegation is simply the act of asking <em>another</em> object to perform a task 20 for an object. To support this design pattern, which is often referred to as the 21 <em>components</em> pattern because it involves many small interacting components, 22 <em>interfaces</em> and <em>adapters</em> were created by the Zope 3 team.</p> 11 <p>Object oriented programming languages allow programmers to reuse 12 portions of existing code by creating new <q>classes</q> of objects 13 which subclass another class. When a class subclasses another, it is 14 said to <em>inherit</em> all of its behaviour. The subclass can 15 then <q>override</q> and <q>extend</q> the behavior provided to it by 16 the superclass. Inheritance is very useful in many situations, but 17 because it is so convenient to use, often becomes abused in large 18 software systems, especially when multiple inheritance is 19 involved. One solution is to use <em>delegation</em> instead 20 of <q>inheritance</q> where appropriate. Delegation is simply the act 21 of asking <em>another</em> object to perform a task for an object. To 22 support this design pattern, which is often referred to as 23 the <em>components</em> pattern because it involves many small 24 interacting components, <em>interfaces</em> and <em>adapters</em> were 25 created by the Zope 3 team.</p> 23 26 24 27 <p><q>Interfaces</q> are simply markers which objects can use to say <q>I 25 28 implement this interface</q>. Other objects may then make requests like … … 100 103 inheritance to break code into small reusable chunks. Let us continue with the 101 104 Multiple Inheritance example, though, because it is often used in practice.</p> 102 105 103 <p>What if both the Color and the Area base class defined the same method, 104 perhaps <code>calculate</code>? Where would the implementation come from? The 105 implementation that is located for <code>Square().calculate()</code> depends on 106 the method resolution order, or MRO, and can change when programmers change 107 seemingly unrelated things by refactoring classes in other parts of the system, 108 causing obscure bugs. Our first thought might be to change the calculate method 109 name to avoid name clashes, to perhaps <code>calculateArea</code> and 110 <code>calculateColor</code>. While explicit, this change could potentially 111 require a large number of changes throughout a system, and is error-prone, 112 especially when attempting to integrate two systems which you didn't write.</p> 106 <p>What if both the Color and the Area base class defined the same 107 method, perhaps <code>calculate</code>? Where would the implementation 108 come from? The implementation that is located 109 for <code>Square().calculate()</code> depends on the method resolution 110 order, or MRO, and can change when programmers change seemingly 111 unrelated things by refactoring classes in other parts of the system, 112 causing obscure bugs. Our first thought might be to change the 113 calculate method name to avoid name clashes, to 114 perhaps <code>calculateArea</code> and <code>calculateColor</code>. 115 While explicit, this change could potentially require a large number 116 of changes throughout a system, and is error-prone, especially when 117 attempting to integrate two systems which you didn't write.</p> 113 118 114 119 <p>Let's imagine another example. We have an electric appliance, say a hair 115 120 dryer. The hair dryer is american voltage. We have two electric sockets, one of … … 151 156 now you have no hair dryer any more. 152 157 </pre> 153 158 154 <p>We are going to attempt to solve this problem by writing an Adapter for the 155 <code>ForeignSocket</code> which converts the voltage for use with an American 156 hair dryer. An Adapter is a class which is constructed with one and only one 157 argument, the <q>adaptee</q> or <q>original</q> object. In this example, we 158 will show all code involved for clarity:</p> 159 <p>We are going to attempt to solve this problem by writing an Adapter 160 for the <code>ForeignSocket</code> which converts the voltage for use 161 with an American hair dryer. An Adapter is a class which is 162 constructed with one and only one argument, the <q>adaptee</q> 163 or <q>original</q> object. In this example, we will show all code 164 involved for clarity:</p> 159 165 160 166 <pre class="python"> 161 167 class AdaptToAmericanSocket: … … 213 219 native language-level support for Interfaces like Java does, this is what 214 220 distinguishes an Interface definition from a Class.</p> 215 221 216 <p>Now that we have a defined Interface, we can talk about objects using terms 217 like this: <q>The <code>AmericanSocket</code> class implements the 218 <code>IAmericanSocket</code> interface</q> and <q>Please give me an object which 222 <p>Now that we have a defined Interface, we can talk about objects 223 using terms like this: <q>The <code>AmericanSocket</code> class 224 implements the <code>IAmericanSocket</code> interface</q> 225 and <q>Please give me an object which 219 226 adapts <code>ForeignSocket</code> to the <code>IAmericanSocket</code> 220 interface</q>. We can make <em>declarations</em> about what interfaces a certain221 class implements, and we can request adapters which implement a certain 222 i nterface for a specific class.</p>227 interface</q>. We can make <em>declarations</em> about what interfaces 228 a certain class implements, and we can request adapters which 229 implement a certain interface for a specific class.</p> 223 230 224 231 <p>Let's look at how we declare that a class implements an interface:</p> 225 232 … … 234 241 return 110 235 242 </pre> 236 243 237 <p>So, to declare that a class implements an interface, we simply call238 <code>zope.interface.implements</code> at the class level.</p>244 <p>So, to declare that a class implements an interface, we simply 245 call <code>zope.interface.implements</code> at the class level.</p> 239 246 240 <p>Now, let's say we want to rewrite the <code>AdaptToAmericanSocket</code> 241 class as a real adapter. In this case we also specify it as implementing 242 <code>IAmericanSocket</code>:</p> 247 <p>Now, let's say we want to rewrite 248 the <code>AdaptToAmericanSocket</code> class as a real adapter. In 249 this case we also specify it as 250 implementing <code>IAmericanSocket</code>:</p> 243 251 244 252 <pre class="python"> 245 253 from zope.interface import implements … … 258 266 return self.original.voltage() / 2 259 267 </pre> 260 268 261 <p>Notice how we placed the implements declaration on this adapter class. So 262 far, we have not achieved anything by using components other than requiring us 263 to type more. In order for components to be useful, we must use the 264 <em>component registry</em>. Since <code>AdaptToAmericanSocket</code> implements 265 <code>IAmericanSocket</code> and regulates the voltage of a 266 <code>ForeignSocket</code> object, we can <em>register 267 <code>AdaptToAmericanSocket</code> as an <code>IAmericanSocket</code> adapter 268 for the <code>ForeignSocket</code> class</em>. It is easier to see how this is 269 done in code than to describe it:</p> 269 <p>Notice how we placed the implements declaration on this adapter 270 class. So far, we have not achieved anything by using components other 271 than requiring us to type more. In order for components to be useful, 272 we must use the <em>component 273 registry</em>. Since <code>AdaptToAmericanSocket</code> 274 implements <code>IAmericanSocket</code> and regulates the voltage of 275 a <code>ForeignSocket</code> object, we 276 can <em>register </em> <code>AdaptToAmericanSocket</code> <em> as 277 an </em> <code>IAmericanSocket</code> <em> adapter for 278 the </em> <code>ForeignSocket</code> <em>class</em>. It is easier to see how 279 this is done in code than to describe it:</p> 270 280 271 281 <pre class="python"> 272 282 from zope.interface import Interface, implements … … 321 331 </pre> 322 332 323 333 <p>As you can see, the <code>AmericanSocket</code> instance claims to 324 implement <code>IAmericanSocket</code>, but the <code>ForeignSocket</code> 325 does not. If we wanted to use the <code>HairDryer</code> with the 326 <code>AmericanSocket</code>, we could know that it would be safe to do so by 327 checking whether it implements <code>IAmericanSocket</code>. However, if we 328 decide we want to use <code>HairDryer</code> with a <code>ForeignSocket</code> 329 instance, we must <em>adapt</em> it to <code>IAmericanSocket</code> before 330 doing so. We use the interface object to do this:</p> 334 implement <code>IAmericanSocket</code>, but 335 the <code>ForeignSocket</code> does not. If we wanted to use 336 the <code>HairDryer</code> with the <code>AmericanSocket</code>, we 337 could know that it would be safe to do so by checking whether it 338 implements <code>IAmericanSocket</code>. However, if we decide we want 339 to use <code>HairDryer</code> with a <code>ForeignSocket</code> 340 instance, we must <em>adapt</em> it to <code>IAmericanSocket</code> 341 before doing so. We use the interface object to do this:</p> 331 342 332 343 <pre class="python-interpreter"> 333 344 >>> IAmericanSocket(fs) 334 345 <__main__.AdaptToAmericanSocket instance at 0x1a5120> 335 346 </pre> 336 347 337 <p>When calling an interface with an object as an argument, the interface 338 looks in the adapter registry for an adapter which implements the interface for 339 the given instance's class. If it finds one, it constructs an instance of the 340 Adapter class, passing the constructor the original instance, and returns it. 341 Now the <code>HairDryer</code> can safely be used with the adapted 342 <code>ForeignSocket</code>. But what happens if we attempt to adapt an object 343 which already implements <code>IAmericanSocket</code>? We simply get back the 344 original instance:</p> 348 <p>When calling an interface with an object as an argument, the 349 interface looks in the adapter registry for an adapter which 350 implements the interface for the given instance's class. If it finds 351 one, it constructs an instance of the Adapter class, passing the 352 constructor the original instance, and returns it. Now 353 the <code>HairDryer</code> can safely be used with the 354 adapted <code>ForeignSocket</code>. But what happens if we attempt to 355 adapt an object which already implements <code>IAmericanSocket</code>? 356 We simply get back the original instance:</p> 345 357 346 358 <pre class="python-interpreter"> 347 359 >>> IAmericanSocket(am) … … 395 407 implements(IPBRoot) 396 408 </pre> 397 409 398 <p>Suppose you have your own class which implements your399 <code>IMyInterface</code> interface:</p>410 <p>Suppose you have your own class which implements 411 your <code>IMyInterface</code> interface:</p> 400 412 401 413 <pre class="python"> 402 414 from zope.interface import implements, Interface … … 408 420 implements(IMyInterface) 409 421 </pre> 410 422 411 <p>Now if you want to make this class inherit from <code>pb.Root</code>,412 the interfaces code will automatically determine that it also implements 413 <code>IPBRoot</code>:</p>423 <p>Now if you want to make this class inherit 424 from <code>pb.Root</code>, the interfaces code will automatically 425 determine that it also implements <code>IPBRoot</code>:</p> 414 426 415 427 <pre class="python"> 416 428 from twisted.spread import pb … … 429 441 True 430 442 </pre> 431 443 432 <p>If you want <code>MyThing</code> to inherit from <code>pb.Root</code> but 433 <em>not</em> implement <code>IPBRoot</code> like <code>pb.Root</code> does, 444 <p>If you want <code>MyThing</code> to inherit 445 from <code>pb.Root</code> but <em>not</em> 446 implement <code>IPBRoot</code> like <code>pb.Root</code> does, 434 447 use <code>implementOnly</code>:</p> 435 448 436 449 <pre class="python"> -
doc/core/howto/cred.xhtml
diff --git a/doc/core/howto/cred.xhtml b/doc/core/howto/cred.xhtml index f16080b..dae222b 100644
a b 65 65 <ul> 66 66 <li><code class="API" base="twisted.cred.portal.Portal">login</code><code>(credentials, mind, *interfaces)</code> 67 67 68 <p>The docstring is quite expansive (see <code class="API">twisted.cred.portal</code>), but in 69 brief, this is what you call when you need to call in order to connect 70 a user to the system. Typically you only pass in one interface, and the mind is 71 <code class="python">None</code>. The interfaces are the possible interfaces the returned 72 avatar is expected to implement, in order of preference. 73 The result is a deferred which fires a tuple of:</p> 68 <p>The docstring is quite expansive 69 (see <code class="API">twisted.cred.portal</code>), but in brief, this 70 is what you call when you need to call in order to connect a user to 71 the system. Typically you only pass in one interface, and the mind 72 is <code class="python">None</code>. The interfaces are the possible 73 interfaces the returned avatar is expected to implement, in order of 74 preference. The result is a deferred which fires a tuple of:</p> 74 75 <ul> 75 76 <li>interface the avatar implements (which was one of the interfaces passed in the *interfaces 76 77 tuple)</li> … … 343 344 344 345 <h3>Building a cred plugin</h3> 345 346 346 <p> To build a plugin for cred, you should first define an <code347 class="python">authType</code>, a short one-word string that defines 348 your plugin to the command-line. Once you have this, the convention is 349 to create a file named <code>myapp_plugins.py</code> in the 350 <code class="API">twisted.plugins</code> module path. </p>347 <p> To build a plugin for cred, you should first define 348 an <code class="python">authType</code>, a short one-word string that 349 defines your plugin to the command-line. Once you have this, the 350 convention is to create a file named <code>myapp_plugins.py</code> in 351 the <code class="API">twisted.plugins</code> module path. </p> 351 352 352 353 <p> Below is an example file structure for an application that defines 353 354 such a plugin: </p>
