Merge pull request #364 from niphlod/enhancement/docstrings
docstrings fixes
This commit is contained in:
196
gluon/cache.py
196
gluon/cache.py
@@ -2,12 +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)
|
||||
|
||||
Basic caching classes and methods
|
||||
=================================
|
||||
---------------------------------
|
||||
|
||||
- Cache - The generic caching object interfacing with the others
|
||||
- CacheInRam - providing caching in ram
|
||||
@@ -42,57 +42,56 @@ __all__ = ['Cache', 'lazy_cache']
|
||||
DEFAULT_TIME_EXPIRE = 300
|
||||
|
||||
|
||||
|
||||
class CacheAbstract(object):
|
||||
"""
|
||||
Abstract class for cache implementations.
|
||||
Main function is now to provide referenced api documentation.
|
||||
Main function just provides referenced api documentation.
|
||||
|
||||
Use CacheInRam or CacheOnDisk instead which are derived from this class.
|
||||
|
||||
Attentions, Michele says:
|
||||
|
||||
There are signatures inside gdbm files that are used directly
|
||||
by the python gdbm adapter that often are lagging behind in the
|
||||
detection code in python part.
|
||||
On every occasion that a gdbm store is probed by the python adapter,
|
||||
the probe fails, because gdbm file version is newer.
|
||||
Using gdbm directly from C would work, because there is backward
|
||||
compatibility, but not from python!
|
||||
The .shelve file is discarded and a new one created (with new
|
||||
signature) and it works until it is probed again...
|
||||
The possible consequences are memory leaks and broken sessions.
|
||||
Note:
|
||||
Michele says: there are signatures inside gdbm files that are used
|
||||
directly by the python gdbm adapter that often are lagging behind in the
|
||||
detection code in python part.
|
||||
On every occasion that a gdbm store is probed by the python adapter,
|
||||
the probe fails, because gdbm file version is newer.
|
||||
Using gdbm directly from C would work, because there is backward
|
||||
compatibility, but not from python!
|
||||
The .shelve file is discarded and a new one created (with new
|
||||
signature) and it works until it is probed again...
|
||||
The possible consequences are memory leaks and broken sessions.
|
||||
"""
|
||||
|
||||
cache_stats_name = 'web2py_cache_statistics'
|
||||
|
||||
def __init__(self, request=None):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
request:
|
||||
the global request object
|
||||
"""Initializes the object
|
||||
|
||||
Args:
|
||||
request: the global request object
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def __call__(self, key, f,
|
||||
time_expire=DEFAULT_TIME_EXPIRE):
|
||||
"""
|
||||
Tries retrieve the value corresponding to `key` from the cache of the
|
||||
object exists and if it did not expire, else it called the function `f`
|
||||
and stores the output in the cache corresponding to `key`. In the case
|
||||
the output of the function is returned.
|
||||
Tries to retrieve the value corresponding to `key` from the cache if the
|
||||
object exists and if it did not expire, else it calls the function `f`
|
||||
and stores the output in the cache corresponding to `key`. It always
|
||||
returns the function that is returned.
|
||||
|
||||
:param key: the key of the object to be store or retrieved
|
||||
:param f: the function, whose output is to be cached
|
||||
:param time_expire: expiration of the cache in microseconds
|
||||
Args:
|
||||
key(str): the key of the object to be stored or retrieved
|
||||
f(function): the function whose output is to be cached.
|
||||
|
||||
- `time_expire` is used to compare the current time with the time when
|
||||
the requested object was last saved in cache. It does not affect
|
||||
future requests.
|
||||
- Setting `time_expire` to 0 or negative value forces the cache to
|
||||
refresh.
|
||||
If `f` is `None` the cache is cleared.
|
||||
time_expire(int): expiration of the cache in seconds.
|
||||
|
||||
If the function `f` is `None` the cache is cleared.
|
||||
It's used to compare the current time with the time
|
||||
when the requested object was last saved in cache. It does not
|
||||
affect future requests. Setting `time_expire` to 0 or negative
|
||||
value forces the cache to refresh.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -101,11 +100,9 @@ class CacheAbstract(object):
|
||||
Clears the cache of all keys that match the provided regular expression.
|
||||
If no regular expression is provided, it clears all entries in cache.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
regex:
|
||||
if provided, only keys matching the regex will be cleared.
|
||||
Otherwise all keys are cleared.
|
||||
Args:
|
||||
regex: if provided, only keys matching the regex will be cleared,
|
||||
otherwise all keys are cleared.
|
||||
"""
|
||||
|
||||
raise NotImplementedError
|
||||
@@ -114,12 +111,9 @@ class CacheAbstract(object):
|
||||
"""
|
||||
Increments the cached value for the given key by the amount in value
|
||||
|
||||
Parameters
|
||||
----------
|
||||
key:
|
||||
key for the cached object to be incremeneted
|
||||
value:
|
||||
amount of the increment (defaults to 1, can be negative)
|
||||
Args:
|
||||
key(str): key for the cached object to be incremeneted
|
||||
value(int): amount of the increment (defaults to 1, can be negative)
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -187,12 +181,17 @@ class CacheInRam(CacheAbstract):
|
||||
time_expire=DEFAULT_TIME_EXPIRE,
|
||||
destroyer=None):
|
||||
"""
|
||||
Attention! cache.ram does not copy the cached object. It just stores a reference to it.
|
||||
Turns out the deepcopying the object has some problems:
|
||||
1) would break backward compatibility
|
||||
2) would be limiting because people may want to cache live objects
|
||||
3) would work unless we deepcopy no storage and retrival which would make things slow.
|
||||
Anyway. You can deepcopy explicitly in the function generating the value to be cached.
|
||||
Attention! cache.ram does not copy the cached object.
|
||||
It just stores a reference to it. Turns out the deepcopying the object
|
||||
has some problems:
|
||||
|
||||
- would break backward compatibility
|
||||
- would be limiting because people may want to cache live objects
|
||||
- would work unless we deepcopy no storage and retrival which would make
|
||||
things slow.
|
||||
|
||||
Anyway. You can deepcopy explicitly in the function generating the value
|
||||
to be cached.
|
||||
"""
|
||||
self.initialize()
|
||||
|
||||
@@ -419,10 +418,8 @@ class Cache(object):
|
||||
|
||||
def __init__(self, request):
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
request:
|
||||
the global request object
|
||||
Args:
|
||||
request: the global request object
|
||||
"""
|
||||
# GAE will have a special caching
|
||||
if have_settings and settings.global_settings.web2py_runtime_gae:
|
||||
@@ -444,24 +441,30 @@ class Cache(object):
|
||||
prefix=None, session=False, vars=True, lang=True,
|
||||
user_agent=False, public=True, valid_statuses=None,
|
||||
quick=None):
|
||||
"""
|
||||
Experimental!
|
||||
"""Better fit for caching an action
|
||||
|
||||
Warning:
|
||||
Experimental!
|
||||
|
||||
Currently only HTTP 1.1 compliant
|
||||
reference : http://code.google.com/p/doctype-mirror/wiki/ArticleHttpCaching
|
||||
time_expire: same as @cache
|
||||
cache_model: same as @cache
|
||||
prefix: add a prefix to the calculated key
|
||||
session: adds response.session_id to the key
|
||||
vars: adds request.env.query_string
|
||||
lang: adds T.accepted_language
|
||||
user_agent: if True, adds is_mobile and is_tablet to the key.
|
||||
Pass a dict to use all the needed values (uses str(.items())) (e.g. user_agent=request.user_agent())
|
||||
used only if session is not True
|
||||
public: if False forces the Cache-Control to be 'private'
|
||||
valid_statuses: by default only status codes starting with 1,2,3 will be cached.
|
||||
pass an explicit list of statuses on which turn the cache on
|
||||
quick: Session,Vars,Lang,User-agent,Public:
|
||||
fast overrides with initial strings, e.g. 'SVLP' or 'VLP', or 'VLP'
|
||||
|
||||
Args:
|
||||
time_expire(int): same as @cache
|
||||
cache_model(str): same as @cache
|
||||
prefix(str): add a prefix to the calculated key
|
||||
session(bool): adds response.session_id to the key
|
||||
vars(bool): adds request.env.query_string
|
||||
lang(bool): adds T.accepted_language
|
||||
user_agent(bool or dict): if True, adds is_mobile and is_tablet to the key.
|
||||
Pass a dict to use all the needed values (uses str(.items()))
|
||||
(e.g. user_agent=request.user_agent()). Used only if session is
|
||||
not True
|
||||
public(bool): if False forces the Cache-Control to be 'private'
|
||||
valid_statuses: by default only status codes starting with 1,2,3 will be cached.
|
||||
pass an explicit list of statuses on which turn the cache on
|
||||
quick: Session,Vars,Lang,User-agent,Public:
|
||||
fast overrides with initials, e.g. 'SVLP' or 'VLP', or 'VLP'
|
||||
"""
|
||||
from gluon import current
|
||||
from gluon.http import HTTP
|
||||
@@ -561,33 +564,32 @@ class Cache(object):
|
||||
"""
|
||||
Decorator function that can be used to cache any function/method.
|
||||
|
||||
Example::
|
||||
Args:
|
||||
key(str) : the key of the object to be store or retrieved
|
||||
time_expire(int) : expiration of the cache in seconds
|
||||
`time_expire` is used to compare the current time with the time
|
||||
when the requested object was last saved in cache.
|
||||
It does not affect future requests.
|
||||
Setting `time_expire` to 0 or negative value forces the cache to
|
||||
refresh.
|
||||
cache_model(str): can be "ram", "disk" or other (like "memcache").
|
||||
Defaults to "ram"
|
||||
|
||||
@cache('key', 5000, cache.ram)
|
||||
def f():
|
||||
return time.ctime()
|
||||
|
||||
When the function f is called, web2py tries to retrieve
|
||||
the value corresponding to `key` from the cache of the
|
||||
When the function `f` is called, web2py tries to retrieve
|
||||
the value corresponding to `key` from the cache if the
|
||||
object exists and if it did not expire, else it calles the function `f`
|
||||
and stores the output in the cache corresponding to `key`. In the case
|
||||
the output of the function is returned.
|
||||
|
||||
:param key: the key of the object to be store or retrieved
|
||||
:param time_expire: expiration of the cache in microseconds
|
||||
:param cache_model: "ram", "disk", or other
|
||||
(like "memcache" if defined). It defaults to "ram".
|
||||
Example: ::
|
||||
|
||||
Notes
|
||||
-----
|
||||
`time_expire` is used to compare the curret time with the time when the
|
||||
requested object was last saved in cache. It does not affect future
|
||||
requests.
|
||||
Setting `time_expire` to 0 or negative value forces the cache to
|
||||
refresh.
|
||||
@cache('key', 5000, cache.ram)
|
||||
def f():
|
||||
return time.ctime()
|
||||
|
||||
If the function `f` is an action, we suggest using
|
||||
@cache.client instead
|
||||
Note:
|
||||
If the function `f` is an action, we suggest using
|
||||
@cache.action instead
|
||||
"""
|
||||
|
||||
def tmp(func, cache=self, cache_model=cache_model):
|
||||
@@ -606,11 +608,13 @@ class Cache(object):
|
||||
|
||||
def lazy_cache(key=None, time_expire=None, cache_model='ram'):
|
||||
"""
|
||||
can be used to cache any function including in modules,
|
||||
Can be used to cache any function including ones in modules,
|
||||
as long as the cached function is only called within a web2py request
|
||||
if a key is not provided, one is generated from the function name
|
||||
the time_expire defaults to None (no cache expiration)
|
||||
if cache_model is "ram" then the model is current.cache.ram, etc.
|
||||
|
||||
If a key is not provided, one is generated from the function name
|
||||
`time_expire` defaults to None (no cache expiration)
|
||||
|
||||
If cache_model is "ram" then the model is current.cache.ram, etc.
|
||||
"""
|
||||
def decorator(f, key=key, time_expire=time_expire, cache_model=cache_model):
|
||||
key = key or repr(f)
|
||||
|
||||
23
gluon/cfs.py
23
gluon/cfs.py
@@ -2,19 +2,19 @@
|
||||
# -*- 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)
|
||||
|
||||
Functions required to execute app components
|
||||
============================================
|
||||
--------------------------------------------
|
||||
|
||||
FOR INTERNAL USE ONLY
|
||||
Note:
|
||||
FOR INTERNAL USE ONLY
|
||||
"""
|
||||
|
||||
from os import stat
|
||||
import thread
|
||||
import logging
|
||||
from gluon.fileutils import read_file
|
||||
|
||||
cfs = {} # for speed-up
|
||||
@@ -26,11 +26,12 @@ def getcfs(key, filename, filter=None):
|
||||
Caches the *filtered* file `filename` with `key` until the file is
|
||||
modified.
|
||||
|
||||
:param key: the cache key
|
||||
:param filename: the file to cache
|
||||
:param filter: is the function used for filtering. Normally `filename` is a
|
||||
.py file and `filter` is a function that bytecode compiles the file.
|
||||
In this way the bytecode compiled file is cached. (Default = None)
|
||||
Args:
|
||||
key(str): the cache key
|
||||
filename: the file to cache
|
||||
filter: is the function used for filtering. Normally `filename` is a
|
||||
.py file and `filter` is a function that bytecode compiles the file.
|
||||
In this way the bytecode compiled file is cached. (Default = None)
|
||||
|
||||
This is used on Google App Engine since pyc files cannot be saved.
|
||||
"""
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
# -*- 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)
|
||||
|
||||
Functions required to execute app components
|
||||
============================================
|
||||
--------------------------------------------
|
||||
|
||||
FOR INTERNAL USE ONLY
|
||||
Note:
|
||||
FOR INTERNAL USE ONLY
|
||||
"""
|
||||
|
||||
import re
|
||||
@@ -125,16 +126,27 @@ def LOAD(c=None, f='index', args=None, vars=None,
|
||||
extension=None, target=None, ajax=False, ajax_trap=False,
|
||||
url=None, user_signature=False, timeout=None, times=1,
|
||||
content='loading...', **attr):
|
||||
""" LOAD a component into the action's document
|
||||
""" LOADs a component into the action's document
|
||||
|
||||
Timing options:
|
||||
-times: An integer or string ("infinity"/"continuous")
|
||||
specifies how many times the component is requested
|
||||
-timeout (milliseconds): specifies the time to wait before
|
||||
starting the request or the frequency if times is greater than
|
||||
1 or "infinity".
|
||||
Timing options default to the normal behavior. The component
|
||||
is added on page loading without delay.
|
||||
Args:
|
||||
c(str): controller
|
||||
f(str): function
|
||||
args(tuple or list): arguments
|
||||
vars(dict): vars
|
||||
extension(str): extension
|
||||
target(str): id of the target
|
||||
ajax(bool): True to enable AJAX bahaviour
|
||||
ajax_trap(bool): True if `ajax` is set to `True`, traps
|
||||
both links and forms "inside" the target
|
||||
url(str): overrides `c`,`f`,`args` and `vars`
|
||||
user_signature(bool): adds hmac signature to all links
|
||||
with a key that is different for every user
|
||||
timeout(int): in milliseconds, specifies the time to wait before
|
||||
starting the request or the frequency if times is greater than
|
||||
1 or "infinity"
|
||||
times(integer or str): how many times the component will be requested
|
||||
"infinity" or "continuous" are accepted to reload indefinitely the
|
||||
component
|
||||
"""
|
||||
from html import TAG, DIV, URL, SCRIPT, XML
|
||||
if args is None:
|
||||
@@ -440,7 +452,8 @@ def read_pyc(filename):
|
||||
Read the code inside a bytecode compiled file if the MAGIC number is
|
||||
compatible
|
||||
|
||||
:returns: a code object
|
||||
Returns:
|
||||
a code object
|
||||
"""
|
||||
data = read_file(filename, 'rb')
|
||||
if not is_gae and data[:4] != imp.get_magic():
|
||||
@@ -518,7 +531,7 @@ def run_models_in(environment):
|
||||
|
||||
folder = environment['request'].folder
|
||||
c = environment['request'].controller
|
||||
f = environment['request'].function
|
||||
f = environment['request'].function
|
||||
response = environment['response']
|
||||
|
||||
path = pjoin(folder, 'models')
|
||||
@@ -528,7 +541,7 @@ def run_models_in(environment):
|
||||
models = sorted(listdir(cpath, '^models[_.][\w.]+\.pyc$', 0), model_cmp)
|
||||
else:
|
||||
models = sorted(listdir(path, '^\w+\.py$', 0, sort=False), model_cmp_sep)
|
||||
models_to_run = None
|
||||
models_to_run = None
|
||||
for model in models:
|
||||
if response.models_to_run != models_to_run:
|
||||
regex = models_to_run = response.models_to_run[:]
|
||||
@@ -540,7 +553,7 @@ def run_models_in(environment):
|
||||
fname = model[n:-4].replace('.','/')+'.py'
|
||||
else:
|
||||
n = len(path)+1
|
||||
fname = model[n:].replace(os.path.sep,'/')
|
||||
fname = model[n:].replace(os.path.sep,'/')
|
||||
if not regex.search(fname) and c != 'appadmin':
|
||||
continue
|
||||
elif compiled:
|
||||
@@ -573,7 +586,7 @@ def run_controller_in(controller, function, environment):
|
||||
filename = pjoin(path, 'controllers_%s_%s.pyc'
|
||||
% (controller, function))
|
||||
### end for backward compatibility
|
||||
if not os.path.exists(filename):
|
||||
if not os.path.exists(filename):
|
||||
raise HTTP(404,
|
||||
rewrite.THREAD_LOCAL.routes.error_message % badf,
|
||||
web2py_error=badf)
|
||||
|
||||
@@ -2,22 +2,22 @@
|
||||
# -*- 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)
|
||||
|
||||
CONTENT_TYPE dictionary created against freedesktop.org' shared mime info
|
||||
CONTENT_TYPE dictionary created against freedesktop.org's shared mime info
|
||||
database version 1.1.
|
||||
|
||||
Deviations from official standards:
|
||||
- '.md': 'application/x-genesis-rom' --> 'text/x-markdown'
|
||||
- '.png': 'image/x-apple-ios-png' --> 'image/png'
|
||||
- .md: application/x-genesis-rom --> text/x-markdown
|
||||
- .png: image/x-apple-ios-png --> image/png
|
||||
Additions:
|
||||
- '.load': 'text/html'
|
||||
- '.json': 'application/json'
|
||||
- '.jsonp': 'application/jsonp'
|
||||
- '.pickle': 'application/python-pickle'
|
||||
- '.w2p': 'application/w2p'
|
||||
- .load: text/html
|
||||
- .json: application/json
|
||||
- .jsonp: application/jsonp
|
||||
- .pickle: application/python-pickle
|
||||
- .w2p': application/w2p
|
||||
"""
|
||||
|
||||
__all__ = ['contenttype']
|
||||
|
||||
Reference in New Issue
Block a user