You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_python-commits@quetz.apache.org by nl...@apache.org on 2005/05/20 18:28:32 UTC
svn commit: r171133 - in /httpd/mod_python/trunk/lib/python/mod_python:
cache.py publisher.py
Author: nlehuen
Date: Fri May 20 09:28:31 2005
New Revision: 171133
URL: http://svn.apache.org/viewcvs?rev=171133&view=rev
Log:
Dropped the import_page function as I don't want to get into the business of recursively managing module dependencies yet. Everything can be done with get_page in a much safer (yet less elegant) way.
Modified:
httpd/mod_python/trunk/lib/python/mod_python/cache.py
httpd/mod_python/trunk/lib/python/mod_python/publisher.py
Modified: httpd/mod_python/trunk/lib/python/mod_python/cache.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/lib/python/mod_python/cache.py?rev=171133&r1=171132&r2=171133&view=diff
==============================================================================
--- httpd/mod_python/trunk/lib/python/mod_python/cache.py (original)
+++ httpd/mod_python/trunk/lib/python/mod_python/cache.py Fri May 20 09:28:31 2005
@@ -61,37 +61,33 @@
def __setitem__(self, name, value):
""" Populates the cache with a given name and value. """
- self._lock.acquire()
+ key = self.key(name)
+
+ entry = self._get_entry(key)
+
+ entry._lock.acquire()
try:
- key = self.key(name)
- entry = self._dict.get(key)
- if not entry:
- entry = Entry(key)
- self._pack(entry, value)
- self._dict[key]=entry
- if self._maxsize:
- entry._next = entry._previous = None
- self._access(entry)
- self._checklru()
- else:
- self._pack(entry, value)
- if self._maxsize:
- self._access(entry)
+ self._pack(entry,value)
self.commit()
finally:
- self._lock.release()
+ entry._lock.release()
def __getitem__(self, name):
- return self.checkitem(name)[1]
-
- def checkitem(self, name):
""" Gets a value from the cache, builds it if required.
- Returns a tuple is_new, value. If is_new is True, the dependency had
- to be rebuilt.
"""
+ return self._checkitem(name)[2]
+
+ def __delitem__(self, name):
self._lock.acquire()
try:
key = self.key(name)
+ del self._dict[key]
+ finally:
+ self._lock.release()
+
+ def _get_entry(self,key):
+ self._lock.acquire()
+ try:
entry = self._dict.get(key)
if not entry:
entry = Entry(key)
@@ -102,9 +98,19 @@
self._checklru()
elif self._maxsize:
self._access(entry)
+ return entry
finally:
self._lock.release()
+ def _checkitem(self, name):
+ """ Gets a value from the cache, builds it if required.
+ Returns a tuple is_new, key, value, entry.
+ If is_new is True, the result had to be rebuilt.
+ """
+ key = self.key(name)
+
+ entry = self._get_entry(key)
+
entry._lock.acquire()
try:
value = self._unpack(entry)
@@ -122,18 +128,10 @@
is_new = True
self._pack(entry, value)
self.commit()
- return is_new, value
+ return is_new, key, value, entry
finally:
entry._lock.release()
- def __delitem__(self, key):
- self._lock.acquire()
- try:
- key = self.key(key)
- del self._dict[key]
- finally:
- self._lock.release()
-
def mru(self):
""" Returns the Most Recently Used key """
if self._maxsize:
@@ -249,21 +247,20 @@
self.mode=mode
def check(self, key, name, entry):
- """ Checks the modification time to determine whether a file has changed or not. """
- f = file(key, self.mode)
- fs = fstat(f.fileno())
- ts1 = fs[-2]
- try:
- ts2 = entry._timestamp
- except AttributeError:
- ts2 = ts1-1
-
- if ts2!=ts1:
- entry._timestamp=ts1
- return f
+ opened = file(key, self.mode)
+
+ timestamp = fstat(opened.fileno())[-2]
+
+ if entry._value is NOT_INITIALIZED:
+ entry._timestamp = timestamp
+ return opened
else:
- f.close()
- return None
+ if entry._timestamp != timestamp:
+ entry._timestamp = timestamp
+ return opened
+ else:
+ opened.close()
+ return None
def build(self, key, name, opened, entry):
""" Return the content of the file as a string. Override this for better behaviour. """
@@ -357,8 +354,9 @@
opened.close()
class ModuleCache(FileCache):
- """ A module cache. Give it a file name, it returns a module-like object
+ """ A module cache. Give it a file name, it returns a module
which results from the execution of the Python script it contains.
+ This module is not inserted into sys.modules.
"""
def __init__(self, max_size=0):
FileCache.__init__(self, max_size, 'r')
@@ -373,8 +371,9 @@
opened.close()
class HttpModuleCache(HTTPCache):
- """ A module cache. Give it a file name, it returns a module-like object
+ """ A module cache. Give it a file name, it returns a module
which results from the execution of the Python script it contains.
+ This module is not inserted into sys.modules.
"""
def __init__(self, max_size=0):
HTTPCache.__init__(self, max_size)
Modified: httpd/mod_python/trunk/lib/python/mod_python/publisher.py
URL: http://svn.apache.org/viewcvs/httpd/mod_python/trunk/lib/python/mod_python/publisher.py?rev=171133&r1=171132&r2=171133&view=diff
==============================================================================
--- httpd/mod_python/trunk/lib/python/mod_python/publisher.py (original)
+++ httpd/mod_python/trunk/lib/python/mod_python/publisher.py Fri May 20 09:28:31 2005
@@ -18,7 +18,7 @@
# $Id$
"""
- This handler is conceputally similar to Zope's ZPublisher, except
+ This handler is conceptually similar to Zope's ZPublisher, except
that it:
1. Is written specifically for mod_python and is therefore much faster
@@ -33,7 +33,7 @@
import sys
import os
-from os.path import normpath, split, isfile, join, dirname
+from os.path import isabs, normpath, split, isfile, join, dirname
import imp
import re
import base64
@@ -78,66 +78,14 @@
page_cache = PageCache()
-class DummyModule(object):
- """
- This class is used to simulate a request object to be able to import
- an arbitrary module from the page cache.
- """
- def __init__(self, filename):
- self.filename = filename
-
- def get_config(self):
- return {}
-
- def log_error(self, message, level):
- apache.log_error(message, level)
-
- def __str__(self):
- return "<mod_python.publisher.DummyModule at 0x%08x for %s>"%(id(self), self.filename)
-
- def __getattr__(self, name):
- return getattr(page_cache[self], name)
-
####################### Interface to the published page cache ##################
-def import_page(relative_path, auto_reload=True):
- """
- This imports a published page. The relative_path argument is a path
- relative to the directory of the page where import_page() is called.
- Hence, if we have index.py and foobar.py in the same directory, index.py
- can simply do something like :
-
- import mod_python.publisher
- foobar = mod_python.publisher.import_page('foobar.py')
-
- If auto_reload is True (the default), the returned object is not really
- the module itself, but a placeholder object which allows the real module
- to be automatically reloaded whenever its source file changes.
- """
-
- # this is quite a hack but this is handy.
- try:
- raise ZeroDivisionError
- except ZeroDivisionError:
- calling_frame = sys.exc_info()[2].tb_frame.f_back
-
- calling_page = calling_frame.f_code.co_filename
-
- # we look for the given page in the same directory as the calling page
- page = normpath(join(dirname(calling_page), relative_path))
-
- if auto_reload:
- return DummyModule(page)
- else:
- # the DummyModule instance can masquerade itself as a request object
- # so the PageCache will be happy.
- return page_cache[DummyModule(page)]
-
-def get_page(req, relative_path):
+def get_page(req, path):
"""
- This imports a published page. The relative_path argument is a path
- relative to the published page where the request is really handled (not
- relative to the path given in the URL).
+ This imports a published page. If the path is absolute it is used as is.
+ If it is a relative path it is relative to the published page
+ where the request is really handled (not relative to the path
+ given in the URL).
Warning : in order to maintain consistency in case of module reloading,
do not store the resulting module in a place that outlives the request
@@ -145,9 +93,15 @@
"""
real_filename = req.filename
- req.filename = normpath(join(dirname(req.filename), relative_path))
+
try:
+ if isabs(path):
+ req.filename = path
+ else:
+ req.filename = normpath(join(dirname(req.filename), path))
+
return page_cache[req]
+
finally:
req.filename = real_filename
@@ -408,7 +362,7 @@
})
# types which are not referenced in the tp_rules dictionary will be traversable
-# AND publishables
+# AND publishable
default_tp_rule = (True, True)
def resolve_object(req, obj, object_str, realm=None, user=None, passwd=None):