Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fc0fa67

Browse filesBrowse files
committed
Merge pull request #1 from kennethreitz/master
Update to match master
2 parents 417afdc + 0f79709 commit fc0fa67
Copy full SHA for fc0fa67

File tree

Expand file treeCollapse file tree

5 files changed

+255
-2
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+255
-2
lines changed

‎docs/contents.rst.inc

Copy file name to clipboardExpand all lines: docs/contents.rst.inc
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ This part of the guide focuses on best practices for writing Python code.
3232
writing/reading
3333
writing/documentation
3434
writing/tests
35+
writing/logging
3536
writing/gotchas
3637
writing/license
3738

@@ -59,6 +60,7 @@ different scenarios.
5960
scenarios/scientific
6061
scenarios/imaging
6162
scenarios/xml
63+
scenarios/json
6264
scenarios/crypto
6365

6466

‎docs/scenarios/cli.rst

Copy file name to clipboardExpand all lines: docs/scenarios/cli.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ who choose to create a command-line interface because it is quick and simple.
5656
Cliff
5757
------
5858

59-
`Cliff <https://cliff.readthedocs.org/en/latest>`_ is a framework for
59+
`Cliff <http://docs.openstack.org/developer/cliff/>`_ is a framework for
6060
building command-line programs. It uses setuptools entry points to provide
6161
subcommands, output formatters, and other extensions. The framework is meant
6262
to be used to create multi-level commands such as subversion and git, where

‎docs/scenarios/json.rst

Copy file name to clipboard
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
JSON
2+
====
3+
4+
The `json <https://docs.python.org/2/library/json.html>`_ library can parse JSON from strings or files. When parsing, the library converts the JSON into a Python dictionary or list. It can also parse Python dictionaries or lists into JSON strings.
5+
6+
Parsing JSON
7+
------------
8+
9+
Take the following string containing JSON data:
10+
11+
.. code-block:: python
12+
13+
json_string = '{"first_name": "Guido", "last_name":"Rossum"}'
14+
15+
It can be parsed like this:
16+
17+
.. code-block:: python
18+
19+
import json
20+
parsed_json = json.loads(json_string)
21+
22+
and can now be used as a normal dictionary:
23+
24+
.. code-block:: python
25+
26+
print(parsed_json['first_name'])
27+
"Guido"
28+
29+
You can also convert a the following to JSON:
30+
31+
.. code-block:: python
32+
33+
d = {
34+
'first_name': 'Guido',
35+
'second_name': 'Rossum',
36+
'titles': ['BDFL', 'Developer'],
37+
}
38+
39+
print(json.dumps(d))
40+
'{"first_name": "Guido", "last_name": "Rossum", "titles": ["BDFL", "Developer"]}'
41+
42+
43+
simplejson
44+
----------
45+
46+
`simplejson <https://simplejson.readthedocs.org/en/latest/>`_ is the externally maintained development version of the json library.
47+
48+
simplejson mimics the json standard library, it is available so that developers that use an older version of python can use the latest features available in the json lib.

‎docs/writing/logging.rst

