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 ...@@ -31,6 +31,9 @@ Features Added
Restructuring Restructuring
+++++++++++++ +++++++++++++
- Add new `ZPublisher.utils.recordMetaData` function and use default
`transaction.manager` as the transaction manager.
- Remove support for repoze.tm2. - Remove support for repoze.tm2.
- Change Testing to use the WSGI publisher for functional and testbrowser - Change Testing to use the WSGI publisher for functional and testbrowser
......
...@@ -17,6 +17,7 @@ import sys ...@@ -17,6 +17,7 @@ import sys
from thread import allocate_lock from thread import allocate_lock
import time import time
import transaction
from zExceptions import ( from zExceptions import (
HTTPOk, HTTPOk,
HTTPRedirection, HTTPRedirection,
...@@ -28,9 +29,10 @@ from zope.publisher.skinnable import setDefaultSkin ...@@ -28,9 +29,10 @@ from zope.publisher.skinnable import setDefaultSkin
from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.Iterators import IUnboundStreamIterator, IStreamIterator
from ZPublisher.mapply import mapply from ZPublisher.mapply import mapply
from ZPublisher import pubevents from ZPublisher import pubevents
from ZPublisher.Iterators import IUnboundStreamIterator, IStreamIterator from ZPublisher.utils import recordMetaData
_NOW = None # overwrite for testing _NOW = None # overwrite for testing
MONTHNAME = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', MONTHNAME = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
...@@ -60,8 +62,8 @@ def build_http_date(when): ...@@ -60,8 +62,8 @@ def build_http_date(when):
WEEKDAYNAME[wd], day, MONTHNAME[month], year, hh, mm, ss) WEEKDAYNAME[wd], day, MONTHNAME[month], year, hh, mm, ss)
def call_object(object, args, request): def call_object(obj, args, request):
return object(*args) return obj(*args)
def dont_publish_class(klass, request): def dont_publish_class(klass, request):
...@@ -104,7 +106,8 @@ def get_module_info(module_name='Zope2'): ...@@ -104,7 +106,8 @@ def get_module_info(module_name='Zope2'):
bobo_after = getattr(module, '__bobo_after__', None) bobo_after = getattr(module, '__bobo_after__', None)
error_hook = getattr(module, 'zpublisher_exception_hook', None) error_hook = getattr(module, 'zpublisher_exception_hook', None)
validated_hook = getattr(module, 'zpublisher_validated_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, info = (bobo_before, bobo_after, app, realm, _DEFAULT_DEBUG_MODE,
error_hook, validated_hook, transactions_manager) error_hook, validated_hook, transactions_manager)
...@@ -237,7 +240,7 @@ def publish(request, module_info): ...@@ -237,7 +240,7 @@ def publish(request, module_info):
notify(pubevents.PubAfterTraversal(request)) notify(pubevents.PubAfterTraversal(request))
if transactions_manager: if transactions_manager:
transactions_manager.recordMetaData(object, request) recordMetaData(object, request)
ok_exception = None ok_exception = None
try: try:
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
############################################################################## ##############################################################################
import unittest import unittest
import transaction
from ZPublisher.WSGIPublisher import get_module_info from ZPublisher.WSGIPublisher import get_module_info
...@@ -162,7 +164,7 @@ class TestPublish(unittest.TestCase): ...@@ -162,7 +164,7 @@ class TestPublish(unittest.TestCase):
_debug_mode = True _debug_mode = True
_err_hook = DummyCallable() _err_hook = DummyCallable()
_validated_hook = object() _validated_hook = object()
_tm = DummyTM() _tm = transaction.manager
module_info = (_before, _after, _object, _realm, _debug_mode, module_info = (_before, _after, _object, _realm, _debug_mode,
_err_hook, _validated_hook, _tm) _err_hook, _validated_hook, _tm)
returned = self._callFUT(request, module_info) returned = self._callFUT(request, module_info)
...@@ -174,9 +176,6 @@ class TestPublish(unittest.TestCase): ...@@ -174,9 +176,6 @@ class TestPublish(unittest.TestCase):
self.assertEqual(_before._called_with, ((), {})) self.assertEqual(_before._called_with, ((), {}))
self.assertEqual(request['PARENTS'], [_object]) self.assertEqual(request['PARENTS'], [_object])
self.assertEqual(request._traversed, ('/', None, _validated_hook)) 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(_object._called_with, ((), {}))
self.assertEqual(response._body, 'RESULT') self.assertEqual(response._body, 'RESULT')
self.assertEqual(_err_hook._called_with, None) self.assertEqual(_err_hook._called_with, None)
...@@ -193,7 +192,7 @@ class TestPublish(unittest.TestCase): ...@@ -193,7 +192,7 @@ class TestPublish(unittest.TestCase):
_debug_mode = True _debug_mode = True
_err_hook = DummyCallable() _err_hook = DummyCallable()
_validated_hook = object() _validated_hook = object()
_tm = DummyTM() _tm = transaction.manager
module_info = (_before, _after, _object, _realm, _debug_mode, module_info = (_before, _after, _object, _realm, _debug_mode,
_err_hook, _validated_hook, _tm) _err_hook, _validated_hook, _tm)
self._callFUT(request, module_info) self._callFUT(request, module_info)
...@@ -464,22 +463,5 @@ class DummyCallable(object): ...@@ -464,22 +463,5 @@ class DummyCallable(object):
return self._result 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): def noopStartResponse(status, headers):
pass pass
...@@ -203,27 +203,8 @@ class _Request(BaseRequest): ...@@ -203,27 +203,8 @@ class _Request(BaseRequest):
pass 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 # define things necessary for publication
bobo_application = _Application() bobo_application = _Application()
zpublisher_transactions_manager = _TransactionsManager()
def zpublisher_exception_hook(parent, request, *unused): 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 ...@@ -18,32 +18,33 @@ import logging
import sys import sys
from time import asctime from time import asctime
from six import reraise
import AccessControl.User 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 newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import noSecurityManager
from Acquisition import aq_acquire from Acquisition import (
from Acquisition import aq_base aq_acquire,
from Acquisition import aq_inner aq_base,
from Acquisition import aq_parent aq_parent,
)
from Acquisition.interfaces import IAcquirer 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 Redirect
from zExceptions import Unauthorized from zExceptions import Unauthorized
import ZODB
from ZODB.POSException import ConflictError from ZODB.POSException import ConflictError
from zope.component import queryMultiAdapter from zope.component import queryMultiAdapter
from zope.event import notify from zope.event import notify
from zope.processlifetime import DatabaseOpened from zope.processlifetime import DatabaseOpened
from zope.processlifetime import DatabaseOpenedWithRoot from zope.processlifetime import DatabaseOpenedWithRoot
from App.config import getConfiguration
import App.ZApplication
import OFS.Application
import Zope2
from ZPublisher import Retry
app = None app = None
startup_time = asctime() startup_time = asctime()
_patched = False _patched = False
...@@ -151,7 +152,7 @@ def startup(): ...@@ -151,7 +152,7 @@ def startup():
notify(DatabaseOpenedWithRoot(DB)) notify(DatabaseOpenedWithRoot(DB))
Zope2.zpublisher_transactions_manager = TransactionsManager() Zope2.zpublisher_transactions_manager = transaction.manager
Zope2.zpublisher_exception_hook = zpublisher_exception_hook Zope2.zpublisher_exception_hook = zpublisher_exception_hook
Zope2.zpublisher_validated_hook = validated_hook Zope2.zpublisher_validated_hook = validated_hook
Zope2.__bobo_before__ = noSecurityManager Zope2.__bobo_before__ = noSecurityManager
...@@ -302,71 +303,3 @@ class ZPublisherExceptionHook: ...@@ -302,71 +303,3 @@ class ZPublisherExceptionHook:
traceback = None traceback = None
zpublisher_exception_hook = ZPublisherExceptionHook() 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