Skip to content

Commit 4cac6b5

Browse files
author
Kenneth Reitz
committed
Merge pull request realpython#232 from Julian/master
Added Travis for Doctesting (and a few doctests)
2 parents 2b82bfc + ad48194 commit 4cac6b5

File tree

3 files changed

+72
-16
lines changed

3 files changed

+72
-16
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
language: python
2+
install: pip install sphinx
3+
script:
4+
- make doctest
5+
- make html
6+

docs/conf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,12 @@
2525

2626
# Add any Sphinx extension module names here, as strings. They can be extensions
2727
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
28-
extensions = ['sphinx.ext.ifconfig', 'sphinx.ext.todo', 'sphinx.ext.intersphinx']
28+
extensions = [
29+
'sphinx.ext.ifconfig',
30+
'sphinx.ext.todo',
31+
'sphinx.ext.intersphinx',
32+
'sphinx.ext.doctest',
33+
]
2934

3035
# Add any paths that contain templates here, relative to this directory.
3136
templates_path = ['_templates']

docs/writing/gotchas.rst

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,39 @@ Mutable Default Arguments
1919
Seemingly the *most* common surprise new Python programmers encounter is
2020
Python's treatment of mutable default arguments in function definitions.
2121

22-
**What You Wrote**
22+
What You Wrote
23+
~~~~~~~~~~~~~~
2324

24-
.. code-block:: python
25+
.. testcode::
2526

2627
def append_to(element, to=[]):
2728
to.append(element)
2829
return to
2930

30-
**What You Might Have Expected to Happen**
31+
What You Might Have Expected to Happen
32+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33+
34+
.. testcode::
35+
36+
my_list = append_to(12)
37+
print my_list
38+
39+
my_other_list = append_to(42)
40+
print my_other_list
3141

3242
A new list is created each time the function is called if a second argument
33-
isn't provided.
43+
isn't provided, so that the output is::
44+
45+
[12]
46+
[42]
47+
48+
What Does Happen
49+
~~~~~~~~~~~~~~~~
50+
51+
.. testoutput::
3452

35-
**What Does Happen**
53+
[12]
54+
[12, 42]
3655

3756
A new list is created *once* when the function is defined, and the same list is
3857
used in each successive call.
@@ -42,7 +61,8 @@ not each time the function is called (like it is in say, Ruby). This means that
4261
if you use a mutable default argument and mutate it, you *will* and have
4362
mutated that object for all future calls to the function as well.
4463

45-
**What You Should Do Instead**
64+
What You Should Do Instead
65+
~~~~~~~~~~~~~~~~~~~~~~~~~~
4666

4767
Create a new object each time the function is called, by using a default arg to
4868
signal that no argument was provided (``None`` is often a good choice).
@@ -56,7 +76,8 @@ signal that no argument was provided (``None`` is often a good choice).
5676
return to
5777
5878
59-
**When the Gotcha Isn't a Gotcha**
79+
When the Gotcha Isn't a Gotcha
80+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6081

6182
Sometimes you specifically can "exploit" (read: use as intended) this behavior
6283
to maintain state between calls of a function. This is often done when writing
@@ -69,19 +90,41 @@ Late Binding Closures
6990
Another common source of confusion is the way Python binds its variables in
7091
closures (or in the surrounding global scope).
7192

72-
**What You Wrote**
93+
What You Wrote
94+
~~~~~~~~~~~~~~
7395

74-
.. code-block:: python
96+
.. testcode::
7597

76-
def create_adders():
98+
def create_multipliers():
7799
return [lambda x : i * x for i in range(5)]
78100

79-
**What You Might Have Expected to Happen**
101+
What You Might Have Expected to Happen
102+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
103+
104+
.. testcode::
105+
106+
for multiplier in create_multipliers():
107+
print multiplier(2)
80108

81109
A list containing five functions that each have their own closed-over ``i``
82-
variable that multiplies their argument.
110+
variable that multiplies their argument, producing::
111+
112+
0
113+
2
114+
4
115+
6
116+
8
117+
118+
What Does Happen
119+
~~~~~~~~~~~~~~~~
120+
121+
.. testoutput::
83122

84-
**What Does Happen**
123+
8
124+
8
125+
8
126+
8
127+
8
85128

86129
Five functions are created, but all of them just multiply ``x`` by 4.
87130

@@ -105,7 +148,8 @@ fact the same exact behavior is exhibited by just using an ordinary ``def``:
105148
return i * x
106149
yield adder
107150
108-
**What You Should Do Instead**
151+
What You Should Do Instead
152+
~~~~~~~~~~~~~~~~~~~~~~~~~~
109153

110154
Well. Here the general solution is arguably a bit of a hack. Due to Python's
111155
afformentioned behavior concerning evaluating default arguments to functions
@@ -117,7 +161,8 @@ its arguments by using a default arg like so:
117161
def create_adders():
118162
return [lambda x, i=i : i * x for i in range(5)]
119163
120-
**When the Gotcha Isn't a Gotcha**
164+
When the Gotcha Isn't a Gotcha
165+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
121166

122167
When you want your closures to behave this way. Late binding is good in lots of
123168
situations. Looping to create unique functions is unfortunately a case where

0 commit comments

Comments
 (0)