pytho****@googl*****
pytho****@googl*****
2011年 3月 20日 (日) 04:35:41 JST
Revision: 81e674add80d Author: Naoki INADA <inada****@klab*****> Date: Sat Mar 19 08:45:35 2011 Log: Add howto/diff http://code.google.com/p/python-doc-ja/source/detail?r=81e674add80d Added: /howto/diff/cporting.rst.diff /howto/diff/cporting.rst.html /howto/diff/curses.rst.diff /howto/diff/curses.rst.html /howto/diff/doanddont.rst.diff /howto/diff/doanddont.rst.html /howto/diff/functional.rst.diff /howto/diff/functional.rst.html /howto/diff/index.rst.diff /howto/diff/index.rst.html /howto/diff/regex.rst.diff /howto/diff/regex.rst.html /howto/diff/sockets.rst.diff /howto/diff/sockets.rst.html /howto/diff/unicode.rst.diff /howto/diff/unicode.rst.html /howto/diff/urllib2.rst.diff /howto/diff/urllib2.rst.html /howto/diff/webservers.rst.diff /howto/diff/webservers.rst.html ======================================= --- /dev/null +++ /howto/diff/cporting.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,29 @@ +--- r262/howto/cporting.rst 2009-04-04 06:56:36.770670000 +0900 ++++ r266/howto/cporting.rst 2010-05-14 23:30:11.711058000 +0900 +@@ -109,25 +109,25 @@ + + if (!PyArg_ParseTuple(args, "ii:add_ints", &one, &two)) + return NULL; + + return PyInt_FromLong(one + two); + } + + + + Module initialization and state + =============================== + +-Python 3.0 has a revamped extension module initialization system. (See PEP ++Python 3.0 has a revamped extension module initialization system. (See + :pep:`3121`.) Instead of storing module state in globals, they should be stored + in an interpreter specific structure. Creating modules that act correctly in + both 2.x and 3.0 is tricky. The following simple example demonstrates how. :: + + #include "Python.h" + + struct module_state { + PyObject *error; + }; + + #if PY_MAJOR_VERSION >= 3 + #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) ======================================= --- /dev/null +++ /howto/diff/cporting.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,50 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to46__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/cporting.rst => r266/howto/cporting.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to46__0"></td><td class="diff_header" id="from46_113">113</td><td nowrap="nowrap"> return PyInt_FromLong(one + two);</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_114">114</td><td nowrap="nowrap"> }</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_115">115</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_116">116</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_117">117</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_118">118</td><td nowrap="nowrap">Module initialization and state</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_119">119</td><td nowrap="nowrap">===============================</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_120">120</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to46__top">t</a></td><td class="diff_header" id="from46_121">121-</td><td nowrap="nowrap">Python 3.0 has a revamped extension module initialization system. (See<span class="diff_sub"> PEP</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to46__top">t</a></td><td class="diff_header" id="to46_121">121+</td><td nowrap="nowrap">Python 3.0 has a revamped extension module initialization system. (See</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from46_122">122</td><td nowrap="nowrap">:pep:`3121`.) Instead of storing module state in globals, they should be stored</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_123">123</td><td nowrap="nowrap">in an interpreter specific structure. Creating modules that act correctly in</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_124">124</td><td nowrap="nowrap">both 2.x and 3.0 is tricky. The following simple example demonstrates how. ::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_125">125</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_126">126</td><td nowrap="nowrap"> #include "Python.h"</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_127">127</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_128">128</td><td nowrap="nowrap"> struct module_state {</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from46_129">129</td><td nowrap="nowrap"> PyObject *error;</td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html> ======================================= --- /dev/null +++ /howto/diff/curses.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,24 @@ +--- r262/howto/curses.rst 2009-01-04 06:55:17.853888000 +0900 ++++ r266/howto/curses.rst 2009-10-27 22:44:06.332664000 +0900 +@@ -417,20 +417,20 @@ + capturing mouse events from an xterm instance. But the Python library page for + the curses modules is now pretty complete. You should browse it next. + + If you're in doubt about the detailed behavior of any of the ncurses entry + points, consult the manual pages for your curses implementation, whether it's + ncurses or a proprietary Unix vendor's. The manual pages will document any + quirks, and provide complete lists of all the functions, attributes, and + :const:`ACS_\*` characters available to you. + + Because the curses API is so large, some functions aren't supported in the + Python interface, not because they're difficult to implement, but because no one + has needed them yet. Feel free to add them and then submit a patch. Also, we +-don't yet have support for the menus or panels libraries associated with ++don't yet have support for the menu library associated with + ncurses; feel free to add that. + + If you write an interesting little program, feel free to contribute it as + another demo. We can always use more of them! + + The ncurses FAQ: http://invisible-island.net/ncurses/ncurses.faq.html + ======================================= --- /dev/null +++ /howto/diff/curses.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,50 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to47__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/curses.rst => r266/howto/curses.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to47__0"></td><td class="diff_header" id="from47_421">421</td><td nowrap="nowrap">points, consult the manual pages for your curses implementation, whether it's</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_422">422</td><td nowrap="nowrap">ncurses or a proprietary Unix vendor's. The manual pages will document any</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_423">423</td><td nowrap="nowrap">quirks, and provide complete lists of all the functions, attributes, and</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_424">424</td><td nowrap="nowrap">:const:`ACS_\*` characters available to you.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_425">425</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_426">426</td><td nowrap="nowrap">Because the curses API is so large, some functions aren't supported in the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_427">427</td><td nowrap="nowrap">Python interface, not because they're difficult to implement, but because no one</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_428">428</td><td nowrap="nowrap">has needed them yet. Feel free to add them and then submit a patch. Also, we</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to47__top">t</a></td><td class="diff_header" id="from47_429">429-</td><td nowrap="nowrap">don't yet have support for the menu<span class="diff_sub">s or panels</span> librar<span class="diff_chg">ies</span> associated with</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to47__top">t</a></td><td class="diff_header" id="to47_429">429+</td><td nowrap="nowrap">don't yet have support for the menu librar<span class="diff_chg">y</span> associated with</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from47_430">430</td><td nowrap="nowrap">ncurses; feel free to add that.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_431">431</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_432">432</td><td nowrap="nowrap">If you write an interesting little program, feel free to contribute it as</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_433">433</td><td nowrap="nowrap">another demo. We can always use more of them!</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_434">434</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_435">435</td><td nowrap="nowrap">The ncurses FAQ: http://invisible-island.net/ncurses/ncurses.faq.html</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from47_436">436</td><td nowrap="nowrap"></td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html> ======================================= --- /dev/null +++ /howto/diff/doanddont.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,168 @@ +--- r262/howto/doanddont.rst 2009-01-04 06:55:17.853888000 +0900 ++++ r266/howto/doanddont.rst 2010-04-25 19:18:59.875456000 +0900 +@@ -21,50 +21,50 @@ + dangerous. + + + from module import \* + --------------------- + + + Inside Function Definitions + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ``from module import *`` is *invalid* inside function definitions. While many + versions of Python do not check for the invalidity, it does not make it more +-valid, no more then having a smart lawyer makes a man innocent. Do not use it ++valid, no more than having a smart lawyer makes a man innocent. Do not use it + like that ever. Even in versions where it was accepted, it made the function + execution slower, because the compiler could not be certain which names are + local and which are global. In Python 2.1 this construct causes warnings, and + sometimes even errors. + + + At Module Level + ^^^^^^^^^^^^^^^ + + While it is valid to use ``from module import *`` at module level it is usually + a bad idea. For one, this loses an important property Python otherwise has --- + you can know where each toplevel name is defined by a simple "search" function + in your favourite editor. You also open yourself to trouble in the future, if + some module grows additional functions or classes. + + One of the most awful question asked on the newsgroup is why this code:: + + f = open("www") + f.read() + + does not work. Of course, it works just fine (assuming you have a file called +-"www".) But it does not work if somewhere in the module, the statement ``from os +-import *`` is present. The :mod:`os` module has a function called :func:`open` +-which returns an integer. While it is very useful, shadowing builtins is one of +-its least useful properties. ++"www".) But it does not work if somewhere in the module, the statement ``from ++os import *`` is present. The :mod:`os` module has a function called ++:func:`open` which returns an integer. While it is very useful, shadowing a ++builtin is one of its least useful properties. + + Remember, you can never know for sure what names a module exports, so either + take what you need --- ``from module import name1, name2``, or keep them in the + module and access on a per-need basis --- ``import module;print module.name``. + + + When It Is Just Fine + ^^^^^^^^^^^^^^^^^^^^ + + There are situations in which ``from module import *`` is just fine: + + * The interactive prompt. For example, ``from math import *`` makes Python an +@@ -102,25 +102,25 @@ + >>> def func(s, **kw): + >>> for var, val in kw.items(): + >>> setattr(s, var, val) + >>> d={} + >>> execfile("handle.py", d, d) + >>> handle = d['handle'] + >>> handle() + + + from module import name1, name2 + ------------------------------- + +-This is a "don't" which is much weaker then the previous "don't"s but is still ++This is a "don't" which is much weaker than the previous "don't"s but is still + something you should not do if you don't have good reasons to do that. The + reason it is usually bad idea is because you suddenly have an object which lives + in two separate namespaces. When the binding in one namespace changes, the + binding in the other will not, so there will be a discrepancy between them. This + happens when, for example, one module is reloaded, or changes the definition of + a function at runtime. + + Bad example:: + + # foo.py + a = 1 + +@@ -223,77 +223,74 @@ + def get_status(file): + return open(file).readline() + + The caller can deal with the exception if it wants (for example, if it tries + several files in a loop), or just let the exception filter upwards to *its* + caller. + + The last version is not very good either --- due to implementation details, the + file would not be closed when an exception is raised until the handler finishes, + and perhaps not at all in non-C implementations (e.g., Jython). :: + + def get_status(file): +- fp = open(file) +- try: ++ with open(file) as fp: + return fp.readline() +- finally: +- fp.close() + + + Using the Batteries + =================== + + Every so often, people seem to be writing stuff in the Python library again, + usually poorly. While the occasional module has a poor interface, it is usually + much better to use the rich standard library and data types that come with +-Python then inventing your own. ++Python than inventing your own. + + A useful module very few people know about is :mod:`os.path`. It always has the + correct path arithmetic for your operating system, and will usually be much +-better then whatever you come up with yourself. ++better than whatever you come up with yourself. + + Compare:: + + # ugh! + return dir+"/"+file + # better + return os.path.join(dir, file) + + More useful functions in :mod:`os.path`: :func:`basename`, :func:`dirname` and + :func:`splitext`. + +-There are also many useful builtin functions people seem not to be aware of for ++There are also many useful built-in functions people seem not to be aware of for + some reason: :func:`min` and :func:`max` can find the minimum/maximum of any + sequence with comparable semantics, for example, yet many people write their own + :func:`max`/:func:`min`. Another highly useful function is :func:`reduce`. A + classical use of :func:`reduce` is something like :: + + import sys, operator + nums = map(float, sys.argv[1:]) + print reduce(operator.add, nums)/len(nums) + + This cute little script prints the average of all numbers given on the command + line. The :func:`reduce` adds up all the numbers, and the rest is just some + pre- and postprocessing. + + On the same note, note that :func:`float`, :func:`int` and :func:`long` all + accept arguments of type string, and so are suited to parsing --- assuming you + are ready to deal with the :exc:`ValueError` they raise. + + + Using Backslash to Continue Statements + ====================================== + + Since Python treats a newline as a statement terminator, and since statements +-are often more then is comfortable to put in one line, many people do:: ++are often more than is comfortable to put in one line, many people do:: + + if foo.bar()['first'][0] == baz.quux(1, 2)[5:9] and \ + calculate_number(10, 20) != forbulate(500, 360): + pass + + You should realize that this is dangerous: a stray space after the ``\`` would + make this line wrong, and stray spaces are notoriously hard to see in editors. + In this case, at least it would be a syntax error, but if the code was:: + + value = foo.bar()['first'][0]*baz.quux(1, 2)[5:9] \ + + calculate_number(10, 20)*forbulate(500, 360) + ======================================= --- /dev/null +++ /howto/diff/doanddont.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,81 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to48__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/doanddont.rst => r266/howto/doanddont.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to48__0"></td><td class="diff_header" id="from48_25">25</td><td nowrap="nowrap">---------------------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_26">26</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_27">27</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_28">28</td><td nowrap="nowrap">Inside Function Definitions</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_29">29</td><td nowrap="nowrap">^^^^^^^^^^^^^^^^^^^^^^^^^^^</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_30">30</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_31">31</td><td nowrap="nowrap">``from module import *`` is *invalid* inside function definitions. While many</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_32">32</td><td nowrap="nowrap">versions of Python do not check for the invalidity, it does not make it more</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to48__1">n</a></td><td class="diff_header" id="from48_33">33-</td><td nowrap="nowrap">valid, no more th<span class="diff_chg">e</span>n having a smart lawyer makes a man innocent. Do not use it</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to48__1">n</a></td><td class="diff_header" id="to48_33">33+</td><td nowrap="nowrap">valid, no more th<span class="diff_chg">a</span>n having a smart lawyer makes a man innocent. Do not use it</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from48_34">34</td><td nowrap="nowrap">like that ever. Even in versions where it was accepted, it made the function</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_35">35</td><td nowrap="nowrap">execution slower, because the compiler could not be certain which names are</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_36">36</td><td nowrap="nowrap">local and which are global. In Python 2.1 this construct causes warnings, and</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_37">37</td><td nowrap="nowrap">sometimes even errors.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_38">38</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_39">39</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_40">40</td><td nowrap="nowrap">At Module Level</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_41">41</td><td nowrap="nowrap">^^^^^^^^^^^^^^^</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to48__1"></td><td class="diff_header" id="from48_47">47</td><td nowrap="nowrap">some module grows additional functions or classes.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_48">48</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_49">49</td><td nowrap="nowrap">One of the most awful question asked on the newsgroup is why this code::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_50">50</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_51">51</td><td nowrap="nowrap"> f = open("www")</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_52">52</td><td nowrap="nowrap"> f.read()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_53">53</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_54">54</td><td nowrap="nowrap">does not work. Of course, it works just fine (assuming you have a file called</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to48__2">n</a></td><td class="diff_header" id="from48_55">55-</td><td nowrap="nowrap">"www".) But it does not work if somewhere in the module, the statement ``from<span class="diff_sub"> os</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to48__2">n</a></td><td class="diff_header" id="to48_55">55+</td><td nowrap="nowrap">"www".) But it does not work if somewhere in the module, the statement ``from</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from48_56">56-</td><td nowrap="nowrap">import *`` is present. The :mod:`os` module has a function called<span class="diff_sub"> :func:`open`</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to48_56">56+</td><td nowrap="nowrap"><span class="diff_add">os </span>import *`` is present. The :mod:`os` module has a function called</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from48_57">57-</td><td nowrap="nowrap">which returns an integer. While it is very useful, shadowing <span class="diff_chg">builtins is one of</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to48_57">57+</td><td nowrap="nowrap"><span class="diff_add">:func:`open` </span>which returns an integer. While it is very useful, shadowing <span class="diff_chg">a</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from48_58">58-</td><td nowrap="nowrap">its least useful properties.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to48_58">58+</td><td nowrap="nowrap"><span class="diff_add">builtin is one of </span>its least useful properties.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from48_59">59</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_60">60</td><td nowrap="nowrap">Remember, you can never know for sure what names a module exports, so either</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_61">61</td><td nowrap="nowrap">take what you need --- ``from module import name1, name2``, or keep them in the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_62">62</td><td nowrap="nowrap">module and access on a per-need basis --- ``import module;print module.name``.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_63">63</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_64">64</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_65">65</td><td nowrap="nowrap">When It Is Just Fine</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_66">66</td><td nowrap="nowrap">^^^^^^^^^^^^^^^^^^^^</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to48__2"></td><td class="diff_header" id="from48_106">106</td><td nowrap="nowrap"> >>> execfile("handle.py", d, d)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_107">107</td><td nowrap="nowrap"> >>> handle = d['handle']</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_108">108</td><td nowrap="nowrap"> >>> handle()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_109">109</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_110">110</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_111">111</td><td nowrap="nowrap">from module import name1, name2</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_112">112</td><td nowrap="nowrap">-------------------------------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_113">113</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to48__3">n</a></td><td class="diff_header" id="from48_114">114-</td><td nowrap="nowrap">This is a "don't" which is much weaker the<span class="diff_sub">n the</span> previous "don't"s but is still</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to48__3">n</a></td><td class="diff_header" id="to48_114">114+</td><td nowrap="nowrap">This is a "don't" which is much weaker <span class="diff_add">than </span>the previous "don't"s but is still</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from48_115">115</td><td nowrap="nowrap">something you should not do if you don't have good reasons to do that. The</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_116">116</td><td nowrap="nowrap">reason it is usually bad idea is because you suddenly have an object which lives</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_117">117</td><td nowrap="nowrap">in two separate namespaces. When the binding in one namespace changes, the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_118">118</td><td nowrap="nowrap">binding in the other will not, so there will be a discrepancy between them. This</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_119">119</td><td nowrap="nowrap">happens when, for example, one module is reloaded, or changes the definition of</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_120">120</td><td nowrap="nowrap">a function at runtime.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_121">121</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_122">122</td><td nowrap="nowrap">Bad example::</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to48__3"></td><td class="diff_header" id="from48_227">227</td><td nowrap="nowrap">several files in a loop), or just let the exception filter upwards to *its*</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_228">228</td><td nowrap="nowrap">caller.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_229">229</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to48__4"></td><td class="diff_header" id="from48_230">230</td><td nowrap="nowrap">The last version is not very good either --- due to implementation details, the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_231">231</td><td nowrap="nowrap">file would not be closed when an exception is raised until the handler finishes,</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_232">232</td><td nowrap="nowrap">and perhaps not at all in non-C implementations (e.g., Jython). ::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_233">233</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_234">234</td><td nowrap="nowrap"> def get_status(file):</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to48__4">n</a></td><td class="diff_header" id="from48_235">235-</td><td nowrap="nowrap"><span class="diff_sub"> fp = open(file)</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to48__4">n</a></td><td class="diff_header" id="to48_235">235+</td><td nowrap="nowrap"><span class="diff_add"> with open(file) as fp:</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from48_236">236-</td><td nowrap="nowrap"><span class="diff_sub"> try:</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from48_237">237</td><td nowrap="nowrap"> return fp.readline()</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to48__5">n</a></td><td class="diff_header" id="from48_238">238-</td><td nowrap="nowrap"><span class="diff_sub"> finally:</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from48_239">239-</td><td nowrap="nowrap"><span class="diff_sub"> fp.close()</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to48__5"></td><td class="diff_header" id="from48_240">240</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_241">241</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_242">242</td><td nowrap="nowrap">Using the Batteries</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_243">243</td><td nowrap="nowrap">===================</td></tr> <tr><td class="diff_next" id="difflib_chg_to48__6"></td><td class="diff_header" id="from48_244">244</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_245">245</td><td nowrap="nowrap">Every so often, people seem to be writing stuff in the Python library again,</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_246">246</td><td nowrap="nowrap">usually poorly. While the occasional module has a poor interface, it is usually</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_247">247</td><td nowrap="nowrap">much better to use the rich standard library and data types that come with</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to48__6">n</a></td><td class="diff_header" id="from48_248">248-</td><td nowrap="nowrap">Python th<span class="diff_chg">e</span>n inventing your own.</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to48__6">n</a></td><td class="diff_header" id="to48_245">245+</td><td nowrap="nowrap">Python th<span class="diff_chg">a</span>n inventing your own.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from48_249">249</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_250">250</td><td nowrap="nowrap">A useful module very few people know about is :mod:`os.path`. It always has the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_251">251</td><td nowrap="nowrap">correct path arithmetic for your operating system, and will usually be much</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to48__7">n</a></td><td class="diff_header" id="from48_252">252-</td><td nowrap="nowrap">better th<span class="diff_chg">e</span>n whatever you come up with yourself.</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to48__7">n</a></td><td class="diff_header" id="to48_249">249+</td><td nowrap="nowrap">better th<span class="diff_chg">a</span>n whatever you come up with yourself.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from48_253">253</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_254">254</td><td nowrap="nowrap">Compare::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_255">255</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to48__7"></td><td class="diff_header" id="from48_256">256</td><td nowrap="nowrap"> # ugh!</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_257">257</td><td nowrap="nowrap"> return dir+"/"+file</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_258">258</td><td nowrap="nowrap"> # better</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_259">259</td><td nowrap="nowrap"> return os.path.join(dir, file)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_260">260</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_261">261</td><td nowrap="nowrap">More useful functions in :mod:`os.path`: :func:`basename`, :func:`dirname` and</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_262">262</td><td nowrap="nowrap">:func:`splitext`.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_263">263</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to48__8">n</a></td><td class="diff_header" id="from48_264">264-</td><td nowrap="nowrap">There are also many useful builtin functions people seem not to be aware of for</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to48__8">n</a></td><td class="diff_header" id="to48_261">261+</td><td nowrap="nowrap">There are also many useful built<span class="diff_add">-</span>in functions people seem not to be aware of for</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from48_265">265</td><td nowrap="nowrap">some reason: :func:`min` and :func:`max` can find the minimum/maximum of any</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_266">266</td><td nowrap="nowrap">sequence with comparable semantics, for example, yet many people write their own</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_267">267</td><td nowrap="nowrap">:func:`max`/:func:`min`. Another highly useful function is :func:`reduce`. A</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_268">268</td><td nowrap="nowrap">classical use of :func:`reduce` is something like ::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_269">269</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_270">270</td><td nowrap="nowrap"> import sys, operator</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_271">271</td><td nowrap="nowrap"> nums = map(float, sys.argv[1:])</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_272">272</td><td nowrap="nowrap"> print reduce(operator.add, nums)/len(nums)</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to48__8"></td><td class="diff_header" id="from48_279">279</td><td nowrap="nowrap">accept arguments of type string, and so are suited to parsing --- assuming you</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_280">280</td><td nowrap="nowrap">are ready to deal with the :exc:`ValueError` they raise.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_281">281</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_282">282</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_283">283</td><td nowrap="nowrap">Using Backslash to Continue Statements</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_284">284</td><td nowrap="nowrap">======================================</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_285">285</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_286">286</td><td nowrap="nowrap">Since Python treats a newline as a statement terminator, and since statements</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to48__top">t</a></td><td class="diff_header" id="from48_287">287-</td><td nowrap="nowrap">are often more th<span class="diff_chg">e</span>n is comfortable to put in one line, many people do::</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to48__top">t</a></td><td class="diff_header" id="to48_284">284+</td><td nowrap="nowrap">are often more th<span class="diff_chg">a</span>n is comfortable to put in one line, many people do::</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from48_288">288</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_289">289</td><td nowrap="nowrap"> if foo.bar()['first'][0] == baz.quux(1, 2)[5:9] and \</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_290">290</td><td nowrap="nowrap"> calculate_number(10, 20) != forbulate(500, 360):</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_291">291</td><td nowrap="nowrap"> pass</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_292">292</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_293">293</td><td nowrap="nowrap">You should realize that this is dangerous: a stray space after the ``\`` would</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_294">294</td><td nowrap="nowrap">make this line wrong, and stray spaces are notoriously hard to see in editors.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from48_295">295</td><td nowrap="nowrap">In this case, at least it would be a syntax error, but if the code was::</td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html> ======================================= --- /dev/null +++ /howto/diff/functional.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,56 @@ +--- r262/howto/functional.rst 2009-01-04 06:55:17.853888000 +0900 ++++ r266/howto/functional.rst 2010-04-05 21:55:05.908767000 +0900 +@@ -326,25 +326,25 @@ + + Generator expressions and list comprehensions + ============================================= + + Two common operations on an iterator's output are 1) performing some operation + for every element, 2) selecting a subset of elements that meet some condition. + For example, given a list of strings, you might want to strip off trailing + whitespace from each line or extract all the strings containing a given + substring. + + List comprehensions and generator expressions (short form: "listcomps" and + "genexps") are a concise notation for such operations, borrowed from the +-functional programming language Haskell (http://www.haskell.org). You can strip ++functional programming language Haskell (http://www.haskell.org/). You can strip + all the whitespace from a stream of strings with the following code:: + + line_list = [' line 1\n', 'line 2 \n', ...] + + # Generator expression -- returns iterator + stripped_iter = (line.strip() for line in line_list) + + # List comprehension -- returns list + stripped_list = [line.strip() for line in line_list] + + You can select only certain elements by adding an ``"if"`` condition:: + +@@ -463,25 +463,25 @@ + When you call a generator function, it doesn't return a single value; instead it + returns a generator object that supports the iterator protocol. On executing + the ``yield`` expression, the generator outputs the value of ``i``, similar to a + ``return`` statement. The big difference between ``yield`` and a ``return`` + statement is that on reaching a ``yield`` the generator's state of execution is + suspended and local variables are preserved. On the next call to the + generator's ``.next()`` method, the function will resume executing. + + Here's a sample usage of the ``generate_ints()`` generator: + + >>> gen = generate_ints(3) + >>> gen +- <generator object at ...> ++ <generator object generate_ints at ...> + >>> gen.next() + 0 + >>> gen.next() + 1 + >>> gen.next() + 2 + >>> gen.next() + Traceback (most recent call last): + File "stdin", line 1, in ? + File "stdin", line 2, in generate_ints + StopIteration + ======================================= --- /dev/null +++ /howto/diff/functional.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,54 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to49__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/functional.rst => r266/howto/functional.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to49__0"></td><td class="diff_header" id="from49_330">330</td><td nowrap="nowrap">Two common operations on an iterator's output are 1) performing some operation</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_331">331</td><td nowrap="nowrap">for every element, 2) selecting a subset of elements that meet some condition.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_332">332</td><td nowrap="nowrap">For example, given a list of strings, you might want to strip off trailing</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_333">333</td><td nowrap="nowrap">whitespace from each line or extract all the strings containing a given</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_334">334</td><td nowrap="nowrap">substring.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_335">335</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_336">336</td><td nowrap="nowrap">List comprehensions and generator expressions (short form: "listcomps" and</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_337">337</td><td nowrap="nowrap">"genexps") are a concise notation for such operations, borrowed from the</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to49__1">n</a></td><td class="diff_header" id="from49_338">338-</td><td nowrap="nowrap">functional programming language Haskell (http://www.haskell.org). You can strip</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to49__1">n</a></td><td class="diff_header" id="to49_338">338+</td><td nowrap="nowrap">functional programming language Haskell (http://www.haskell.org<span class="diff_add">/</span>). You can strip</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from49_339">339</td><td nowrap="nowrap">all the whitespace from a stream of strings with the following code::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_340">340</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_341">341</td><td nowrap="nowrap"> line_list = [' line 1\n', 'line 2 \n', ...]</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_342">342</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_343">343</td><td nowrap="nowrap"> # Generator expression -- returns iterator</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_344">344</td><td nowrap="nowrap"> stripped_iter = (line.strip() for line in line_list)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_345">345</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_346">346</td><td nowrap="nowrap"> # List comprehension -- returns list</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to49__1"></td><td class="diff_header" id="from49_467">467</td><td nowrap="nowrap">statement is that on reaching a ``yield`` the generator's state of execution is</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_468">468</td><td nowrap="nowrap">suspended and local variables are preserved. On the next call to the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_469">469</td><td nowrap="nowrap">generator's ``.next()`` method, the function will resume executing.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_470">470</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_471">471</td><td nowrap="nowrap">Here's a sample usage of the ``generate_ints()`` generator:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_472">472</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_473">473</td><td nowrap="nowrap"> >>> gen = generate_ints(3)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_474">474</td><td nowrap="nowrap"> >>> gen</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to49__top">t</a></td><td class="diff_header" id="from49_475">475-</td><td nowrap="nowrap"> <generator object at ...></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to49__top">t</a></td><td class="diff_header" id="to49_475">475+</td><td nowrap="nowrap"> <generator object <span class="diff_add">gener</span>at<span class="diff_add">e_ints at</span> ...></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from49_476">476</td><td nowrap="nowrap"> >>> gen.next()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_477">477</td><td nowrap="nowrap"> 0</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_478">478</td><td nowrap="nowrap"> >>> gen.next()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_479">479</td><td nowrap="nowrap"> 1</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_480">480</td><td nowrap="nowrap"> >>> gen.next()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_481">481</td><td nowrap="nowrap"> 2</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_482">482</td><td nowrap="nowrap"> >>> gen.next()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from49_483">483</td><td nowrap="nowrap"> Traceback (most recent call last):</td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html> ======================================= --- /dev/null +++ /howto/diff/index.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,25 @@ +--- r262/howto/index.rst 2008-09-26 11:58:36.001088000 +0900 ++++ r266/howto/index.rst 2010-04-11 17:17:32.454948000 +0900 +@@ -7,20 +7,22 @@ + Documentation Project's HOWTO collection, this collection is an + effort to foster documentation that's more detailed than the + Python Library Reference. + + Currently, the HOWTOs are: + + .. toctree:: + :maxdepth: 1 + + advocacy.rst + cporting.rst + curses.rst ++ descriptor.rst + doanddont.rst + functional.rst + regex.rst + sockets.rst ++ sorting.rst + unicode.rst + urllib2.rst + webservers.rst + ======================================= --- /dev/null +++ /howto/diff/index.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,50 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to50__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/index.rst => r266/howto/index.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to50__0"></td><td class="diff_header" id="from50_11">11</td><td nowrap="nowrap">Currently, the HOWTOs are:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_12">12</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_13">13</td><td nowrap="nowrap">.. toctree::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_14">14</td><td nowrap="nowrap"> :maxdepth: 1</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_15">15</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to50__1"></td><td class="diff_header" id="from50_16">16</td><td nowrap="nowrap"> advocacy.rst</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_17">17</td><td nowrap="nowrap"> cporting.rst</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_18">18</td><td nowrap="nowrap"> curses.rst</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to50__1">n</a></td><td class="diff_header" id="to50_19">19+</td><td nowrap="nowrap"><span class="diff_add"> descriptor.rst</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from50_19">19</td><td nowrap="nowrap"> doanddont.rst</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_20">20</td><td nowrap="nowrap"> functional.rst</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_21">21</td><td nowrap="nowrap"> regex.rst</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_22">22</td><td nowrap="nowrap"> sockets.rst</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to50__top">t</a></td><td class="diff_header" id="to50_24">24+</td><td nowrap="nowrap"><span class="diff_add"> sorting.rst</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from50_23">23</td><td nowrap="nowrap"> unicode.rst</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_24">24</td><td nowrap="nowrap"> urllib2.rst</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_25">25</td><td nowrap="nowrap"> webservers.rst</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from50_26">26</td><td nowrap="nowrap"></td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html> ======================================= --- /dev/null +++ /howto/diff/regex.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,242 @@ +--- r262/howto/regex.rst 2009-04-06 09:24:29.561602000 +0900 ++++ r266/howto/regex.rst 2009-10-27 23:19:50.039185000 +0900 +@@ -248,32 +248,32 @@ + Using Regular Expressions + ========================= + + Now that we've looked at some simple regular expressions, how do we actually use + them in Python? The :mod:`re` module provides an interface to the regular + expression engine, allowing you to compile REs into objects and then perform + matches with them. + + + Compiling Regular Expressions + ----------------------------- + +-Regular expressions are compiled into :class:`RegexObject` instances, which have ++Regular expressions are compiled into pattern objects, which have + methods for various operations such as searching for pattern matches or + performing string substitutions. :: + + >>> import re + >>> p = re.compile('ab*') + >>> print p +- <re.RegexObject instance at 80b4150> ++ <_sre.SRE_Pattern object at 80b4150> + + :func:`re.compile` also accepts an optional *flags* argument, used to enable + various special features and syntax variations. We'll go over the available + settings later, but for now a single example will do:: + + >>> p = re.compile('ab*', re.IGNORECASE) + + The RE is passed to :func:`re.compile` as a string. REs are handled as strings + because regular expressions aren't part of the core Python language, and no + special syntax was created for expressing them. (There are applications that + don't need REs at all, so there's no need to bloat the language specification by + including them.) Instead, the :mod:`re` module is simply a C extension module +@@ -327,25 +327,25 @@ + | ``"ab*"`` | ``r"ab*"`` | + +-------------------+------------------+ + | ``"\\\\section"`` | ``r"\\section"`` | + +-------------------+------------------+ + | ``"\\w+\\s+\\1"`` | ``r"\w+\s+\1"`` | + +-------------------+------------------+ + + + Performing Matches + ------------------ + + Once you have an object representing a compiled regular expression, what do you +-do with it? :class:`RegexObject` instances have several methods and attributes. ++do with it? Pattern objects have several methods and attributes. + Only the most significant ones will be covered here; consult the :mod:`re` docs + for a complete listing. + + +------------------+-----------------------------------------------+ + | Method/Attribute | Purpose | + +==================+===============================================+ + | ``match()`` | Determine if the RE matches at the beginning | + | | of the string. | + +------------------+-----------------------------------------------+ + | ``search()`` | Scan through a string, looking for any | + | | location where this RE matches. | + +------------------+-----------------------------------------------+ +@@ -418,90 +418,90 @@ + + >>> m.group() + 'tempo' + >>> m.start(), m.end() + (0, 5) + >>> m.span() + (0, 5) + + :meth:`group` returns the substring that was matched by the RE. :meth:`start` + and :meth:`end` return the starting and ending index of the match. :meth:`span` + returns both start and end indexes in a single tuple. Since the :meth:`match` + method only checks if the RE matches at the start of a string, :meth:`start` +-will always be zero. However, the :meth:`search` method of :class:`RegexObject` +-instances scans through the string, so the match may not start at zero in that ++will always be zero. However, the :meth:`search` method of patterns ++scans through the string, so the match may not start at zero in that + case. :: + + >>> print p.match('::: message') + None + >>> m = p.search('::: message') ; print m + <re.MatchObject instance at 80c9650> + >>> m.group() + 'message' + >>> m.span() + (4, 11) + + In actual programs, the most common style is to store the :class:`MatchObject` + in a variable, and then check if it was ``None``. This usually looks like:: + + p = re.compile( ... ) + m = p.match( 'string goes here' ) + if m: + print 'Match found: ', m.group() + else: + print 'No match' + +-Two :class:`RegexObject` methods return all of the matches for a pattern. ++Two pattern methods return all of the matches for a pattern. + :meth:`findall` returns a list of matching strings:: + + >>> p = re.compile('\d+') + >>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping') + ['12', '11', '10'] + + :meth:`findall` has to create the entire list before it can be returned as the + result. The :meth:`finditer` method returns a sequence of :class:`MatchObject` + instances as an :term:`iterator`. [#]_ :: + + >>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...') + >>> iterator + <callable-iterator object at 0x401833ac> + >>> for match in iterator: + ... print match.span() + ... + (0, 2) + (22, 24) + (29, 31) + + + Module-Level Functions + ---------------------- + +-You don't have to create a :class:`RegexObject` and call its methods; the ++You don't have to create a pattern object and call its methods; the + :mod:`re` module also provides top-level functions called :func:`match`, + :func:`search`, :func:`findall`, :func:`sub`, and so forth. These functions +-take the same arguments as the corresponding :class:`RegexObject` method, with ++take the same arguments as the corresponding pattern method, with + the RE string added as the first argument, and still return either ``None`` or a + :class:`MatchObject` instance. :: + + >>> print re.match(r'From\s+', 'Fromage amk') + None + >>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998') + <re.MatchObject instance at 80c5978> + +-Under the hood, these functions simply produce a :class:`RegexObject` for you ++Under the hood, these functions simply create a pattern object for you + and call the appropriate method on it. They also store the compiled object in a + cache, so future calls using the same RE are faster. + + Should you use these module-level functions, or should you get the +-:class:`RegexObject` and call its methods yourself? That choice depends on how ++pattern and call its methods yourself? That choice depends on how + frequently the RE will be used, and on your personal coding style. If the RE is + being used at only one point in the code, then the module functions are probably + more convenient. If a program contains a lot of regular expressions, or re-uses + the same ones in several locations, then it might be worthwhile to collect all + the definitions in one place, in a section of code that compiles all the REs + ahead of time. To take an example from the standard library, here's an extract + from :file:`xmllib.py`:: + + ref = re.compile( ... ) + entityref = re.compile( ... ) + charref = re.compile( ... ) + starttagopen = re.compile( ... ) +@@ -1021,45 +1021,45 @@ + Excluding another filename extension is now easy; simply add it as an + alternative inside the assertion. The following pattern excludes filenames that + end in either ``bat`` or ``exe``: + + ``.*[.](?!bat$|exe$).*$`` + + + Modifying Strings + ================= + + Up to this point, we've simply performed searches against a static string. + Regular expressions are also commonly used to modify strings in various ways, +-using the following :class:`RegexObject` methods: ++using the following pattern methods: + + +------------------+-----------------------------------------------+ + | Method/Attribute | Purpose | + +==================+===============================================+ + | ``split()`` | Split the string into a list, splitting it | + | | wherever the RE matches | + +------------------+-----------------------------------------------+ + | ``sub()`` | Find all substrings where the RE matches, and | + | | replace them with a different string | + +------------------+-----------------------------------------------+ + | ``subn()`` | Does the same thing as :meth:`sub`, but | + | | returns the new string and the number of | + | | replacements | + +------------------+-----------------------------------------------+ + + + Splitting Strings + ----------------- + +-The :meth:`split` method of a :class:`RegexObject` splits a string apart ++The :meth:`split` method of a pattern splits a string apart + wherever the RE matches, returning a list of the pieces. It's similar to the + :meth:`split` method of strings but provides much more generality in the + delimiters that you can split by; :meth:`split` only supports splitting by + whitespace or by a fixed string. As you'd expect, there's a module-level + :func:`re.split` function, too. + + + .. method:: .split(string [, maxsplit=0]) + :noindex: + + Split *string* by the matches of the regular expression. If capturing + parentheses are used in the RE, then their contents will also be returned as +@@ -1186,28 +1186,28 @@ + hexadecimal:: + + >>> def hexrepl( match ): + ... "Return the hex string for a decimal number" + ... value = int( match.group() ) + ... return hex(value) + ... + >>> p = re.compile(r'\d+') + >>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.') + 'Call 0xffd2 for printing, 0xc000 for user code.' + + When using the module-level :func:`re.sub` function, the pattern is passed as +-the first argument. The pattern may be a string or a :class:`RegexObject`; if ++the first argument. The pattern may be provided as an object or as a string; if + you need to specify regular expression flags, you must either use a +-:class:`RegexObject` as the first parameter, or use embedded modifiers in the +-pattern, e.g. ``sub("(?i)b+", "x", "bbbb BBBB")`` returns ``'x x'``. ++pattern object as the first parameter, or use embedded modifiers in the ++pattern string, e.g. ``sub("(?i)b+", "x", "bbbb BBBB")`` returns ``'x x'``. + + + Common Problems + =============== + + Regular expressions are a powerful tool for some applications, but in some ways + their behaviour isn't intuitive and at times they don't behave the way you may + expect them to. This section will point out some of the most common pitfalls. + + + Use String Methods + ------------------ ======================================= --- /dev/null +++ /howto/diff/regex.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,92 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to51__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/regex.rst => r266/howto/regex.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to51__0"></td><td class="diff_header" id="from51_252">252</td><td nowrap="nowrap">them in Python? The :mod:`re` module provides an interface to the regular</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_253">253</td><td nowrap="nowrap">expression engine, allowing you to compile REs into objects and then perform</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_254">254</td><td nowrap="nowrap">matches with them.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_255">255</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_256">256</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_257">257</td><td nowrap="nowrap">Compiling Regular Expressions</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_258">258</td><td nowrap="nowrap">-----------------------------</td></tr> <tr><td class="diff_next" id="difflib_chg_to51__1"></td><td class="diff_header" id="from51_259">259</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__1">n</a></td><td class="diff_header" id="from51_260">260-</td><td nowrap="nowrap">Regular expressions are compiled into <span class="diff_chg">:cl</span>a<span class="diff_chg">ss:`R</span>e<span class="diff_chg">gexO</span>bject<span class="diff_sub">` instance</span>s, which have</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__1">n</a></td><td class="diff_header" id="to51_260">260+</td><td nowrap="nowrap">Regular expressions are compiled into <span class="diff_chg">p</span>a<span class="diff_chg">tt</span>e<span class="diff_chg">rn o</span>bjects, which have</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_261">261</td><td nowrap="nowrap">methods for various operations such as searching for pattern matches or</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_262">262</td><td nowrap="nowrap">performing string substitutions. ::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_263">263</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_264">264</td><td nowrap="nowrap"> >>> import re</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_265">265</td><td nowrap="nowrap"> >>> p = re.compile('ab*')</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_266">266</td><td nowrap="nowrap"> >>> print p</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__2">n</a></td><td class="diff_header" id="from51_267">267-</td><td nowrap="nowrap"><span class="diff_sub"> <re.RegexObject instance at 80b4150></span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__2">n</a></td><td class="diff_header" id="to51_267">267+</td><td nowrap="nowrap"><span class="diff_add"> <_sre.SRE_Pattern object at 80b4150></span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_268">268</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_269">269</td><td nowrap="nowrap">:func:`re.compile` also accepts an optional *flags* argument, used to enable</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_270">270</td><td nowrap="nowrap">various special features and syntax variations. We'll go over the available</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_271">271</td><td nowrap="nowrap">settings later, but for now a single example will do::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_272">272</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_273">273</td><td nowrap="nowrap"> >>> p = re.compile('ab*', re.IGNORECASE)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_274">274</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_275">275</td><td nowrap="nowrap">The RE is passed to :func:`re.compile` as a string. REs are handled as strings</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to51__2"></td><td class="diff_header" id="from51_331">331</td><td nowrap="nowrap">| ``"\\w+\\s+\\1"`` | ``r"\w+\s+\1"`` | </td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_332">332</td><td nowrap="nowrap">+-------------------+------------------+</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_333">333</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_334">334</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_335">335</td><td nowrap="nowrap">Performing Matches</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_336">336</td><td nowrap="nowrap">------------------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_337">337</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_338">338</td><td nowrap="nowrap">Once you have an object representing a compiled regular expression, what do you</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__3">n</a></td><td class="diff_header" id="from51_339">339-</td><td nowrap="nowrap">do with it? <span class="diff_chg">:cl</span>a<span class="diff_chg">ss:`R</span>e<span class="diff_chg">gexO</span>bject<span class="diff_sub">` in</span>s<span class="diff_sub">tances</span> have several methods and attributes.</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__3">n</a></td><td class="diff_header" id="to51_339">339+</td><td nowrap="nowrap">do with it? <span class="diff_chg">P</span>a<span class="diff_chg">tt</span>e<span class="diff_chg">rn o</span>bjects have several methods and attributes.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_340">340</td><td nowrap="nowrap">Only the most significant ones will be covered here; consult the :mod:`re` docs</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_341">341</td><td nowrap="nowrap">for a complete listing.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_342">342</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_343">343</td><td nowrap="nowrap">+------------------+-----------------------------------------------+</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_344">344</td><td nowrap="nowrap">| Method/Attribute | Purpose | </td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_345">345</td><td nowrap="nowrap">+==================+===============================================+</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_346">346</td><td nowrap="nowrap">| ``match()`` | Determine if the RE matches at the beginning | </td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_347">347</td><td nowrap="nowrap">| | of the string. | </td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to51__3"></td><td class="diff_header" id="from51_422">422</td><td nowrap="nowrap"> (0, 5)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_423">423</td><td nowrap="nowrap"> >>> m.span()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_424">424</td><td nowrap="nowrap"> (0, 5)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_425">425</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_426">426</td><td nowrap="nowrap">:meth:`group` returns the substring that was matched by the RE. :meth:`start`</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_427">427</td><td nowrap="nowrap">and :meth:`end` return the starting and ending index of the match. :meth:`span`</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_428">428</td><td nowrap="nowrap">returns both start and end indexes in a single tuple. Since the :meth:`match`</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_429">429</td><td nowrap="nowrap">method only checks if the RE matches at the start of a string, :meth:`start`</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__4">n</a></td><td class="diff_header" id="from51_430">430-</td><td nowrap="nowrap">will always be zero. However, the :meth:`search` method of <span class="diff_chg">:cl</span>as<span class="diff_sub">s:`RegexObject`</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__4">n</a></td><td class="diff_header" id="to51_430">430+</td><td nowrap="nowrap">will always be zero. However, the :meth:`search` method of <span class="diff_chg">p</span>a<span class="diff_add">ttern</span>s</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from51_431">431-</td><td nowrap="nowrap"><span class="diff_sub">instances </span>scans through the string, so the match may not start at zero in that</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to51_431">431+</td><td nowrap="nowrap">scans through the string, so the match may not start at zero in that</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_432">432</td><td nowrap="nowrap">case. ::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_433">433</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_434">434</td><td nowrap="nowrap"> >>> print p.match('::: message')</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_435">435</td><td nowrap="nowrap"> None</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_436">436</td><td nowrap="nowrap"> >>> m = p.search('::: message') ; print m</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_437">437</td><td nowrap="nowrap"> <re.MatchObject instance at 80c9650></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_438">438</td><td nowrap="nowrap"> >>> m.group()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_439">439</td><td nowrap="nowrap"> 'message'</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to51__4"></td><td class="diff_header" id="from51_445">445</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_446">446</td><td nowrap="nowrap"> p = re.compile( ... )</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_447">447</td><td nowrap="nowrap"> m = p.match( 'string goes here' )</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_448">448</td><td nowrap="nowrap"> if m:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_449">449</td><td nowrap="nowrap"> print 'Match found: ', m.group()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_450">450</td><td nowrap="nowrap"> else:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_451">451</td><td nowrap="nowrap"> print 'No match'</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_452">452</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__5">n</a></td><td class="diff_header" id="from51_453">453-</td><td nowrap="nowrap">Two <span class="diff_chg">:cl</span>a<span class="diff_chg">ss:`R</span>e<span class="diff_chg">gexObject`</span> methods return all of the matches for a pattern.</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__5">n</a></td><td class="diff_header" id="to51_453">453+</td><td nowrap="nowrap">Two <span class="diff_chg">p</span>a<span class="diff_chg">tt</span>e<span class="diff_chg">rn</span> methods return all of the matches for a pattern.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_454">454</td><td nowrap="nowrap">:meth:`findall` returns a list of matching strings::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_455">455</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_456">456</td><td nowrap="nowrap"> >>> p = re.compile('\d+')</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_457">457</td><td nowrap="nowrap"> >>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping')</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_458">458</td><td nowrap="nowrap"> ['12', '11', '10']</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_459">459</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_460">460</td><td nowrap="nowrap">:meth:`findall` has to create the entire list before it can be returned as the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_461">461</td><td nowrap="nowrap">result. The :meth:`finditer` method returns a sequence of :class:`MatchObject`</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to51__5"></td><td class="diff_header" id="from51_470">470</td><td nowrap="nowrap"> (0, 2)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_471">471</td><td nowrap="nowrap"> (22, 24)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_472">472</td><td nowrap="nowrap"> (29, 31)</td></tr> <tr><td class="diff_next" id="difflib_chg_to51__6"></td><td class="diff_header" id="from51_473">473</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_474">474</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_475">475</td><td nowrap="nowrap">Module-Level Functions</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_476">476</td><td nowrap="nowrap">----------------------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_477">477</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__6">n</a></td><td class="diff_header" id="from51_478">478-</td><td nowrap="nowrap">You don't have to create a <span class="diff_chg">:cl</span>a<span class="diff_chg">ss:`R</span>e<span class="diff_chg">gexO</span>bject<span class="diff_sub">`</span> and call its methods; the</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__6">n</a></td><td class="diff_header" id="to51_478">478+</td><td nowrap="nowrap">You don't have to create a <span class="diff_chg">p</span>a<span class="diff_chg">tt</span>e<span class="diff_chg">rn o</span>bject and call its methods; the</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_479">479</td><td nowrap="nowrap">:mod:`re` module also provides top-level functions called :func:`match`,</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_480">480</td><td nowrap="nowrap">:func:`search`, :func:`findall`, :func:`sub`, and so forth. These functions</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__7">n</a></td><td class="diff_header" id="from51_481">481-</td><td nowrap="nowrap">take the same arguments as the corresponding <span class="diff_chg">:cl</span>a<span class="diff_chg">ss:`R</span>e<span class="diff_chg">gexObject`</span> method, with</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__7">n</a></td><td class="diff_header" id="to51_481">481+</td><td nowrap="nowrap">take the same arguments as the corresponding <span class="diff_chg">p</span>a<span class="diff_chg">tt</span>e<span class="diff_chg">rn</span> method, with</td></tr> + <tr><td class="diff_next" id="difflib_chg_to51__7"></td><td class="diff_header" id="from51_482">482</td><td nowrap="nowrap">the RE string added as the first argument, and still return either ``None`` or a</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_483">483</td><td nowrap="nowrap">:class:`MatchObject` instance. ::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_484">484</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_485">485</td><td nowrap="nowrap"> >>> print re.match(r'From\s+', 'Fromage amk')</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_486">486</td><td nowrap="nowrap"> None</td></tr> <tr><td class="diff_next" id="difflib_chg_to51__8"></td><td class="diff_header" id="from51_487">487</td><td nowrap="nowrap"> >>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_488">488</td><td nowrap="nowrap"> <re.MatchObject instance at 80c5978></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_489">489</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__8">n</a></td><td class="diff_header" id="from51_490">490-</td><td nowrap="nowrap"><span class="diff_sub">Under the hood, these functions simply produce a :class:`RegexObject` for you</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__8">n</a></td><td class="diff_header" id="to51_490">490+</td><td nowrap="nowrap"><span class="diff_add">Under the hood, these functions simply create a pattern object for you</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_491">491</td><td nowrap="nowrap">and call the appropriate method on it. They also store the compiled object in a</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_492">492</td><td nowrap="nowrap">cache, so future calls using the same RE are faster.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_493">493</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_494">494</td><td nowrap="nowrap">Should you use these module-level functions, or should you get the</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__9">n</a></td><td class="diff_header" id="from51_495">495-</td><td nowrap="nowrap"><span class="diff_chg">:cl</span>a<span class="diff_chg">ss:`R</span>e<span class="diff_chg">gexObject`</span> and call its methods yourself? That choice depends on how</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__9">n</a></td><td class="diff_header" id="to51_495">495+</td><td nowrap="nowrap"><span class="diff_chg">p</span>a<span class="diff_chg">tt</span>e<span class="diff_chg">rn</span> and call its methods yourself? That choice depends on how</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_496">496</td><td nowrap="nowrap">frequently the RE will be used, and on your personal coding style. If the RE is</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_497">497</td><td nowrap="nowrap">being used at only one point in the code, then the module functions are probably</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_498">498</td><td nowrap="nowrap">more convenient. If a program contains a lot of regular expressions, or re-uses</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_499">499</td><td nowrap="nowrap">the same ones in several locations, then it might be worthwhile to collect all</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_500">500</td><td nowrap="nowrap">the definitions in one place, in a section of code that compiles all the REs</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_501">501</td><td nowrap="nowrap">ahead of time. To take an example from the standard library, here's an extract</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_502">502</td><td nowrap="nowrap">from :file:`xmllib.py`::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_503">503</td><td nowrap="nowrap"></td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to51__9"></td><td class="diff_header" id="from51_1025">1025</td><td nowrap="nowrap">``.*[.](?!bat$|exe$).*$``</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1026">1026</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1027">1027</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1028">1028</td><td nowrap="nowrap">Modifying Strings</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1029">1029</td><td nowrap="nowrap">=================</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1030">1030</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1031">1031</td><td nowrap="nowrap">Up to this point, we've simply performed searches against a static string.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1032">1032</td><td nowrap="nowrap">Regular expressions are also commonly used to modify strings in various ways,</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__10">n</a></td><td class="diff_header" id="from51_1033">1033-</td><td nowrap="nowrap"><span class="diff_sub">using the following :class:`RegexObject` methods:</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__10">n</a></td><td class="diff_header" id="to51_1033">1033+</td><td nowrap="nowrap"><span class="diff_add">using the following pattern methods:</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_1034">1034</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1035">1035</td><td nowrap="nowrap">+------------------+-----------------------------------------------+</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1036">1036</td><td nowrap="nowrap">| Method/Attribute | Purpose | </td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1037">1037</td><td nowrap="nowrap">+==================+===============================================+</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1038">1038</td><td nowrap="nowrap">| ``split()`` | Split the string into a list, splitting it | </td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1039">1039</td><td nowrap="nowrap">| | wherever the RE matches | </td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1040">1040</td><td nowrap="nowrap">+------------------+-----------------------------------------------+</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1041">1041</td><td nowrap="nowrap">| ``sub()`` | Find all substrings where the RE matches, and | </td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to51__10"></td><td class="diff_header" id="from51_1045">1045</td><td nowrap="nowrap">| | returns the new string and the number of | </td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1046">1046</td><td nowrap="nowrap">| | replacements | </td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1047">1047</td><td nowrap="nowrap">+------------------+-----------------------------------------------+</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1048">1048</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1049">1049</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1050">1050</td><td nowrap="nowrap">Splitting Strings</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1051">1051</td><td nowrap="nowrap">-----------------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1052">1052</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__11">n</a></td><td class="diff_header" id="from51_1053">1053-</td><td nowrap="nowrap">The :meth:`split` method of a <span class="diff_chg">:cl</span>a<span class="diff_chg">ss:`R</span>e<span class="diff_chg">gexObject`</span> splits a string apart</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__11">n</a></td><td class="diff_header" id="to51_1053">1053+</td><td nowrap="nowrap">The :meth:`split` method of a <span class="diff_chg">p</span>a<span class="diff_chg">tt</span>e<span class="diff_chg">rn</span> splits a string apart</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_1054">1054</td><td nowrap="nowrap">wherever the RE matches, returning a list of the pieces. It's similar to the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1055">1055</td><td nowrap="nowrap">:meth:`split` method of strings but provides much more generality in the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1056">1056</td><td nowrap="nowrap">delimiters that you can split by; :meth:`split` only supports splitting by</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1057">1057</td><td nowrap="nowrap">whitespace or by a fixed string. As you'd expect, there's a module-level</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1058">1058</td><td nowrap="nowrap">:func:`re.split` function, too.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1059">1059</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1060">1060</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1061">1061</td><td nowrap="nowrap">.. method:: .split(string [, maxsplit=0])</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to51__11"></td><td class="diff_header" id="from51_1190">1190</td><td nowrap="nowrap"> ... value = int( match.group() )</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1191">1191</td><td nowrap="nowrap"> ... return hex(value)</td></tr> <tr><td class="diff_next" id="difflib_chg_to51__12"></td><td class="diff_header" id="from51_1192">1192</td><td nowrap="nowrap"> ...</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1193">1193</td><td nowrap="nowrap"> >>> p = re.compile(r'\d+')</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1194">1194</td><td nowrap="nowrap"> >>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1195">1195</td><td nowrap="nowrap"> 'Call 0xffd2 for printing, 0xc000 for user code.'</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1196">1196</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1197">1197</td><td nowrap="nowrap">When using the module-level :func:`re.sub` function, the pattern is passed as</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__12">n</a></td><td class="diff_header" id="from51_1198">1198-</td><td nowrap="nowrap"><span class="diff_sub">the first argument. The pattern may be a string or a :class:`RegexObject`; if</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__12">n</a></td><td class="diff_header" id="to51_1198">1198+</td><td nowrap="nowrap"><span class="diff_add">the first argument. The pattern may be provided as an object or as a string; if</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_1199">1199</td><td nowrap="nowrap">you need to specify regular expression flags, you must either use a</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to51__top">t</a></td><td class="diff_header" id="from51_1200">1200-</td><td nowrap="nowrap"><span class="diff_chg">:cl</span>a<span class="diff_chg">ss:`R</span>e<span class="diff_chg">gexO</span>bject<span class="diff_sub">`</span> as the first parameter, or use embedded modifiers in the</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to51__top">t</a></td><td class="diff_header" id="to51_1200">1200+</td><td nowrap="nowrap"><span class="diff_chg">p</span>a<span class="diff_chg">tt</span>e<span class="diff_chg">rn o</span>bject as the first parameter, or use embedded modifiers in the</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from51_1201">1201-</td><td nowrap="nowrap">pattern, e.g.<span class="diff_sub"> </span> ``sub("(?i)b+", "x", "bbbb BBBB")`` returns ``'x x'``.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to51_1201">1201+</td><td nowrap="nowrap">pattern<span class="diff_add"> string</span>, e.g. ``sub("(?i)b+", "x", "bbbb BBBB")`` returns ``'x x'``.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from51_1202">1202</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1203">1203</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1204">1204</td><td nowrap="nowrap">Common Problems</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1205">1205</td><td nowrap="nowrap">===============</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1206">1206</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1207">1207</td><td nowrap="nowrap">Regular expressions are a powerful tool for some applications, but in some ways</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1208">1208</td><td nowrap="nowrap">their behaviour isn't intuitive and at times they don't behave the way you may</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from51_1209">1209</td><td nowrap="nowrap">expect them to. This section will point out some of the most common pitfalls.</td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html> ======================================= --- /dev/null +++ /howto/diff/sockets.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,40 @@ +--- r262/howto/sockets.rst 2009-01-04 06:55:17.853888000 +0900 ++++ r266/howto/sockets.rst 2009-10-27 23:19:50.039185000 +0900 +@@ -195,35 +195,33 @@ + socket.AF_INET, socket.SOCK_STREAM) + else: + self.sock = sock + + def connect(self, host, port): + self.sock.connect((host, port)) + + def mysend(self, msg): + totalsent = 0 + while totalsent < MSGLEN: + sent = self.sock.send(msg[totalsent:]) + if sent == 0: +- raise RuntimeError, \ +- "socket connection broken" ++ raise RuntimeError("socket connection broken") + totalsent = totalsent + sent + + def myreceive(self): + msg = '' + while len(msg) < MSGLEN: + chunk = self.sock.recv(MSGLEN-len(msg)) + if chunk == '': +- raise RuntimeError, \ +- "socket connection broken" ++ raise RuntimeError("socket connection broken") + msg = msg + chunk + return msg + + The sending code here is usable for almost any messaging scheme - in Python you + send strings, and you can use ``len()`` to determine its length (even if it has + embedded ``\0`` characters). It's mostly the receiving code that gets more + complex. (And in C, it's not much worse, except you can't use ``strlen`` if the + message has embedded ``\0``\ s.) + + The easiest enhancement is to make the first character of the message an + indicator of message type, and have the type determine the length. Now you have + two ``recv``\ s - the first to get (at least) that first character so you can ======================================= --- /dev/null +++ /howto/diff/sockets.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,54 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to52__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/sockets.rst => r266/howto/sockets.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to52__0"></td><td class="diff_header" id="from52_199">199</td><td nowrap="nowrap"> def connect(self, host, port):</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_200">200</td><td nowrap="nowrap"> self.sock.connect((host, port))</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_201">201</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_202">202</td><td nowrap="nowrap"> def mysend(self, msg):</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_203">203</td><td nowrap="nowrap"> totalsent = 0</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_204">204</td><td nowrap="nowrap"> while totalsent < MSGLEN:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_205">205</td><td nowrap="nowrap"> sent = self.sock.send(msg[totalsent:])</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_206">206</td><td nowrap="nowrap"> if sent == 0:</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to52__1">n</a></td><td class="diff_header" id="from52_207">207-</td><td nowrap="nowrap"><span class="diff_sub"> raise RuntimeError, \</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to52__1"></td><td class="diff_header" id="from52_208">208-</td><td nowrap="nowrap"> <span class="diff_chg"> </span>"socket connection broken"</td></tr> +<tr><td class="diff_next" id="difflib_chg_to52__1"></td><td class="diff_header" id="to52_207">207+</td><td nowrap="nowrap"> <span class="diff_chg">raise RuntimeError(</span>"socket connection broken"<span class="diff_add">)</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from52_209">209</td><td nowrap="nowrap"> totalsent = totalsent + sent</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_210">210</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_211">211</td><td nowrap="nowrap"> def myreceive(self):</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_212">212</td><td nowrap="nowrap"> msg = ''</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_213">213</td><td nowrap="nowrap"> while len(msg) < MSGLEN:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_214">214</td><td nowrap="nowrap"> chunk = self.sock.recv(MSGLEN-len(msg))</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_215">215</td><td nowrap="nowrap"> if chunk == '':</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to52__top">t</a></td><td class="diff_header" id="from52_216">216-</td><td nowrap="nowrap"><span class="diff_sub"> raise RuntimeError, \</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from52_217">217-</td><td nowrap="nowrap"> <span class="diff_chg"> </span>"socket connection broken"</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to52_215">215+</td><td nowrap="nowrap"> <span class="diff_chg">raise RuntimeError(</span>"socket connection broken"<span class="diff_add">)</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from52_218">218</td><td nowrap="nowrap"> msg = msg + chunk</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_219">219</td><td nowrap="nowrap"> return msg</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_220">220</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_221">221</td><td nowrap="nowrap">The sending code here is usable for almost any messaging scheme - in Python you</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_222">222</td><td nowrap="nowrap">send strings, and you can use ``len()`` to determine its length (even if it has</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_223">223</td><td nowrap="nowrap">embedded ``\0`` characters). It's mostly the receiving code that gets more</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_224">224</td><td nowrap="nowrap">complex. (And in C, it's not much worse, except you can't use ``strlen`` if the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from52_225">225</td><td nowrap="nowrap">message has embedded ``\0``\ s.)</td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html> ======================================= --- /dev/null +++ /howto/diff/unicode.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,65 @@ +--- r262/howto/unicode.rst 2009-01-04 06:55:17.853888000 +0900 ++++ r266/howto/unicode.rst 2009-10-28 00:08:27.384772000 +0900 +@@ -201,29 +201,30 @@ + References + ---------- + + The Unicode Consortium site at <http://www.unicode.org> has character charts, a + glossary, and PDF versions of the Unicode specification. Be prepared for some + difficult reading. <http://www.unicode.org/history/> is a chronology of the + origin and development of Unicode. + + To help understand the standard, Jukka Korpela has written an introductory guide + to reading the Unicode character tables, available at + <http://www.cs.tut.fi/~jkorpela/unicode/guide.html>. + +-Two other good introductory articles were written by Joel Spolsky +-<http://www.joelonsoftware.com/articles/Unicode.html> and Jason Orendorff +-<http://www.jorendorff.com/articles/unicode/>. If this introduction didn't make +-things clear to you, you should try reading one of these alternate articles +-before continuing. ++Another good introductory article was written by Joel Spolsky ++<http://www.joelonsoftware.com/articles/Unicode.html>. ++If this introduction didn't make things clear to you, you should try reading this ++alternate article before continuing. ++ ++.. Jason Orendorff XXX http://www.jorendorff.com/articles/unicode/ is broken + + Wikipedia entries are often helpful; see the entries for "character encoding" + <http://en.wikipedia.org/wiki/Character_encoding> and UTF-8 + <http://en.wikipedia.org/wiki/UTF-8>, for example. + + + Python's Unicode Support + ======================== + + Now that you've learned the rudiments of Unicode, we can look at Python's + Unicode features. + +@@ -462,25 +463,25 @@ + 1 0bf2 No TAMIL NUMBER ONE THOUSAND + 2 0f84 Mn TIBETAN MARK HALANTA + 3 1770 Lo TAGBANWA LETTER SA + 4 33af So SQUARE RAD OVER S SQUARED + 1000.0 + + The category codes are abbreviations describing the nature of the character. + These are grouped into categories such as "Letter", "Number", "Punctuation", or + "Symbol", which in turn are broken up into subcategories. To take the codes + from the above output, ``'Ll'`` means 'Letter, lowercase', ``'No'`` means + "Number, other", ``'Mn'`` is "Mark, nonspacing", and ``'So'`` is "Symbol, + other". See +-<http://www.unicode.org/Public/UNIDATA/UCD.html#General_Category_Values> for a ++<http://unicode.org/Public/5.1.0/ucd/UCD.html#General_Category_Values> for a + list of category codes. + + References + ---------- + + The Unicode and 8-bit string types are described in the Python library reference + at :ref:`typesseq`. + + The documentation for the :mod:`unicodedata` module. + + The documentation for the :mod:`codecs` module. + ======================================= --- /dev/null +++ /howto/diff/unicode.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,63 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to53__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/unicode.rst => r266/howto/unicode.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to53__0"></td><td class="diff_header" id="from53_205">205</td><td nowrap="nowrap">glossary, and PDF versions of the Unicode specification. Be prepared for some</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_206">206</td><td nowrap="nowrap">difficult reading. <http://www.unicode.org/history/> is a chronology of the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_207">207</td><td nowrap="nowrap">origin and development of Unicode.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_208">208</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_209">209</td><td nowrap="nowrap">To help understand the standard, Jukka Korpela has written an introductory guide</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_210">210</td><td nowrap="nowrap">to reading the Unicode character tables, available at</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_211">211</td><td nowrap="nowrap"><http://www.cs.tut.fi/~jkorpela/unicode/guide.html>.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_212">212</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to53__1">n</a></td><td class="diff_header" id="from53_213">213-</td><td nowrap="nowrap"><span class="diff_chg">Two </span>other good introductory articles<span class="diff_sub"> were</span> written by Joel Spolsky</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to53__1">n</a></td><td class="diff_header" id="to53_213">213+</td><td nowrap="nowrap"><span class="diff_chg">An</span>other good introductory article<span class="diff_add"> wa</span>s written by Joel Spolsky</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from53_214">214-</td><td nowrap="nowrap"><http://www.joelonsoftware.com/articles/Unicode.html><span class="diff_chg"> and Jason Orendorff</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to53_214">214+</td><td nowrap="nowrap"><http://www.joelonsoftware.com/articles/Unicode.html><span class="diff_chg">.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from53_215">215-</td><td nowrap="nowrap"><span class="diff_sub"><http://www.jorendorff.com/articles/unicode/>. If this introduction didn't make</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to53_215">215+</td><td nowrap="nowrap"><span class="diff_add">If this introduction didn't make things clear to you, you should try reading this</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from53_216">216-</td><td nowrap="nowrap"><span class="diff_sub">things clear to you, you should try reading one of these alternate articles</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to53_216">216+</td><td nowrap="nowrap"><span class="diff_add">alternate article before continuing.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from53_217">217-</td><td nowrap="nowrap"><span class="diff_sub">before continuing.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to53_217">217+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to53_218">218+</td><td nowrap="nowrap"><span class="diff_add">.. Jason Orendorff XXX http://www.jorendorff.com/articles/unicode/ is broken</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from53_218">218</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_219">219</td><td nowrap="nowrap">Wikipedia entries are often helpful; see the entries for "character encoding"</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_220">220</td><td nowrap="nowrap"><http://en.wikipedia.org/wiki/Character_encoding> and UTF-8</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_221">221</td><td nowrap="nowrap"><http://en.wikipedia.org/wiki/UTF-8>, for example.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_222">222</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_223">223</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_224">224</td><td nowrap="nowrap">Python's Unicode Support</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_225">225</td><td nowrap="nowrap">========================</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to53__1"></td><td class="diff_header" id="from53_466">466</td><td nowrap="nowrap"> 1000.0</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_467">467</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_468">468</td><td nowrap="nowrap">The category codes are abbreviations describing the nature of the character.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_469">469</td><td nowrap="nowrap">These are grouped into categories such as "Letter", "Number", "Punctuation", or</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_470">470</td><td nowrap="nowrap">"Symbol", which in turn are broken up into subcategories. To take the codes</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_471">471</td><td nowrap="nowrap">from the above output, ``'Ll'`` means 'Letter, lowercase', ``'No'`` means</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_472">472</td><td nowrap="nowrap">"Number, other", ``'Mn'`` is "Mark, nonspacing", and ``'So'`` is "Symbol,</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_473">473</td><td nowrap="nowrap">other". See</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to53__top">t</a></td><td class="diff_header" id="from53_474">474-</td><td nowrap="nowrap"><http://<span class="diff_sub">www.</span>unicode.org/Public/<span class="diff_chg">UNIDATA</span>/UCD.html#General_Category_Values> for a</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to53__top">t</a></td><td class="diff_header" id="to53_475">475+</td><td nowrap="nowrap"><http://unicode.org/Public/<span class="diff_chg">5.1.0/ucd</span>/UCD.html#General_Category_Values> for a</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from53_475">475</td><td nowrap="nowrap">list of category codes.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_476">476</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_477">477</td><td nowrap="nowrap">References</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_478">478</td><td nowrap="nowrap">----------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_479">479</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_480">480</td><td nowrap="nowrap">The Unicode and 8-bit string types are described in the Python library reference</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_481">481</td><td nowrap="nowrap">at :ref:`typesseq`.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from53_482">482</td><td nowrap="nowrap"></td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html> ======================================= --- /dev/null +++ /howto/diff/urllib2.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,88 @@ +--- r262/howto/urllib2.rst 2009-01-04 06:55:17.853888000 +0900 ++++ r266/howto/urllib2.rst 2009-10-27 23:37:48.900246000 +0900 +@@ -173,28 +173,27 @@ + data = urllib.urlencode(values) + req = urllib2.Request(url, data, headers) + response = urllib2.urlopen(req) + the_page = response.read() + + The response also has two useful methods. See the section on `info and geturl`_ + which comes after we have a look at what happens when things go wrong. + + + Handling Exceptions + =================== + +-*urlopen* raises :exc:`URLError` when it cannot handle a response (though as usual +-with Python APIs, builtin exceptions such as +-:exc:`ValueError`, :exc:`TypeError` etc. may also +-be raised). ++*urlopen* raises :exc:`URLError` when it cannot handle a response (though as ++usual with Python APIs, built-in exceptions such as :exc:`ValueError`, ++:exc:`TypeError` etc. may also be raised). + + :exc:`HTTPError` is the subclass of :exc:`URLError` raised in the specific case of + HTTP URLs. + + URLError + -------- + + Often, URLError is raised because there is no network connection (no route to + the specified server), or the specified server doesn't exist. In this case, the + exception raised will have a 'reason' attribute, which is a tuple containing an + error code and a text error message. + +@@ -302,25 +301,25 @@ + 'The gateway server did not receive a timely response'), + 505: ('HTTP Version Not Supported', 'Cannot fulfill request.'), + } + + When an error is raised the server responds by returning an HTTP error code + *and* an error page. You can use the :exc:`HTTPError` instance as a response on the + page returned. This means that as well as the code attribute, it also has read, + geturl, and info, methods. :: + + >>> req = urllib2.Request('http://www.python.org/fish.html') + >>> try: + >>> urllib2.urlopen(req) +- >>> except URLError, e: ++ >>> except HTTPError, e: + >>> print e.code + >>> print e.read() + >>> + 404 + <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> + <?xml-stylesheet href="./css/ht2html.css" + type="text/css"?> + <html><head><title>Error 404: File Not Found</title> + ...... etc... + + Wrapping it Up +@@ -479,25 +478,25 @@ + # create "opener" (OpenerDirector instance) + opener = urllib2.build_opener(handler) + + # use the opener to fetch a URL + opener.open(a_url) + + # Install the opener. + # Now all calls to urllib2.urlopen use our opener. + urllib2.install_opener(opener) + + .. note:: + +- In the above example we only supplied our ``HHTPBasicAuthHandler`` to ++ In the above example we only supplied our ``HTTPBasicAuthHandler`` to + ``build_opener``. By default openers have the handlers for normal situations + -- ``ProxyHandler``, ``UnknownHandler``, ``HTTPHandler``, + ``HTTPDefaultErrorHandler``, ``HTTPRedirectHandler``, ``FTPHandler``, + ``FileHandler``, ``HTTPErrorProcessor``. + + ``top_level_url`` is in fact *either* a full URL (including the 'http:' scheme + component and the hostname and optionally the port number) + e.g. "http://example.com/" *or* an "authority" (i.e. the hostname, + optionally including the port number) e.g. "example.com" or "example.com:8080" + (the latter example includes a port number). The authority, if present, must + NOT contain the "userinfo" component - for example "joe @ password:example.com" is + not correct. ======================================= --- /dev/null +++ /howto/diff/urllib2.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,63 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to54__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/urllib2.rst => r266/howto/urllib2.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to54__0"></td><td class="diff_header" id="from54_177">177</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_178">178</td><td nowrap="nowrap">The response also has two useful methods. See the section on `info and geturl`_</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_179">179</td><td nowrap="nowrap">which comes after we have a look at what happens when things go wrong.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_180">180</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_181">181</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_182">182</td><td nowrap="nowrap">Handling Exceptions</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_183">183</td><td nowrap="nowrap">===================</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_184">184</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to54__1">n</a></td><td class="diff_header" id="from54_185">185-</td><td nowrap="nowrap">*urlopen* raises :exc:`URLError` when it cannot handle a response (though as<span class="diff_sub"> usual</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to54__1">n</a></td><td class="diff_header" id="to54_185">185+</td><td nowrap="nowrap">*urlopen* raises :exc:`URLError` when it cannot handle a response (though as</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from54_186">186-</td><td nowrap="nowrap">with Python APIs, builtin exceptions such as</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to54_186">186+</td><td nowrap="nowrap"><span class="diff_add">usual </span>with Python APIs, built<span class="diff_add">-</span>in exceptions such as<span class="diff_add"> :exc:`ValueError`,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from54_187">187-</td><td nowrap="nowrap"><span class="diff_sub">:exc:`ValueError`, :exc:`TypeError` etc. may also</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to54_187">187+</td><td nowrap="nowrap"><span class="diff_add">:exc:`TypeError` etc. may also be raised).</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from54_188">188-</td><td nowrap="nowrap"><span class="diff_sub">be raised).</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from54_189">189</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_190">190</td><td nowrap="nowrap">:exc:`HTTPError` is the subclass of :exc:`URLError` raised in the specific case of</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_191">191</td><td nowrap="nowrap">HTTP URLs.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_192">192</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_193">193</td><td nowrap="nowrap">URLError</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_194">194</td><td nowrap="nowrap">--------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_195">195</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_196">196</td><td nowrap="nowrap">Often, URLError is raised because there is no network connection (no route to</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to54__1"></td><td class="diff_header" id="from54_306">306</td><td nowrap="nowrap">When an error is raised the server responds by returning an HTTP error code</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_307">307</td><td nowrap="nowrap">*and* an error page. You can use the :exc:`HTTPError` instance as a response on the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_308">308</td><td nowrap="nowrap">page returned. This means that as well as the code attribute, it also has read,</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_309">309</td><td nowrap="nowrap">geturl, and info, methods. ::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_310">310</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_311">311</td><td nowrap="nowrap"> >>> req = urllib2.Request('http://www.python.org/fish.html')</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_312">312</td><td nowrap="nowrap"> >>> try:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_313">313</td><td nowrap="nowrap"> >>> urllib2.urlopen(req)</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to54__2">n</a></td><td class="diff_header" id="from54_314">314-</td><td nowrap="nowrap"> >>> except <span class="diff_chg">URL</span>Error, e:</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to54__2">n</a></td><td class="diff_header" id="to54_313">313+</td><td nowrap="nowrap"> >>> except <span class="diff_chg">HTTP</span>Error, e:</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from54_315">315</td><td nowrap="nowrap"> >>> print e.code</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_316">316</td><td nowrap="nowrap"> >>> print e.read()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_317">317</td><td nowrap="nowrap"> >>></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_318">318</td><td nowrap="nowrap"> 404</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_319">319</td><td nowrap="nowrap"> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_320">320</td><td nowrap="nowrap"> "http://www.w3.org/TR/html4/loose.dtd"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_321">321</td><td nowrap="nowrap"> <?xml-stylesheet href="./css/ht2html.css"</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_322">322</td><td nowrap="nowrap"> type="text/css"?></td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to54__2"></td><td class="diff_header" id="from54_483">483</td><td nowrap="nowrap"> opener.open(a_url)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_484">484</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_485">485</td><td nowrap="nowrap"> # Install the opener.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_486">486</td><td nowrap="nowrap"> # Now all calls to urllib2.urlopen use our opener.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_487">487</td><td nowrap="nowrap"> urllib2.install_opener(opener)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_488">488</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_489">489</td><td nowrap="nowrap">.. note::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_490">490</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to54__top">t</a></td><td class="diff_header" id="from54_491">491-</td><td nowrap="nowrap"> In the above example we only supplied our ``H<span class="diff_chg">H</span>TPBasicAuthHandler`` to</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to54__top">t</a></td><td class="diff_header" id="to54_490">490+</td><td nowrap="nowrap"> In the above example we only supplied our ``H<span class="diff_chg">T</span>TPBasicAuthHandler`` to</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from54_492">492</td><td nowrap="nowrap"> ``build_opener``. By default openers have the handlers for normal situations</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_493">493</td><td nowrap="nowrap"> -- ``ProxyHandler``, ``UnknownHandler``, ``HTTPHandler``,</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_494">494</td><td nowrap="nowrap"> ``HTTPDefaultErrorHandler``, ``HTTPRedirectHandler``, ``FTPHandler``,</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_495">495</td><td nowrap="nowrap"> ``FileHandler``, ``HTTPErrorProcessor``.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_496">496</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_497">497</td><td nowrap="nowrap">``top_level_url`` is in fact *either* a full URL (including the 'http:' scheme</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_498">498</td><td nowrap="nowrap">component and the hostname and optionally the port number)</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from54_499">499</td><td nowrap="nowrap">e.g. "http://example.com/" *or* an "authority" (i.e. the hostname,</td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html> ======================================= --- /dev/null +++ /howto/diff/webservers.rst.diff Sat Mar 19 08:45:35 2011 @@ -0,0 +1,1132 @@ +--- r262/howto/webservers.rst 2009-02-23 19:41:11.107573000 +0900 ++++ r266/howto/webservers.rst 2010-04-05 13:00:14.619029000 +0900 +@@ -1,96 +1,97 @@ + ******************************* + HOWTO Use Python in the web + ******************************* + + :Author: Marek Kubica + + .. topic:: Abstract + +- This document shows how Python fits into the web. It presents some ways on +- how to integrate Python with the web server and general practices useful for ++ This document shows how Python fits into the web. It presents some ways ++ to integrate Python with a web server, and general practices useful for + developing web sites. + + +-Programming for the Web has become a hot topic since the raise of the "Web 2.0", ++Programming for the Web has become a hot topic since the rise of "Web 2.0", + which focuses on user-generated content on web sites. It has always been + possible to use Python for creating web sites, but it was a rather tedious task. +-Therefore, many so-called "frameworks" and helper tools were created to help +-developers creating sites faster and these sites being more robust. This HOWTO +-describes some of the methods used to combine Python with a web server to create +-dynamic content. It is not meant as a general introduction as this topic is far +-too broad to be covered in one single document. However, a short overview of +-the most popular libraries is provided. ++Therefore, many frameworks and helper tools have been created to assist ++developers in creating faster and more robust sites. This HOWTO describes ++some of the methods used to combine Python with a web server to create ++dynamic content. It is not meant as a complete introduction, as this topic is ++far too broad to be covered in one single document. However, a short overview ++of the most popular libraries is provided. + + .. seealso:: + +- While this HOWTO tries to give an overview over Python in the Web, it cannot +- always be as up to date as desired. Web development in Python is moving +- forward rapidly, so the wiki page on `Web Programming +- <http://wiki.python.org/moin/WebProgramming>`_ might be more in sync with ++ While this HOWTO tries to give an overview of Python in the web, it cannot ++ always be as up to date as desired. Web development in Python is rapidly ++ moving forward, so the wiki page on `Web Programming ++ <http://wiki.python.org/moin/WebProgramming>`_ may be more in sync with + recent development. + + +-The low-level view ++The Low-Level View + ================== + +-.. .. image:: http.png +- +-When a user enters a web site, his browser makes a connection to the site's +-webserver (this is called the *request*). The server looks up the file in the ++When a user enters a web site, their browser makes a connection to the site's ++web server (this is called the *request*). The server looks up the file in the + file system and sends it back to the user's browser, which displays it (this is +-the *response*). This is roughly how the unterlying protocol, HTTP works. ++the *response*). This is roughly how the underlying protocol, HTTP, works. + +-Now, dynamic web sites are not files in the file system, but rather programs +-which are run by the web server when a request comes in. They can do all sorts +-of useful things, like display the postings of a bulletin board, show your +-mails, configurate software or just display the current time. These programs +-can be written in about any programming language the server supports, so it is +-easy to use Python for creating dynamic web sites. +- +-As most of HTTP servers are written in C or C++, they cannot execute Python code +-in a simple way -- a bridge is needed between the server and the program. These +-bridges or rather interfaces define how programs interact with the server. In +-the past there have been numerous attempts to create the best possible +-interface, but there are only a few worth mentioning. +- +-Not every web server supports every interface. Many web servers do support only +-old, now-obsolete interfaces. But they can often be extended using some +-third-party modules to support new interfaces. ++Dynamic web sites are not based on files in the file system, but rather on ++programs which are run by the web server when a request comes in, and which ++*generate* the content that is returned to the user. They can do all sorts of ++useful things, like display the postings of a bulletin board, show your email, ++configure software, or just display the current time. These programs can be ++written in any programming language the server supports. Since most servers ++support Python, it is easy to use Python to create dynamic web sites. ++ ++Most HTTP servers are written in C or C++, so they cannot execute Python code ++directly -- a bridge is needed between the server and the program. These ++bridges, or rather interfaces, define how programs interact with the server. ++There have been numerous attempts to create the best possible interface, but ++there are only a few worth mentioning. ++ ++Not every web server supports every interface. Many web servers only support ++old, now-obsolete interfaces; however, they can often be extended using ++third-party modules to support newer ones. + + + Common Gateway Interface + ------------------------ + +-This interface is the oldest one, supported by nearly every web server out of +-the box. Programs using CGI to communicate with their web server need to be +-started by the server for every request. So, every request starts a new Python +-interpreter -- which takes some time to start up -- thus making the whole +-interface only usable for low load situations. +- +-The upside of CGI is that it is simple -- writing a program which uses CGI is a +-matter of about three lines of code. But this simplicity comes at a price: it +-does very few things to help the developer. +- +-Writing CGI programs, while still possible, is not recommended anymore. With +-WSGI (more on that later) it is possible to write programs that emulate CGI, so +-they can be run as CGI if no better option is available. ++This interface, most commonly referred to as "CGI", is the oldest, and is ++supported by nearly every web server out of the box. Programs using CGI to ++communicate with their web server need to be started by the server for every ++request. So, every request starts a new Python interpreter -- which takes some ++time to start up -- thus making the whole interface only usable for low load ++situations. ++ ++The upside of CGI is that it is simple -- writing a Python program which uses ++CGI is a matter of about three lines of code. This simplicity comes at a ++price: it does very few things to help the developer. ++ ++Writing CGI programs, while still possible, is no longer recommended. With ++:ref:`WSGI <WSGI>`, a topic covered later in this document, it is possible to write ++programs that emulate CGI, so they can be run as CGI if no better option is ++available. + + .. seealso:: + + The Python standard library includes some modules that are helpful for + creating plain CGI programs: + + * :mod:`cgi` -- Handling of user input in CGI scripts +- * :mod:`cgitb` -- Displays nice tracebacks when errors happen in of CGI ++ * :mod:`cgitb` -- Displays nice tracebacks when errors happen in CGI + applications, instead of presenting a "500 Internal Server Error" message + + The Python wiki features a page on `CGI scripts + <http://wiki.python.org/moin/CgiScripts>`_ with some additional information + about CGI in Python. + + + Simple script for testing CGI + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + To test whether your web server works with CGI, you can use this short and + simple CGI program:: +@@ -98,189 +99,201 @@ + #!/usr/bin/env python + # -*- coding: UTF-8 -*- + + # enable debugging + import cgitb + cgitb.enable() + + print "Content-Type: text/plain;charset=utf-8" + print + + print "Hello World!" + +-You need to write this code into a file with a ``.py`` or ``.cgi`` extension, +-this depends on your web server configuration. Depending on your web server +-configuration, this file may also need to be in a ``cgi-bin`` folder, for +-security reasons. ++Depending on your web server configuration, you may need to save this code with ++a ``.py`` or ``.cgi`` extension. Additionally, this file may also need to be ++in a ``cgi-bin`` folder, for security reasons. + + You might wonder what the ``cgitb`` line is about. This line makes it possible + to display a nice traceback instead of just crashing and displaying an "Internal + Server Error" in the user's browser. This is useful for debugging, but it might +-risk exposing some confident data to the user. Don't use it when the script is +-ready for production use. Still, you should *always* catch exceptions, and ++risk exposing some confidential data to the user. You should not use ``cgitb`` ++in production code for this reason. You should *always* catch exceptions, and + display proper error pages -- end-users don't like to see nondescript "Internal + Server Errors" in their browsers. + + + Setting up CGI on your own server + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + If you don't have your own web server, this does not apply to you. You can +-check whether if works as-is and if not you need to talk to the administrator of +-your web server anyway. If it is a big hoster, you can try filing a ticket +-asking for Python support. +- +-If you're your own administrator or want to install it for testing purposes on +-your own computers, you have to configure it by yourself. There is no one and +-single way on how to configure CGI, as there are many web servers with different +-configuration options. The currently most widely used free web server is +-`Apache HTTPd <http://httpd.apache.org/>`_, Apache for short -- this is the one +-that most people use, it can be easily installed on nearly every system using +-the systems' package management. But `lighttpd <http://www.lighttpd.net>`_ has +-been gaining attention since some time and is said to have a better performance. +-On many systems this server can also be installed using the package management, +-so manually compiling the web server is never needed. ++check whether it works as-is, and if not you will need to talk to the ++administrator of your web server. If it is a big host, you can try filing a ++ticket asking for Python support. ++ ++If you are your own administrator or want to set up CGI for testing purposes on ++your own computers, you have to configure it by yourself. There is no single ++way to configure CGI, as there are many web servers with different ++configuration options. Currently the most widely used free web server is ++`Apache HTTPd <http://httpd.apache.org/>`_, or Apache for short. Apache can be ++easily installed on nearly every system using the system's package management ++tool. `lighttpd <http://www.lighttpd.net>`_ is another alternative and is ++said to have better performance. On many systems this server can also be ++installed using the package management tool, so manually compiling the web ++server may not be needed. + +-* On Apache you can take a look into the `Dynamic Content with CGI ++* On Apache you can take a look at the `Dynamic Content with CGI + <http://httpd.apache.org/docs/2.2/howto/cgi.html>`_ tutorial, where everything + is described. Most of the time it is enough just to set ``+ExecCGI``. The + tutorial also describes the most common gotchas that might arise. ++ + * On lighttpd you need to use the `CGI module +- <http://trac.lighttpd.net/trac/wiki/Docs%3AModCGI>`_ which can be configured ++ <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModCGI>`_\ , which can be configured + in a straightforward way. It boils down to setting ``cgi.assign`` properly. + + + Common problems with CGI scripts + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +-Trying to use CGI sometimes leads to small annoyances that one might experience +-while trying to get these scripts to run. Sometimes it happens that a seemingly +-correct script does not work as expected, which is caused by some small hidden +-reason that's difficult to spot. ++Using CGI sometimes leads to small annoyances while trying to get these ++scripts to run. Sometimes a seemingly correct script does not work as ++expected, the cause being some small hidden problem that's difficult to spot. + +-Some of these reasons are: ++Some of these potential problems are: + +-* The Python script is not marked executable. When CGI scripts are not +- executable most of the web servers will let the user download it, instead of ++* The Python script is not marked as executable. When CGI scripts are not ++ executable most web servers will let the user download it, instead of + running it and sending the output to the user. For CGI scripts to run +- properly the ``+x`` bit needs to be set. Using ``chmod a+x your_script.py`` +- might already solve the problem. +-* The line endings must be of Unix-type. This is important because the web +- server checks the first line of the script (called shebang) and tries to run +- the program specified there. It gets easily confused by Windows line endings +- (Carriage Return & Line Feed, also called CRLF), so you have to convert the +- file to Unix line endings (only Line Feed, LF). This can be done +- automatically by uploading the file via FTP in text mode instead of binary +- mode, but the preferred way is just telling your editor to save the files with +- Unix line endings. Most proper editors support this. +-* Your web server must be able to read the file, you need to make sure the +- permissions are fine. Often the server runs as user and group ``www-data``, +- so it might be worth a try to change the file ownership or making the file +- world readable by using ``chmod a+r your_script.py``. +-* The webserver must be able to know that the file you're trying to access is a +- CGI script. Check the configuration of your web server, maybe there is some +- mistake. +-* The path to the interpreter in the shebang (``#!/usr/bin/env python``) must be +- currect. This line calls ``/usr/bin/env`` to find Python, but it'll fail if +- there is no ``/usr/bin/env``. If you know where your Python is installed, you +- can also use that path. The commands ``whereis python`` and ``type -p +- python`` might also help to find where it is installed. Once this is known, +- the shebang line can be changed accordingly: ``#!/usr/bin/python``. ++ properly on Unix-like operating systems, the ``+x`` bit needs to be set. ++ Using ``chmod a+x your_script.py`` may solve this problem. ++ ++* On a Unix-like system, The line endings in the program file must be Unix ++ style line endings. This is important because the web server checks the ++ first line of the script (called shebang) and tries to run the program ++ specified there. It gets easily confused by Windows line endings (Carriage ++ Return & Line Feed, also called CRLF), so you have to convert the file to ++ Unix line endings (only Line Feed, LF). This can be done automatically by ++ uploading the file via FTP in text mode instead of binary mode, but the ++ preferred way is just telling your editor to save the files with Unix line ++ endings. Most editors support this. ++ ++* Your web server must be able to read the file, and you need to make sure the ++ permissions are correct. On unix-like systems, the server often runs as user ++ and group ``www-data``, so it might be worth a try to change the file ++ ownership, or making the file world readable by using ``chmod a+r ++ your_script.py``. ++ ++* The web server must know that the file you're trying to access is a CGI script. ++ Check the configuration of your web server, as it may be configured ++ to expect a specific file extension for CGI scripts. ++ ++* On Unix-like systems, the path to the interpreter in the shebang ++ (``#!/usr/bin/env python``) must be correct. This line calls ++ ``/usr/bin/env`` to find Python, but it will fail if there is no ++ ``/usr/bin/env``, or if Python is not in the web server's path. If you know ++ where your Python is installed, you can also use that full path. The ++ commands ``whereis python`` and ``type -p python`` could help you find ++ where it is installed. Once you know the path, you can change the shebang ++ accordingly: ``#!/usr/bin/python``. ++ + * The file must not contain a BOM (Byte Order Mark). The BOM is meant for +- determining the byte order of UTF-16 encodings, but some editors write this +- also into UTF-8 files. The BOM interferes with the shebang line, so be sure +- to tell your editor not to write the BOM. +-* :ref:`mod-python` might be making problems. mod_python is able to handle CGI +- scripts by itself, but it can also be a source for problems. Be sure you +- disable it. ++ determining the byte order of UTF-16 and UTF-32 encodings, but some editors ++ write this also into UTF-8 files. The BOM interferes with the shebang line, ++ so be sure to tell your editor not to write the BOM. ++ ++* If the web server is using :ref:`mod-python`, ``mod_python`` may be having ++ problems. ``mod_python`` is able to handle CGI scripts by itself, but it can ++ also be a source of issues. + + + .. _mod-python: + + mod_python + ---------- + + People coming from PHP often find it hard to grasp how to use Python in the web. +-Their first thought is mostly `mod_python <http://www.modpython.org/>`_ because +-they think that this is the equivalent to ``mod_php``. Actually it is not +-really. It does embed the interpreter into the Apache process, thus speeding up +-requests by not having to start a Python interpreter every request. On the +-other hand, it is by far not "Python intermixed with HTML" as PHP often does. +-The Python equivalent of that is a template engine. mod_python itself is much +-more powerful and gives more access to Apache internals. It can emulate CGI, it +-can work an a "Python Server Pages" mode similar to JSP which is "HTML +-intermangled with Python" and it has a "Publisher" which destignates one file to +-accept all requests and decide on what to do then. +- +-But mod_python has some problems. Unlike the PHP interpreter the Python +-interpreter uses caching when executing files, so when changing a file the whole +-web server needs to be re-started to update. Another problem ist the basic +-concept -- Apache starts some child processes to handle the requests and +-unfortunately every child process needs to load the whole Python interpreter +-even if it does not use it. This makes the whole web server slower. Another +-problem is that as mod_python is linked against a specific version of +-``libpython``, it is not possible to switch from an older version to a newer +-(e.g. 2.4 to 2.5) without recompiling mod_python. mod_python is also bound to +-the Apache web server, so programs written for mod_python cannot easily run on +-other web servers. +- +-These are the reasons why mod_python should be avoided when writing new +-programs. In some circumstances it might be still a good idea to use mod_python +-for deployment, but WSGI makes it possible to run WSGI programs under mod_python +-as well. ++Their first thought is mostly `mod_python <http://www.modpython.org/>`_\ , ++because they think that this is the equivalent to ``mod_php``. Actually, there ++are many differences. What ``mod_python`` does is embed the interpreter into ++the Apache process, thus speeding up requests by not having to start a Python ++interpreter for each request. On the other hand, it is not "Python intermixed ++with HTML" in the way that PHP is often intermixed with HTML. The Python ++equivalent of that is a template engine. ``mod_python`` itself is much more ++powerful and provides more access to Apache internals. It can emulate CGI, ++work in a "Python Server Pages" mode (similar to JSP) which is "HTML ++intermingled with Python", and it has a "Publisher" which designates one file ++to accept all requests and decide what to do with them. ++ ++``mod_python`` does have some problems. Unlike the PHP interpreter, the Python ++interpreter uses caching when executing files, so changes to a file will ++require the web server to be restarted. Another problem is the basic concept ++-- Apache starts child processes to handle the requests, and unfortunately ++every child process needs to load the whole Python interpreter even if it does ++not use it. This makes the whole web server slower. Another problem is that, ++because ``mod_python`` is linked against a specific version of ``libpython``, ++it is not possible to switch from an older version to a newer (e.g. 2.4 to 2.5) ++without recompiling ``mod_python``. ``mod_python`` is also bound to the Apache ++web server, so programs written for ``mod_python`` cannot easily run on other ++web servers. ++ ++These are the reasons why ``mod_python`` should be avoided when writing new ++programs. In some circumstances it still might be a good idea to use ++``mod_python`` for deployment, but WSGI makes it possible to run WSGI programs ++under ``mod_python`` as well. + + + FastCGI and SCGI + ---------------- + + FastCGI and SCGI try to solve the performance problem of CGI in another way. + Instead of embedding the interpreter into the web server, they create +-long-running processes which run in the background. There still is some module +-in the web server which makes it possible for the web server to "speak" with the +-background process. As the background process is independent from the server, +-it can be written in any language of course also in Python. The language just +-needs to have a library which handles the communication with the web server. ++long-running background processes. There is still a module in the web server ++which makes it possible for the web server to "speak" with the background ++process. As the background process is independent of the server, it can be ++written in any language, including Python. The language just needs to have a ++library which handles the communication with the webserver. + + The difference between FastCGI and SCGI is very small, as SCGI is essentially +-just a "simpler FastCGI". But as the web server support for SCGI is limited ++just a "simpler FastCGI". As the web server support for SCGI is limited, + most people use FastCGI instead, which works the same way. Almost everything +-that applies to SCGI also applies to FastCGI as well, so we'll only write about ++that applies to SCGI also applies to FastCGI as well, so we'll only cover + the latter. + +-These days, FastCGI is never used directly. Just like ``mod_python`` it is only ++These days, FastCGI is never used directly. Just like ``mod_python``, it is only + used for the deployment of WSGI applications. + + .. seealso:: + + * `FastCGI, SCGI, and Apache: Background and Future + <http://www.vmunix.com/mark/blog/archives/2006/01/02/fastcgi-scgi-and-apache-background-and-future/>`_ + is a discussion on why the concept of FastCGI and SCGI is better that that + of mod_python. + + + Setting up FastCGI + ^^^^^^^^^^^^^^^^^^ + +-Depending on the web server you need to have a special module. ++Each web server requires a specific module. + +-* Apache has both `mod_fastcgi <http://www.fastcgi.com/>`_ and `mod_fcgid ++* Apache has both `mod_fastcgi <http://www.fastcgi.com/drupal/>`_ and `mod_fcgid + <http://fastcgi.coremail.cn/>`_. ``mod_fastcgi`` is the original one, but it +- has some licensing issues that's why it is sometimes considered non-free. +- ``mod_fcgid`` is a smaller, compatible alternative. One of these modules needs ++ has some licensing issues, which is why it is sometimes considered non-free. ++ ``mod_fcgid`` is a smaller, compatible alternative. One of these modules needs + to be loaded by Apache. ++ + * lighttpd ships its own `FastCGI module +- <http://trac.lighttpd.net/trac/wiki/Docs%3AModFastCGI>`_ as well as an `SCGI +- module <http://trac.lighttpd.net/trac/wiki/Docs%3AModSCGI>`_. +-* nginx also supports `FastCGI +- <http://wiki.codemongers.com/NginxSimplePythonFCGI>`_. ++ <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModFastCGI>`_ as well as an ++ `SCGI module <http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModSCGI>`_. ++ ++* `nginx <http://nginx.org/>`_ also supports `FastCGI ++ <http://wiki.nginx.org/NginxSimplePythonFCGI>`_. + + Once you have installed and configured the module, you can test it with the + following WSGI-application:: + + #!/usr/bin/env python + # -*- coding: UTF-8 -*- + + from cgi import escape + import sys, os + from flup.server.fcgi import WSGIServer + + def app(environ, start_response): +@@ -292,407 +305,440 @@ + yield '<tr><th>%s</th><td>%s</td></tr>' % (escape(k), escape(v)) + yield '</table>' + + WSGIServer(app).run() + + This is a simple WSGI application, but you need to install `flup + <http://pypi.python.org/pypi/flup/1.0>`_ first, as flup handles the low level + FastCGI access. + + .. seealso:: + + There is some documentation on `setting up Django with FastCGI +- <http://www.djangoproject.com/documentation/fastcgi/>`_, most of which can be +- reused for other WSGI-compliant frameworks and libraries. Only the +- ``manage.py`` part has to be changed, the example used here can be used +- instead. Django does more or less the exact same thing. ++ <http://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/>`_, most of ++ which can be reused for other WSGI-compliant frameworks and libraries. ++ Only the ``manage.py`` part has to be changed, the example used here can be ++ used instead. Django does more or less the exact same thing. + + + mod_wsgi + -------- + +-`mod_wsgi <http://www.modwsgi.org/>`_ is an attempt to get rid of the low level +-gateways. As FastCGI, SCGI, mod_python are mostly used to deploy WSGI +-applications anyway, mod_wsgi was started to directly embed WSGI aplications +-into the Apache web server. The benefit from this approach is that WSGI +-applications can be deployed much easier as is is specially designed to host +-WSGI applications -- unlike the other low level methods which have glue code to +-host WSGI applications (like flup which was mentioned before). The downside is +-that mod_wsgi is limited to the Apache web server, other servers would need ++`mod_wsgi <http://code.google.com/p/modwsgi/>`_ is an attempt to get rid of the ++low level gateways. Given that FastCGI, SCGI, and mod_python are mostly used to ++deploy WSGI applications, mod_wsgi was started to directly embed WSGI applications ++into the Apache web server. mod_wsgi is specifically designed to host WSGI ++applications. It makes the deployment of WSGI applications much easier than ++deployment using other low level methods, which need glue code. The downside ++is that mod_wsgi is limited to the Apache web server; other servers would need + their own implementations of mod_wsgi. + +-It supports two modes: the embedded mode in which it integrates with the Apache +-process and the daemon mode which is more FastCGI-like. Contrary to FastCGI, +-mod_wsgi handles the worker-processes by itself which makes administration ++mod_wsgi supports two modes: embedded mode, in which it integrates with the ++Apache process, and daemon mode, which is more FastCGI-like. Unlike FastCGI, ++mod_wsgi handles the worker-processes by itself, which makes administration + easier. + + + .. _WSGI: + + Step back: WSGI + =============== + +-WSGI was already mentioned several times so it has to be something important. +-In fact it really is, so now it's time to explain. ++WSGI has already been mentioned several times, so it has to be something ++important. In fact it really is, and now it is time to explain it. + +-The *Web Server Gateway Interface*, :pep:`333` or WSGI for short is currently +-the best possible way to Python web programming. While it is great for +-programmers writing frameworks, the normal person does not need to get in direct +-contact with it. But when choosing a framework for web development it is a good +-idea to take one which supports WSGI. +- +-The big profit from WSGI is the unification. When your program is compatible +-with WSGI -- that means that your framework has support for WSGI, your program +-can be deployed on every web server interface for which there are WSGI wrappers. +-So you do not need to care about whether the user uses mod_python or FastCGI -- +-with WSGI it just works on any gateway interface. The Python standard library +-contains its own WSGI server :mod:`wsgiref`, which is a small web server that +-can be used for testing. +- +-A really great WSGI feature are the middlewares. Middlewares are layers around +-your program which can add various functionality to it. There is a `number of +-middlewares <http://wsgi.org/wsgi/Middleware_and_Utilities>`_ already available. +-For example, instead of writing your own session management (to identify a user +-in subsequent requests, as HTTP does not maintain state, so it does now know +-that the requests belong to the same user) you can just take one middleware, +-plug it in and you can rely an already existing functionality. The same thing +-is compression -- say you want to compress your HTML using gzip, to save your +-server's bandwidth. So you only need to plug-in a middleware and you're done. +-Authentication is also a problem easily solved using a middleware. +- +-So, generally -- although WSGI may seem complex, the initial phase of learning +-can be very rewarding as WSGI does already have solutions to many problems that +-might arise while writing web sites. ++The *Web Server Gateway Interface*, or WSGI for short, is defined in ++:pep:`333` and is currently the best way to do Python web programming. While ++it is great for programmers writing frameworks, a normal web developer does not ++need to get in direct contact with it. When choosing a framework for web ++development it is a good idea to choose one which supports WSGI. ++ ++The big benefit of WSGI is the unification of the application programming ++interface. When your program is compatible with WSGI -- which at the outer ++level means that the framework you are using has support for WSGI -- your ++program can be deployed via any web server interface for which there are WSGI ++wrappers. You do not need to care about whether the application user uses ++mod_python or FastCGI or mod_wsgi -- with WSGI your application will work on ++any gateway interface. The Python standard library contains its own WSGI ++server, :mod:`wsgiref`, which is a small web server that can be used for ++testing. ++ ++A really great WSGI feature is middleware. Middleware is a layer around your ++program which can add various functionality to it. There is quite a bit of ++`middleware <http://wsgi.org/wsgi/Middleware_and_Utilities>`_ already ++available. For example, instead of writing your own session management (HTTP ++is a stateless protocol, so to associate multiple HTTP requests with a single ++user your application must create and manage such state via a session), you can ++just download middleware which does that, plug it in, and get on with coding ++the unique parts of your application. The same thing with compression -- there ++is existing middleware which handles compressing your HTML using gzip to save ++on your server's bandwidth. Authentication is another a problem easily solved ++using existing middleware. ++ ++Although WSGI may seem complex, the initial phase of learning can be very ++rewarding because WSGI and the associated middleware already have solutions to ++many problems that might arise while developing web sites. + + + WSGI Servers + ------------ + + The code that is used to connect to various low level gateways like CGI or +-mod_python is called *WSGI server*. One of these servers is ``flup`` which was +-already mentioned and supports FastCGI, SCGI as well as `AJP ++mod_python is called a *WSGI server*. One of these servers is ``flup``, which ++supports FastCGI and SCGI, as well as `AJP + <http://en.wikipedia.org/wiki/Apache_JServ_Protocol>`_. Some of these servers +-are written in Python as ``flup`` is, but there also exist others which are ++are written in Python, as ``flup`` is, but there also exist others which are + written in C and can be used as drop-in replacements. + +-There are quite a lot of servers already available, so a Python web application +-can be deployed nearly everywhere. This is one big advantage that Python has +-compared with other web techniques. ++There are many servers already available, so a Python web application ++can be deployed nearly anywhere. This is one big advantage that Python has ++compared with other web technologies. + + .. seealso:: + +- A good overview of all WSGI-related code can be found in the `WSGI wiki ++ A good overview of WSGI-related code can be found in the `WSGI wiki + <http://wsgi.org/wsgi>`_, which contains an extensive list of `WSGI servers +- <http://wsgi.org/wsgi/Servers>`_, which can be used by *every* application ++ <http://wsgi.org/wsgi/Servers>`_ which can be used by *any* application + supporting WSGI. + + You might be interested in some WSGI-supporting modules already contained in + the standard library, namely: + + * :mod:`wsgiref` -- some tiny utilities and servers for WSGI + + + Case study: MoinMoin + -------------------- + +-What does WSGI give the web application developer? Let's take a look on one +-long existing web application written in Python without using WSGI. +- +-One of the most widely used wiki software is `MoinMoin <http://moinmo.in/>`_. +-It was created in 2000, so it predates WSGI by about three years. While it now +-includes support for WSGI, older versions needed separate code to run on CGI, +-mod_python, FastCGI and standalone. Now, this all is possible by using WSGI and +-the already-written gateways. For running with on FastCGI ``flup`` can be used, +-for running a standalone server :mod:`wsgiref` is the way to go. ++What does WSGI give the web application developer? Let's take a look at ++an application that's been around for a while, which was written in ++Python without using WSGI. ++ ++One of the most widely used wiki software packages is `MoinMoin ++<http://moinmo.in/>`_. It was created in 2000, so it predates WSGI by about ++three years. Older versions needed separate code to run on CGI, mod_python, ++FastCGI and standalone. ++ ++It now includes support for WSGI. Using WSGI, it is possible to deploy ++MoinMoin on any WSGI compliant server, with no additional glue code. ++Unlike the pre-WSGI versions, this could include WSGI servers that the ++authors of MoinMoin know nothing about. + + +-Model-view-controller ++Model-View-Controller + ===================== + +-The term *MVC* is often heard in statements like "framework *foo* supports MVC". +-While MVC is not really something technical but rather organisational, many web +-frameworks use this model to help the developer to bring structure into his +-program. Bigger web applications can have lots of code so it is a good idea to +-have structure in the program right from the beginnings. That way, even users +-of other frameworks (or even languages, as MVC is nothing Python-specific) can +-understand the existing code easier, as they are already familiar with the +-structure. ++The term *MVC* is often encountered in statements such as "framework *foo* ++supports MVC". MVC is more about the overall organization of code, rather than ++any particular API. Many web frameworks use this model to help the developer ++bring structure to their program. Bigger web applications can have lots of ++code, so it is a good idea to have an effective structure right from the beginning. ++That way, even users of other frameworks (or even other languages, since MVC is ++not Python-specific) can easily understand the code, given that they are ++already familiar with the MVC structure. + + MVC stands for three components: + +-* The *model*. This is the data that is meant to modify. In Python frameworks +- this component is often represented by the classes used by the +- object-relational mapper. So, all declarations go here. ++* The *model*. This is the data that will be displayed and modified. In ++ Python frameworks, this component is often represented by the classes used by ++ an object-relational mapper. ++ + * The *view*. This component's job is to display the data of the model to the +- user. Typically this component is represented by the templates. ++ user. Typically this component is implemented via templates. ++ + * The *controller*. This is the layer between the user and the model. The +- controller reacts on user actions (like opening some specific URL) and tells +- the model to modify the data if neccessary. ++ controller reacts to user actions (like opening some specific URL), tells ++ the model to modify the data if necessary, and tells the view code what to ++ display, + + While one might think that MVC is a complex design pattern, in fact it is not. + It is used in Python because it has turned out to be useful for creating clean, + maintainable web sites. + + .. note:: + + While not all Python frameworks explicitly support MVC, it is often trivial +- to create a web site which uses the MVC pattern by seperating the data logic ++ to create a web site which uses the MVC pattern by separating the data logic + (the model) from the user interaction logic (the controller) and the +- templates (the view). That's why it is important not to write unneccessary +- Python code in the templates -- it is against MVC and creates more chaos. ++ templates (the view). That's why it is important not to write unnecessary ++ Python code in the templates -- it works against the MVC model and creates ++ chaos in the code base, making it harder to understand and modify. + + .. seealso:: + +- The english Wikipedia has an article about the `Model-View-Controller pattern +- <http://en.wikipedia.org/wiki/Model-view-controller>`_, which includes a long +- list of web frameworks for different programming languages. ++ The English Wikipedia has an article about the `Model-View-Controller pattern ++ <http://en.wikipedia.org/wiki/Model-view-controller>`_. It includes a long ++ list of web frameworks for various programming languages. + + +-Ingredients for web sites +-========================= +- +-Web sites are complex constructs, so tools were created to help the web site +-developer to make his work maintainable. None of these tools are in any way +-Python specific, they also exist for other programming languages as well. Of +-course, developers are not forced to use these tools and often there is no +-"best" tool, but it is worth informing yourself before choosing something +-because of the big number of helpers that the developer can use. ++Ingredients for Websites ++======================== ++ ++Websites are complex constructs, so tools have been created to help web ++developers make their code easier to write and more maintainable. Tools like ++these exist for all web frameworks in all languages. Developers are not forced ++to use these tools, and often there is no "best" tool. It is worth learning ++about the available tools because they can greatly simplify the process of ++developing a web site. + + + .. seealso:: + +- People have written far more components that can be combined than these +- presented here. The Python wiki has a page about these components, called ++ There are far more components than can be presented here. The Python wiki ++ has a page about these components, called + `Web Components <http://wiki.python.org/moin/WebComponents>`_. + + + Templates + --------- + +-Mixing of HTML and Python code is possible with some libraries. While ++Mixing of HTML and Python code is made possible by a few libraries. While + convenient at first, it leads to horribly unmaintainable code. That's why + templates exist. Templates are, in the simplest case, just HTML files with +-placeholders. The HTML is sent to the user's browser after filling out the ++placeholders. The HTML is sent to the user's browser after filling in the + placeholders. + +-Python already includes such simple templates:: ++Python already includes two ways to build simple templates:: + +- # a simple template +- template = "<html><body><h1>Hello %s!</h1></body></html>" +- print template % "Reader" +- +-The Python standard library also includes some more advanced templates usable +-through :class:`string.Template`, but in HTML templates it is needed to use +-conditional and looping contructs like Python's *for* and *if*. So, some +-*template engine* is needed. +- +-Now, Python has a lot of template engines which can be used with or without a +-`framework`_. Some of these are using a plain-text programming language which +-is very easy to learn as it is quite limited while others use XML so the +-template output is always guaranteed to be valid XML. Some `frameworks`_ ship +-their own template engine or recommend one particular. If one is not yet sure, +-using these is a good idea. +- +-.. note:: +- +- While Python has quite a lot of different template engines it usually does +- not make sense to use a homebrewed template system. The time needed to +- evaluate all templating systems is not really worth it, better invest the +- time in looking through the most popular ones. Some frameworks have their +- own template engine or have a recommentation for one. It's wise to use +- these. +- +- Popular template engines include: +- +- * Mako +- * Genshi +- * Jinja ++ >>> template = "<html><body><h1>Hello %s!</h1></body></html>" ++ >>> print template % "Reader" ++ <html><body><h1>Hello Reader!</h1></body></html> ++ ++ >>> from string import Template ++ >>> template = Template("<html><body><h1>Hello ${name}</h1></body></html>") ++ >>> print template.substitute(dict(name='Dinsdale')) ++ <html><body><h1>Hello Dinsdale!</h1></body></html> ++ ++To generate complex HTML based on non-trivial model data, conditional ++and looping constructs like Python's *for* and *if* are generally needed. ++*Template engines* support templates of this complexity. ++ ++There are a lot of template engines available for Python which can be used with ++or without a `framework`_. Some of these define a plain-text programming ++language which is easy to learn, partly because it is limited in scope. ++Others use XML, and the template output is guaranteed to be always be valid ++XML. There are many other variations. ++ ++Some `frameworks`_ ship their own template engine or recommend one in ++particular. In the absence of a reason to use a different template engine, ++using the one provided by or recommended by the framework is a good idea. ++ ++Popular template engines include: ++ ++ * `Mako <http://www.makotemplates.org/>`_ ++ * `Genshi <http://genshi.edgewall.org/>`_ ++ * `Jinja <http://jinja.pocoo.org/2/>`_ + + .. seealso:: + +- Lots of different template engines divide the attention between themselves +- because it's easy to create them in Python. The page `Templating ++ There are many template engines competing for attention, becuase it is ++ pretty easy to create them in Python. The page `Templating + <http://wiki.python.org/moin/Templating>`_ in the wiki lists a big, +- ever-growing number of these. ++ ever-growing number of these. The three listed above are considered "second ++ generation" template engines and are a good place to start. + + + Data persistence + ---------------- + +-*Data persistence*, while sounding very complicated is just about storing data. +-This data might be the text of blog entries, the postings of a bulletin board or +-the text of a wiki page. As always, there are different ways to store +-informations on a web server. +- +-Often relational database engines like `MySQL <http://www.mysql.com/>`_ or +-`PostgreSQL <http://http://www.postgresql.org/>`_ are used due to their good +-performance handling very large databases consisting of up to millions of +-entries. These are *queried* using a language called `SQL +-<http://en.wikipedia.org/wiki/SQL>`_. Python programmers in general do not like +-SQL too much, they prefer to work with objects. It is possible to save Python +-objects into a database using a technology called `ORM +-<http://en.wikipedia.org/wiki/Object-relational_mapping>`_. ORM translates all +-object-oriented access into SQL code under the hood, the user does not need to +-think about it. Most `frameworks`_ use ORMs and it works quite well. +- +-A second possibility is using files that are saved on the hard disk (sometimes +-called flatfiles). This is very easy, but is not too fast. There is even a +-small database engine called `SQLite <http://www.sqlite.org/>`_ which is bundled +-with Python in the :mod:`sqlite` module and uses only one file. This database +-can be used to store objects via an ORM and has no other dependencies. For +-smaller sites SQLite is just enough. But it is not the only way in which data +-can be saved into the file systems. Sometimes normal, plain text files are +-enough. +- +-The third and least used possibility are so-called object oriented databases. +-These databases store the *actual objects* instead of the relations that +-OR-mapping creates between rows in a database. This has the advantage that +-nearly all objects can be saven in a straightforward way, unlike in relational +-databases where some objects are very hard to represent with ORMs. +- +-`Frameworks`_ often give the users hints on which method to choose, it is +-usually a good idea to stick to these unless there are some special requirements +-which require to use the one method and not the other. ++*Data persistence*, while sounding very complicated, is just about storing data. ++This data might be the text of blog entries, the postings on a bulletin board or ++the text of a wiki page. There are, of course, a number of different ways to store ++information on a web server. ++ ++Often, relational database engines like `MySQL <http://www.mysql.com/>`_ or ++`PostgreSQL <http://www.postgresql.org/>`_ are used because of their good ++performance when handling very large databases consisting of millions of ++entries. There is also a small database engine called `SQLite ++<http://www.sqlite.org/>`_, which is bundled with Python in the :mod:`sqlite3` ++module, and which uses only one file. It has no other dependencies. For ++smaller sites SQLite is just enough. ++ ++Relational databases are *queried* using a language called `SQL ++<http://en.wikipedia.org/wiki/SQL>`_. Python programmers in general do not ++like SQL too much, as they prefer to work with objects. It is possible to save ++Python objects into a database using a technology called `ORM ++<http://en.wikipedia.org/wiki/Object-relational_mapping>`_ (Object Relational ++Mapping). ORM translates all object-oriented access into SQL code under the ++hood, so the developer does not need to think about it. Most `frameworks`_ use ++ORMs, and it works quite well. ++ ++A second possibility is storing data in normal, plain text files (some ++times called "flat files"). This is very easy for simple sites, ++but can be difficult to get right if the web site is performing many ++updates to the stored data. ++ ++A third possibility are object oriented databases (also called "object ++databases"). These databases store the object data in a form that closely ++parallels the way the objects are structured in memory during program ++execution. (By contrast, ORMs store the object data as rows of data in tables ++and relations between those rows.) Storing the objects directly has the ++advantage that nearly all objects can be saved in a straightforward way, unlike ++in relational databases where some objects are very hard to represent. ++ ++`Frameworks`_ often give hints on which data storage method to choose. It is ++usually a good idea to stick to the data store recommended by the framework ++unless the application has special requirements better satisfied by an ++alternate storage mechanism. + + .. seealso:: + + * `Persistence Tools <http://wiki.python.org/moin/PersistenceTools>`_ lists +- possibilities on how to save data in the file system, some of these modules +- are part of the standard library ++ possibilities on how to save data in the file system. Some of these ++ modules are part of the standard library ++ + * `Database Programming <http://wiki.python.org/moin/DatabaseProgramming>`_ +- helps on choosing a method on how to save the data +- * `SQLAlchemy <http://www.sqlalchemy.org/>`_, the most powerful OR-Mapper for +- Python and `Elixir <http://elixir.ematia.de/>`_ which makes it easier to +- use ++ helps with choosing a method for saving data ++ ++ * `SQLAlchemy <http://www.sqlalchemy.org/>`_, the most powerful OR-Mapper ++ for Python, and `Elixir <http://elixir.ematia.de/>`_, which makes ++ SQLAlchemy easier to use ++ + * `SQLObject <http://www.sqlobject.org/>`_, another popular OR-Mapper ++ + * `ZODB <https://launchpad.net/zodb>`_ and `Durus + <http://www.mems-exchange.org/software/durus/>`_, two object oriented + databases + + + .. _framework: + + Frameworks + ========== + +-As web sites can easily become quite large, there are so-called frameworks which +-were created to help the developer with making these sites. Although the most +-well-known framework is Ruby on Rails, Python does also have its own frameworks +-which are partly inspired by Rails or which were existing a long time before +-Rails. +- +-Two possible approaches to web frameworks exist: the minimalistic approach and +-the all-inclusive approach (somtimes called *full-stack*). Frameworks which are +-all-inclusive give you everything you need to start working, like a template +-engine, some way to save and access data in databases and many features more. +-Most users are best off using these as they are widely used by lots of other +-users and well documented in form of books and tutorials. Other web frameworks +-go the minimalistic approach trying to be as flexible as possible leaving the +-user the freedom to choose what's best for him. +- +-The majority of users is best off with all-inclusive framewors. They bring +-everything along so a user can just jump in and start to code. While they do +-have some limitations they can fullfill 80% of what one will ever want to +-perfectly. They consist of various components which are designed to work +-together as good as possible. +- +-The multitude of web frameworks written in Python demonstrates that it is really +-easy to write one. One of the most well-known web applications written in +-Python is `Zope <http://www.zope.org/>`_ which can be regarded as some kind of +-big framework. But Zope was not the only framework, there were some others +-which are by now nearly forgotten. These do not need to be mentioned anymore, +-because most people that used them moved on to newer ones. ++The process of creating code to run web sites involves writing code to provide ++various services. The code to provide a particular service often works the ++same way regardless of the complexity or purpose of the web site in question. ++Abstracting these common solutions into reusable code produces what are called ++"frameworks" for web development. Perhaps the most well-known framework for ++web development is Ruby on Rails, but Python has its own frameworks. Some of ++these were partly inspired by Rails, or borrowed ideas from Rails, but many ++existed a long time before Rails. ++ ++Originally Python web frameworks tended to incorporate all of the services ++needed to develop web sites as a giant, integrated set of tools. No two web ++frameworks were interoperable: a program developed for one could not be ++deployed on a different one without considerable re-engineering work. This led ++to the development of "minimalist" web frameworks that provided just the tools ++to communicate between the Python code and the http protocol, with all other ++services to be added on top via separate components. Some ad hoc standards ++were developed that allowed for limited interoperability between frameworks, ++such as a standard that allowed different template engines to be used ++interchangeably. ++ ++Since the advent of WSGI, the Python web framework world has been evolving ++toward interoperability based on the WSGI standard. Now many web frameworks, ++whether "full stack" (providing all the tools one needs to deploy the most ++complex web sites) or minimalist, or anything in between, are built from ++collections of reusable components that can be used with more than one ++framework. ++ ++The majority of users will probably want to select a "full stack" framework ++that has an active community. These frameworks tend to be well documented, ++and provide the easiest path to producing a fully functional web site in ++minimal time. + + + Some notable frameworks + ----------------------- + +-There is an incredible number of frameworks, so there is no way to describe them +-all. It is not even neccessary, as most of these frameworks are nothing special +-and everything that can be done with these can also be done with one of the +-popular ones. ++There are an incredible number of frameworks, so they cannot all be covered ++here. Instead we will briefly touch on some of the most popular. + + + Django ***The diff for this file has been truncated for email.*** ======================================= --- /dev/null +++ /howto/diff/webservers.rst.html Sat Mar 19 08:45:35 2011 @@ -0,0 +1,828 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html> + +<head> + <meta http-equiv="Content-Type" + content="text/html; charset=ISO-8859-1" /> + <title></title> + <style type="text/css"> + table.diff {font-family:Courier; border:medium;} + .diff_header {background-color:#e0e0e0} + td.diff_header {text-align:right} + .diff_next {background-color:#c0c0c0} + .diff_add {background-color:#aaffaa} + .diff_chg {background-color:#ffff77} + .diff_sub {background-color:#ffaaaa} + </style> +</head> + +<body> + + <table class="diff" id="difflib_chg_to55__top" + cellspacing="0" cellpadding="0" rules="groups" > + <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> + <thead><tr><th class="diff_next"><br /></th><th colspan="2" class="diff_header">r262/howto/webservers.rst => r266/howto/webservers.rst</th></tr></thead> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to55__0"><a href="#difflib_chg_to55__0">f</a></td><td class="diff_header" id="from55_1">1</td><td nowrap="nowrap">*******************************</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_2">2</td><td nowrap="nowrap"> HOWTO Use Python in the web</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_3">3</td><td nowrap="nowrap">*******************************</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_4">4</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_5">5</td><td nowrap="nowrap">:Author: Marek Kubica</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__1"></td><td class="diff_header" id="from55_6">6</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_7">7</td><td nowrap="nowrap">.. topic:: Abstract</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_8">8</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__2"><a href="#difflib_chg_to55__1">n</a></td><td class="diff_header" id="from55_9">9-</td><td nowrap="nowrap"> This document shows how Python fits into the web. It presents some ways<span class="diff_sub"> on</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__2"><a href="#difflib_chg_to55__1">n</a></td><td class="diff_header" id="to55_9">9+</td><td nowrap="nowrap"> This document shows how Python fits into the web. It presents some ways</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_10">10-</td><td nowrap="nowrap"> <span class="diff_sub"> how</span> to integrate Python with <span class="diff_chg">the</span> web server and general practices useful for</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_10">10+</td><td nowrap="nowrap"> to integrate Python with <span class="diff_chg">a</span> web server<span class="diff_add">,</span> and general practices useful for</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_11">11</td><td nowrap="nowrap"> developing web sites.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_12">12</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_13">13</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__2">n</a></td><td class="diff_header" id="from55_14">14-</td><td nowrap="nowrap">Programming for the Web has become a hot topic since the r<span class="diff_sub">a</span>ise of<span class="diff_sub"> the</span> "Web 2.0",</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__2">n</a></td><td class="diff_header" id="to55_14">14+</td><td nowrap="nowrap">Programming for the Web has become a hot topic since the rise of "Web 2.0",</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_15">15</td><td nowrap="nowrap">which focuses on user-generated content on web sites. It has always been</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_16">16</td><td nowrap="nowrap">possible to use Python for creating web sites, but it was a rather tedious task.</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__3">n</a></td><td class="diff_header" id="from55_17">17-</td><td nowrap="nowrap">Therefore, many <span class="diff_sub">so-called "</span>frameworks<span class="diff_sub">"</span> and helper tools <span class="diff_chg">w</span>e<span class="diff_chg">r</span>e created to <span class="diff_chg">help</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__3">n</a></td><td class="diff_header" id="to55_17">17+</td><td nowrap="nowrap">Therefore, many frameworks and helper tools <span class="diff_chg">hav</span>e<span class="diff_chg"> b</span>e<span class="diff_add">en</span> created to <span class="diff_chg">assist</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__3"></td><td class="diff_header" id="from55_18">18-</td><td nowrap="nowrap"><span class="diff_sub">developers creating sites faster and these sites being more robust. This HOWTO</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__3"></td><td class="diff_header" id="to55_18">18+</td><td nowrap="nowrap"><span class="diff_add">developers in creating faster and more robust sites. This HOWTO describes</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_19">19-</td><td nowrap="nowrap"><span class="diff_sub">describes </span>some of the methods used to combine Python with a web server to create</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_19">19+</td><td nowrap="nowrap">some of the methods used to combine Python with a web server to create</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_20">20-</td><td nowrap="nowrap">dynamic content. It is not meant as a <span class="diff_chg">g</span>e<span class="diff_chg">n</span>e<span class="diff_sub">ral</span> introduction as this topic is<span class="diff_sub"> far</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_20">20+</td><td nowrap="nowrap">dynamic content. It is not meant as a <span class="diff_chg">compl</span>e<span class="diff_chg">t</span>e introduction<span class="diff_add">,</span> as this topic is</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_21">21-</td><td nowrap="nowrap">too broad to be covered in one single document. However, a short overview<span class="diff_sub"> of</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_21">21+</td><td nowrap="nowrap"><span class="diff_add">far </span>too broad to be covered in one single document. However, a short overview</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_22">22-</td><td nowrap="nowrap">the most popular libraries is provided.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_22">22+</td><td nowrap="nowrap"><span class="diff_add">of </span>the most popular libraries is provided.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_23">23</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_24">24</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__4"></td><td class="diff_header" id="from55_25">25</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__4">n</a></td><td class="diff_header" id="from55_26">26-</td><td nowrap="nowrap"> While this HOWTO tries to give an overview o<span class="diff_chg">ver</span> Python in the <span class="diff_chg">W</span>eb, it cannot</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__4">n</a></td><td class="diff_header" id="to55_26">26+</td><td nowrap="nowrap"> While this HOWTO tries to give an overview o<span class="diff_chg">f</span> Python in the <span class="diff_chg">w</span>eb, it cannot</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_27">27-</td><td nowrap="nowrap"> always be as up to date as desired. Web development in Python is <span class="diff_chg">mov</span>i<span class="diff_chg">ng</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_27">27+</td><td nowrap="nowrap"> always be as up to date as desired. Web development in Python is <span class="diff_chg">rap</span>i<span class="diff_chg">dly</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__5"></td><td class="diff_header" id="from55_28">28-</td><td nowrap="nowrap"> forward<span class="diff_sub"> rapidly</span>, so the wiki page on `Web Programming</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__5"></td><td class="diff_header" id="to55_28">28+</td><td nowrap="nowrap"> <span class="diff_add"> moving</span> forward, so the wiki page on `Web Programming</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_29">29-</td><td nowrap="nowrap"> <http://wiki.python.org/moin/WebProgramming>`_ m<span class="diff_chg">ight</span> be more in sync with</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_29">29+</td><td nowrap="nowrap"> <http://wiki.python.org/moin/WebProgramming>`_ m<span class="diff_chg">ay</span> be more in sync with</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_30">30</td><td nowrap="nowrap"> recent development.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_31">31</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_32">32</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__6"><a href="#difflib_chg_to55__5">n</a></td><td class="diff_header" id="from55_33">33-</td><td nowrap="nowrap">The <span class="diff_chg">l</span>ow-<span class="diff_chg">l</span>evel <span class="diff_chg">v</span>iew</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__6"><a href="#difflib_chg_to55__5">n</a></td><td class="diff_header" id="to55_33">33+</td><td nowrap="nowrap">The <span class="diff_chg">L</span>ow-<span class="diff_chg">L</span>evel <span class="diff_chg">V</span>iew</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_34">34</td><td nowrap="nowrap">==================</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__7"></td><td class="diff_header" id="from55_35">35</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__6">n</a></td><td class="diff_header" id="from55_36">36-</td><td nowrap="nowrap"><span class="diff_sub">.. .. image:: http.png</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_37">37-</td><td nowrap="nowrap"><span class="diff_sub"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_38">38-</td><td nowrap="nowrap">When a user enters a web site, hi<span class="diff_chg">s</span> browser makes a connection to the site's</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_36">36+</td><td nowrap="nowrap">When a user enters a web site, <span class="diff_add">t</span>h<span class="diff_add">e</span>i<span class="diff_chg">r</span> browser makes a connection to the site's</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_39">39-</td><td nowrap="nowrap">webserver (this is called the *request*). The server looks up the file in the</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_37">37+</td><td nowrap="nowrap">web<span class="diff_add"> </span>server (this is called the *request*). The server looks up the file in the</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_40">40</td><td nowrap="nowrap">file system and sends it back to the user's browser, which displays it (this is</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__7">n</a></td><td class="diff_header" id="from55_41">41-</td><td nowrap="nowrap">the *response*). This is roughly how the un<span class="diff_chg">t</span>erlying protocol, HTTP works.</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__7">n</a></td><td class="diff_header" id="to55_39">39+</td><td nowrap="nowrap">the *response*). This is roughly how the un<span class="diff_chg">d</span>erlying protocol, HTTP<span class="diff_add">,</span> works.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_42">42</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__8"><a href="#difflib_chg_to55__8">n</a></td><td class="diff_header" id="from55_43">43-</td><td nowrap="nowrap"><span class="diff_chg">Now, d</span>ynamic web sites are not files in the file system, but rather <span class="diff_sub">pr</span>o<span class="diff_chg">grams</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__8"><a href="#difflib_chg_to55__8">n</a></td><td class="diff_header" id="to55_41">41+</td><td nowrap="nowrap"><span class="diff_chg">D</span>ynamic web sites are not<span class="diff_add"> based on</span> files in the file system, but rather o<span class="diff_chg">n</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_44">44-</td><td nowrap="nowrap">which are run by the web server when a request comes in<span class="diff_chg">. They c</span>an<span class="diff_sub"> </span>d<span class="diff_chg">o all sorts</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_42">42+</td><td nowrap="nowrap"><span class="diff_add">programs </span>which are run by the web server when a request comes in<span class="diff_chg">, </span>and<span class="diff_chg"> which</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_43">43+</td><td nowrap="nowrap"><span class="diff_add">*generate* the content that is returned to the user. They can do all sorts of</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_45">45-</td><td nowrap="nowrap"><span class="diff_sub">of </span>useful things, like display the postings of a bulletin board, show your</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_44">44+</td><td nowrap="nowrap">useful things, like display the postings of a bulletin board, show your<span class="diff_add"> email,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_46">46-</td><td nowrap="nowrap"><span class="diff_sub">mails, </span>configur<span class="diff_sub">at</span>e software or just display the current time. These programs</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_45">45+</td><td nowrap="nowrap">configure software<span class="diff_add">,</span> or just display the current time. These programs<span class="diff_add"> can be</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_47">47-</td><td nowrap="nowrap"><span class="diff_sub">can be </span>written in<span class="diff_sub"> about</span> any programming language the server supports<span class="diff_chg">, </span>s<span class="diff_sub">o i</span>t <span class="diff_sub">i</span>s</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_46">46+</td><td nowrap="nowrap">written in any programming language the server supports<span class="diff_chg">. Since mo</span>st s<span class="diff_add">ervers</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__9"></td><td class="diff_header" id="from55_48">48-</td><td nowrap="nowrap"><span class="diff_sub">easy to use Python for creating dynamic web sites.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__9"></td><td class="diff_header" id="to55_47">47+</td><td nowrap="nowrap"><span class="diff_add">support Python, it is easy to use Python to create dynamic web sites.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_49">49</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__9">n</a></td><td class="diff_header" id="from55_50">50-</td><td nowrap="nowrap"><span class="diff_chg">As m</span>ost<span class="diff_sub"> of</span> HTTP servers are written in C or C++, they cannot execute Python code</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__9">n</a></td><td class="diff_header" id="to55_49">49+</td><td nowrap="nowrap"><span class="diff_chg">M</span>ost HTTP servers are written in C or C++, <span class="diff_add">so </span>they cannot execute Python code</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_51">51-</td><td nowrap="nowrap">i<span class="diff_chg">n a simp</span>l<span class="diff_sub">e wa</span>y -- a bridge is needed between the server and the program. These</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_50">50+</td><td nowrap="nowrap"><span class="diff_add">d</span>i<span class="diff_chg">rect</span>ly -- a bridge is needed between the server and the program. These</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_52">52-</td><td nowrap="nowrap">bridges or rather interfaces define how programs interact with the server.<span class="diff_sub"> In</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_51">51+</td><td nowrap="nowrap">bridges<span class="diff_add">,</span> or rather interfaces<span class="diff_add">,</span> define how programs interact with the server.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_53">53-</td><td nowrap="nowrap"><span class="diff_chg">the past t</span>here have been numerous attempts to create the best possible</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_52">52+</td><td nowrap="nowrap"><span class="diff_chg">T</span>here have been numerous attempts to create the best possible<span class="diff_add"> interface, but</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_54">54-</td><td nowrap="nowrap"><span class="diff_sub">interface, but </span>there are only a few worth mentioning.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_53">53+</td><td nowrap="nowrap">there are only a few worth mentioning.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_55">55</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__10"><a href="#difflib_chg_to55__10">n</a></td><td class="diff_header" id="from55_56">56-</td><td nowrap="nowrap">Not every web server supports every interface. Many web servers <span class="diff_sub">d</span>o support<span class="diff_sub"> only</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__10"><a href="#difflib_chg_to55__10">n</a></td><td class="diff_header" id="to55_55">55+</td><td nowrap="nowrap">Not every web server supports every interface. Many web servers o<span class="diff_add">nly</span> support</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_57">57-</td><td nowrap="nowrap">old, now-obsolete interfaces<span class="diff_chg">. But</span> they can often be extended using<span class="diff_sub"> some</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_56">56+</td><td nowrap="nowrap">old, now-obsolete interfaces<span class="diff_chg">; however,</span> they can often be extended using</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_58">58-</td><td nowrap="nowrap">third-party modules to support new<span class="diff_sub"> int</span>er<span class="diff_chg">fac</span>es.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_57">57+</td><td nowrap="nowrap">third-party modules to support newer<span class="diff_chg"> on</span>es.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_59">59</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_60">60</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_61">61</td><td nowrap="nowrap">Common Gateway Interface</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_62">62</td><td nowrap="nowrap">------------------------</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__11"></td><td class="diff_header" id="from55_63">63</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__11">n</a></td><td class="diff_header" id="from55_64">64-</td><td nowrap="nowrap"><span class="diff_sub">This interface is the oldest one, supported by nearly every web server out of</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__11">n</a></td><td class="diff_header" id="to55_63">63+</td><td nowrap="nowrap"><span class="diff_add">This interface, most commonly referred to as "CGI", is the oldest, and is</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_65">65-</td><td nowrap="nowrap"><span class="diff_sub">the box. Programs using CGI to communicate with their web server need to be</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_64">64+</td><td nowrap="nowrap"><span class="diff_add">supported by nearly every web server out of the box. Programs using CGI to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_66">66-</td><td nowrap="nowrap"><span class="diff_sub">started by the server for every request. So, every request starts a new Python</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_65">65+</td><td nowrap="nowrap"><span class="diff_add">communicate with their web server need to be started by the server for every</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__12"></td><td class="diff_header" id="from55_67">67-</td><td nowrap="nowrap"><span class="diff_sub">interpreter -- which takes some time to start up -- thus making the whole</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__12"></td><td class="diff_header" id="to55_66">66+</td><td nowrap="nowrap"><span class="diff_add">request. So, every request starts a new Python interpreter -- which takes some</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_68">68-</td><td nowrap="nowrap"><span class="diff_sub">interface only usable for low load situations.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_67">67+</td><td nowrap="nowrap"><span class="diff_add">time to start up -- thus making the whole interface only usable for low load</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_68">68+</td><td nowrap="nowrap"><span class="diff_add">situations.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_69">69</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__12">n</a></td><td class="diff_header" id="from55_70">70-</td><td nowrap="nowrap">The upside of CGI is that it is simple -- writing a program which uses<span class="diff_sub"> CGI is a</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__12">n</a></td><td class="diff_header" id="to55_70">70+</td><td nowrap="nowrap">The upside of CGI is that it is simple -- writing a<span class="diff_add"> Python</span> program which uses</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_71">71-</td><td nowrap="nowrap">matter of about three lines of code. <span class="diff_chg">But t</span>his simplicity comes at a<span class="diff_sub"> price: it</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_71">71+</td><td nowrap="nowrap"><span class="diff_add">CGI is a </span>matter of about three lines of code. <span class="diff_chg">T</span>his simplicity comes at a</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_72">72-</td><td nowrap="nowrap">does very few things to help the developer.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_72">72+</td><td nowrap="nowrap"><span class="diff_add">price: it </span>does very few things to help the developer.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_73">73</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__13">n</a></td><td class="diff_header" id="from55_74">74-</td><td nowrap="nowrap">Writing CGI programs, while still possible, is no<span class="diff_chg">t</span> recommended<span class="diff_sub"> anymore</span>. With</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__13">n</a></td><td class="diff_header" id="to55_74">74+</td><td nowrap="nowrap">Writing CGI programs, while still possible, is no<span class="diff_chg"> longer</span> recommended. With</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_75">75-</td><td nowrap="nowrap"><span class="diff_sub">WSGI (more on that later) it is possible to write programs that emulate CGI, so</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_75">75+</td><td nowrap="nowrap"><span class="diff_add">:ref:`WSGI <WSGI>`, a topic covered later in this document, it is possible to write</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_76">76-</td><td nowrap="nowrap"><span class="diff_sub">they can be run as CGI if no better option is available.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_76">76+</td><td nowrap="nowrap"><span class="diff_add">programs that emulate CGI, so they can be run as CGI if no better option is</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__13"></td><td class="diff_header" id="to55_77">77+</td><td nowrap="nowrap"><span class="diff_add">available.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_77">77</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_78">78</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_79">79</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_80">80</td><td nowrap="nowrap"> The Python standard library includes some modules that are helpful for</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_81">81</td><td nowrap="nowrap"> creating plain CGI programs:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_82">82</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_83">83</td><td nowrap="nowrap"> * :mod:`cgi` -- Handling of user input in CGI scripts</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__14">n</a></td><td class="diff_header" id="from55_84">84-</td><td nowrap="nowrap"> * :mod:`cgitb` -- Displays nice tracebacks when errors happen in<span class="diff_sub"> of</span> CGI</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__14">n</a></td><td class="diff_header" id="to55_85">85+</td><td nowrap="nowrap"> * :mod:`cgitb` -- Displays nice tracebacks when errors happen in CGI</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_85">85</td><td nowrap="nowrap"> applications, instead of presenting a "500 Internal Server Error" message</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_86">86</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_87">87</td><td nowrap="nowrap"> The Python wiki features a page on `CGI scripts</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_88">88</td><td nowrap="nowrap"> <http://wiki.python.org/moin/CgiScripts>`_ with some additional information</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_89">89</td><td nowrap="nowrap"> about CGI in Python.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_90">90</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_91">91</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_92">92</td><td nowrap="nowrap">Simple script for testing CGI</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to55__14"></td><td class="diff_header" id="from55_102">102</td><td nowrap="nowrap"> import cgitb</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_103">103</td><td nowrap="nowrap"> cgitb.enable()</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_104">104</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_105">105</td><td nowrap="nowrap"> print "Content-Type: text/plain;charset=utf-8"</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_106">106</td><td nowrap="nowrap"> print</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_107">107</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_108">108</td><td nowrap="nowrap"> print "Hello World!"</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_109">109</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__15"><a href="#difflib_chg_to55__15">n</a></td><td class="diff_header" id="from55_110">110-</td><td nowrap="nowrap"><span class="diff_sub">You need to write this code into a file with a ``.py`` or ``.cgi`` extension,</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__15"><a href="#difflib_chg_to55__15">n</a></td><td class="diff_header" id="to55_111">111+</td><td nowrap="nowrap"><span class="diff_add">Depending on your web server configuration, you may need to save this code with</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_111">111-</td><td nowrap="nowrap"><span class="diff_sub">this depends on your web server configuration. Depending on your web server</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_112">112+</td><td nowrap="nowrap"><span class="diff_add">a ``.py`` or ``.cgi`` extension. Additionally, this file may also need to be</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_112">112-</td><td nowrap="nowrap"><span class="diff_sub">configuration, this file may also need to be in a ``cgi-bin`` folder, for</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_113">113+</td><td nowrap="nowrap"><span class="diff_add">in a ``cgi-bin`` folder, for security reasons.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_113">113-</td><td nowrap="nowrap"><span class="diff_sub">security reasons.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_114">114</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_115">115</td><td nowrap="nowrap">You might wonder what the ``cgitb`` line is about. This line makes it possible</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_116">116</td><td nowrap="nowrap">to display a nice traceback instead of just crashing and displaying an "Internal</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_117">117</td><td nowrap="nowrap">Server Error" in the user's browser. This is useful for debugging, but it might</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__16">n</a></td><td class="diff_header" id="from55_118">118-</td><td nowrap="nowrap"><span class="diff_sub">risk exposing some confident data to the user. Don't use it when the script is</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__16">n</a></td><td class="diff_header" id="to55_118">118+</td><td nowrap="nowrap"><span class="diff_add">risk exposing some confidential data to the user. You should not use ``cgitb``</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_119">119-</td><td nowrap="nowrap"><span class="diff_sub">ready for production use. Still, you should *always* catch exceptions, and</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_119">119+</td><td nowrap="nowrap"><span class="diff_add">in production code for this reason. You should *always* catch exceptions, and</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__16"></td><td class="diff_header" id="from55_120">120</td><td nowrap="nowrap">display proper error pages -- end-users don't like to see nondescript "Internal</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_121">121</td><td nowrap="nowrap">Server Errors" in their browsers.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_122">122</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_123">123</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to55__17"></td><td class="diff_header" id="from55_124">124</td><td nowrap="nowrap">Setting up CGI on your own server</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_125">125</td><td nowrap="nowrap">^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_126">126</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_127">127</td><td nowrap="nowrap">If you don't have your own web server, this does not apply to you. You can</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__17">n</a></td><td class="diff_header" id="from55_128">128-</td><td nowrap="nowrap">check whether i<span class="diff_chg">f</span> works as-is and if not you need to talk to the<span class="diff_sub"> administrator of</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__17">n</a></td><td class="diff_header" id="to55_128">128+</td><td nowrap="nowrap">check whether i<span class="diff_chg">t</span> works as-is<span class="diff_add">,</span> and if not you<span class="diff_add"> will</span> need to talk to the</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_129">129-</td><td nowrap="nowrap">your web server<span class="diff_sub"> anyway</span>. If it is a big host<span class="diff_sub">er</span>, you can try filing a<span class="diff_sub"> ticket</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_129">129+</td><td nowrap="nowrap"><span class="diff_add">administrator of </span>your web server. If it is a big host, you can try filing a</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_130">130-</td><td nowrap="nowrap">asking for Python support.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_130">130+</td><td nowrap="nowrap"><span class="diff_add">ticket </span>asking for Python support.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_131">131</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__18">n</a></td><td class="diff_header" id="from55_132">132-</td><td nowrap="nowrap">If you<span class="diff_chg">'</span>re your own administrator or want to <span class="diff_sub">in</span>st<span class="diff_chg">all it</span> for testing purposes on</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__18">n</a></td><td class="diff_header" id="to55_132">132+</td><td nowrap="nowrap">If you<span class="diff_chg"> a</span>re your own administrator or want to s<span class="diff_add">e</span>t<span class="diff_chg"> up CGI</span> for testing purposes on</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_133">133-</td><td nowrap="nowrap">your own computers, you have to configure it by yourself. There is no <span class="diff_chg">o</span>ne<span class="diff_sub"> and</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_133">133+</td><td nowrap="nowrap">your own computers, you have to configure it by yourself. There is no <span class="diff_chg">si</span>n<span class="diff_add">gl</span>e</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_134">134-</td><td nowrap="nowrap"><span class="diff_sub">single </span>way <span class="diff_sub">on how </span>to configure CGI, as there are many web servers with different</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_134">134+</td><td nowrap="nowrap">way to configure CGI, as there are many web servers with different</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__18"></td><td class="diff_header" id="from55_135">135-</td><td nowrap="nowrap">configuration options. <span class="diff_chg">The c</span>urrently most widely used free web server is</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__18"></td><td class="diff_header" id="to55_135">135+</td><td nowrap="nowrap">configuration options. <span class="diff_chg">C</span>urrently <span class="diff_add">the </span>most widely used free web server is</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_136">136-</td><td nowrap="nowrap">`Apache HTTPd <http://httpd.apache.org/>`_, Apache for short<span class="diff_chg"> -- this is t</span>he <span class="diff_chg">o</span>ne</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_136">136+</td><td nowrap="nowrap">`Apache HTTPd <http://httpd.apache.org/>`_, <span class="diff_add">or </span>Apache for short<span class="diff_chg">. Apac</span>he <span class="diff_chg">ca</span>n<span class="diff_add"> b</span>e</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_137">137-</td><td nowrap="nowrap"><span class="diff_sub">that most people use, it can be easily installed on nearly every system using</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_137">137+</td><td nowrap="nowrap"><span class="diff_add">easily installed on nearly every system using the system's package management</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_138">138-</td><td nowrap="nowrap"><span class="diff_sub">the systems' package management. But `lighttpd <http://www.lighttpd.net>`_ has</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_138">138+</td><td nowrap="nowrap"><span class="diff_add">tool. `lighttpd <http://www.lighttpd.net>`_ is another alternative and is</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__19"></td><td class="diff_header" id="from55_139">139-</td><td nowrap="nowrap"><span class="diff_sub">been gaining attention since some time and is said to have a better performance.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__19"></td><td class="diff_header" id="to55_139">139+</td><td nowrap="nowrap"><span class="diff_add">said to have better performance. On many systems this server can also be</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_140">140-</td><td nowrap="nowrap"><span class="diff_sub">On many systems this server can also be installed using the package management,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_140">140+</td><td nowrap="nowrap"><span class="diff_add">installed using the package management tool, so manually compiling the web</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__20"></td><td class="diff_header" id="from55_141">141-</td><td nowrap="nowrap"><span class="diff_sub">so manually compiling the web server is never needed.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__20"></td><td class="diff_header" id="to55_141">141+</td><td nowrap="nowrap"><span class="diff_add">server may not be needed.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_142">142</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__19">n</a></td><td class="diff_header" id="from55_143">143-</td><td nowrap="nowrap">* On Apache you can take a look <span class="diff_chg">in</span>t<span class="diff_sub">o</span> the `Dynamic Content with CGI</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__19">n</a></td><td class="diff_header" id="to55_143">143+</td><td nowrap="nowrap">* On Apache you can take a look <span class="diff_chg">a</span>t the `Dynamic Content with CGI</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_144">144</td><td nowrap="nowrap"> <http://httpd.apache.org/docs/2.2/howto/cgi.html>`_ tutorial, where everything</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_145">145</td><td nowrap="nowrap"> is described. Most of the time it is enough just to set ``+ExecCGI``. The</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_146">146</td><td nowrap="nowrap"> tutorial also describes the most common gotchas that might arise.</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__20">n</a></td><td class="diff_header" id="to55_147">147+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__21"></td><td class="diff_header" id="from55_147">147</td><td nowrap="nowrap">* On lighttpd you need to use the `CGI module</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__21">n</a></td><td class="diff_header" id="from55_148">148-</td><td nowrap="nowrap"> <http://<span class="diff_sub">t</span>r<span class="diff_chg">ac</span>.lighttpd.net/<span class="diff_sub">trac/</span>wiki/Docs<span class="diff_chg">%3A</span>ModCGI>`_ which can be configured</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__21">n</a></td><td class="diff_header" id="to55_149">149+</td><td nowrap="nowrap"> <http://r<span class="diff_chg">edmine</span>.lighttpd.net/wiki/<span class="diff_add">lighttpd/</span>Docs<span class="diff_chg">:</span>ModCGI>`_<span class="diff_add">\ ,</span> which can be configured</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_149">149</td><td nowrap="nowrap"> in a straightforward way. It boils down to setting ``cgi.assign`` properly.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_150">150</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_151">151</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to55__22"></td><td class="diff_header" id="from55_152">152</td><td nowrap="nowrap">Common problems with CGI scripts</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_153">153</td><td nowrap="nowrap">^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__23"></td><td class="diff_header" id="from55_154">154</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__22">n</a></td><td class="diff_header" id="from55_155">155-</td><td nowrap="nowrap"><span class="diff_sub">Trying to use CGI sometimes leads to small annoyances that one might experience</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__22">n</a></td><td class="diff_header" id="to55_156">156+</td><td nowrap="nowrap"><span class="diff_add">Using CGI sometimes leads to small annoyances while trying to get these</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_156">156-</td><td nowrap="nowrap"><span class="diff_sub">while trying to get these scripts to run. Sometimes it happens that a seemingly</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_157">157+</td><td nowrap="nowrap"><span class="diff_add">scripts to run. Sometimes a seemingly correct script does not work as</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__24"></td><td class="diff_header" id="from55_157">157-</td><td nowrap="nowrap"><span class="diff_sub">correct script does not work as expected, which is caused by some small hidden</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__24"></td><td class="diff_header" id="to55_158">158+</td><td nowrap="nowrap"><span class="diff_add">expected, the cause being some small hidden problem that's difficult to spot.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_158">158-</td><td nowrap="nowrap"><span class="diff_sub">reason that's difficult to spot.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_159">159</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__23">n</a></td><td class="diff_header" id="from55_160">160-</td><td nowrap="nowrap"><span class="diff_sub">Some of these reasons are:</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__23">n</a></td><td class="diff_header" id="to55_160">160+</td><td nowrap="nowrap"><span class="diff_add">Some of these potential problems are:</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_161">161</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__24">n</a></td><td class="diff_header" id="from55_162">162-</td><td nowrap="nowrap">* The Python script is not marked executable. When CGI scripts are not</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__24">n</a></td><td class="diff_header" id="to55_162">162+</td><td nowrap="nowrap">* The Python script is not marked<span class="diff_add"> as</span> executable. When CGI scripts are not</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_163">163-</td><td nowrap="nowrap"> executable most <span class="diff_sub">of the </span>web servers will let the user download it, instead of</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_163">163+</td><td nowrap="nowrap"> executable most web servers will let the user download it, instead of</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_164">164</td><td nowrap="nowrap"> running it and sending the output to the user. For CGI scripts to run</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__25">n</a></td><td class="diff_header" id="from55_165">165-</td><td nowrap="nowrap"><span class="diff_sub"> properly the ``+x`` bit needs to be set. Using ``chmod a+x your_script.py``</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__25">n</a></td><td class="diff_header" id="to55_165">165+</td><td nowrap="nowrap"><span class="diff_add"> properly on Unix-like operating systems, the ``+x`` bit needs to be set.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_166">166-</td><td nowrap="nowrap"><span class="diff_sub"> might already solve the problem.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_166">166+</td><td nowrap="nowrap"><span class="diff_add"> Using ``chmod a+x your_script.py`` may solve this problem.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_167">167-</td><td nowrap="nowrap"><span class="diff_sub">* The line endings must be of Unix-type. This is important because the web</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_167">167+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_168">168+</td><td nowrap="nowrap"><span class="diff_add">* On a Unix-like system, The line endings in the program file must be Unix</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_169">169+</td><td nowrap="nowrap"><span class="diff_add"> style line endings. This is important because the web server checks the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_168">168-</td><td nowrap="nowrap"> <span class="diff_sub"> server checks the</span> first line of the script (called shebang) and tries to run</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_170">170+</td><td nowrap="nowrap"> first line of the script (called shebang) and tries to run<span class="diff_add"> the program</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_169">169-</td><td nowrap="nowrap"> <span class="diff_sub"> the program</span> specified there. It gets easily confused by Windows line endings</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_171">171+</td><td nowrap="nowrap"> specified there. It gets easily confused by Windows line endings<span class="diff_add"> (Carriage</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_170">170-</td><td nowrap="nowrap"> <span class="diff_sub"> (Carriage</span> Return & Line Feed, also called CRLF), so you have to convert the</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_172">172+</td><td nowrap="nowrap"> Return & Line Feed, also called CRLF), so you have to convert the<span class="diff_add"> file to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_171">171-</td><td nowrap="nowrap"> <span class="diff_sub"> file to</span> Unix line endings (only Line Feed, LF). This can be done</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_173">173+</td><td nowrap="nowrap"> Unix line endings (only Line Feed, LF). This can be done<span class="diff_add"> automatically by</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_172">172-</td><td nowrap="nowrap"> <span class="diff_sub"> automatically by</span> uploading the file via FTP in text mode instead of binary</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_174">174+</td><td nowrap="nowrap"> uploading the file via FTP in text mode instead of binary<span class="diff_add"> mode, but the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_173">173-</td><td nowrap="nowrap"> <span class="diff_sub"> mode, but the</span> preferred way is just telling your editor to save the files with</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_175">175+</td><td nowrap="nowrap"> preferred way is just telling your editor to save the files with<span class="diff_add"> Unix line</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_174">174-</td><td nowrap="nowrap"> <span class="diff_sub"> Unix line</span> endings. Most<span class="diff_sub"> proper</span> editors support this.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_176">176+</td><td nowrap="nowrap"> endings. Most editors support this.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_177">177+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_175">175-</td><td nowrap="nowrap">* Your web server must be able to read the file, you need to make sure the</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_178">178+</td><td nowrap="nowrap">* Your web server must be able to read the file, <span class="diff_add">and </span>you need to make sure the</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_176">176-</td><td nowrap="nowrap"><span class="diff_sub"> permissions are fine. Often the server runs as user and group ``www-data``,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_179">179+</td><td nowrap="nowrap"><span class="diff_add"> permissions are correct. On unix-like systems, the server often runs as user</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_177">177-</td><td nowrap="nowrap"><span class="diff_sub"> so it might be worth a try to change the file ownership or making the file</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_180">180+</td><td nowrap="nowrap"><span class="diff_add"> and group ``www-data``, so it might be worth a try to change the file</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_178">178-</td><td nowrap="nowrap"><span class="diff_sub"> world readable by using ``chmod a+r your_script.py``.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_181">181+</td><td nowrap="nowrap"><span class="diff_add"> ownership, or making the file world readable by using ``chmod a+r</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_182">182+</td><td nowrap="nowrap"><span class="diff_add"> your_script.py``.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_183">183+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_179">179-</td><td nowrap="nowrap">* The webserver must <span class="diff_sub">be able to </span>know that the file you're trying to access is a</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_184">184+</td><td nowrap="nowrap">* The web<span class="diff_add"> </span>server must know that the file you're trying to access is a<span class="diff_add"> CGI script.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_180">180-</td><td nowrap="nowrap"><span class="diff_sub"> CGI script. Check the configuration of your web server, maybe there is some</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_185">185+</td><td nowrap="nowrap"><span class="diff_add"> Check the configuration of your web server, as it may be configured</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_181">181-</td><td nowrap="nowrap"><span class="diff_sub"> mistake.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_186">186+</td><td nowrap="nowrap"><span class="diff_add"> to expect a specific file extension for CGI scripts.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_182">182-</td><td nowrap="nowrap"><span class="diff_sub">* The path to the interpreter in the shebang (``#!/usr/bin/env python``) must be</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_187">187+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_183">183-</td><td nowrap="nowrap"><span class="diff_sub"> currect. This line calls ``/usr/bin/env`` to find Python, but it'll fail if</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_188">188+</td><td nowrap="nowrap"><span class="diff_add">* On Unix-like systems, the path to the interpreter in the shebang</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_184">184-</td><td nowrap="nowrap"><span class="diff_sub"> there is no ``/usr/bin/env``. If you know where your Python is installed, you</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_189">189+</td><td nowrap="nowrap"><span class="diff_add"> (``#!/usr/bin/env python``) must be correct. This line calls</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__25"></td><td class="diff_header" id="from55_185">185-</td><td nowrap="nowrap"><span class="diff_sub"> can also use that path. The commands ``whereis python`` and ``type -p</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__25"></td><td class="diff_header" id="to55_190">190+</td><td nowrap="nowrap"><span class="diff_add"> ``/usr/bin/env`` to find Python, but it will fail if there is no</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_186">186-</td><td nowrap="nowrap"><span class="diff_sub"> python`` might also help to find where it is installed. Once this is known,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_191">191+</td><td nowrap="nowrap"><span class="diff_add"> ``/usr/bin/env``, or if Python is not in the web server's path. If you know</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_187">187-</td><td nowrap="nowrap"><span class="diff_sub"> the shebang line can be changed accordingly: ``#!/usr/bin/python``.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_192">192+</td><td nowrap="nowrap"><span class="diff_add"> where your Python is installed, you can also use that full path. The</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_193">193+</td><td nowrap="nowrap"><span class="diff_add"> commands ``whereis python`` and ``type -p python`` could help you find</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_194">194+</td><td nowrap="nowrap"><span class="diff_add"> where it is installed. Once you know the path, you can change the shebang</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_195">195+</td><td nowrap="nowrap"><span class="diff_add"> accordingly: ``#!/usr/bin/python``.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_196">196+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_188">188</td><td nowrap="nowrap">* The file must not contain a BOM (Byte Order Mark). The BOM is meant for</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__26">n</a></td><td class="diff_header" id="from55_189">189-</td><td nowrap="nowrap"> determining the byte order of UTF-16 encodings, but some editors<span class="diff_sub"> write this</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__26">n</a></td><td class="diff_header" id="to55_198">198+</td><td nowrap="nowrap"> determining the byte order of UTF-16<span class="diff_add"> and UTF-32</span> encodings, but some editors</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_190">190-</td><td nowrap="nowrap"> also into UTF-8 files. The BOM interferes with the shebang line,<span class="diff_sub"> so be sure</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_199">199+</td><td nowrap="nowrap"> <span class="diff_add"> write this</span> also into UTF-8 files. The BOM interferes with the shebang line,</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_191">191-</td><td nowrap="nowrap"> to tell your editor not to write the BOM.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_200">200+</td><td nowrap="nowrap"> <span class="diff_add"> so be sure</span> to tell your editor not to write the BOM.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_192">192-</td><td nowrap="nowrap"><span class="diff_sub">* :ref:`mod-python` might be making problems. mod_python is able to handle CGI</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_201">201+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_193">193-</td><td nowrap="nowrap"><span class="diff_sub"> scripts by itself, but it can also be a source for problems. Be sure you</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_202">202+</td><td nowrap="nowrap"><span class="diff_add">* If the web server is using :ref:`mod-python`, ``mod_python`` may be having</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_194">194-</td><td nowrap="nowrap"><span class="diff_sub"> disable it.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_203">203+</td><td nowrap="nowrap"><span class="diff_add"> problems. ``mod_python`` is able to handle CGI scripts by itself, but it can</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_204">204+</td><td nowrap="nowrap"><span class="diff_add"> also be a source of issues.</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__26"></td><td class="diff_header" id="from55_195">195</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_196">196</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_197">197</td><td nowrap="nowrap">.. _mod-python:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_198">198</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_199">199</td><td nowrap="nowrap">mod_python</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_200">200</td><td nowrap="nowrap">----------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_201">201</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_202">202</td><td nowrap="nowrap">People coming from PHP often find it hard to grasp how to use Python in the web.</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__27">n</a></td><td class="diff_header" id="from55_203">203-</td><td nowrap="nowrap">Their first thought is mostly `mod_python <http://www.modpython.org/>`_<span class="diff_chg"> because</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__27">n</a></td><td class="diff_header" id="to55_213">213+</td><td nowrap="nowrap">Their first thought is mostly `mod_python <http://www.modpython.org/>`_<span class="diff_chg">\ ,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_204">204-</td><td nowrap="nowrap">they think that this is the equivalent to ``mod_php``. Actually<span class="diff_chg"> i</span>t<span class="diff_chg"> is not</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_214">214+</td><td nowrap="nowrap"><span class="diff_add">because </span>they think that this is the equivalent to ``mod_php``. Actually<span class="diff_chg">, </span>t<span class="diff_chg">here</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_205">205-</td><td nowrap="nowrap"><span class="diff_sub">really. It does embed the interpreter into the Apache process, thus speeding up</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_215">215+</td><td nowrap="nowrap"><span class="diff_add">are many differences. What ``mod_python`` does is embed the interpreter into</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_206">206-</td><td nowrap="nowrap"><span class="diff_sub">requests by not having to start a Python interpreter every request. On the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_216">216+</td><td nowrap="nowrap"><span class="diff_add">the Apache process, thus speeding up requests by not having to start a Python</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__27"></td><td class="diff_header" id="from55_207">207-</td><td nowrap="nowrap"><span class="diff_sub">other hand, it is by far not "Python intermixed with HTML" as PHP often does.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__27"></td><td class="diff_header" id="to55_217">217+</td><td nowrap="nowrap"><span class="diff_add">interpreter for each request. On the other hand, it is not "Python intermixed</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_218">218+</td><td nowrap="nowrap"><span class="diff_add">with HTML" in the way that PHP is often intermixed with HTML. The Python</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_208">208-</td><td nowrap="nowrap"><span class="diff_sub">The Python </span>equivalent of that is a template engine. mod_python itself is much</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_219">219+</td><td nowrap="nowrap">equivalent of that is a template engine. <span class="diff_add">``</span>mod_python<span class="diff_add">``</span> itself is much<span class="diff_add"> more</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_209">209-</td><td nowrap="nowrap"><span class="diff_sub">more </span>powerful and <span class="diff_chg">g</span>i<span class="diff_chg">v</span>es more access to Apache internals. It can emulate CGI,<span class="diff_sub"> it</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_220">220+</td><td nowrap="nowrap">powerful and <span class="diff_chg">prov</span>i<span class="diff_chg">d</span>es more access to Apache internals. It can emulate CGI,</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_210">210-</td><td nowrap="nowrap"><span class="diff_sub">can </span>work a<span class="diff_sub">n a</span> "Python Server Pages" mode similar to JSP which is "HTML</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_221">221+</td><td nowrap="nowrap">work <span class="diff_add">in </span>a "Python Server Pages" mode <span class="diff_add">(</span>similar to JSP<span class="diff_add">)</span> which is "HTML</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_211">211-</td><td nowrap="nowrap">interm<span class="diff_chg">a</span>ngled with Python" and it has a "Publisher" which des<span class="diff_sub">t</span>ignates one file<span class="diff_sub"> to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_222">222+</td><td nowrap="nowrap">interm<span class="diff_chg">i</span>ngled with Python"<span class="diff_add">,</span> and it has a "Publisher" which designates one file</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_212">212-</td><td nowrap="nowrap">accept all requests and decide <span class="diff_sub">on </span>what to do the<span class="diff_chg">n</span>.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_223">223+</td><td nowrap="nowrap"><span class="diff_add">to </span>accept all requests and decide what to do<span class="diff_add"> with</span> the<span class="diff_chg">m</span>.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_213">213</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__28">n</a></td><td class="diff_header" id="from55_214">214-</td><td nowrap="nowrap"><span class="diff_chg">But </span>mod_python ha<span class="diff_chg">s</span> some problems. Unlike the PHP interpreter the Python</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__28">n</a></td><td class="diff_header" id="to55_225">225+</td><td nowrap="nowrap"><span class="diff_chg">``</span>mod_python<span class="diff_add">`` does</span> ha<span class="diff_chg">ve</span> some problems. Unlike the PHP interpreter<span class="diff_add">,</span> the Python</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_215">215-</td><td nowrap="nowrap">interpreter uses caching when executing files, so<span class="diff_sub"> when</span> chang<span class="diff_chg">ing</span> a file <span class="diff_sub">the </span>w<span class="diff_chg">ho</span>l<span class="diff_chg">e</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_226">226+</td><td nowrap="nowrap">interpreter uses caching when executing files, so chang<span class="diff_chg">es to</span> a file w<span class="diff_chg">i</span>l<span class="diff_chg">l</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_216">216-</td><td nowrap="nowrap">web server <span class="diff_sub">needs </span>to be re<span class="diff_sub">-</span>started<span class="diff_sub"> to update</span>. Another problem is<span class="diff_sub">t</span> the basic</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_227">227+</td><td nowrap="nowrap"><span class="diff_add">require the </span>web server to be restarted. Another problem is the basic<span class="diff_add"> concept</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_217">217-</td><td nowrap="nowrap"><span class="diff_sub">concept </span>-- Apache starts <span class="diff_sub">some </span>child processes to handle the requests and</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_228">228+</td><td nowrap="nowrap">-- Apache starts child processes to handle the requests<span class="diff_add">,</span> and<span class="diff_add"> unfortunately</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__28"></td><td class="diff_header" id="from55_218">218-</td><td nowrap="nowrap"><span class="diff_sub">unfortunately </span>every child process needs to load the whole Python interpreter</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__28"></td><td class="diff_header" id="to55_229">229+</td><td nowrap="nowrap">every child process needs to load the whole Python interpreter<span class="diff_add"> even if it does</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_219">219-</td><td nowrap="nowrap"><span class="diff_sub">even if it does </span>not use it. This makes the whole web server slower. Another</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_230">230+</td><td nowrap="nowrap">not use it. This makes the whole web server slower. Another<span class="diff_add"> problem is that,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_220">220-</td><td nowrap="nowrap"><span class="diff_sub">problem is that as mod_python is linked against a specific version of</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_231">231+</td><td nowrap="nowrap"><span class="diff_add">because ``mod_python`` is linked against a specific version of ``libpython``,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_221">221-</td><td nowrap="nowrap"><span class="diff_sub">``libpython``, </span>it is not possible to switch from an older version to a newer</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_232">232+</td><td nowrap="nowrap">it is not possible to switch from an older version to a newer<span class="diff_add"> (e.g. 2.4 to 2.5)</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_222">222-</td><td nowrap="nowrap"><span class="diff_sub">(e.g. 2.4 to 2.5) </span>without recompiling mod_python. mod_python is also bound to</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_233">233+</td><td nowrap="nowrap">without recompiling <span class="diff_add">``</span>mod_python<span class="diff_add">``</span>. <span class="diff_add">``</span>mod_python<span class="diff_add">``</span> is also bound to<span class="diff_add"> the Apache</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_223">223-</td><td nowrap="nowrap"><span class="diff_sub">the Apache </span>web server, so programs written for mod_python cannot easily run on</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_234">234+</td><td nowrap="nowrap">web server, so programs written for <span class="diff_add">``</span>mod_python<span class="diff_add">``</span> cannot easily run on<span class="diff_add"> other</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_224">224-</td><td nowrap="nowrap"><span class="diff_sub">other </span>web servers.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_235">235+</td><td nowrap="nowrap">web servers.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_225">225</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__29">n</a></td><td class="diff_header" id="from55_226">226-</td><td nowrap="nowrap">These are the reasons why mod_python should be avoided when writing new</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__29">n</a></td><td class="diff_header" id="to55_237">237+</td><td nowrap="nowrap">These are the reasons why <span class="diff_add">``</span>mod_python<span class="diff_add">``</span> should be avoided when writing new</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_227">227-</td><td nowrap="nowrap">programs. In some circumstances it might be <span class="diff_sub">still </span>a good idea to use<span class="diff_sub"> mod_python</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_238">238+</td><td nowrap="nowrap">programs. In some circumstances it<span class="diff_add"> still</span> might be a good idea to use</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_228">228-</td><td nowrap="nowrap">for deployment, but WSGI makes it possible to run WSGI programs<span class="diff_sub"> under mod_python</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_239">239+</td><td nowrap="nowrap"><span class="diff_add">``mod_python`` </span>for deployment, but WSGI makes it possible to run WSGI programs</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__29"></td><td class="diff_header" id="from55_229">229-</td><td nowrap="nowrap"><span class="diff_sub">as well.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__29"></td><td class="diff_header" id="to55_240">240+</td><td nowrap="nowrap"><span class="diff_add">under ``mod_python`` as well.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_230">230</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_231">231</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_232">232</td><td nowrap="nowrap">FastCGI and SCGI</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_233">233</td><td nowrap="nowrap">----------------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_234">234</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_235">235</td><td nowrap="nowrap">FastCGI and SCGI try to solve the performance problem of CGI in another way.</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__30"></td><td class="diff_header" id="from55_236">236</td><td nowrap="nowrap">Instead of embedding the interpreter into the web server, they create</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__30">n</a></td><td class="diff_header" id="from55_237">237-</td><td nowrap="nowrap"><span class="diff_sub">long-running processes which run in the background. There still is some module</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__30">n</a></td><td class="diff_header" id="to55_248">248+</td><td nowrap="nowrap"><span class="diff_add">long-running background processes. There is still a module in the web server</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__31"></td><td class="diff_header" id="from55_238">238-</td><td nowrap="nowrap"><span class="diff_sub">in the web server </span>which makes it possible for the web server to "speak" with the</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__31"></td><td class="diff_header" id="to55_249">249+</td><td nowrap="nowrap">which makes it possible for the web server to "speak" with the<span class="diff_add"> background</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_239">239-</td><td nowrap="nowrap"><span class="diff_sub">background process. As the background process is independent from the server,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_250">250+</td><td nowrap="nowrap"><span class="diff_add">process. As the background process is independent of the server, it can be</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_240">240-</td><td nowrap="nowrap"><span class="diff_sub">it can be written in any language of course also in Python. The language just</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_251">251+</td><td nowrap="nowrap"><span class="diff_add">written in any language, including Python. The language just needs to have a</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__32"></td><td class="diff_header" id="from55_241">241-</td><td nowrap="nowrap"><span class="diff_sub">needs to have a </span>library which handles the communication with the web<span class="diff_sub"> </span>server.</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__32"></td><td class="diff_header" id="to55_252">252+</td><td nowrap="nowrap">library which handles the communication with the webserver.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_242">242</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_243">243</td><td nowrap="nowrap">The difference between FastCGI and SCGI is very small, as SCGI is essentially</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__31">n</a></td><td class="diff_header" id="from55_244">244-</td><td nowrap="nowrap">just a "simpler FastCGI". <span class="diff_chg">But a</span>s the web server support for SCGI is limited</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__31">n</a></td><td class="diff_header" id="to55_255">255+</td><td nowrap="nowrap">just a "simpler FastCGI". <span class="diff_chg">A</span>s the web server support for SCGI is limited<span class="diff_add">,</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_245">245</td><td nowrap="nowrap">most people use FastCGI instead, which works the same way. Almost everything</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__32">n</a></td><td class="diff_header" id="from55_246">246-</td><td nowrap="nowrap">that applies to SCGI also applies to FastCGI as well, so we'll only <span class="diff_chg">w</span>r<span class="diff_sub">ite about</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__32">n</a></td><td class="diff_header" id="to55_257">257+</td><td nowrap="nowrap">that applies to SCGI also applies to FastCGI as well, so we'll only <span class="diff_chg">cove</span>r</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_247">247</td><td nowrap="nowrap">the latter.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_248">248</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__33">n</a></td><td class="diff_header" id="from55_249">249-</td><td nowrap="nowrap">These days, FastCGI is never used directly. Just like ``mod_python`` it is only</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__33">n</a></td><td class="diff_header" id="to55_260">260+</td><td nowrap="nowrap">These days, FastCGI is never used directly. Just like ``mod_python``<span class="diff_add">,</span> it is only</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_250">250</td><td nowrap="nowrap">used for the deployment of WSGI applications.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_251">251</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_252">252</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_253">253</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_254">254</td><td nowrap="nowrap"> * `FastCGI, SCGI, and Apache: Background and Future</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__33"></td><td class="diff_header" id="from55_255">255</td><td nowrap="nowrap"> <http://www.vmunix.com/mark/blog/archives/2006/01/02/fastcgi-scgi-and-apache-background-and-future/>`_</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_256">256</td><td nowrap="nowrap"> is a discussion on why the concept of FastCGI and SCGI is better that that</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__34"></td><td class="diff_header" id="from55_257">257</td><td nowrap="nowrap"> of mod_python.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_258">258</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to55__35"></td><td class="diff_header" id="from55_259">259</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_260">260</td><td nowrap="nowrap">Setting up FastCGI</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_261">261</td><td nowrap="nowrap">^^^^^^^^^^^^^^^^^^</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__36"></td><td class="diff_header" id="from55_262">262</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__34">n</a></td><td class="diff_header" id="from55_263">263-</td><td nowrap="nowrap"><span class="diff_sub">Depending on the web server you need to have a special module.</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__34">n</a></td><td class="diff_header" id="to55_274">274+</td><td nowrap="nowrap"><span class="diff_add">Each web server requires a specific module.</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__37"></td><td class="diff_header" id="from55_264">264</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__35">n</a></td><td class="diff_header" id="from55_265">265-</td><td nowrap="nowrap">* Apache has both `mod_fastcgi <http://www.fastcgi.com/>`_ and `mod_fcgid</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__35">n</a></td><td class="diff_header" id="to55_276">276+</td><td nowrap="nowrap">* Apache has both `mod_fastcgi <http://www.fastcgi.com/<span class="diff_add">drupal/</span>>`_ and `mod_fcgid</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_266">266</td><td nowrap="nowrap"> <http://fastcgi.coremail.cn/>`_. ``mod_fastcgi`` is the original one, but it</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__36">n</a></td><td class="diff_header" id="from55_267">267-</td><td nowrap="nowrap"> has some licensing issues<span class="diff_chg"> t</span>h<span class="diff_chg">at'</span>s why it is sometimes considered non-free.</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__36">n</a></td><td class="diff_header" id="to55_278">278+</td><td nowrap="nowrap"> has some licensing issues<span class="diff_chg">, w</span>h<span class="diff_chg">ich i</span>s why it is sometimes considered non-free.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_268">268-</td><td nowrap="nowrap"> ``mod_fcgid`` is a smaller, compatible alternative. One of these modules needs</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_279">279+</td><td nowrap="nowrap"> ``mod_fcgid`` is a smaller, compatible alternative. <span class="diff_add"> </span>One of these modules needs</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_269">269</td><td nowrap="nowrap"> to be loaded by Apache.</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__37">n</a></td><td class="diff_header" id="to55_281">281+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_270">270</td><td nowrap="nowrap">* lighttpd ships its own `FastCGI module</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__38">n</a></td><td class="diff_header" id="from55_271">271-</td><td nowrap="nowrap"> <http://<span class="diff_sub">t</span>r<span class="diff_chg">ac</span>.lighttpd.net/<span class="diff_sub">trac/</span>wiki/Docs<span class="diff_chg">%3A</span>ModFastCGI>`_ as well as an<span class="diff_sub"> `SCGI</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__38">n</a></td><td class="diff_header" id="to55_283">283+</td><td nowrap="nowrap"> <http://r<span class="diff_chg">edmine</span>.lighttpd.net/wiki/<span class="diff_add">lighttpd/</span>Docs<span class="diff_chg">:</span>ModFastCGI>`_ as well as an</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_272">272-</td><td nowrap="nowrap"> module <http://<span class="diff_sub">t</span>r<span class="diff_chg">ac</span>.lighttpd.net/<span class="diff_sub">trac/</span>wiki/Docs<span class="diff_chg">%3A</span>ModSCGI>`_.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_284">284+</td><td nowrap="nowrap"> <span class="diff_add"> `SCGI</span> module <http://r<span class="diff_chg">edmine</span>.lighttpd.net/wiki/<span class="diff_add">lighttpd/</span>Docs<span class="diff_chg">:</span>ModSCGI>`_.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_273">273-</td><td nowrap="nowrap"><span class="diff_sub">* nginx also supports `FastCGI</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_285">285+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_286">286+</td><td nowrap="nowrap"><span class="diff_add">* `nginx <http://nginx.org/>`_ also supports `FastCGI</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_274">274-</td><td nowrap="nowrap"> <http://wiki.<span class="diff_sub">codemo</span>ng<span class="diff_chg">e</span>r<span class="diff_chg">s.com</span>/NginxSimplePythonFCGI>`_.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_287">287+</td><td nowrap="nowrap"> <http://wiki.ng<span class="diff_chg">inx.o</span>r<span class="diff_chg">g</span>/NginxSimplePythonFCGI>`_.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_275">275</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_276">276</td><td nowrap="nowrap">Once you have installed and configured the module, you can test it with the</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_277">277</td><td nowrap="nowrap">following WSGI-application::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_278">278</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_279">279</td><td nowrap="nowrap"> #!/usr/bin/env python</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_280">280</td><td nowrap="nowrap"> # -*- coding: UTF-8 -*-</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_281">281</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_282">282</td><td nowrap="nowrap"> from cgi import escape</td></tr> </tbody> + <tbody> + <tr><td class="diff_next" id="difflib_chg_to55__38"></td><td class="diff_header" id="from55_296">296</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_297">297</td><td nowrap="nowrap">This is a simple WSGI application, but you need to install `flup</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_298">298</td><td nowrap="nowrap"><http://pypi.python.org/pypi/flup/1.0>`_ first, as flup handles the low level</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_299">299</td><td nowrap="nowrap">FastCGI access.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_300">300</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_301">301</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_302">302</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_303">303</td><td nowrap="nowrap"> There is some documentation on `setting up Django with FastCGI</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__39">n</a></td><td class="diff_header" id="from55_304">304-</td><td nowrap="nowrap"><span class="diff_sub"> <http://www.djangoproject.com/documentation/fastcgi/>`_, most of which can be</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__39">n</a></td><td class="diff_header" id="to55_317">317+</td><td nowrap="nowrap"><span class="diff_add"> <http://docs.djangoproject.com/en/dev/howto/deployment/fastcgi/>`_, most of</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__39"></td><td class="diff_header" id="from55_305">305-</td><td nowrap="nowrap"> reused for other WSGI-compliant frameworks and libraries.<span class="diff_sub"> Only the</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__39"></td><td class="diff_header" id="to55_318">318+</td><td nowrap="nowrap"> <span class="diff_add"> which can be</span> reused for other WSGI-compliant frameworks and libraries.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_306">306-</td><td nowrap="nowrap"> ``manage.py`` part has to be changed, the example used here can be<span class="diff_sub"> used</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_319">319+</td><td nowrap="nowrap"> <span class="diff_add"> Only the</span> ``manage.py`` part has to be changed, the example used here can be</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_307">307-</td><td nowrap="nowrap"> instead. Django does more or less the exact same thing.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_320">320+</td><td nowrap="nowrap"> <span class="diff_add"> used</span> instead. <span class="diff_add"> </span>Django does more or less the exact same thing.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_308">308</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_309">309</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_310">310</td><td nowrap="nowrap">mod_wsgi</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_311">311</td><td nowrap="nowrap">--------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_312">312</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__40">n</a></td><td class="diff_header" id="from55_313">313-</td><td nowrap="nowrap">`mod_wsgi <http://<span class="diff_chg">www</span>.modwsgi<span class="diff_sub">.org</span>/>`_ is an attempt to get rid of the<span class="diff_sub"> low level</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__40">n</a></td><td class="diff_header" id="to55_326">326+</td><td nowrap="nowrap">`mod_wsgi <http://<span class="diff_chg">code</span>.<span class="diff_add">google.com/p/</span>modwsgi/>`_ is an attempt to get rid of the</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_314">314-</td><td nowrap="nowrap"><span class="diff_sub">gateways. As FastCGI, SCGI, mod_python are mostly used to deploy WSGI</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_327">327+</td><td nowrap="nowrap"><span class="diff_add">low level gateways. Given that FastCGI, SCGI, and mod_python are mostly used to</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__40"></td><td class="diff_header" id="from55_315">315-</td><td nowrap="nowrap">applications<span class="diff_sub"> anyway</span>, mod_wsgi was started to directly embed WSGI aplications</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__40"></td><td class="diff_header" id="to55_328">328+</td><td nowrap="nowrap"><span class="diff_add">deploy WSGI </span>applications, mod_wsgi was started to directly embed WSGI a<span class="diff_add">p</span>plications</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_316">316-</td><td nowrap="nowrap"><span class="diff_sub">into the Apache web server. The benefit from this approach is that WSGI</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_329">329+</td><td nowrap="nowrap"><span class="diff_add">into the Apache web server. mod_wsgi is specifically designed to host WSGI</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_317">317-</td><td nowrap="nowrap"><span class="diff_sub">applications can be deployed much easier as is is specially designed to host</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_330">330+</td><td nowrap="nowrap"><span class="diff_add">applications. It makes the deployment of WSGI applications much easier than</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_318">318-</td><td nowrap="nowrap"><span class="diff_sub">WSGI applications -- unlike the other low level methods which have glue code to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_331">331+</td><td nowrap="nowrap"><span class="diff_add">deployment using other low level methods, which need glue code. The downside</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_319">319-</td><td nowrap="nowrap"><span class="diff_sub">host WSGI applications (like flup which was mentioned before). The downside is</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_320">320-</td><td nowrap="nowrap">that mod_wsgi is limited to the Apache web server<span class="diff_chg">,</span> other servers would need</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_332">332+</td><td nowrap="nowrap"><span class="diff_add">is </span>that mod_wsgi is limited to the Apache web server<span class="diff_chg">;</span> other servers would need</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_321">321</td><td nowrap="nowrap">their own implementations of mod_wsgi.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_322">322</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__41">n</a></td><td class="diff_header" id="from55_323">323-</td><td nowrap="nowrap"><span class="diff_chg">It</span> supports two modes:<span class="diff_sub"> the</span> embedded mode in which it integrates with the<span class="diff_sub"> Apache</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__41">n</a></td><td class="diff_header" id="to55_335">335+</td><td nowrap="nowrap"><span class="diff_chg">mod_wsgi</span> supports two modes: embedded mode<span class="diff_add">,</span> in which it integrates with the</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_324">324-</td><td nowrap="nowrap">process and<span class="diff_sub"> the</span> daemon mode which is more FastCGI-like. <span class="diff_chg">Co</span>n<span class="diff_chg">trary to</span> FastCGI,</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_336">336+</td><td nowrap="nowrap"><span class="diff_add">Apache </span>process<span class="diff_add">,</span> and daemon mode<span class="diff_add">,</span> which is more FastCGI-like. <span class="diff_chg">U</span>n<span class="diff_chg">like</span> FastCGI,</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_325">325-</td><td nowrap="nowrap">mod_wsgi handles the worker-processes by itself which makes administration</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_337">337+</td><td nowrap="nowrap">mod_wsgi handles the worker-processes by itself<span class="diff_add">,</span> which makes administration</td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__41"></td><td class="diff_header" id="from55_326">326</td><td nowrap="nowrap">easier.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_327">327</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_328">328</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to55__42"></td><td class="diff_header" id="from55_329">329</td><td nowrap="nowrap">.. _WSGI:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_330">330</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_331">331</td><td nowrap="nowrap">Step back: WSGI</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_332">332</td><td nowrap="nowrap">===============</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_333">333</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__42">n</a></td><td class="diff_header" id="from55_334">334-</td><td nowrap="nowrap">WSGI <span class="diff_chg">w</span>as already mentioned several times so it has to be something<span class="diff_sub"> important.</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__42">n</a></td><td class="diff_header" id="to55_346">346+</td><td nowrap="nowrap">WSGI <span class="diff_chg">h</span>as already<span class="diff_add"> been</span> mentioned several times<span class="diff_add">,</span> so it has to be something</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__43"></td><td class="diff_header" id="from55_335">335-</td><td nowrap="nowrap">In fact it really is, <span class="diff_chg">so</span> now it<span class="diff_chg">'</span>s time to explain.</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__43"></td><td class="diff_header" id="to55_347">347+</td><td nowrap="nowrap"><span class="diff_add">important. </span>In fact it really is, <span class="diff_chg">and</span> now it<span class="diff_chg"> i</span>s time to explain<span class="diff_add"> it</span>.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_336">336</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__43">n</a></td><td class="diff_header" id="from55_337">337-</td><td nowrap="nowrap">The *Web Server Gateway Interface*, <span class="diff_sub">:pep:`333`</span> or WSGI for short is <span class="diff_chg">curr</span>en<span class="diff_chg">tly</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__43">n</a></td><td class="diff_header" id="to55_349">349+</td><td nowrap="nowrap">The *Web Server Gateway Interface*, or WSGI for short<span class="diff_add">,</span> is <span class="diff_chg">d</span>e<span class="diff_add">fi</span>n<span class="diff_chg">ed in</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_338">338-</td><td nowrap="nowrap"><span class="diff_sub">the best possible way to Python web programming. While it is great for</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_350">350+</td><td nowrap="nowrap"><span class="diff_add">:pep:`333` and is currently the best way to do Python web programming. While</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_339">339-</td><td nowrap="nowrap"><span class="diff_sub">programmers writing frameworks, the normal person does not need to get in direct</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_351">351+</td><td nowrap="nowrap"><span class="diff_add">it is great for programmers writing frameworks, a normal web developer does not</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_340">340-</td><td nowrap="nowrap"><span class="diff_sub">contact with it. But when choosing a framework for web development it is a good</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_352">352+</td><td nowrap="nowrap"><span class="diff_add">need to get in direct contact with it. When choosing a framework for web</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_341">341-</td><td nowrap="nowrap"><span class="diff_sub">idea to take one which supports WSGI.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_353">353+</td><td nowrap="nowrap"><span class="diff_add">development it is a good idea to choose one which supports WSGI.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_342">342</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__44">n</a></td><td class="diff_header" id="from55_343">343-</td><td nowrap="nowrap"><span class="diff_sub">The big profit from WSGI is the unification. When your program is compatible</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__44">n</a></td><td class="diff_header" id="to55_355">355+</td><td nowrap="nowrap"><span class="diff_add">The big benefit of WSGI is the unification of the application programming</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_344">344-</td><td nowrap="nowrap"><span class="diff_sub">with WSGI -- that means that your framework has support for WSGI, your program</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_356">356+</td><td nowrap="nowrap"><span class="diff_add">interface. When your program is compatible with WSGI -- which at the outer</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__44"></td><td class="diff_header" id="to55_357">357+</td><td nowrap="nowrap"><span class="diff_add">level means that the framework you are using has support for WSGI -- your</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_345">345-</td><td nowrap="nowrap">can be deployed <span class="diff_chg">o</span>n<span class="diff_sub"> ever</span>y web server interface for which there are WSGI<span class="diff_sub"> wrappers.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_358">358+</td><td nowrap="nowrap"><span class="diff_add">program </span>can be deployed <span class="diff_chg">via a</span>ny web server interface for which there are WSGI</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_346">346-</td><td nowrap="nowrap"><span class="diff_sub">So you do not need to care about whether the user uses mod_python or FastCGI --</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_359">359+</td><td nowrap="nowrap"><span class="diff_add">wrappers. You do not need to care about whether the application user uses</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_347">347-</td><td nowrap="nowrap"><span class="diff_sub">with WSGI it just works on any gateway interface. The Python standard library</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_360">360+</td><td nowrap="nowrap"><span class="diff_add">mod_python or FastCGI or mod_wsgi -- with WSGI your application will work on</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_348">348-</td><td nowrap="nowrap"><span class="diff_sub">contains its own WSGI server :mod:`wsgiref`, which is a small web server that</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_361">361+</td><td nowrap="nowrap"><span class="diff_add">any gateway interface. The Python standard library contains its own WSGI</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_349">349-</td><td nowrap="nowrap"><span class="diff_sub">can be used for testing.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_362">362+</td><td nowrap="nowrap"><span class="diff_add">server, :mod:`wsgiref`, which is a small web server that can be used for</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_363">363+</td><td nowrap="nowrap"><span class="diff_add">testing.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_350">350</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__45">n</a></td><td class="diff_header" id="from55_351">351-</td><td nowrap="nowrap">A really great WSGI feature <span class="diff_chg">are the</span> middleware<span class="diff_sub">s</span>. Middlewares a<span class="diff_sub">re</span> layer<span class="diff_sub">s</span> around</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__45">n</a></td><td class="diff_header" id="to55_365">365+</td><td nowrap="nowrap">A really great WSGI feature <span class="diff_chg">is</span> middleware. Middleware<span class="diff_add"> i</span>s a layer around<span class="diff_add"> your</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_352">352-</td><td nowrap="nowrap"><span class="diff_sub">your </span>program which can add various functionality to it. There is a <span class="diff_sub">`num</span>b<span class="diff_chg">er</span> of</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_366">366+</td><td nowrap="nowrap">program which can add various functionality to it. There is <span class="diff_add">quite </span>a b<span class="diff_chg">it</span> of</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_353">353-</td><td nowrap="nowrap">middleware<span class="diff_sub">s</span> <http://wsgi.org/wsgi/Middleware_and_Utilities>`_ already<span class="diff_sub"> available.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_367">367+</td><td nowrap="nowrap"><span class="diff_add">`</span>middleware <http://wsgi.org/wsgi/Middleware_and_Utilities>`_ already</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_354">354-</td><td nowrap="nowrap">For example, instead of writing your own session management (<span class="diff_chg">to identify a user</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_368">368+</td><td nowrap="nowrap"><span class="diff_add">available. </span>For example, instead of writing your own session management (<span class="diff_chg">HTTP</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__45"></td><td class="diff_header" id="from55_355">355-</td><td nowrap="nowrap"><span class="diff_sub">in subsequent requests, as HTTP does not maintain state, so it does now know</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__45"></td><td class="diff_header" id="to55_369">369+</td><td nowrap="nowrap"><span class="diff_add">is a stateless protocol, so to associate multiple HTTP requests with a single</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_356">356-</td><td nowrap="nowrap"><span class="diff_sub">that the requests belong to the same user) you can just take one middleware,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_370">370+</td><td nowrap="nowrap"><span class="diff_add">user your application must create and manage such state via a session), you can</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_357">357-</td><td nowrap="nowrap"><span class="diff_sub">plug it in and you can rely an already existing functionality. The same thing</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_371">371+</td><td nowrap="nowrap"><span class="diff_add">just download middleware which does that, plug it in, and get on with coding</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_358">358-</td><td nowrap="nowrap"><span class="diff_sub">is compression -- say you want to compress your HTML using gzip, to save your</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_372">372+</td><td nowrap="nowrap"><span class="diff_add">the unique parts of your application. The same thing with compression -- there</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_359">359-</td><td nowrap="nowrap"><span class="diff_sub">server's bandwidth. So you only need to plug-in a middleware and you're done.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_373">373+</td><td nowrap="nowrap"><span class="diff_add">is existing middleware which handles compressing your HTML using gzip to save</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_360">360-</td><td nowrap="nowrap"><span class="diff_sub">Authentication is also a problem easily solved using a middleware.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_374">374+</td><td nowrap="nowrap"><span class="diff_add">on your server's bandwidth. Authentication is another a problem easily solved</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_375">375+</td><td nowrap="nowrap"><span class="diff_add">using existing middleware.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_361">361</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__46">n</a></td><td class="diff_header" id="from55_362">362-</td><td nowrap="nowrap"><span class="diff_chg">So, generally -- a</span>lthough WSGI may seem complex, the initial phase of learning</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__46">n</a></td><td class="diff_header" id="to55_377">377+</td><td nowrap="nowrap"><span class="diff_chg">A</span>lthough WSGI may seem complex, the initial phase of learning<span class="diff_add"> can be very</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__46"></td><td class="diff_header" id="from55_363">363-</td><td nowrap="nowrap"><span class="diff_sub">can be very rewarding as WSGI does already have solutions to many problems that</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__46"></td><td class="diff_header" id="to55_378">378+</td><td nowrap="nowrap"><span class="diff_add">rewarding because WSGI and the associated middleware already have solutions to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_364">364-</td><td nowrap="nowrap"><span class="diff_sub">might arise while writing web sites.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_379">379+</td><td nowrap="nowrap"><span class="diff_add">many problems that might arise while developing web sites.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_365">365</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to55__47"></td><td class="diff_header" id="from55_366">366</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_367">367</td><td nowrap="nowrap">WSGI Servers</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_368">368</td><td nowrap="nowrap">------------</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__48"></td><td class="diff_header" id="from55_369">369</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_370">370</td><td nowrap="nowrap">The code that is used to connect to various low level gateways like CGI or</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__47">n</a></td><td class="diff_header" id="from55_371">371-</td><td nowrap="nowrap">mod_python is called *WSGI server*. One of these servers is ``flup`` which<span class="diff_sub"> was</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__47">n</a></td><td class="diff_header" id="to55_386">386+</td><td nowrap="nowrap">mod_python is called <span class="diff_add">a </span>*WSGI server*. One of these servers is ``flup``<span class="diff_add">,</span> which</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_372">372-</td><td nowrap="nowrap"><span class="diff_sub">already mentioned and supports FastCGI, SCGI as well as `AJP</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_387">387+</td><td nowrap="nowrap"><span class="diff_add">supports FastCGI and SCGI, as well as `AJP</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_373">373</td><td nowrap="nowrap"><http://en.wikipedia.org/wiki/Apache_JServ_Protocol>`_. Some of these servers</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__48">n</a></td><td class="diff_header" id="from55_374">374-</td><td nowrap="nowrap">are written in Python as ``flup`` is, but there also exist others which are</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__48">n</a></td><td class="diff_header" id="to55_389">389+</td><td nowrap="nowrap">are written in Python<span class="diff_add">,</span> as ``flup`` is, but there also exist others which are</td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__49"></td><td class="diff_header" id="from55_375">375</td><td nowrap="nowrap">written in C and can be used as drop-in replacements.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_376">376</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__50"><a href="#difflib_chg_to55__49">n</a></td><td class="diff_header" id="from55_377">377-</td><td nowrap="nowrap">There are <span class="diff_chg">quite </span>a<span class="diff_chg"> lot of</span> servers already available, so a Python web application</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__50"><a href="#difflib_chg_to55__49">n</a></td><td class="diff_header" id="to55_392">392+</td><td nowrap="nowrap">There are <span class="diff_chg">m</span>a<span class="diff_chg">ny</span> servers already available, so a Python web application</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_378">378-</td><td nowrap="nowrap">can be deployed nearly <span class="diff_chg">ever</span>ywhere. This is one big advantage that Python has</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_393">393+</td><td nowrap="nowrap">can be deployed nearly <span class="diff_chg">an</span>ywhere. This is one big advantage that Python has</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_379">379-</td><td nowrap="nowrap">compared with other web techni<span class="diff_sub">qu</span>es.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_394">394+</td><td nowrap="nowrap">compared with other web techn<span class="diff_add">olog</span>ies.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_380">380</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_381">381</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_382">382</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__50">n</a></td><td class="diff_header" id="from55_383">383-</td><td nowrap="nowrap"> A good overview of<span class="diff_sub"> all</span> WSGI-related code can be found in the `WSGI wiki</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__50">n</a></td><td class="diff_header" id="to55_398">398+</td><td nowrap="nowrap"> A good overview of WSGI-related code can be found in the `WSGI wiki</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_384">384</td><td nowrap="nowrap"> <http://wsgi.org/wsgi>`_, which contains an extensive list of `WSGI servers</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__51">n</a></td><td class="diff_header" id="from55_385">385-</td><td nowrap="nowrap"> <http://wsgi.org/wsgi/Servers>`_<span class="diff_sub">,</span> which can be used by *<span class="diff_chg">ever</span>y* application</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__51">n</a></td><td class="diff_header" id="to55_400">400+</td><td nowrap="nowrap"> <http://wsgi.org/wsgi/Servers>`_ which can be used by *<span class="diff_chg">an</span>y* application</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_386">386</td><td nowrap="nowrap"> supporting WSGI.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_387">387</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_388">388</td><td nowrap="nowrap"> You might be interested in some WSGI-supporting modules already contained in</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__51"></td><td class="diff_header" id="from55_389">389</td><td nowrap="nowrap"> the standard library, namely:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_390">390</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_391">391</td><td nowrap="nowrap"> * :mod:`wsgiref` -- some tiny utilities and servers for WSGI</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_392">392</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to55__52"></td><td class="diff_header" id="from55_393">393</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_394">394</td><td nowrap="nowrap">Case study: MoinMoin</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_395">395</td><td nowrap="nowrap">--------------------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_396">396</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__52">n</a></td><td class="diff_header" id="from55_397">397-</td><td nowrap="nowrap">What does WSGI give the web application developer? Let's take a look <span class="diff_chg">on one</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__52">n</a></td><td class="diff_header" id="to55_412">412+</td><td nowrap="nowrap">What does WSGI give the web application developer? Let's take a look <span class="diff_chg">at</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_398">398-</td><td nowrap="nowrap"><span class="diff_sub">long existing web application written in Python without using WSGI.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_413">413+</td><td nowrap="nowrap"><span class="diff_add">an application that's been around for a while, which was written in</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_414">414+</td><td nowrap="nowrap"><span class="diff_add">Python without using WSGI.</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__53"></td><td class="diff_header" id="from55_399">399</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__53">n</a></td><td class="diff_header" id="from55_400">400-</td><td nowrap="nowrap">One of the most widely used wiki software is `MoinMoin<span class="diff_sub"> <http://moinmo.in/>`_.</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__53">n</a></td><td class="diff_header" id="to55_416">416+</td><td nowrap="nowrap">One of the most widely used wiki software <span class="diff_add">packages </span>is `MoinMoin</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_401">401-</td><td nowrap="nowrap"><span class="diff_sub">It was created in 2000, so it predates WSGI by about three years. While it now</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_417">417+</td><td nowrap="nowrap"><span class="diff_add"><http://moinmo.in/>`_. It was created in 2000, so it predates WSGI by about</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_402">402-</td><td nowrap="nowrap"><span class="diff_sub">includes support for WSGI, older versions needed separate code to run on CGI,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_418">418+</td><td nowrap="nowrap"><span class="diff_add">three years. Older versions needed separate code to run on CGI, mod_python,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_403">403-</td><td nowrap="nowrap"><span class="diff_sub">mod_python, FastCGI and standalone. Now, this all is possible by using WSGI and</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_419">419+</td><td nowrap="nowrap"><span class="diff_add">FastCGI and standalone.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__54"></td><td class="diff_header" id="from55_404">404-</td><td nowrap="nowrap"><span class="diff_sub">the already-written gateways. For running with on FastCGI ``flup`` can be used,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_405">405-</td><td nowrap="nowrap"><span class="diff_sub">for running a standalone server :mod:`wsgiref` is the way to go.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_406">406</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__54">n</a></td><td class="diff_header" id="to55_421">421+</td><td nowrap="nowrap"><span class="diff_add">It now includes support for WSGI. Using WSGI, it is possible to deploy</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__55"></td><td class="diff_header" id="to55_422">422+</td><td nowrap="nowrap"><span class="diff_add">MoinMoin on any WSGI compliant server, with no additional glue code.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_423">423+</td><td nowrap="nowrap"><span class="diff_add">Unlike the pre-WSGI versions, this could include WSGI servers that the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_424">424+</td><td nowrap="nowrap"><span class="diff_add">authors of MoinMoin know nothing about.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_407">407</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__55">n</a></td><td class="diff_header" id="to55_426">426+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_408">408-</td><td nowrap="nowrap">Model-<span class="diff_chg">v</span>iew-<span class="diff_chg">c</span>ontroller</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_427">427+</td><td nowrap="nowrap">Model-<span class="diff_chg">V</span>iew-<span class="diff_chg">C</span>ontroller</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_409">409</td><td nowrap="nowrap">=====================</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_410">410</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__56">n</a></td><td class="diff_header" id="from55_411">411-</td><td nowrap="nowrap">The term *MVC* is often <span class="diff_sub">h</span>e<span class="diff_chg">a</span>rd in statements <span class="diff_chg">like</span> "framework *foo*<span class="diff_sub"> supports MVC".</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__56">n</a></td><td class="diff_header" id="to55_430">430+</td><td nowrap="nowrap">The term *MVC* is often e<span class="diff_chg">ncounte</span>r<span class="diff_add">e</span>d in statements <span class="diff_chg">such as</span> "framework *foo*</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_412">412-</td><td nowrap="nowrap"><span class="diff_sub">While MVC is not really something technical but rather organisational, many web</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_431">431+</td><td nowrap="nowrap"><span class="diff_add">supports MVC". MVC is more about the overall organization of code, rather than</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_413">413-</td><td nowrap="nowrap"><span class="diff_sub">frameworks use this model to help the developer to bring structure into his</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_432">432+</td><td nowrap="nowrap"><span class="diff_add">any particular API. Many web frameworks use this model to help the developer</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__56"></td><td class="diff_header" id="from55_414">414-</td><td nowrap="nowrap"><span class="diff_sub">program. Bigger web applications can have lots of code so it is a good idea to</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__56"></td><td class="diff_header" id="to55_433">433+</td><td nowrap="nowrap"><span class="diff_add">bring structure to their program. Bigger web applications can have lots of</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_415">415-</td><td nowrap="nowrap"><span class="diff_sub">have structure in the program right from the beginnings. That way, even users</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_434">434+</td><td nowrap="nowrap"><span class="diff_add">code, so it is a good idea to have an effective structure right from the beginning.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_416">416-</td><td nowrap="nowrap"><span class="diff_sub">of other frameworks (or even languages, as MVC is nothing Python-specific) can</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_435">435+</td><td nowrap="nowrap"><span class="diff_add">That way, even users of other frameworks (or even other languages, since MVC is</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_417">417-</td><td nowrap="nowrap"><span class="diff_sub">understand the existing code easier, as they are already familiar with the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_436">436+</td><td nowrap="nowrap"><span class="diff_add">not Python-specific) can easily understand the code, given that they are</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_418">418-</td><td nowrap="nowrap"><span class="diff_sub">structure.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_437">437+</td><td nowrap="nowrap"><span class="diff_add">already familiar with the MVC structure.</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__57"></td><td class="diff_header" id="from55_419">419</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_420">420</td><td nowrap="nowrap">MVC stands for three components:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_421">421</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__58"><a href="#difflib_chg_to55__57">n</a></td><td class="diff_header" id="from55_422">422-</td><td nowrap="nowrap"><span class="diff_sub">* The *model*. This is the data that is meant to modify. In Python frameworks</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__58"><a href="#difflib_chg_to55__57">n</a></td><td class="diff_header" id="to55_441">441+</td><td nowrap="nowrap"><span class="diff_add">* The *model*. This is the data that will be displayed and modified. In</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_423">423-</td><td nowrap="nowrap"> this component is often represented by the classes used by<span class="diff_sub"> the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_442">442+</td><td nowrap="nowrap"> <span class="diff_add"> Python frameworks,</span> this component is often represented by the classes used by</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_424">424-</td><td nowrap="nowrap"><span class="diff_sub"> object-relational mapper. So, all declarations go here.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_443">443+</td><td nowrap="nowrap"><span class="diff_add"> an object-relational mapper.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_444">444+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_425">425</td><td nowrap="nowrap">* The *view*. This component's job is to display the data of the model to the</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__58">n</a></td><td class="diff_header" id="from55_426">426-</td><td nowrap="nowrap"> user. Typically this component is <span class="diff_chg">r</span>e<span class="diff_chg">pres</span>ented <span class="diff_chg">by the</span> templates.</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__58">n</a></td><td class="diff_header" id="to55_446">446+</td><td nowrap="nowrap"> user. Typically this component is <span class="diff_chg">impl</span>e<span class="diff_chg">m</span>ented <span class="diff_chg">via</span> templates.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_447">447+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_427">427</td><td nowrap="nowrap">* The *controller*. This is the layer between the user and the model. The</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__59">n</a></td><td class="diff_header" id="from55_428">428-</td><td nowrap="nowrap"> controller reacts o<span class="diff_sub">n</span> user actions (like opening some specific URL)<span class="diff_chg"> and</span> tells</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__59">n</a></td><td class="diff_header" id="to55_449">449+</td><td nowrap="nowrap"> controller reacts <span class="diff_add">t</span>o user actions (like opening some specific URL)<span class="diff_chg">,</span> tells</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_429">429-</td><td nowrap="nowrap"><span class="diff_sub"> the model to modify the data if neccessary.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_450">450+</td><td nowrap="nowrap"><span class="diff_add"> the model to modify the data if necessary, and tells the view code what to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_451">451+</td><td nowrap="nowrap"><span class="diff_add"> display,</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__59"></td><td class="diff_header" id="from55_430">430</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_431">431</td><td nowrap="nowrap">While one might think that MVC is a complex design pattern, in fact it is not.</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__60"></td><td class="diff_header" id="from55_432">432</td><td nowrap="nowrap">It is used in Python because it has turned out to be useful for creating clean,</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_433">433</td><td nowrap="nowrap">maintainable web sites.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_434">434</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_435">435</td><td nowrap="nowrap">.. note::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_436">436</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_437">437</td><td nowrap="nowrap"> While not all Python frameworks explicitly support MVC, it is often trivial</td></tr><tr><td class="diff_next" id="difflib_chg_to55__61"><a href="#difflib_chg_to55__60">n</a></td><td class="diff_header" id="from55_438">438-</td><td nowrap="nowrap"> to create a web site which uses the MVC pattern by sep<span class="diff_chg">e</span>rating the data logic</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__61"><a href="#difflib_chg_to55__60">n</a></td><td class="diff_header" id="to55_460">460+</td><td nowrap="nowrap"> to create a web site which uses the MVC pattern by sep<span class="diff_chg">a</span>rating the data logic</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_439">439</td><td nowrap="nowrap"> (the model) from the user interaction logic (the controller) and the</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__61">n</a></td><td class="diff_header" id="from55_440">440-</td><td nowrap="nowrap"> templates (the view). That's why it is important not to write unne<span class="diff_sub">c</span>cessary</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__61">n</a></td><td class="diff_header" id="to55_462">462+</td><td nowrap="nowrap"> templates (the view). That's why it is important not to write unnecessary</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_441">441-</td><td nowrap="nowrap"> Python code in the templates -- it <span class="diff_chg">i</span>s against MVC and creates<span class="diff_sub"> more chaos.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_463">463+</td><td nowrap="nowrap"> Python code in the templates -- it <span class="diff_chg">work</span>s against <span class="diff_add">the </span>MVC <span class="diff_add">model </span>and creates</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_464">464+</td><td nowrap="nowrap"><span class="diff_add"> chaos in the code base, making it harder to understand and modify.</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__62"></td><td class="diff_header" id="from55_442">442</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_443">443</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_444">444</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__63"><a href="#difflib_chg_to55__62">n</a></td><td class="diff_header" id="from55_445">445-</td><td nowrap="nowrap"> The <span class="diff_chg">e</span>nglish Wikipedia has an article about the `Model-View-Controller pattern</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__63"><a href="#difflib_chg_to55__62">n</a></td><td class="diff_header" id="to55_468">468+</td><td nowrap="nowrap"> The <span class="diff_chg">E</span>nglish Wikipedia has an article about the `Model-View-Controller pattern</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_446">446-</td><td nowrap="nowrap"> <http://en.wikipedia.org/wiki/Model-view-controller>`_<span class="diff_chg">, which</span> includes a long</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_469">469+</td><td nowrap="nowrap"> <http://en.wikipedia.org/wiki/Model-view-controller>`_<span class="diff_chg">. It</span> includes a long</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_447">447-</td><td nowrap="nowrap"> list of web frameworks for <span class="diff_chg">d</span>i<span class="diff_chg">fferent</span> programming languages.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_470">470+</td><td nowrap="nowrap"> list of web frameworks for <span class="diff_chg">var</span>i<span class="diff_chg">ous</span> programming languages.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_448">448</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_449">449</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__63">n</a></td><td class="diff_header" id="from55_450">450-</td><td nowrap="nowrap">Ingredients for <span class="diff_chg">w</span>eb<span class="diff_sub"> </span>sites</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__63">n</a></td><td class="diff_header" id="to55_473">473+</td><td nowrap="nowrap">Ingredients for <span class="diff_chg">W</span>ebsites</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_451">451-</td><td nowrap="nowrap">========================<span class="diff_sub">=</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_474">474+</td><td nowrap="nowrap">========================</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_452">452</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__64">n</a></td><td class="diff_header" id="from55_453">453-</td><td nowrap="nowrap">Web<span class="diff_sub"> </span>sites are complex constructs, so tools <span class="diff_chg">w</span>e<span class="diff_chg">r</span>e created to help <span class="diff_sub">the </span>web<span class="diff_sub"> site</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__64">n</a></td><td class="diff_header" id="to55_476">476+</td><td nowrap="nowrap">Websites are complex constructs, so tools <span class="diff_chg">hav</span>e<span class="diff_chg"> b</span>e<span class="diff_add">en</span> created to help web</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_454">454-</td><td nowrap="nowrap"><span class="diff_sub">developer to make his work maintainable. None of these tools are in any way</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_477">477+</td><td nowrap="nowrap"><span class="diff_add">developers make their code easier to write and more maintainable. Tools like</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__64"></td><td class="diff_header" id="from55_455">455-</td><td nowrap="nowrap"><span class="diff_sub">Python specific, they also exist for other programming languages as well. Of</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__64"></td><td class="diff_header" id="to55_478">478+</td><td nowrap="nowrap"><span class="diff_add">these exist for all web frameworks in all languages. Developers are not forced</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_456">456-</td><td nowrap="nowrap"><span class="diff_sub">course, developers are not forced to use these tools and often there is no</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_479">479+</td><td nowrap="nowrap"><span class="diff_add">to use these tools, and often there is no "best" tool. It is worth learning</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_457">457-</td><td nowrap="nowrap"><span class="diff_sub">"best" tool, but it is worth informing yourself before choosing something</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_480">480+</td><td nowrap="nowrap"><span class="diff_add">about the available tools because they can greatly simplify the process of</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_458">458-</td><td nowrap="nowrap"><span class="diff_sub">because of the big number of helpers that the developer can use.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_481">481+</td><td nowrap="nowrap"><span class="diff_add">developing a web site.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_459">459</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_460">460</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_461">461</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_462">462</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__65"><a href="#difflib_chg_to55__65">n</a></td><td class="diff_header" id="from55_463">463-</td><td nowrap="nowrap"><span class="diff_sub"> People have written far more components that can be combined than these</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__65"><a href="#difflib_chg_to55__65">n</a></td><td class="diff_header" id="to55_486">486+</td><td nowrap="nowrap"><span class="diff_add"> There are far more components than can be presented here. The Python wiki</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_464">464-</td><td nowrap="nowrap"><span class="diff_sub"> presented here. The Python wiki has a page about these components, called</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_487">487+</td><td nowrap="nowrap"><span class="diff_add"> has a page about these components, called</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_465">465</td><td nowrap="nowrap"> `Web Components <http://wiki.python.org/moin/WebComponents>`_.</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__66"></td><td class="diff_header" id="from55_466">466</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_467">467</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_468">468</td><td nowrap="nowrap">Templates</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__67"></td><td class="diff_header" id="from55_469">469</td><td nowrap="nowrap">---------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_470">470</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__68"><a href="#difflib_chg_to55__66">n</a></td><td class="diff_header" id="from55_471">471-</td><td nowrap="nowrap">Mixing of HTML and Python code is possible w<span class="diff_sub">ith some</span> libraries. While</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__68"><a href="#difflib_chg_to55__66">n</a></td><td class="diff_header" id="to55_494">494+</td><td nowrap="nowrap">Mixing of HTML and Python code is<span class="diff_add"> made</span> possible <span class="diff_add">by a fe</span>w libraries. While</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_472">472</td><td nowrap="nowrap">convenient at first, it leads to horribly unmaintainable code. That's why</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_473">473</td><td nowrap="nowrap">templates exist. Templates are, in the simplest case, just HTML files with</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__67">n</a></td><td class="diff_header" id="from55_474">474-</td><td nowrap="nowrap">placeholders. The HTML is sent to the user's browser after filling <span class="diff_chg">out</span> the</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__67">n</a></td><td class="diff_header" id="to55_497">497+</td><td nowrap="nowrap">placeholders. The HTML is sent to the user's browser after filling <span class="diff_chg">in</span> the</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_475">475</td><td nowrap="nowrap">placeholders.</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__69"></td><td class="diff_header" id="from55_476">476</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__68">n</a></td><td class="diff_header" id="from55_477">477-</td><td nowrap="nowrap">Python already includes su<span class="diff_chg">ch</span> simple templates::</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__68">n</a></td><td class="diff_header" id="to55_500">500+</td><td nowrap="nowrap">Python already includes <span class="diff_add">two way</span>s<span class="diff_add"> to b</span>u<span class="diff_chg">ild</span> simple templates::</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_478">478</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__69">n</a></td><td class="diff_header" id="from55_479">479-</td><td nowrap="nowrap"><span class="diff_sub"> # a simple template</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_480">480-</td><td nowrap="nowrap"> template = "<html><body><h1>Hello %s!</h1></body></html>"</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_502">502+</td><td nowrap="nowrap"> <span class="diff_add"> >>></span> template = "<html><body><h1>Hello %s!</h1></body></html>"</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__70"></td><td class="diff_header" id="from55_481">481-</td><td nowrap="nowrap"> print template % "Reader"</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__70"></td><td class="diff_header" id="to55_503">503+</td><td nowrap="nowrap"> <span class="diff_add"> >>></span> print template % "Reader"</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_504">504+</td><td nowrap="nowrap"><span class="diff_add"> <html><body><h1>Hello Reader!</h1></body></html></span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_482">482</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__70">n</a></td><td class="diff_header" id="from55_483">483-</td><td nowrap="nowrap"><span class="diff_sub">The Python standard library also includes some more advanced templates usable</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__70">n</a></td><td class="diff_header" id="to55_506">506+</td><td nowrap="nowrap"><span class="diff_add"> >>> from string import Template</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_484">484-</td><td nowrap="nowrap"><span class="diff_sub">through :class:`string.Template`, but in HTML templates it is needed to use</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_507">507+</td><td nowrap="nowrap"><span class="diff_add"> >>> template = Template("<html><body><h1>Hello ${name}</h1></body></html>")</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_485">485-</td><td nowrap="nowrap"><span class="diff_sub">conditional and looping contructs like Python's *for* and *if*. So, some</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_508">508+</td><td nowrap="nowrap"><span class="diff_add"> >>> print template.substitute(dict(name='Dinsdale'))</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_486">486-</td><td nowrap="nowrap"><span class="diff_sub">*template engine* is needed.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_509">509+</td><td nowrap="nowrap"><span class="diff_add"> <html><body><h1>Hello Dinsdale!</h1></body></html></span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_487">487</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__71">n</a></td><td class="diff_header" id="from55_488">488-</td><td nowrap="nowrap"><span class="diff_sub">Now, Python has a lot of template engines which can be used with or without a</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__71">n</a></td><td class="diff_header" id="to55_511">511+</td><td nowrap="nowrap"><span class="diff_add">To generate complex HTML based on non-trivial model data, conditional</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_512">512+</td><td nowrap="nowrap"><span class="diff_add">and looping constructs like Python's *for* and *if* are generally needed.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_513">513+</td><td nowrap="nowrap"><span class="diff_add">*Template engines* support templates of this complexity.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__71"></td><td class="diff_header" id="to55_514">514+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_515">515+</td><td nowrap="nowrap"><span class="diff_add">There are a lot of template engines available for Python which can be used with</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_489">489-</td><td nowrap="nowrap">`framework`_. Some of these <span class="diff_chg">ar</span>e<span class="diff_chg"> us</span>in<span class="diff_chg">g</span> a plain-text programming<span class="diff_sub"> language which</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_516">516+</td><td nowrap="nowrap"><span class="diff_add">or without a </span>`framework`_. Some of these <span class="diff_chg">d</span>e<span class="diff_chg">f</span>in<span class="diff_chg">e</span> a plain-text programming</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_490">490-</td><td nowrap="nowrap"><span class="diff_sub">is very easy to learn as it is quite limited while others use XML so the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_517">517+</td><td nowrap="nowrap"><span class="diff_add">language which is easy to learn, partly because it is limited in scope.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__72"></td><td class="diff_header" id="from55_491">491-</td><td nowrap="nowrap"><span class="diff_sub">template output is always guaranteed to be valid XML. Some `frameworks`_ ship</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__72"></td><td class="diff_header" id="to55_518">518+</td><td nowrap="nowrap"><span class="diff_add">Others use XML, and the template output is guaranteed to be always be valid</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_492">492-</td><td nowrap="nowrap"><span class="diff_sub">their own template engine or recommend one particular. If one is not yet sure,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_519">519+</td><td nowrap="nowrap"><span class="diff_add">XML. There are many other variations.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_493">493-</td><td nowrap="nowrap"><span class="diff_sub">using these is a good idea.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_494">494</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__72">n</a></td><td class="diff_header" id="from55_495">495-</td><td nowrap="nowrap"><span class="diff_sub">.. note::</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__72">n</a></td><td class="diff_header" id="to55_521">521+</td><td nowrap="nowrap"><span class="diff_add">Some `frameworks`_ ship their own template engine or recommend one in</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_522">522+</td><td nowrap="nowrap"><span class="diff_add">particular. In the absence of a reason to use a different template engine,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_523">523+</td><td nowrap="nowrap"><span class="diff_add">using the one provided by or recommended by the framework is a good idea.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_496">496</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__73">n</a></td><td class="diff_header" id="from55_497">497-</td><td nowrap="nowrap"><span class="diff_sub"> While Python has quite a lot of different template engines it usually does</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__73"></td><td class="diff_header" id="from55_498">498-</td><td nowrap="nowrap"><span class="diff_sub"> not make sense to use a homebrewed template system. The time needed to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_499">499-</td><td nowrap="nowrap"><span class="diff_sub"> evaluate all templating systems is not really worth it, better invest the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_500">500-</td><td nowrap="nowrap"><span class="diff_sub"> time in looking through the most popular ones. Some frameworks have their</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_501">501-</td><td nowrap="nowrap"><span class="diff_sub"> own template engine or have a recommentation for one. It's wise to use</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_502">502-</td><td nowrap="nowrap"><span class="diff_sub"> these.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_503">503-</td><td nowrap="nowrap"><span class="diff_sub"> </span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__74"></td><td class="diff_header" id="from55_504">504-</td><td nowrap="nowrap"><span class="diff_sub"> </span>Popular template engines include:</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__74"></td><td class="diff_header" id="to55_525">525+</td><td nowrap="nowrap">Popular template engines include:</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_505">505</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__74">n</a></td><td class="diff_header" id="from55_506">506-</td><td nowrap="nowrap"><span class="diff_sub"> * Mako</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__74">n</a></td><td class="diff_header" id="to55_527">527+</td><td nowrap="nowrap"><span class="diff_add"> * `Mako <http://www.makotemplates.org/>`_</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__75"></td><td class="diff_header" id="from55_507">507-</td><td nowrap="nowrap"><span class="diff_sub"> * Genshi</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__75"></td><td class="diff_header" id="to55_528">528+</td><td nowrap="nowrap"><span class="diff_add"> * `Genshi <http://genshi.edgewall.org/>`_</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_508">508-</td><td nowrap="nowrap"><span class="diff_sub"> * Jinja</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_529">529+</td><td nowrap="nowrap"><span class="diff_add"> * `Jinja <http://jinja.pocoo.org/2/>`_</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_509">509</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_510">510</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_511">511</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__75">n</a></td><td class="diff_header" id="from55_512">512-</td><td nowrap="nowrap"><span class="diff_sub"> Lots of different template engines divide the attention between themselves</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__75">n</a></td><td class="diff_header" id="to55_533">533+</td><td nowrap="nowrap"><span class="diff_add"> There are many template engines competing for attention, becuase it is</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_513">513-</td><td nowrap="nowrap"> <span class="diff_chg">b</span>e<span class="diff_sub">cause i</span>t<span class="diff_chg">'s</span> easy to create them in Python. The page `Templating</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_534">534+</td><td nowrap="nowrap"> <span class="diff_chg">pr</span>et<span class="diff_chg">ty</span> easy to create them in Python. The page `Templating</td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__76"></td><td class="diff_header" id="from55_514">514</td><td nowrap="nowrap"> <http://wiki.python.org/moin/Templating>`_ in the wiki lists a big,</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__76">n</a></td><td class="diff_header" id="from55_515">515-</td><td nowrap="nowrap"><span class="diff_sub"> ever-growing number of these.</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__76">n</a></td><td class="diff_header" id="to55_536">536+</td><td nowrap="nowrap"><span class="diff_add"> ever-growing number of these. The three listed above are considered "second</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_537">537+</td><td nowrap="nowrap"><span class="diff_add"> generation" template engines and are a good place to start.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_516">516</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_517">517</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next" id="difflib_chg_to55__77"></td><td class="diff_header" id="from55_518">518</td><td nowrap="nowrap">Data persistence</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_519">519</td><td nowrap="nowrap">----------------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_520">520</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__77">n</a></td><td class="diff_header" id="from55_521">521-</td><td nowrap="nowrap">*Data persistence*, while sounding very complicated is just about storing data.</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__77">n</a></td><td class="diff_header" id="to55_543">543+</td><td nowrap="nowrap">*Data persistence*, while sounding very complicated<span class="diff_add">,</span> is just about storing data.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_522">522-</td><td nowrap="nowrap">This data might be the text of blog entries, the postings o<span class="diff_chg">f</span> a bulletin board or</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_544">544+</td><td nowrap="nowrap">This data might be the text of blog entries, the postings o<span class="diff_chg">n</span> a bulletin board or</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_523">523-</td><td nowrap="nowrap">the text of a wiki page. <span class="diff_chg">As always, t</span>here are different ways to store</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_545">545+</td><td nowrap="nowrap">the text of a wiki page. <span class="diff_chg">T</span>here are<span class="diff_add">, of course, a number of</span> different ways to store</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_524">524-</td><td nowrap="nowrap">information<span class="diff_sub">s</span> on a web server.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_546">546+</td><td nowrap="nowrap">information on a web server.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_525">525</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__78">n</a></td><td class="diff_header" id="from55_526">526-</td><td nowrap="nowrap">Often relational database engines like `MySQL <http://www.mysql.com/>`_ or</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__78">n</a></td><td class="diff_header" id="to55_548">548+</td><td nowrap="nowrap">Often<span class="diff_add">,</span> relational database engines like `MySQL <http://www.mysql.com/>`_ or</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_527">527-</td><td nowrap="nowrap">`PostgreSQL <<span class="diff_sub">http://</span>http://www.postgresql.org/>`_ are used <span class="diff_chg">d</span>ue <span class="diff_sub">t</span>o their good</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_549">549+</td><td nowrap="nowrap">`PostgreSQL <http://www.postgresql.org/>`_ are used <span class="diff_chg">beca</span>u<span class="diff_add">s</span>e o<span class="diff_add">f</span> their good</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_528">528-</td><td nowrap="nowrap">performance handling very large databases consisting of<span class="diff_sub"> up to</span> millions of</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_550">550+</td><td nowrap="nowrap">performance <span class="diff_add">when </span>handling very large databases consisting of millions of</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_551">551+</td><td nowrap="nowrap"><span class="diff_add">entries. There is also a small database engine called `SQLite</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_552">552+</td><td nowrap="nowrap"><span class="diff_add"><http://www.sqlite.org/>`_, which is bundled with Python in the :mod:`sqlite3`</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_553">553+</td><td nowrap="nowrap"><span class="diff_add">module, and which uses only one file. It has no other dependencies. For</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_554">554+</td><td nowrap="nowrap"><span class="diff_add">smaller sites SQLite is just enough.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_555">555+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_529">529-</td><td nowrap="nowrap">ent<span class="diff_chg">ri</span>es<span class="diff_sub">. These</span> are *queried* using a language called `SQL</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_556">556+</td><td nowrap="nowrap"><span class="diff_add">R</span>e<span class="diff_add">latio</span>n<span class="diff_add">al da</span>t<span class="diff_chg">abas</span>es are *queried* using a language called `SQL</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__78"></td><td class="diff_header" id="from55_530">530-</td><td nowrap="nowrap"><http://en.wikipedia.org/wiki/SQL>`_. Python programmers in general do not<span class="diff_sub"> like</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__78"></td><td class="diff_header" id="to55_557">557+</td><td nowrap="nowrap"><http://en.wikipedia.org/wiki/SQL>`_. Python programmers in general do not</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_531">531-</td><td nowrap="nowrap">SQL too much, they prefer to work with objects. It is possible to save<span class="diff_sub"> Python</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_558">558+</td><td nowrap="nowrap"><span class="diff_add">like </span>SQL too much, <span class="diff_add">as </span>they prefer to work with objects. It is possible to save</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_532">532-</td><td nowrap="nowrap">objects into a database using a technology called `ORM</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_559">559+</td><td nowrap="nowrap"><span class="diff_add">Python </span>objects into a database using a technology called `ORM</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_533">533-</td><td nowrap="nowrap"><http://en.wikipedia.org/wiki/Object-relational_mapping>`_<span class="diff_chg">. </span>OR<span class="diff_chg">M trans</span>lat<span class="diff_chg">es </span>al<span class="diff_sub">l</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_560">560+</td><td nowrap="nowrap"><http://en.wikipedia.org/wiki/Object-relational_mapping>`_<span class="diff_chg"> (</span>O<span class="diff_add">bject </span>R<span class="diff_chg">e</span>lat<span class="diff_chg">ion</span>al</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_534">534-</td><td nowrap="nowrap"><span class="diff_sub">object-oriented access into SQL code under the hood, the user does not need to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_561">561+</td><td nowrap="nowrap"><span class="diff_add">Mapping). ORM translates all object-oriented access into SQL code under the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_535">535-</td><td nowrap="nowrap"><span class="diff_sub">think about it. Most `frameworks`_ use ORMs and it works quite well.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_562">562+</td><td nowrap="nowrap"><span class="diff_add">hood, so the developer does not need to think about it. Most `frameworks`_ use</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_563">563+</td><td nowrap="nowrap"><span class="diff_add">ORMs, and it works quite well.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_536">536</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__79">n</a></td><td class="diff_header" id="from55_537">537-</td><td nowrap="nowrap"><span class="diff_sub">A second possibility is using files that are saved on the hard disk (sometimes</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__79">n</a></td><td class="diff_header" id="to55_565">565+</td><td nowrap="nowrap"><span class="diff_add">A second possibility is storing data in normal, plain text files (some</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__79"></td><td class="diff_header" id="from55_538">538-</td><td nowrap="nowrap"><span class="diff_sub">called flatfiles). This is very easy, but is not too fast. There is even a</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__79"></td><td class="diff_header" id="to55_566">566+</td><td nowrap="nowrap"><span class="diff_add">times called "flat files"). This is very easy for simple sites,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_539">539-</td><td nowrap="nowrap"><span class="diff_sub">small database engine called `SQLite <http://www.sqlite.org/>`_ which is bundled</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_567">567+</td><td nowrap="nowrap"><span class="diff_add">but can be difficult to get right if the web site is performing many</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_540">540-</td><td nowrap="nowrap"><span class="diff_sub">with Python in the :mod:`sqlite` module and uses only one file. This database</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_568">568+</td><td nowrap="nowrap"><span class="diff_add">updates to the stored data.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_541">541-</td><td nowrap="nowrap"><span class="diff_sub">can be used to store objects via an ORM and has no other dependencies. For</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_542">542-</td><td nowrap="nowrap"><span class="diff_sub">smaller sites SQLite is just enough. But it is not the only way in which data</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_543">543-</td><td nowrap="nowrap"><span class="diff_sub">can be saved into the file systems. Sometimes normal, plain text files are</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_544">544-</td><td nowrap="nowrap"><span class="diff_sub">enough.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_545">545</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__80"><a href="#difflib_chg_to55__80">n</a></td><td class="diff_header" id="from55_546">546-</td><td nowrap="nowrap"><span class="diff_sub">The third and least used possibility are so-called object oriented databases.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__80"><a href="#difflib_chg_to55__80">n</a></td><td class="diff_header" id="to55_570">570+</td><td nowrap="nowrap"><span class="diff_add">A third possibility are object oriented databases (also called "object</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_547">547-</td><td nowrap="nowrap"><span class="diff_sub">These databases store the *actual objects* instead of the relations that</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_571">571+</td><td nowrap="nowrap"><span class="diff_add">databases"). These databases store the object data in a form that closely</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_548">548-</td><td nowrap="nowrap"><span class="diff_sub">OR-mapping creates between rows in a database. This has the advantage that</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_572">572+</td><td nowrap="nowrap"><span class="diff_add">parallels the way the objects are structured in memory during program</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_573">573+</td><td nowrap="nowrap"><span class="diff_add">execution. (By contrast, ORMs store the object data as rows of data in tables</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_574">574+</td><td nowrap="nowrap"><span class="diff_add">and relations between those rows.) Storing the objects directly has the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_549">549-</td><td nowrap="nowrap">nearly all objects can be save<span class="diff_chg">n</span> in a straightforward way, unlike<span class="diff_sub"> in relational</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_575">575+</td><td nowrap="nowrap"><span class="diff_add">advantage that </span>nearly all objects can be save<span class="diff_chg">d</span> in a straightforward way, unlike</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_550">550-</td><td nowrap="nowrap">databases where some objects are very hard to represent<span class="diff_sub"> with ORMs</span>.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_576">576+</td><td nowrap="nowrap"><span class="diff_add">in relational </span>databases where some objects are very hard to represent.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_551">551</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__81"><a href="#difflib_chg_to55__81">n</a></td><td class="diff_header" id="from55_552">552-</td><td nowrap="nowrap">`Frameworks`_ often give<span class="diff_sub"> the users</span> hints on which method to choose<span class="diff_chg">, i</span>t is</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__81"><a href="#difflib_chg_to55__81">n</a></td><td class="diff_header" id="to55_578">578+</td><td nowrap="nowrap">`Frameworks`_ often give hints on which<span class="diff_add"> data storage</span> method to choose<span class="diff_chg">. I</span>t is</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_553">553-</td><td nowrap="nowrap"><span class="diff_sub">usually a good idea to stick to these unless there are some special requirements</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_579">579+</td><td nowrap="nowrap"><span class="diff_add">usually a good idea to stick to the data store recommended by the framework</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_554">554-</td><td nowrap="nowrap"><span class="diff_sub">which require to use the one method and not the other.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_580">580+</td><td nowrap="nowrap"><span class="diff_add">unless the application has special requirements better satisfied by an</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_581">581+</td><td nowrap="nowrap"><span class="diff_add">alternate storage mechanism.</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__82"></td><td class="diff_header" id="from55_555">555</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_556">556</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_557">557</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_558">558</td><td nowrap="nowrap"> * `Persistence Tools <http://wiki.python.org/moin/PersistenceTools>`_ lists</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__82">n</a></td><td class="diff_header" id="from55_559">559-</td><td nowrap="nowrap"> possibilities on how to save data in the file system<span class="diff_chg">, s</span>ome of these<span class="diff_sub"> modules</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__82">n</a></td><td class="diff_header" id="to55_586">586+</td><td nowrap="nowrap"> possibilities on how to save data in the file system<span class="diff_chg">. S</span>ome of these</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_560">560-</td><td nowrap="nowrap"> are part of the standard library</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_587">587+</td><td nowrap="nowrap"> <span class="diff_add"> modules</span> are part of the standard library</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_588">588+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__83"></td><td class="diff_header" id="from55_561">561</td><td nowrap="nowrap"> * `Database Programming <http://wiki.python.org/moin/DatabaseProgramming>`_</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__83">n</a></td><td class="diff_header" id="from55_562">562-</td><td nowrap="nowrap"> helps <span class="diff_chg">on</span> choosing a method o<span class="diff_chg">n how to</span> sav<span class="diff_chg">e the</span> data</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__83">n</a></td><td class="diff_header" id="to55_590">590+</td><td nowrap="nowrap"> helps <span class="diff_chg">with</span> choosing a method <span class="diff_add">f</span>o<span class="diff_chg">r</span> sav<span class="diff_chg">ing</span> data</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_591">591+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_563">563-</td><td nowrap="nowrap"> * `SQLAlchemy <http://www.sqlalchemy.org/>`_, the most powerful OR-Mapper<span class="diff_sub"> for</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_592">592+</td><td nowrap="nowrap"> * `SQLAlchemy <http://www.sqlalchemy.org/>`_, the most powerful OR-Mapper</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_564">564-</td><td nowrap="nowrap"> Python and `Elixir <http://elixir.ematia.de/>`_ which makes<span class="diff_sub"> it easier to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_593">593+</td><td nowrap="nowrap"> <span class="diff_add"> for</span> Python<span class="diff_add">,</span> and `Elixir <http://elixir.ematia.de/>`_<span class="diff_add">,</span> which makes</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_565">565-</td><td nowrap="nowrap"><span class="diff_sub"> use</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_594">594+</td><td nowrap="nowrap"><span class="diff_add"> SQLAlchemy easier to use</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_595">595+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_566">566</td><td nowrap="nowrap"> * `SQLObject <http://www.sqlobject.org/>`_, another popular OR-Mapper</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__84">n</a></td><td class="diff_header" id="to55_597">597+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_567">567</td><td nowrap="nowrap"> * `ZODB <https://launchpad.net/zodb>`_ and `Durus</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_568">568</td><td nowrap="nowrap"> <http://www.mems-exchange.org/software/durus/>`_, two object oriented</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__84"></td><td class="diff_header" id="from55_569">569</td><td nowrap="nowrap"> databases</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_570">570</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_571">571</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_572">572</td><td nowrap="nowrap">.. _framework:</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_573">573</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_574">574</td><td nowrap="nowrap">Frameworks</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_575">575</td><td nowrap="nowrap">==========</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_576">576</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__85">n</a></td><td class="diff_header" id="from55_577">577-</td><td nowrap="nowrap"><span class="diff_sub">As web sites can easily become quite large, there are so-called frameworks which</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__85">n</a></td><td class="diff_header" id="to55_608">608+</td><td nowrap="nowrap"><span class="diff_add">The process of creating code to run web sites involves writing code to provide</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__85"></td><td class="diff_header" id="from55_578">578-</td><td nowrap="nowrap"><span class="diff_sub">were created to help the developer with making these sites. Although the most</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__85"></td><td class="diff_header" id="to55_609">609+</td><td nowrap="nowrap"><span class="diff_add">various services. The code to provide a particular service often works the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_579">579-</td><td nowrap="nowrap"><span class="diff_sub">well-known framework is Ruby on Rails, Python does also have its own frameworks</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_610">610+</td><td nowrap="nowrap"><span class="diff_add">same way regardless of the complexity or purpose of the web site in question.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_580">580-</td><td nowrap="nowrap"><span class="diff_sub">which are partly inspired by Rails or which were existing a long time before</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_611">611+</td><td nowrap="nowrap"><span class="diff_add">Abstracting these common solutions into reusable code produces what are called</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_581">581-</td><td nowrap="nowrap"><span class="diff_sub">Rails.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_612">612+</td><td nowrap="nowrap"><span class="diff_add">"frameworks" for web development. Perhaps the most well-known framework for</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_613">613+</td><td nowrap="nowrap"><span class="diff_add">web development is Ruby on Rails, but Python has its own frameworks. Some of</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_614">614+</td><td nowrap="nowrap"><span class="diff_add">these were partly inspired by Rails, or borrowed ideas from Rails, but many</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_615">615+</td><td nowrap="nowrap"><span class="diff_add">existed a long time before Rails.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_582">582</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__86">n</a></td><td class="diff_header" id="from55_583">583-</td><td nowrap="nowrap"><span class="diff_sub">Two possible approaches to web frameworks exist: the minimalistic approach and</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__86">n</a></td><td class="diff_header" id="to55_617">617+</td><td nowrap="nowrap"><span class="diff_add">Originally Python web frameworks tended to incorporate all of the services</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_584">584-</td><td nowrap="nowrap"><span class="diff_sub">the all-inclusive approach (somtimes called *full-stack*). Frameworks which are</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_618">618+</td><td nowrap="nowrap"><span class="diff_add">needed to develop web sites as a giant, integrated set of tools. No two web</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_585">585-</td><td nowrap="nowrap"><span class="diff_sub">all-inclusive give you everything you need to start working, like a template</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_619">619+</td><td nowrap="nowrap"><span class="diff_add">frameworks were interoperable: a program developed for one could not be</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__86"></td><td class="diff_header" id="from55_586">586-</td><td nowrap="nowrap"><span class="diff_sub">engine, some way to save and access data in databases and many features more.</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__86"></td><td class="diff_header" id="to55_620">620+</td><td nowrap="nowrap"><span class="diff_add">deployed on a different one without considerable re-engineering work. This led</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_587">587-</td><td nowrap="nowrap"><span class="diff_sub">Most users are best off using these as they are widely used by lots of other</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_621">621+</td><td nowrap="nowrap"><span class="diff_add">to the development of "minimalist" web frameworks that provided just the tools</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_588">588-</td><td nowrap="nowrap"><span class="diff_sub">users and well documented in form of books and tutorials. Other web frameworks</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_622">622+</td><td nowrap="nowrap"><span class="diff_add">to communicate between the Python code and the http protocol, with all other</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_589">589-</td><td nowrap="nowrap"><span class="diff_sub">go the minimalistic approach trying to be as flexible as possible leaving the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_623">623+</td><td nowrap="nowrap"><span class="diff_add">services to be added on top via separate components. Some ad hoc standards</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_590">590-</td><td nowrap="nowrap"><span class="diff_sub">user the freedom to choose what's best for him.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_624">624+</td><td nowrap="nowrap"><span class="diff_add">were developed that allowed for limited interoperability between frameworks,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_625">625+</td><td nowrap="nowrap"><span class="diff_add">such as a standard that allowed different template engines to be used</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_626">626+</td><td nowrap="nowrap"><span class="diff_add">interchangeably.</span></td></tr> + <tr><td class="diff_next" id="difflib_chg_to55__87"></td><td class="diff_header" id="from55_591">591</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__87">n</a></td><td class="diff_header" id="from55_592">592-</td><td nowrap="nowrap"><span class="diff_sub">The majority of users is best off with all-inclusive framewors. They bring</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__87">n</a></td><td class="diff_header" id="to55_628">628+</td><td nowrap="nowrap"><span class="diff_add">Since the advent of WSGI, the Python web framework world has been evolving</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_593">593-</td><td nowrap="nowrap"><span class="diff_sub">everything along so a user can just jump in and start to code. While they do</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_629">629+</td><td nowrap="nowrap"><span class="diff_add">toward interoperability based on the WSGI standard. Now many web frameworks,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_594">594-</td><td nowrap="nowrap"><span class="diff_sub">have some limitations they can fullfill 80% of what one will ever want to</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_630">630+</td><td nowrap="nowrap"><span class="diff_add">whether "full stack" (providing all the tools one needs to deploy the most</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_595">595-</td><td nowrap="nowrap"><span class="diff_sub">perfectly. They consist of various components which are designed to work</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_631">631+</td><td nowrap="nowrap"><span class="diff_add">complex web sites) or minimalist, or anything in between, are built from</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_596">596-</td><td nowrap="nowrap"><span class="diff_sub">together as good as possible.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_632">632+</td><td nowrap="nowrap"><span class="diff_add">collections of reusable components that can be used with more than one</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_633">633+</td><td nowrap="nowrap"><span class="diff_add">framework.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_597">597</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__88">n</a></td><td class="diff_header" id="from55_598">598-</td><td nowrap="nowrap"><span class="diff_sub">The multitude of web frameworks written in Python demonstrates that it is really</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__88">n</a></td><td class="diff_header" id="to55_635">635+</td><td nowrap="nowrap"><span class="diff_add">The majority of users will probably want to select a "full stack" framework</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_599">599-</td><td nowrap="nowrap"><span class="diff_sub">easy to write one. One of the most well-known web applications written in</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_636">636+</td><td nowrap="nowrap"><span class="diff_add">that has an active community. These frameworks tend to be well documented,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_600">600-</td><td nowrap="nowrap"><span class="diff_sub">Python is `Zope <http://www.zope.org/>`_ which can be regarded as some kind of</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_637">637+</td><td nowrap="nowrap"><span class="diff_add">and provide the easiest path to producing a fully functional web site in</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__88"></td><td class="diff_header" id="from55_601">601-</td><td nowrap="nowrap"><span class="diff_sub">big framework. But Zope was not the only framework, there were some others</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__88"></td><td class="diff_header" id="to55_638">638+</td><td nowrap="nowrap"><span class="diff_add">minimal time.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_602">602-</td><td nowrap="nowrap"><span class="diff_sub">which are by now nearly forgotten. These do not need to be mentioned anymore,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_603">603-</td><td nowrap="nowrap"><span class="diff_sub">because most people that used them moved on to newer ones.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_604">604</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_605">605</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_606">606</td><td nowrap="nowrap">Some notable frameworks</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_607">607</td><td nowrap="nowrap">-----------------------</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_608">608</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__89">n</a></td><td class="diff_header" id="from55_609">609-</td><td nowrap="nowrap"><span class="diff_sub">There is an incredible number of frameworks, so there is no way to describe them</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__89">n</a></td><td class="diff_header" id="to55_644">644+</td><td nowrap="nowrap"><span class="diff_add">There are an incredible number of frameworks, so they cannot all be covered</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_610">610-</td><td nowrap="nowrap"><span class="diff_sub">all. It is not even neccessary, as most of these frameworks are nothing special</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_645">645+</td><td nowrap="nowrap"><span class="diff_add">here. Instead we will briefly touch on some of the most popular.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_611">611-</td><td nowrap="nowrap"><span class="diff_sub">and everything that can be done with these can also be done with one of the</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__89"></td><td class="diff_header" id="from55_612">612-</td><td nowrap="nowrap"><span class="diff_sub">popular ones.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_613">613</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_614">614</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_615">615</td><td nowrap="nowrap">Django</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_616">616</td><td nowrap="nowrap">^^^^^^</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_617">617</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_618">618</td><td nowrap="nowrap">`Django <http://www.djangoproject.com/>`_ is a framework consisting of several</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_619">619</td><td nowrap="nowrap">tightly coupled elements which were written from scratch and work together very</td></tr><tr><td class="diff_next" id="difflib_chg_to55__90"><a href="#difflib_chg_to55__90">n</a></td><td class="diff_header" id="from55_620">620-</td><td nowrap="nowrap">well. It includes an ORM which is quite powerful while being simple to use<span class="diff_chg"> and</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__90"><a href="#difflib_chg_to55__90">n</a></td><td class="diff_header" id="to55_653">653+</td><td nowrap="nowrap">well. It includes an ORM which is quite powerful while being simple to use<span class="diff_chg">,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_621">621-</td><td nowrap="nowrap">has a great online administration interface which makes it possible to edit<span class="diff_sub"> the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_654">654+</td><td nowrap="nowrap"><span class="diff_add">and </span>has a great online administration interface which makes it possible to edit</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_622">622-</td><td nowrap="nowrap">data in the database with a browser. The template engine is text-based and<span class="diff_sub"> is</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_655">655+</td><td nowrap="nowrap"><span class="diff_add">the </span>data in the database with a browser. The template engine is text-based and</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__91"></td><td class="diff_header" id="from55_623">623-</td><td nowrap="nowrap">designed to be usable for page designers who cannot write Python. It<span class="diff_sub"> supports</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__91"></td><td class="diff_header" id="to55_656">656+</td><td nowrap="nowrap"><span class="diff_add">is </span>designed to be usable for page designers who cannot write Python. It</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_624">624-</td><td nowrap="nowrap">so<span class="diff_chg">-called</span> template inheritance and filters (which work like Unix pipes). Django</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_657">657+</td><td nowrap="nowrap">s<span class="diff_add">upp</span>o<span class="diff_chg">rts</span> template inheritance and filters (which work like Unix pipes). Django</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_625">625-</td><td nowrap="nowrap">has many handy features bundled, <span class="diff_chg">like</span> creation of RSS feeds or generic views</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_658">658+</td><td nowrap="nowrap">has many handy features bundled, <span class="diff_chg">such as</span> creation of RSS feeds or generic views<span class="diff_add">,</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_626">626-</td><td nowrap="nowrap">which make it possible to <span class="diff_chg">w</span>r<span class="diff_chg">i</span>te web sites <span class="diff_sub">ne</span>a<span class="diff_sub">r</span>l<span class="diff_chg">y</span> without any Python code.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_659">659+</td><td nowrap="nowrap">which make it possible to <span class="diff_chg">c</span>r<span class="diff_chg">ea</span>te web sites al<span class="diff_chg">most</span> without <span class="diff_add">writing </span>any Python code.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_627">627</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__91">n</a></td><td class="diff_header" id="from55_628">628-</td><td nowrap="nowrap">It has a big, international community which ha<span class="diff_chg">s</span> created many<span class="diff_sub"> sites using Django.</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__91">n</a></td><td class="diff_header" id="to55_661">661+</td><td nowrap="nowrap">It has a big, international community<span class="diff_add">, the members of</span> which ha<span class="diff_chg">ve</span> created many</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__92"></td><td class="diff_header" id="from55_629">629-</td><td nowrap="nowrap">There are also <span class="diff_sub">quite </span>a lot of add-on projects which extend Django's normal</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__92"></td><td class="diff_header" id="to55_662">662+</td><td nowrap="nowrap"><span class="diff_add">web sites. </span>There are also a lot of add-on projects which extend Django's normal</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_630">630</td><td nowrap="nowrap">functionality. This is partly due to Django's well written `online</td></tr><tr><td class="diff_next" id="difflib_chg_to55__93"><a href="#difflib_chg_to55__92">n</a></td><td class="diff_header" id="from55_631">631-</td><td nowrap="nowrap">documentation <http://doc.djangoproject.com/>`_ and the `Django book</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__93"><a href="#difflib_chg_to55__92">n</a></td><td class="diff_header" id="to55_664">664+</td><td nowrap="nowrap">documentation <http://doc<span class="diff_add">s</span>.djangoproject.com/>`_ and the `Django book</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_632">632</td><td nowrap="nowrap"><http://www.djangobook.com/>`_.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_633">633</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_634">634</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_635">635</td><td nowrap="nowrap">.. note::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_636">636</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next" id="difflib_chg_to55__94"><a href="#difflib_chg_to55__93">n</a></td><td class="diff_header" id="from55_637">637-</td><td nowrap="nowrap"> Although Django is an MVC-style framework, it <span class="diff_chg">c</span>a<span class="diff_chg">ll</span>s the <span class="diff_chg">co</span>m<span class="diff_sub">pon</span>ents</td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__94"><a href="#difflib_chg_to55__93">n</a></td><td class="diff_header" id="to55_670">670+</td><td nowrap="nowrap"> Although Django is an MVC-style framework, it <span class="diff_chg">n</span>a<span class="diff_chg">me</span>s the <span class="diff_chg">ele</span>ments</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_638">638</td><td nowrap="nowrap"> differently, which is described in the `Django FAQ</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__94">n</a></td><td class="diff_header" id="from55_639">639-</td><td nowrap="nowrap"> <http://<span class="diff_chg">www</span>.djangoproject.com/<span class="diff_sub">docum</span>en<span class="diff_chg">tation</span>/faq/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names>`_.</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__94">n</a></td><td class="diff_header" id="to55_672">672+</td><td nowrap="nowrap"> <http://<span class="diff_chg">docs</span>.djangoproject.com/en<span class="diff_chg">/dev</span>/faq<span class="diff_add">/general</span>/#django-appears-to-be-a-mvc-framework-but-you-call-the-controller-the-view-and-the-view-the-template-how-come-you-don-t-use-the-standard-names>`_.</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_640">640</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_641">641</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_642">642</td><td nowrap="nowrap">TurboGears</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_643">643</td><td nowrap="nowrap">^^^^^^^^^^</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_644">644</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__95">n</a></td><td class="diff_header" id="from55_645">645-</td><td nowrap="nowrap"><span class="diff_chg">The </span>other popular web framework <span class="diff_chg">in</span> Python is `TurboGears</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__95">n</a></td><td class="diff_header" id="to55_678">678+</td><td nowrap="nowrap"><span class="diff_chg">An</span>other popular web framework <span class="diff_chg">for</span> Python is `TurboGears</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_646">646-</td><td nowrap="nowrap"><http://www.turbogears.org/>`_. <span class="diff_chg">It</span> takes the approach of using already<span class="diff_sub"> existing</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_679">679+</td><td nowrap="nowrap"><http://www.turbogears.org/>`_. <span class="diff_chg">TurboGears</span> takes the approach of using already</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_647">647-</td><td nowrap="nowrap">components and combining them with glue code to create a seamless<span class="diff_sub"> experience.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_680">680+</td><td nowrap="nowrap"><span class="diff_add">existing </span>components and combining them with glue code to create a seamless</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_648">648-</td><td nowrap="nowrap"><span class="diff_sub">TurboGears gives the user more flexibility on which components to choose, the</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_681">681+</td><td nowrap="nowrap"><span class="diff_add">experience. TurboGears gives the user flexibility in choosing components. For</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_649">649-</td><td nowrap="nowrap"><span class="diff_sub">ORM can be switched between some easy to use but limited and complex but very</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_682">682+</td><td nowrap="nowrap"><span class="diff_add">example the ORM and template engine can be changed to use packages different</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_650">650-</td><td nowrap="nowrap"><span class="diff_sub">powerful. Same goes for the template engine. One strong point about TurboGears</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_683">683+</td><td nowrap="nowrap"><span class="diff_add">from those used by default.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_651">651-</td><td nowrap="nowrap"><span class="diff_sub">is that the components that it consists of can be used easily in other projects</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__95"></td><td class="diff_header" id="from55_652">652-</td><td nowrap="nowrap"><span class="diff_sub">without depending on TurboGears, for example the underlying web server CherryPy.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_653">653</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_654">654</td><td nowrap="nowrap">The documentation can be found in the `TurboGears wiki</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_655">655</td><td nowrap="nowrap"><http://docs.turbogears.org/>`_, where links to screencasts can be found.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_656">656</td><td nowrap="nowrap">TurboGears has also an active user community which can respond to most related</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_657">657</td><td nowrap="nowrap">questions. There is also a `TurboGears book <http://turbogearsbook.com/>`_</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_658">658</td><td nowrap="nowrap">published, which is a good starting point.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_659">659</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__96">n</a></td><td class="diff_header" id="from55_660">660-</td><td nowrap="nowrap"><span class="diff_sub">The plan for the next major version of TurboGears, version 2.0 is to switch to a</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__96">n</a></td><td class="diff_header" id="to55_691">691+</td><td nowrap="nowrap"><span class="diff_add">The newest version of TurboGears, version 2.0, moves even further in direction</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_661">661-</td><td nowrap="nowrap"><span class="diff_sub">more flexible base provided by another very flexible web framework called</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_692">692+</td><td nowrap="nowrap"><span class="diff_add">of WSGI support and a component-based architecture. TurboGears 2 is based on</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_693">693+</td><td nowrap="nowrap"><span class="diff_add">the WSGI stack of another popular component-based web framework, `Pylons</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_662">662-</td><td nowrap="nowrap"><span class="diff_sub">`Pylons </span><http://pylonshq.com/>`_.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_694">694+</td><td nowrap="nowrap"><http://pylonshq.com/>`_.</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_695">695+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_696">696+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_697">697+</td><td nowrap="nowrap"><span class="diff_add">Zope</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_698">698+</td><td nowrap="nowrap"><span class="diff_add">^^^^</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_699">699+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_700">700+</td><td nowrap="nowrap"><span class="diff_add">The Zope framework is one of the "old original" frameworks. Its current</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_701">701+</td><td nowrap="nowrap"><span class="diff_add">incarnation in Zope2 is a tightly integrated full-stack framework. One of its</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_702">702+</td><td nowrap="nowrap"><span class="diff_add">most interesting feature is its tight integration with a powerful object</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_703">703+</td><td nowrap="nowrap"><span class="diff_add">database called the `ZODB <https://launchpad.net/zodb>`_ (Zope Object Database).</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_704">704+</td><td nowrap="nowrap"><span class="diff_add">Because of its highly integrated nature, Zope wound up in a somewhat isolated</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_705">705+</td><td nowrap="nowrap"><span class="diff_add">ecosystem: code written for Zope wasn't very usable outside of Zope, and</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_706">706+</td><td nowrap="nowrap"><span class="diff_add">vice-versa. To solve this problem the Zope 3 effort was started. Zope 3</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_707">707+</td><td nowrap="nowrap"><span class="diff_add">re-engineers Zope as a set of more cleanly isolated components. This effort</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_708">708+</td><td nowrap="nowrap"><span class="diff_add">was started before the advent of the WSGI standard, but there is WSGI support</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_709">709+</td><td nowrap="nowrap"><span class="diff_add">for Zope 3 from the `Repoze <http://repoze.org/>`_ project. Zope components</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_710">710+</td><td nowrap="nowrap"><span class="diff_add">have many years of production use behind them, and the Zope 3 project gives</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_711">711+</td><td nowrap="nowrap"><span class="diff_add">access to these components to the wider Python community. There is even a</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_712">712+</td><td nowrap="nowrap"><span class="diff_add">separate framework based on the Zope components: `Grok</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_713">713+</td><td nowrap="nowrap"><span class="diff_add"><http://grok.zope.org/>`_.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_714">714+</td><td nowrap="nowrap"><span class="diff_add"> </span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__96"></td><td class="diff_header" id="to55_715">715+</td><td nowrap="nowrap"><span class="diff_add">Zope is also the infrastructure used by the `Plone <http://plone.org/>`_ content</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_716">716+</td><td nowrap="nowrap"><span class="diff_add">management system, one of the most powerful and popular content management</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_717">717+</td><td nowrap="nowrap"><span class="diff_add">systems available.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_663">663</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_664">664</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_665">665</td><td nowrap="nowrap">Other notable frameworks</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_666">666</td><td nowrap="nowrap">^^^^^^^^^^^^^^^^^^^^^^^^</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_667">667</td><td nowrap="nowrap"></td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__97">n</a></td><td class="diff_header" id="from55_668">668-</td><td nowrap="nowrap"><span class="diff_chg">These two are o</span>f course not the only frameworks that are available<span class="diff_chg">, t</span>here are</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__97">n</a></td><td class="diff_header" id="to55_723">723+</td><td nowrap="nowrap"><span class="diff_chg">O</span>f course <span class="diff_add">these are </span>not the only frameworks that are available<span class="diff_chg">. T</span>here are</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_669">669-</td><td nowrap="nowrap"><span class="diff_sub">also some less-popular frameworks worth mentioning.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_724">724+</td><td nowrap="nowrap"><span class="diff_add">many other frameworks worth mentioning.</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_670">670-</td><td nowrap="nowrap"><span class="diff_sub"> </span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_671">671-</td><td nowrap="nowrap"><span class="diff_sub">One of these is the already mentioned Zope, which has been around for quite a</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__97"></td><td class="diff_header" id="from55_672">672-</td><td nowrap="nowrap"><span class="diff_sub">long time. With Zope 2.x having been known as rather un-pythonic, the newer</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_673">673-</td><td nowrap="nowrap"><span class="diff_sub">Zope 3.x tries to change that and therefore gets more acceptance from Python</span></td></tr> +<tr><td class="diff_next" id="difflib_chg_to55__98"></td><td class="diff_header" id="from55_674">674-</td><td nowrap="nowrap"><span class="diff_sub">programmers. These efforts already showed results, there is a project which</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_675">675-</td><td nowrap="nowrap"><span class="diff_sub">connects Zope with WSGI called `Repoze <http://repoze.org/>`_ and another</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_676">676-</td><td nowrap="nowrap"><span class="diff_sub">project called `Grok <http://grok.zope.org/>`_ which makes it possible for</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_677">677-</td><td nowrap="nowrap"><span class="diff_sub">"normal" Python programmers use the very mature Zope components.</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_678">678</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_679">679</td><td nowrap="nowrap">Another framework that's already been mentioned is `Pylons`_. Pylons is much</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__98">n</a></td><td class="diff_header" id="from55_680">680-</td><td nowrap="nowrap">like TurboGears with a<span class="diff_chg">b</span> even stronger emphasis on flexibility, which <span class="diff_chg">i</span>s<span class="diff_sub"> bought</span></td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__98">n</a></td><td class="diff_header" id="to55_727">727+</td><td nowrap="nowrap">like TurboGears<span class="diff_add">, but</span> with a<span class="diff_chg">n</span> even stronger emphasis on flexibility, which <span class="diff_chg">come</span>s</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_681">681</td><td nowrap="nowrap">at the cost of being more difficult to use. Nearly every component can be</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__99">n</a></td><td class="diff_header" id="from55_682">682-</td><td nowrap="nowrap">exchanged, which makes it ne<span class="diff_sub">c</span>cessary to use the documentation of every single</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__99">n</a></td><td class="diff_header" id="to55_729">729+</td><td nowrap="nowrap">exchanged, which makes it necessary to use the documentation of every single</td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_683">683-</td><td nowrap="nowrap"><span class="diff_sub">component, because there are so many Pylons combinations possible that can</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="to55_730">730+</td><td nowrap="nowrap"><span class="diff_add">component, of which there are many. Pylons builds upon `Paste</span></td></tr> +<tr><td class="diff_next"></td><td class="diff_header" id="from55_684">684-</td><td nowrap="nowrap"><span class="diff_sub">satisfy every requirement. Pylons builds upon `Paste</span></td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_685">685</td><td nowrap="nowrap"><http://pythonpaste.org/>`_, an extensive set of tools which are handy for WSGI.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_686">686</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_687">687</td><td nowrap="nowrap">And that's still not everything. The most up-to-date information can always be</td></tr> <tr><td class="diff_next" id="difflib_chg_to55__99"></td><td class="diff_header" id="from55_688">688</td><td nowrap="nowrap">found in the Python wiki.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_689">689</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_690">690</td><td nowrap="nowrap">.. seealso::</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_691">691</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_692">692</td><td nowrap="nowrap"> The Python wiki contains an extensive list of `web frameworks</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_693">693</td><td nowrap="nowrap"> <http://wiki.python.org/moin/WebFrameworks>`_.</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_694">694</td><td nowrap="nowrap"></td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_695">695</td><td nowrap="nowrap"> Most frameworks also have their own mailing lists and IRC channels, look out</td></tr><tr><td class="diff_next"><a href="#difflib_chg_to55__top">t</a></td><td class="diff_header" id="from55_696">696-</td><td nowrap="nowrap"> for these on the projects' websites. There is also a general "Python in the</td></tr> +<tr><td class="diff_next"><a href="#difflib_chg_to55__top">t</a></td><td class="diff_header" id="to55_742">742+</td><td nowrap="nowrap"> for these on the projects' web<span class="diff_add"> </span>sites. There is also a general "Python in the</td></tr> + <tr><td class="diff_next"></td><td class="diff_header" id="from55_697">697</td><td nowrap="nowrap"> Web" IRC channel on freenode called `#python.web</td></tr> <tr><td class="diff_next"></td><td class="diff_header" id="from55_698">698</td><td nowrap="nowrap"> <http://wiki.python.org/moin/PoundPythonWeb>`_.</td></tr> </tbody> + </table> + <table class="diff" summary="Legends"> + <tr> <th colspan="2"> Legends </th> </tr> + <tr> <td> <table border="" summary="Colors"> + <tr><th> Colors </th> </tr> + <tr><td class="diff_add"> Added </td></tr> + <tr><td class="diff_chg">Changed</td> </tr> + <tr><td class="diff_sub">Deleted</td> </tr> + </table></td> + <td> <table border="" summary="Links"> + <tr><th colspan="2"> Links </th> </tr> + <tr><td>(f)irst change</td> </tr> + <tr><td>(n)ext change</td> </tr> + <tr><td>(t)op</td> </tr> + </table></td> </tr> + </table> +</body> + +</html>