Copy file name to clipboard
+203Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
Logging
2+
=======
3+
4+
The :mod:`logging` module has been a part of Python's Standard Library since
5+
version 2.3. It is succinctly described in :pep:`282`. The documentation
6+
is notoriously hard to read, except for the `basic logging tutorial`_.
7+
8+
Logging serves two purposes:
9+
10+
- **Diagnostic logging** records events related to the application's
11+
operation. If a user calls in to report an error, for example, the logs
12+
can be searched for context.
13+
- **Audit logging** records events for business analysis. A user's
14+
transactions can be extracted and combined with other user details for
15+
reports or to optimize a business goal.
16+
17+
18+
... or Print?
19+
-------------
20+
21+
The only time that ``print`` is a better option than logging is when
22+
the goal is to display a help statement for a command line application.
23+
Other reasons why logging is better than ``print``:
24+
25+
- The `log record`_, which is created with every logging event, contains
26+
readily available diagnostic information such as the file name,
27+
full path, function, and line number of the logging event.
28+
- Events logged in included modules are automatically accessible via the
29+
root logger
30+
to your application's logging stream, unless you filter them out.
31+
- Logging can be selectively silenced by using the method
32+
:meth:`logging.Logger.setLevel` or disabled by setting the attribute
33+
:attr:`logging.Logger.disabled` to ``True``.
34+
35+
36+
Logging in a Library
37+
--------------------
38+
39+
Notes for `configuring logging for a library`_ are in the
40+
`logging tutorial`_. Because the *user*, not the library, should
41+
dictate what happens when a logging event occurs, one admonition bears
42+
repeating:
43+
44+
.. note::
45+
It is strongly advised that you do not add any handlers other than
46+
NullHandler to your library’s loggers.
47+
48+
49+
Best practice when instantiating loggers in a library is to only create them
50+
using the ``__name__`` global variable: the :mod:`logging` module creates a
51+
hierarchy of loggers using dot notation, so using ``__name__`` ensures
52+
no name collisions.
53+
54+
Here is an example of best practice from the `requests source`_ -- place
55+
this in your ``__init__.py``
56+
57+
.. code-block:: python
58+
59+
# Set default logging handler to avoid "No handler found" warnings.
60+
import logging
61+
try: # Python 2.7+
62+
from logging import NullHandler
63+
except ImportError:
64+
class NullHandler(logging.Handler):
65+
def emit(self, record):
66+
pass
67+
68+
logging.getLogger(__name__).addHandler(NullHandler())
69+
70+
71+
72+
Logging in an Application
73+
-------------------------
74+
75+
The `twelve factor app <http://12factor.net>`_, an authoritative reference
76+
for good practice in application development, contains a section on
77+
`logging best practice <http://12factor.net/logs>`_. It emphatically
78+
advocates for treating log events as an event stream, and for
79+
sending that event stream to standard output to be handled by the
80+
application environment.
81+
82+
83+
There are at least three ways to configure a logger:
84+
85+
- Using an INI-formatted file:
86+
- **Pro**: possible to update configuration while running
87+
using the function :func:`logging.config.listen` to listen
88+
on a socket.
89+
- **Con**: less control (*e.g.* custom subclassed filters or loggers)
90+
than possible when configuring a logger in code.
91+
- Using a dictionary or a JSON-formatted file:
92+
- **Pro**: in addition to updating while running, it is possible to
93+
load from a file using the :mod:`json` module, in the standard
94+
library since Python 2.6.
95+
- **Con**: less control than when configuring a logger in code.
96+
- Using code:
97+
- **Pro**: complete control over the configuration.
98+
- **Con**: modifications require a change to source code.
99+
100+
101+
Example Configuration via an INI File
102+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
103+
104+
Let us say the file is named ``logging_config.ini``.
105+
More details for the file format are in the `logging configuration`_
106+
section of the `logging tutorial`_.
107+
108+
.. code-block:: ini
109+
110+
[loggers]
111+
keys=root
112+
113+
[handlers]
114+
keys=stream_handler
115+
116+
[formatters]
117+
keys=formatter
118+
119+
[logger_root]
120+
level=DEBUG
121+
handlers=stream_handler
122+
123+
[handler_stream_handler]
124+
class=StreamHandler
125+
level=DEBUG
126+
formatter=formatter
127+
args=(sys.stderr,)
128+
129+
[formatter_formatter]
130+
format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s
131+
132+
133+
Then use :meth:`logging.config.fileConfig` in the code:
134+
135+
.. code-block:: python
136+
137+
import logging
138+
from logging.config import fileConfig
139+
140+
fileConfig('logging_config.ini')
141+
logger = logging.getLogger()
142+
logger.debug('often makes a very good meal of %s', 'visiting tourists')
143+
144+
145+
Example Configuration via a Dictionary
146+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
147+
148+
As of Python 2.7, you can use a dictionary with configuration details.
149+
:pep:`319` contains a list of the mandatory and optional elements in
150+
the configuration dictionary.
151+
152+
.. code-block:: python
153+
154+
import logging
155+
from logging.config import dictConfig
156+
157+
logging_config = dict(
158+
version = 1,
159+
formatters = {
160+
'f': {'format':
161+
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s'}
162+
},
163+
handlers = {
164+
'h': {'class': 'logging.StreamHandler',
165+
'formatter': 'f',
166+
'level': logging.DEBUG}
167+
},
168+
loggers = {
169+
root : {'handlers': ['h'],
170+
'level': logging.DEBUG}
171+
}
172+
)
173+
174+
dictConfig(logging_config)
175+
176+
logger = logging.getLogger()
177+
logger.debug('often makes a very good meal of %s', 'visiting tourists')
178+
179+
180+
Example Configuration Directly in Code
181+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
182+
183+
.. code-block:: python
184+
185+
import logging
186+
187+
logger = logging.getLogger()
188+
handler = logging.StreamHandler()
189+
formatter = logging.Formatter(
190+
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
191+
handler.setFormatter(formatter)
192+
logger.addHandler(handler)
193+
logger.setLevel(logging.DEBUG)
194+
195+
logger.debug('often makes a very good meal of %s', 'visiting tourists')
196+
197+
198+
.. _basic logging tutorial: http://docs.python.org/howto/logging.html#logging-basic-tutorial
199+
.. _logging configuration: https://docs.python.org/howto/logging.html#configuring-logging
200+
.. _logging tutorial: http://docs.python.org/howto/logging.html
201+
.. _configuring logging for a library: https://docs.python.org/howto/logging.html#configuring-logging-for-a-library
202+
.. _log record: https://docs.python.org/library/logging.html#logrecord-attributes
203+
.. _requests source: https://github.com/kennethreitz/requests

‎docs/writing/tests.rst

Copy file name to clipboardExpand all lines: docs/writing/tests.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Some general rules of testing:
5858
good set of tests, you or other maintainers will rely largely on the
5959
testing suite to fix the problem or modify a given behavior. Therefore
6060
the testing code will be read as much as or even more than the running
61-
code. A unit test whose purpose is unclear is not very helpful is this
61+
code. A unit test whose purpose is unclear is not very helpful in this
6262
case.
6363

6464
- Another use of the testing code is as an introduction to new developers. When

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.