sphinx-compatible docstrings

This commit is contained in:
niphlod
2014-03-11 22:18:33 +01:00
parent c14e5cbae5
commit c44cfcb27c
4 changed files with 146 additions and 108 deletions

View File

@@ -2,9 +2,12 @@
# -*- coding: utf-8 -*-
"""
This file is part of the web2py Web Framework
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
| This file is part of the web2py Web Framework
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
HTTP statuses helpers
--------------------------------------------
"""
import re
@@ -58,6 +61,18 @@ defined_status = {
regex_status = re.compile('^\d{3} [0-9A-Z ]+$')
class HTTP(Exception):
"""Raises an HTTP response
Args:
status: usually an integer. If it's a well known status code, the ERROR
message will be automatically added. A string can also be passed
as `510 Foo Bar` and in that case the status code and the error
message will be parsed accordingly
body: what to return as body. If left as is, will return the error code
and the status message in the body itself
cookies: pass cookies along (usually not needed)
headers: pass headers as usual dict mapping
"""
def __init__(
self,
@@ -136,6 +151,14 @@ class HTTP(Exception):
def redirect(location='', how=303, client_side=False):
"""Raises a redirect (303)
Args:
location: the url where to redirect
how: what HTTP status code to use when redirecting
client_side: if set to True, it triggers a reload of the entire page
when the fragment has been loaded as a component
"""
if location:
from gluon import current
loc = location.replace('\r', '%0D').replace('\n', '%0A')

View File

@@ -2,12 +2,13 @@
# -*- coding: utf-8 -*-
"""
This file is part of the web2py Web Framework
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
| This file is part of the web2py Web Framework
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
| Plural subsystem is created by Vladyslav Kozlovskyy (Ukraine) <dbdevelop@gmail.com>
Plural subsystem is created by Vladyslav Kozlovskyy (Ukraine)
<dbdevelop@gmail.com>
Translation system
--------------------------------------------
"""
import os
@@ -165,7 +166,7 @@ def read_dict_aux(filename):
def read_dict(filename):
""" return dictionary with translation messages
""" Returns dictionary with translation messages
"""
return getcfs('lang:' + filename, filename,
lambda: read_dict_aux(filename))
@@ -173,8 +174,8 @@ def read_dict(filename):
def read_possible_plural_rules():
"""
create list of all possible plural rules files
result is cached in PLURAL_RULES dictionary to increase speed
Creates list of all possible plural rules files
The result is cached in PLURAL_RULES dictionary to increase speed
"""
plurals = {}
try:
@@ -328,7 +329,7 @@ def write_dict(filename, contents):
class lazyT(object):
"""
never to be called explicitly, returned by
Never to be called explicitly, returned by
translator.__call__() or translator.M()
"""
m = s = T = f = t = None
@@ -428,22 +429,22 @@ copy_reg.pickle(lazyT, pickle_lazyT)
class translator(object):
"""
this class is instantiated by gluon.compileapp.build_environment
This class is instantiated by gluon.compileapp.build_environment
as the T object
::
Example:
T.force(None) # turns off translation
T.force('fr, it') # forces web2py to translate using fr.py or it.py
T(\"Hello World\") # translates \"Hello World\" using the selected file
T("Hello World") # translates "Hello World" using the selected file
notice 1: there is no need to force since, by default, T uses
http_accept_language to determine a translation file.
notice 2:
en and en-en are considered different languages!
notice 3:
if language xx-yy is not found force() probes other similar
languages using such algorithm:
xx-yy.py -> xx.py -> xx-yy*.py -> xx*.py
Note:
- there is no need to force since, by default, T uses
http_accept_language to determine a translation file.
- en and en-en are considered different languages!
- if language xx-yy is not found force() probes other similar languages
using such algorithm: `xx-yy.py -> xx.py -> xx-yy*.py -> xx*.py`
"""
def __init__(self, langpath, http_accept_language):
@@ -473,25 +474,26 @@ class translator(object):
self.otherTs = {}
self.filter = markmin
self.ftag = 'markmin'
self.ns = None
def get_possible_languages_info(self, lang=None):
"""
return info for selected language or dictionary with all
possible languages info from APP/languages/*.py
args:
*lang* (str): language
returns:
if *lang* is defined:
return tuple(langcode, langname, langfile_mtime,
pluraldict_fname, pluraldict_mtime,
prules_langcode, nplurals,
get_plural_id, construct_plural_form)
or None
Returns info for selected language or dictionary with all
possible languages info from `APP/languages/*.py`
It Returns:
- a tuple containing::
langcode, langname, langfile_mtime,
pluraldict_fname, pluraldict_mtime,
prules_langcode, nplurals,
get_plural_id, construct_plural_form
or None
- if *lang* is NOT defined a dictionary with all possible
languages::
if *lang* is NOT defined:
returns dictionary with all possible languages:
{ langcode(from filename):
( langcode, # language code from !langcode!
langname,
@@ -504,6 +506,10 @@ class translator(object):
get_plural_id, # get_plural_id() for current language
construct_plural_form) # construct_plural_form() for current language
}
Args:
lang (str): language
"""
info = read_possible_languages(self.langpath)
if lang:
@@ -511,19 +517,18 @@ class translator(object):
return info
def get_possible_languages(self):
""" get list of all possible languages for current applications """
""" Gets list of all possible languages for current application """
return list(set(self.current_languages +
[lang for lang in read_possible_languages(self.langpath).iterkeys()
if lang != 'default']))
def set_current_languages(self, *languages):
"""
set current AKA "default" languages
setting one of this languages makes force() function
turn translation off to use default language
Sets current AKA "default" languages
Setting one of this languages makes the force() function to turn
translation off
"""
if len(languages) == 1 and isinstance(
languages[0], (tuple, list)):
if len(languages) == 1 and isinstance(languages[0], (tuple, list)):
languages = languages[0]
if not languages or languages[0] is None:
# set default language from default.py/DEFAULT_LANGUAGE
@@ -543,17 +548,19 @@ class translator(object):
self.force(self.http_accept_language)
def plural(self, word, n):
""" get plural form of word for number *n*
NOTE: *word" MUST be defined in current language
(T.accepted_language)
""" Gets plural form of word for number *n*
invoked from T()/T.M() in `%%{}` tag
invoked from T()/T.M() in %%{} tag
args:
word (str): word in singular
n (numeric): number plural form created for
Args:
word (str): word in singular
n (numeric): number plural form created for
Returns:
word (str): word in appropriate singular/plural form
Note:
"word" MUST be defined in current language (T.accepted_language)
returns:
(str): word in appropriate singular/plural form
"""
if int(n) == 1:
return word
@@ -582,11 +589,10 @@ class translator(object):
def force(self, *languages):
"""
select language(s) for translation
Selects language(s) for translation
if a list of languages is passed as a parameter,
first language from this list that matches the ones
the first language from this list that matches the ones
from the possible_languages dictionary will be
selected
@@ -691,11 +697,11 @@ class translator(object):
self.ns = ns
otherT = self.__get_otherT__(language, ns)
return otherT(message, symbols, lazy=lazy)
def __get_otherT__(self, language=None, namespace=None):
if not language and not namespace:
raise Exception('Incorrect parameters')
if namespace:
if language:
index = '%s/%s' % (namespace, language)
@@ -742,7 +748,7 @@ class translator(object):
def M(self, message, symbols={}, language=None,
lazy=None, filter=None, ftag=None, ns=None):
"""
get cached translated markmin-message with inserted parametes
Gets cached translated markmin-message with inserted parametes
if lazy==True lazyT object is returned
"""
if lazy is None:
@@ -760,16 +766,16 @@ class translator(object):
def get_t(self, message, prefix=''):
"""
user ## to add a comment into a translation string
Use ## to add a comment into a translation string
the comment can be useful do discriminate different possible
translations for the same string (for example different locations)
translations for the same string (for example different locations)::
T(' hello world ') -> ' hello world '
T(' hello world ## token') -> ' hello world '
T('hello ## world## token') -> 'hello ## world'
T(' hello world ') -> ' hello world '
T(' hello world ## token') -> ' hello world '
T('hello ## world## token') -> 'hello ## world'
the ## notation is ignored in multiline strings and strings that
start with ##. this is to allow markmin syntax to be translated
start with ##. This is needed to allow markmin syntax to be translated
"""
if isinstance(message, unicode):
message = message.encode('utf8')
@@ -793,25 +799,30 @@ class translator(object):
def params_substitution(self, message, symbols):
"""
substitute parameters from symbols into message using %.
also parse %%{} placeholders for plural-forms processing.
returns: string with parameters
NOTE: *symbols* MUST BE OR tuple OR dict of parameters!
Substitutes parameters from symbols into message using %.
also parse `%%{}` placeholders for plural-forms processing.
Returns:
string with parameters
Note:
*symbols* MUST BE OR tuple OR dict of parameters!
"""
def sub_plural(m):
"""string in %{} is transformed by this rules:
If string starts with \\, ! or ? such transformations
take place:
"""String in `%{}` is transformed by this rules:
If string starts with `\\`, `!` or `?` such transformations
take place::
"!string of words" -> "String of word" (Capitalize)
"!!string of words" -> "String Of Word" (Title)
"!!!string of words" -> "STRING OF WORD" (Upper)
"\\!string of words" -> "!string of word"
(remove \\ and disable transformations)
"?word?number" -> "word" (return word, if number == 1)
"?number" or "??number" -> "" (remove number,
if number == 1)
"?word?number" -> "number" (if number != 1)
"!string of words" -> "String of word" (Capitalize)
"!!string of words" -> "String Of Word" (Title)
"!!!string of words" -> "STRING OF WORD" (Upper)
"\\!string of words" -> "!string of word"
(remove \\ and disable transformations)
"?word?number" -> "word" (return word, if number == 1)
"?number" or "??number" -> "" (remove number,
if number == 1)
"?word?number" -> "number" (if number != 1)
"""
def sub_tuple(m):
""" word[number], !word[number], !!word[number], !!!word[number]
@@ -894,7 +905,7 @@ class translator(object):
def translate(self, message, symbols):
"""
get cached translated message with inserted parameters(symbols)
Gets cached translated message with inserted parameters(symbols)
"""
message = get_from_cache(self.cache, message,
lambda: self.get_t(message))
@@ -917,7 +928,8 @@ class translator(object):
def findT(path, language=DEFAULT_LANGUAGE):
"""
must be run by the admin app
Note:
Must be run by the admin app
"""
lang_file = pjoin(path, 'languages', language + '.py')
sentences = read_dict(lang_file)
@@ -954,6 +966,10 @@ def findT(path, language=DEFAULT_LANGUAGE):
write_dict(lang_file, sentences)
def update_all_languages(application_path):
"""
Note:
Must be run by the admin app
"""
path = pjoin(application_path, 'languages/')
for language in oslistdir(path):
if regex_langfile.match(language):

View File

@@ -2,14 +2,12 @@
# -*- coding: utf-8 -*-
"""
This file is part of the web2py Web Framework
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
Contains:
- wsgibase: the gluon wsgi application
| This file is part of the web2py Web Framework
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
The gluon wsgi application
---------------------------
"""
if False: import import_all # DO NOT REMOVE PART OF FREEZE PROCESS
@@ -135,9 +133,9 @@ HTTPS_SCHEMES = set(('https', 'HTTPS'))
def get_client(env):
"""
guess the client address from the environment variables
Guesses the client address from the environment variables
first tries 'http_x_forwarded_for', secondly 'remote_addr'
First tries 'http_x_forwarded_for', secondly 'remote_addr'
if all fails, assume '127.0.0.1' or '::1' (running locally)
"""
eget = env.get
@@ -160,7 +158,7 @@ def get_client(env):
def serve_controller(request, response, session):
"""
this function is used to generate a dynamic page.
This function is used to generate a dynamic page.
It first runs all models, then runs the function in the controller,
and then tries to render the output using a view/template.
this function must run from the [application] folder.
@@ -234,7 +232,7 @@ class LazyWSGI(object):
return self._environ
def start_response(self,status='200', headers=[], exec_info=None):
"""
in controller you can use::
in controller you can use:
- request.wsgi.environ
- request.wsgi.start_response
@@ -249,7 +247,7 @@ class LazyWSGI(object):
"""
In you controller use::
@request.wsgi.middleware(middleware1, middleware2, ...)
@request.wsgi.middleware(middleware1, middleware2, ...)
to decorate actions with WSGI middleware. actions must return strings.
uses a simulated environment so it may have weird behavior in some cases
@@ -271,9 +269,9 @@ class LazyWSGI(object):
def wsgibase(environ, responder):
"""
this is the gluon wsgi application. the first function called when a page
is requested (static or dynamic). it can be called by paste.httpserver
or by apache mod_wsgi.
The gluon wsgi application. The first function called when a page
is requested (static or dynamic). It can be called by paste.httpserver
or by apache mod_wsgi (or any WSGI-compatible server).
- fills request with info
- the environment variables, replacing '.' with '_'
@@ -290,13 +288,11 @@ def wsgibase(environ, responder):
2. for dynamic pages:
- /<application>[/<controller>[/<function>[/<sub>]]][.<extension>]
- (sub may go several levels deep, currently 3 levels are supported:
sub1/sub2/sub3)
The naming conventions are:
- application, controller, function and extension may only contain
[a-zA-Z0-9_]
`[a-zA-Z0-9_]`
- file and sub may also contain '-', '=', '.' and '/'
"""
eget = environ.get
@@ -567,7 +563,7 @@ def wsgibase(environ, responder):
def save_password(password, port):
"""
used by main() to save the password in the parameters_port.py file.
Used by main() to save the password in the parameters_port.py file.
"""
password_file = abspath('parameters_%i.py' % port)
@@ -607,10 +603,10 @@ def appfactory(wsgiapp=wsgibase,
generates a wsgi application that does logging and profiling and calls
wsgibase
.. function:: gluon.main.appfactory(
[wsgiapp=wsgibase
[, logfilename='httpserver.log'
[, profilerfilename='profiler.log']]])
Args:
wsgiapp: the base application
logfilename: where to store apache-compatible requests log
profiler_dir: where to store profile files
"""
if profilerfilename is not None:

View File

@@ -2,9 +2,12 @@
# -*- coding: utf-8 -*-
"""
This file is part of the web2py Web Framework
Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
| This file is part of the web2py Web Framework
| Copyrighted by Massimo Di Pierro <mdipierro@cs.depaul.edu>
| License: LGPLv3 (http://www.gnu.org/licenses/lgpl.html)
Useful regexes
---------------
"""
import re