Commit eefbc5a0 authored by Hanno Schlichting's avatar Hanno Schlichting

Use default `transaction.manager` as the transaction manager.

Add new `ZPublisher.utils.recordMetaData` function to replace the
method previously found on the manager.
parent 4b3b0281
......@@ -31,6 +31,9 @@ Features Added
Restructuring
+++++++++++++
- Add new `ZPublisher.utils.recordMetaData` function and use default
`transaction.manager` as the transaction manager.
- Remove support for repoze.tm2.
- Change Testing to use the WSGI publisher for functional and testbrowser
......
......@@ -17,6 +17,7 @@ import sys
from thread import allocate_lock
import time
import transaction
from zExceptions import (
HTTPOk,
HTTPRedirection,
......@@ -28,9 +29,10 @@ from zope.publisher.skinnable import setDefaultSkin
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.Iterators import IUnboundStreamIterator, IStreamIterator
from ZPublisher.mapply import mapply
from ZPublisher import pubevents
from ZPublisher.Iterators import IUnboundStreamIterator, IStreamIterator
from ZPublisher.utils import recordMetaData
_NOW = None # overwrite for testing
MONTHNAME = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
......@@ -60,8 +62,8 @@ def build_http_date(when):
WEEKDAYNAME[wd], day, MONTHNAME[month], year, hh, mm, ss)
def call_object(object, args, request):
return object(*args)
def call_object(obj, args, request):
return obj(*args)
def dont_publish_class(klass, request):
......@@ -104,7 +106,8 @@ def get_module_info(module_name='Zope2'):
bobo_after = getattr(module, '__bobo_after__', None)
error_hook = getattr(module, 'zpublisher_exception_hook', None)
validated_hook = getattr(module, 'zpublisher_validated_hook', None)
transactions_manager = module.zpublisher_transactions_manager
transactions_manager = getattr(
module, 'zpublisher_transactions_manager', transaction.manager)
info = (bobo_before, bobo_after, app, realm, _DEFAULT_DEBUG_MODE,
error_hook, validated_hook, transactions_manager)
......@@ -237,7 +240,7 @@ def publish(request, module_info):
notify(pubevents.PubAfterTraversal(request))
if transactions_manager:
transactions_manager.recordMetaData(object, request)
recordMetaData(object, request)
ok_exception = None
try:
......
......@@ -12,6 +12,8 @@
##############################################################################
import unittest
import transaction
from ZPublisher.WSGIPublisher import get_module_info
......@@ -162,7 +164,7 @@ class TestPublish(unittest.TestCase):
_debug_mode = True
_err_hook = DummyCallable()
_validated_hook = object()
_tm = DummyTM()
_tm = transaction.manager
module_info = (_before, _after, _object, _realm, _debug_mode,
_err_hook, _validated_hook, _tm)
returned = self._callFUT(request, module_info)
......@@ -174,9 +176,6 @@ class TestPublish(unittest.TestCase):
self.assertEqual(_before._called_with, ((), {}))
self.assertEqual(request['PARENTS'], [_object])
self.assertEqual(request._traversed, ('/', None, _validated_hook))
self.assertEqual(_tm._recorded, (_object, request))
self.assertTrue(_tm._begin)
self.assertTrue(_tm._commit)
self.assertEqual(_object._called_with, ((), {}))
self.assertEqual(response._body, 'RESULT')
self.assertEqual(_err_hook._called_with, None)
......@@ -193,7 +192,7 @@ class TestPublish(unittest.TestCase):
_debug_mode = True
_err_hook = DummyCallable()
_validated_hook = object()
_tm = DummyTM()
_tm = transaction.manager
module_info = (_before, _after, _object, _realm, _debug_mode,
_err_hook, _validated_hook, _tm)
self._callFUT(request, module_info)
......@@ -464,22 +463,5 @@ class DummyCallable(object):
return self._result
class DummyTM(object):
_recorded = _raise = _result = None
_abort = _begin = _commit = False
def abort(self):
self._abort = True
def begin(self):
self._begin = True
def commit(self):
self._commit = True
def recordMetaData(self, *args):
self._recorded = args
def noopStartResponse(status, headers):
pass
......@@ -203,27 +203,8 @@ class _Request(BaseRequest):
pass
class _TransactionsManager(object):
def __init__(self, *args, **kw):
self.tracer = []
def abort(self):
self.tracer.append('abort')
def begin(self):
self.tracer.append('begin')
def commit(self):
self.tracer.append('commit')
def recordMetaData(self, obj, request):
pass
# define things necessary for publication
bobo_application = _Application()
zpublisher_transactions_manager = _TransactionsManager()
def zpublisher_exception_hook(parent, request, *unused):
......
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import logging
from Acquisition import aq_inner, aq_parent
import transaction
AC_LOGGER = logging.getLogger('event.AccessControl')
def recordMetaData(object, request):
if hasattr(object, 'getPhysicalPath'):
path = '/'.join(object.getPhysicalPath())
else:
# Try hard to get the physical path of the object,
# but there are many circumstances where that's not possible.
to_append = ()
if hasattr(object, 'im_self') and hasattr(object, '__name__'):
# object is a Python method.
to_append = (object.__name__,)
object = object.im_self
while (object is not None and
not hasattr(object, 'getPhysicalPath')):
if getattr(object, '__name__', None) is None:
object = None
break
to_append = (object.__name__,) + to_append
object = aq_parent(aq_inner(object))
if object is not None:
path = '/'.join(object.getPhysicalPath() + to_append)
else:
# As Jim would say, "Waaaaaaaa!"
# This may cause problems with virtual hosts
# since the physical path is different from the path
# used to retrieve the object.
path = request.get('PATH_INFO')
T = transaction.get()
T.note(path)
auth_user = request.get('AUTHENTICATED_USER', None)
if auth_user:
auth_folder = aq_parent(auth_user)
if auth_folder is None:
AC_LOGGER.warning(
'A user object of type %s has no aq_parent.',
type(auth_user))
auth_path = request.get('AUTHENTICATION_PATH')
else:
auth_path = '/'.join(auth_folder.getPhysicalPath()[1:-1])
T.setUser(auth_user.getId(), auth_path)
......@@ -18,32 +18,33 @@ import logging
import sys
from time import asctime
from six import reraise
import AccessControl.User
import App.ZApplication
import ExtensionClass
import OFS.Application
import transaction
import ZODB
import Zope2
from ZPublisher import Retry
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from Acquisition import aq_acquire
from Acquisition import aq_base
from Acquisition import aq_inner
from Acquisition import aq_parent
from Acquisition import (
aq_acquire,
aq_base,
aq_parent,
)
from Acquisition.interfaces import IAcquirer
from App.config import getConfiguration
import ExtensionClass
from six import reraise
import transaction
from zExceptions import Redirect
from zExceptions import Unauthorized
import ZODB
from ZODB.POSException import ConflictError
from zope.component import queryMultiAdapter
from zope.event import notify
from zope.processlifetime import DatabaseOpened
from zope.processlifetime import DatabaseOpenedWithRoot
from App.config import getConfiguration
import App.ZApplication
import OFS.Application
import Zope2
from ZPublisher import Retry
app = None
startup_time = asctime()
_patched = False
......@@ -151,7 +152,7 @@ def startup():
notify(DatabaseOpenedWithRoot(DB))
Zope2.zpublisher_transactions_manager = TransactionsManager()
Zope2.zpublisher_transactions_manager = transaction.manager
Zope2.zpublisher_exception_hook = zpublisher_exception_hook
Zope2.zpublisher_validated_hook = validated_hook
Zope2.__bobo_before__ = noSecurityManager
......@@ -302,71 +303,3 @@ class ZPublisherExceptionHook:
traceback = None
zpublisher_exception_hook = ZPublisherExceptionHook()
ac_logger = logging.getLogger('event.AccessControl')
class TransactionsManager(object):
def begin(self,
# Optimize global var lookups:
transaction=transaction):
transaction.begin()
def commit(self):
if hasattr(transaction, 'isDoomed') and transaction.isDoomed():
transaction.abort()
else:
transaction.commit()
def abort(self):
transaction.abort()
def recordMetaData(self, object, request,
# Optimize global var lookups:
hasattr=hasattr, getattr=getattr,
logger=ac_logger,
):
request_get = request.get
if hasattr(object, 'getPhysicalPath'):
path = '/'.join(object.getPhysicalPath())
else:
# Try hard to get the physical path of the object,
# but there are many circumstances where that's not possible.
to_append = ()
if hasattr(object, 'im_self') and hasattr(object, '__name__'):
# object is a Python method.
to_append = (object.__name__,)
object = object.im_self
while (object is not None and
not hasattr(object, 'getPhysicalPath')):
if getattr(object, '__name__', None) is None:
object = None
break
to_append = (object.__name__,) + to_append
object = aq_parent(aq_inner(object))
if object is not None:
path = '/'.join(object.getPhysicalPath() + to_append)
else:
# As Jim would say, "Waaaaaaaa!"
# This may cause problems with virtual hosts
# since the physical path is different from the path
# used to retrieve the object.
path = request_get('PATH_INFO')
T = transaction.get()
T.note(path)
auth_user = request_get('AUTHENTICATED_USER', None)
if auth_user is not None:
auth_folder = aq_parent(auth_user)
if auth_folder is None:
ac_logger.warning(
'A user object of type %s has no aq_parent.',
type(auth_user))
auth_path = request_get('AUTHENTICATION_PATH')
else:
auth_path = '/'.join(auth_folder.getPhysicalPath()[1:-1])
T.setUser(auth_user.getId(), auth_path)
##############################################################################
#
# Copyright (c) 2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
import unittest
import transaction
class DoomedTransactionInManagerTest(unittest.TestCase):
def testDoomedFails(self):
transaction.begin()
trans = transaction.get()
trans.doom()
from transaction.interfaces import DoomedTransaction
self.assertRaises(DoomedTransaction, trans.commit)
def testDoomedSilentInTM(self):
from Zope2.App.startup import TransactionsManager
tm = TransactionsManager()
transaction.begin()
trans = transaction.get()
trans.doom()
tm.commit()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment