rpms/TurboGears/devel TurboGears-1.0.4.3-sqlalchemy-backport.patch, NONE, 1.1 TurboGears.spec, 1.31, 1.32
Toshio くらとみ (toshio)
fedora-extras-commits at redhat.com
Fri Feb 22 18:38:48 UTC 2008
- Previous message (by thread): rpms/xorg-x11-drv-mga/devel .cvsignore, 1.10, 1.11 sources, 1.10, 1.11 xorg-x11-drv-mga.spec, 1.26, 1.27
- Next message (by thread): rpms/ocaml-fileutils/F-8 ocaml-fileutils.spec, NONE, 1.1 .cvsignore, 1.1, 1.2 sources, 1.1, 1.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: toshio
Update of /cvs/pkgs/rpms/TurboGears/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv24476
Modified Files:
TurboGears.spec
Added Files:
TurboGears-1.0.4.3-sqlalchemy-backport.patch
Log Message:
* Thu Feb 21 2008 Toshio Kuratomi <tkuratom at redhat.com> 1.0.4.3-2
- Fixes for SQLAlchemy-0.4 and exceptions. Upstream Bug #1721.
TurboGears-1.0.4.3-sqlalchemy-backport.patch:
--- NEW FILE TurboGears-1.0.4.3-sqlalchemy-backport.patch ---
--- TurboGears-1.0.4.3/turbogears/database.py 2007-12-02 09:00:50.000000000 -0800
+++ 1.0/turbogears/database.py 2008-02-21 22:29:57.000000000 -0800
@@ -1,5 +1,4 @@
-"""Provides convenient access to an SQLObject or SQLAlchemy
-managed database."""
+"""Convenient access to an SQLObject or SQLAlchemy managed database."""
import sys
import time
@@ -149,7 +148,7 @@
ConnectionHub.__init__(self)
def _is_interesting_version(self):
- "Return True only if version of MySQLdb <= 1.0."
+ """Return True only if version of MySQLdb <= 1.0."""
import MySQLdb
module_version = MySQLdb.version_info[0:2]
major = module_version[0]
@@ -200,7 +199,7 @@
self.threadingLocal = threading_local()
def begin(self, conn=None):
- "Starts a transaction."
+ """Start a transaction."""
if not self.supports_transactions:
return conn
if not conn:
@@ -215,7 +214,7 @@
return trans
def commit(self):
- "Commits the current transaction."
+ """Commit the current transaction."""
if not self.supports_transactions:
return
try:
@@ -226,7 +225,7 @@
self.threadingLocal.connection.commit()
def rollback(self):
- "Rolls back the current transaction."
+ """Rollback the current transaction."""
if not self.supports_transactions:
return
try:
@@ -237,7 +236,7 @@
self.threadingLocal.connection.rollback()
def end(self):
- "Ends the transaction, returning to a standard connection."
+ """End the transaction, returning to a standard connection."""
if not self.supports_transactions:
return
try:
@@ -322,17 +321,17 @@
})
def commit_all():
- "Commits the Transactions in all registered hubs (for this thread)"
+ """Commits the transactions in all registered hubs (for this thread)."""
for hub in hub_registry:
hub.commit()
def rollback_all():
- "Rolls back the Transactions in all registered hubs (for this thread)"
+ """Rollback the transactions in all registered hubs (for this thread)."""
for hub in hub_registry:
hub.rollback()
def end_all():
- "Ends the Transactions in all registered hubs (for this thread)"
+ """End the transactions in all registered hubs (for this thread)."""
for hub in hub_registry:
hub.end()
@@ -348,7 +347,8 @@
# check to see if sqlalchemy has been imported and configured
return _engine is not None
-[run_with_transaction.when("not _use_sa(args)")] # include "args" to avoid call being pre-cached
+# include "args" to avoid call being pre-cached
+[run_with_transaction.when("not _use_sa(args)")]
def so_rwt(func, *args, **kw):
log.debug("Starting SQLObject transaction")
try:
@@ -363,14 +363,15 @@
commit_all()
raise
except:
- # No need to "rollback" the sqlalchemy unit of work, because nothing
- # has hit the db yet.
+ # No need to "rollback" the sqlalchemy unit of work,
+ # because nothing has hit the db yet.
rollback_all()
raise
finally:
end_all()
-[restart_transaction.when("not _use_sa(args)")] # include "args" to avoid call being pre-cached
+# include "args" to avoid call being pre-cached
+[restart_transaction.when("not _use_sa(args)")]
def so_restart_transaction(args):
#log.debug("ReStarting SQLObject transaction")
# Disable for now for compatibility
@@ -387,10 +388,8 @@
try:
output = dispatch_error(
controller, real_func, None, exception, *args, **kw)
-
except dispatch.NoApplicableMethods:
raise exc_type, exc_value, exc_trace
-
else:
del exc_trace
return output
@@ -398,65 +397,80 @@
# include "args" to avoid call being pre-cached
[run_with_transaction.when("_use_sa(args)")]
def sa_rwt(func, *args, **kw):
- log.debug("New SA transaction")
- req = cherrypy.request
- req.sa_transaction = make_sa_transaction(session)
-
+ log.debug("Starting SA transaction")
+ request = cherrypy.request
+ request.sa_transaction = make_sa_transaction(session)
try:
- retval = func(*args, **kw)
-
- except (cherrypy.HTTPRedirect, cherrypy.InternalRedirect):
- log.debug('this is only a redirect')
- # If a redirect happens; commit and proceed with redirect
- if sa_tr_active(req.sa_transaction):
- req.sa_transaction.commit()
- raise
-
- except:
- log.debug('this is an exception, ROLLBACK now!')
- # If any other exception happens; rollback and re-raise error
- if sa_tr_active(req.sa_transaction):
- req.sa_transaction.rollback()
- raise
-
- # If the call was successful; commit and proceed
- if sa_tr_active(req.sa_transaction):
- log.debug('The transaction was successful, COMMIT now!')
- req.sa_transaction.commit()
-
+ try:
+ retval = func(*args, **kw)
+ except (cherrypy.HTTPRedirect, cherrypy.InternalRedirect):
+ # If a redirect happens, commit and proceed with redirect
+ if sa_transaction_active(request.sa_transaction):
+ log.debug('Redirect in active transaction - will commit now')
+ if hasattr(session, 'commit'):
+ session.commit()
+ else: # SA < 0.4
+ request.sa_transaction.commit()
+ else:
+ log.debug('Redirect in inactive transaction')
+ raise
+ except:
+ # If any other exception happens, rollback and re-raise error
+ if sa_transaction_active(request.sa_transaction):
+ log.debug('Error in active transaction - will rollback now')
+ if hasattr(session, 'rollback'):
+ session.rollback()
+ else: # SA < 0.4
+ request.sa_transaction.rollback()
+ else:
+ log.debug('Error in inactive transaction')
+ raise
+ # If the call was successful, commit and proceed
+ if sa_transaction_active(request.sa_transaction):
+ log.debug('Transaction is still active - will commit now')
+ if hasattr(session, 'commit'):
+ session.commit()
+ else: # SA < 0.4
+ request.sa_transaction.commit()
+ else:
+ log.debug('Transaction is already inactive')
+ finally:
+ log.debug('Ending SA transaction')
+ session.close()
return retval
# include "args" to avoid call being pre-cached
[restart_transaction.when("_use_sa(args)")]
def sa_restart_transaction(args):
log.debug("Restarting SA transaction")
- req = cherrypy.request
- if sa_tr_active(req.sa_transaction):
- req.sa_transaction.rollback()
- session.clear()
- req.sa_transaction = make_sa_transaction(session)
-
-def sa_tr_active(tr):
- if hasattr(session, 'context'):
- # SA 0.3
- return tr.session.transaction
+ request = cherrypy.request
+ if sa_transaction_active(request.sa_transaction):
+ log.debug('Transaction is still active - will rollback now')
+ if hasattr(session, 'rollback'):
+ session.rollback()
+ else: # SA < 0.4
+ request.sa_transaction.rollback()
else:
- # SA 0.4 (effectively always active - commit or rollback don't fail)
- return True
+ log.debug('Transaction is already inactive')
+ session.close()
+ request.sa_transaction = make_sa_transaction(session)
def make_sa_transaction(session):
- if hasattr(session, 'context'):
- # SA 0.3
- tr = session.create_transaction()
- return tr
+ """Create a new transaction in an SA session."""
+ try:
+ return session.begin()
+ except AttributeError: # SA < 0.4
+ return session.create_transaction()
- else:
- # SA 0.4
- session.begin()
- return session
+def sa_transaction_active(transaction):
+ """Check whether SA transaction is still active."""
+ try:
+ return transaction and transaction.is_active
+ except AttributeError: # SA < 0.4.3
+ return transaction.session.transaction
def so_to_dict(sqlobj):
- "Converts SQLObject to a dictionary based on columns"
+ """Convert SQLObject to a dictionary based on columns."""
d = {}
if sqlobj == None:
# stops recursion
@@ -471,8 +485,11 @@
return d
def so_columns(sqlclass, columns=None):
- """Returns a dict with all columns from a SQLObject including those from
- InheritableSO's bases"""
+ """Return a dict with all columns from a SQLObject.
+
+ This includes the columns from InheritableSO's bases.
+
+ """
if columns is None:
columns = {}
columns.update(filter(lambda i: i[0] != 'childName',
@@ -482,8 +499,11 @@
return columns
def so_joins(sqlclass, joins=None):
- """Returns a list with all joins from a SQLObject including those from
- InheritableSO's bases"""
+ """Return a list with all joins from a SQLObject.
+
+ The list includes the columns from InheritableSO's bases.
+
+ """
if joins is None:
joins = []
joins.extend(sqlclass.sqlmeta.joins)
--- TurboGears-1.0.4.3/turbogears/tests/test_sqlalchemy.py 2007-12-02 09:00:49.000000000 -0800
+++ 1.0/turbogears/tests/test_sqlalchemy.py 2008-02-21 22:29:53.000000000 -0800
@@ -1,54 +1,83 @@
-"Tests for SQLAlchemy support"
+"""Tests for SQLAlchemy support"""
import cherrypy, os, threading, turbogears
-from sqlalchemy import *
+from sqlalchemy import MetaData, Table, Column, ForeignKey, Integer, String
from sqlalchemy.ext.activemapper import ActiveMapper, column, one_to_many
-from turbogears import config, redirect, expose, database, errorhandling
-from turbogears.testutil import create_request, capture_log, print_log, \
- sqlalchemy_cleanup
+from turbogears import config, redirect, expose, errorhandling
from turbogears.database import get_engine, metadata, session, mapper
from turbogears.controllers import RootController
+from turbogears.testutil import create_request, sqlalchemy_cleanup, \
+ capture_log, print_log
-config.update({"sqlalchemy.dburi" : "sqlite:///:memory:"})
-get_engine()
-
-metadata.bind.echo = True
-
-users_table = Table("users", metadata,
- Column("user_id", Integer, primary_key=True),
- Column("user_name", String(40)),
- Column("password", String(10))
- )
+# Fixture
class User(object):
def __repr__(self):
return "(User %s, password %s)" % (self.user_name, self.password)
-usermapper = mapper(User, users_table)
-
-class Person(ActiveMapper):
- class mapping:
- id = column(Integer, primary_key=True)
- name = column(String(40))
- addresses = one_to_many("Address")
-
-class Address(ActiveMapper):
- class mapping:
- id = column(Integer, primary_key=True)
- address = column(String(40))
- city = column(String(40))
- person_id = column(Integer, foreign_key=ForeignKey("person.id"))
def setup_module():
+ global fresh_metadata, users_table, test_table, Person, Address
+
+ config.update({
+ "sqlalchemy.dburi" : "sqlite:///:memory:"})
+
+ if os.path.exists('freshtest.db'):
+ os.unlink('freshtest.db')
+
+ get_engine()
+ fresh_metadata = MetaData()
+ # :memory: can't be used in multiple threads
+ fresh_metadata.bind = 'sqlite:///freshtest.db'
+ metadata.bind.echo = True
+ fresh_metadata.bind.echo = True
+
+ users_table = Table("users", metadata,
+ Column("user_id", Integer, primary_key=True),
+ Column("user_name", String(40)),
+ Column("password", String(10)))
+
+ mapper(User, users_table)
+
+ class Person(ActiveMapper):
+ class mapping:
+ id = column(Integer, primary_key=True)
+ name = column(String(40))
+ addresses = one_to_many("Address")
+
+ class Address(ActiveMapper):
+ class mapping:
+ id = column(Integer, primary_key=True)
+ address = column(String(40))
+ city = column(String(40))
+ person_id = column(Integer, foreign_key=ForeignKey("person.id"))
+
+ test_table = Table("test", fresh_metadata,
+ Column("id", Integer, primary_key=True),
+ Column("val", String(40)))
+
+ class Test(object):
+ pass
+
+ mapper(Test, test_table)
+
metadata.create_all()
+ fresh_metadata.create_all()
def teardown_module():
metadata.drop_all()
+ fresh_metadata.drop_all()
+ fresh_metadata.bind.dispose()
+ if os.path.exists('freshtest.db'):
+ os.unlink('freshtest.db')
sqlalchemy_cleanup()
+
+# Simple database tests
+
def test_query_in_session():
i = users_table.insert()
i.execute(user_name="globbo", password="thegreat!")
@@ -76,29 +105,45 @@
assert ford is not p
assert len(ford.addresses) == 1
+
+# Exception handling
+
class MyRoot(RootController):
+ """A small root controller for our exception handling tests"""
+
def no_error(self, name):
- p = Person(name=name)
+ """Test controller"""
+ Person(name=name)
raise redirect("/confirm")
no_error = expose()(no_error)
def e_handler(self, tg_exceptions=None):
+ """Test error handler"""
cherrypy.response.code = 501
- return "An exception ocurred: %r (%s)" % ((tg_exceptions,)*2)
+ return "An exception occurred: %r (%s)" % ((tg_exceptions,)*2)
- def create_person(self, id, docom=0, doerr=0):
- p = Person(id=id)
+ def create_person(self, id, docom=0, doerr=0, doflush=0):
+ """Test controller"""
+ Person(id=id)
if int(docom):
cherrypy.request.sa_transaction.commit()
if int(doerr) == 1:
raise Exception('User generated exception')
if int(doerr) == 2:
raise turbogears.redirect('/')
- return "No exceptions ocurred"
+ if int(doflush):
+ try:
+ session.flush()
+ except Exception:
+ if int(doflush) == 1:
+ raise
+ return "No exceptions occurred"
create_person = expose()(create_person)
create_person = errorhandling.exception_handler(e_handler)(create_person)
+
def test_implicit_trans_no_error():
+ """If a controller runs sucessfully, the transaction is commited."""
capture_log("turbogears.database")
cherrypy.root = MyRoot()
create_request("/no_error?name=A.%20Dent")
@@ -108,49 +153,62 @@
arthur = q.filter_by(name="A. Dent").one()
def test_raise_sa_exception():
+ """If a controller causes an SA exception, it is raised properly."""
capture_log("turbogears.database")
cherrypy.root = MyRoot()
create_request("/create_person?id=20")
output = cherrypy.response.body[0]
- print output
- assert "No exceptions" in output
-
+ assert 'No exceptions occurred' in output
create_request("/create_person?id=20")
output = cherrypy.response.body[0]
- print output
-
- # Note that the specific DB2API may be either OperationalError or
- # IntegrityError depending on what version of sqlite and pysqlite
- # is used.
- # SA 0.3 uses SQLError; 0.4 DBAPIError
- assert "SQLError" in output or "DBAPIError" in output
+ # SA 0.3 uses SQLError, 0.4 DBAPIError
+ assert 'SQLError' in output or 'DBAPIError' in output
-# Check that if a controller raises an exception, transactions are rolled back
def test_user_exception():
+ """If a controller raises an exception, transactions are rolled back."""
cherrypy.root = MyRoot()
create_request("/create_person?id=21&doerr=1")
session.clear() # should be done automatically, but just in case
assert Person.query().get(21) is None
-# Check that if a controller redirects, transactions are committed
def test_user_redirect():
+ """If a controller redirects, transactions are committed."""
cherrypy.root = MyRoot()
create_request("/create_person?id=22&doerr=2")
session.clear() # should be done automatically, but just in case
assert Person.query().get(22) is not None
-# Check it's safe to commit a transaction in the controller
def test_cntrl_commit():
+ """It's safe to commit a transaction in the controller."""
cherrypy.root = MyRoot()
create_request("/create_person?id=23&docom=1")
- assert 'InvalidRequestError: This transaction is inactive' not in cherrypy.response.body[0]
+ assert 'InvalidRequestError' not in cherrypy.response.body[0]
+
+def test_cntrl_flush():
+ """It's safe to flush in the controller."""
+ cherrypy.root = MyRoot()
+ create_request("/create_person?id=24&doflush=1")
+ assert 'No exceptions occurred' in cherrypy.response.body[0]
+ create_request("/create_person?id=24&doflush=0")
+ assert 'IntegrityError' in cherrypy.response.body[0]
+ create_request("/create_person?id=24&doflush=1")
+ assert 'IntegrityError' in cherrypy.response.body[0]
+ create_request("/create_person?id=24&doflush=2")
+ assert 'No exceptions occurred' in cherrypy.response.body[0]
+
+
+# Exception handling with rollback
-# Check an exception within a tg.exception_handler causes a rollback
class RbRoot(RootController):
+ """A small root controller for our transaction rollback tests"""
+
def handerr(self, id):
+ """Test error handler"""
Person(id=int(id)+1)
return dict()
+
def doerr(self, id, dorb=0):
+ """Test controller"""
Person(id=id)
if int(dorb):
cherrypy.request.sa_transaction.rollback()
@@ -158,70 +216,59 @@
doerr = errorhandling.exception_handler(handerr)(doerr)
doerr = expose()(doerr)
+
def test_exc_rollback():
+ """"An exception within a controller method causes a rollback."""
cherrypy.root = RbRoot()
- create_request('/doerr?id=24')
- print cherrypy.response.body[0]
- assert Person.query().get(24) is None
- assert Person.query().get(25) is not None
+ create_request('/doerr?id=25')
+ assert Person.query().get(25) is None
+ assert Person.query().get(26) is not None
-# Check that if controller method manually rollbacks, error handler doesn't cause problems
def test_exc_done_rollback():
+ """No problems with error handler if controller manually rollbacks."""
cherrypy.root = RbRoot()
- create_request('/doerr?id=26&dorb=1')
- print cherrypy.response.body[0]
+ create_request('/doerr?id=27&dorb=1')
assert cherrypy.response.body[0] == '{"tg_flash": null}'
-#--
-# Check for session freshness, ticket #1419
-# It checks that changes made to the data in thread B are reflected in thread A.
-#--
-fresh_md = MetaData()
-test_table = Table("test", fresh_md,
- Column("id", Integer, primary_key=True),
- Column("val", String(40))
- )
-class Test(object):
- pass
-mapper(Test, test_table)
+
+# Session freshness tests
class FreshRoot(RootController):
+ """A small root controller for our session freshness tests"""
+
def test1(self):
assert session.query(Test).get(1).val == 'a'
return dict()
test1 = expose()(test1)
+
def test2(self):
session.query(Test).get(1).val = 'b'
return dict()
test2 = expose()(test2)
+
def test3(self):
assert session.query(Test).get(1).val == 'b'
return dict()
test3 = expose()(test3)
+
def test_session_freshness():
- if os.path.exists('freshtest.db'):
- os.unlink('freshtest.db')
- fresh_md.bind = 'sqlite:///freshtest.db' # :memory: can't be used in multiple threads
- test_table.create()
- fresh_md.bind.execute(test_table.insert(), dict(id=1, val='a'))
+ """Check for session freshness.
- cherrypy.root = FreshRoot()
+ Changes made to the data in thread B should be reflected in thread A.
+ """
+ fresh_metadata.bind.execute(test_table.insert(), dict(id=1, val='a'))
+ cherrypy.root = FreshRoot()
create_request("/test1")
- print cherrypy.response.body[0]
assert 'AssertionError' not in cherrypy.response.body[0]
-
# Call test2 in a different thread
class ThreadB(threading.Thread):
def run(self):
create_request("/test2")
- print cherrypy.response.body[0]
assert 'AssertionError' not in cherrypy.response.body[0]
thrdb = ThreadB()
thrdb.start()
thrdb.join()
-
create_request("/test3")
- print cherrypy.response.body[0]
assert 'AssertionError' not in cherrypy.response.body[0]
--- TurboGears-1.0.4.3/turbogears/testutil.py 2008-01-21 13:34:11.000000000 -0800
+++ 1.0/turbogears/testutil.py 2008-02-21 22:29:57.000000000 -0800
@@ -1,31 +1,28 @@
+import os
import types
-import inspect
import logging
import unittest
-import cStringIO as StringIO
import Cookie
+import cStringIO as StringIO
import cherrypy
+from cherrypy import _cphttptools
+
try:
import sqlobject
from sqlobject.inheritance import InheritableSQLObject
except ImportError:
sqlobject = None
-
try:
import sqlalchemy
except ImportError:
sqlalchemy = None
-from cherrypy import _cphttptools
-
-from turbogears import database, controllers, startup, validators, config, \
- update_config
+from turbogears import startup, config, update_config, \
+ controllers, database, validators
+from turbogears.identity import current_provider
from turbogears.util import get_model
-import os
-from os.path import *
-
cwd = os.getcwd()
# For clean tests, remove all compiled Kid templates
@@ -33,49 +30,52 @@
if w[0] != '.svn':
for f in w[2]:
if f.endswith('.kid'):
- f = join(w[0], f[:-3] + 'pyc')
- if exists(f):
+ f = os.path.join(w[0], f[:-3] + 'pyc')
+ if os.path.exists(f):
os.remove(f)
# Override config of all applications with test.cfg
-if exists(join(cwd, "test.cfg")):
+if os.path.exists(os.path.join(cwd, "test.cfg")):
modulename = None
for w in os.walk(cwd):
if w[0].endswith("config"):
config_dir = w[0].replace(cwd, "")[1:]
modulename = "%s.app" % config_dir.replace(os.sep, ".")
break
- update_config(configfile=join(cwd, "test.cfg"), modulename=modulename)
+ update_config(configfile=os.path.join(cwd, "test.cfg"),
+ modulename=modulename)
else:
database.set_db_uri("sqlite:///:memory:")
-config.update({"global" : {"tg.new_style_logging" : True}})
-config.update({"global" : {"autoreload.on" : False}})
+config.update({'global':
+ {'autoreload.on': False, 'tg.new_style_logging': True}})
+
def start_cp():
if not config.get("cherrypy_started", False):
cherrypy.server.start(serverClass=None, initOnly=True)
config.update({"cherrypy_started" : True})
+
test_user = None
+
def set_identity_user(user):
- "Setup a user which will be used to configure request's identity."
+ """Setup a user for configuring request's identity."""
global test_user
test_user = user
+
def attach_identity(req):
- from turbogears.identity import current_provider
if config.get("identity.on", False):
- if test_user:
- id = current_provider.authenticated_identity(test_user)
- else:
- id = current_provider.anonymous_identity()
- req.identity = id
+ req.identity = (test_user
+ and current_provider.authenticated_identity(test_user)
+ or current_provider.anonymous_identity())
+
def create_request(request, method="GET", protocol="HTTP/1.1",
- headers={}, rfile=None, clientAddress="127.0.0.1",
- remoteHost="localhost", scheme="http"):
+ headers={}, rfile=None, clientAddress="127.0.0.1",
+ remoteHost="localhost", scheme="http"):
start_cp()
if not rfile:
rfile = StringIO.StringIO("")
@@ -93,10 +93,11 @@
cherrypy.serving.response = _cphttptools.Response()
req.run(" ".join((method, request, protocol)), headerList, rfile)
-createRequest = create_request
+createRequest = create_request # deprecated
class BrowsingSession(object):
+
def __init__(self):
self.visit = None
self.response, self.status = None, None
@@ -116,12 +117,15 @@
def _return_directly(output, *args):
return output
+
class DummySession:
session_storage = dict
to_be_loaded = None
+
class DummyRequest:
- "A very simple dummy request."
+ """A very simple dummy request."""
+
remote_host = "127.0.0.1"
def __init__(self, method='GET', path='/', headers=None):
@@ -130,16 +134,23 @@
self.path = path
self.base = ''
self._session = DummySession()
+
def purge__(self):
pass
+
def call(method, *args, **kw):
start_cp()
output, response = call_with_request(method, DummyRequest(), *args, **kw)
return output
+
def call_with_request(method, request, *args, **kw):
- "More fine-grained version of call method, allowing to use request/response."
+ """More fine-grained version of call method.
+
+ This allows using request/response.
+
+ """
orig_proc_output = controllers._process_output
controllers._process_output = _return_directly
cherrypy.serving.response = _cphttptools.Response()
@@ -157,6 +168,7 @@
class DBTest(unittest.TestCase):
+
model = None
def _get_soClasses(self):
@@ -186,21 +198,25 @@
and item != InheritableSQLObject:
item.dropTable(ifExists=True)
+
def reset_cp():
cherrypy.root = None
+
def catch_validation_errors(widget, value):
- """ Catches and unpacks validation errors. For testing purposes. """
- errors = {}
+ """Catch and unpack validation errors (for testing purposes)."""
try:
value = widget.validate(value)
- except validators.Invalid, e:
- if hasattr(e, 'unpack_errors'):
- errors = e.unpack_errors()
- else:
- errors = e
+ except validators.Invalid, errors:
+ try:
+ errors = errors.unpack_errors()
+ except AttributeError:
+ pass
+ else:
+ errors = {}
return value, errors
+
class MemoryListHandler(logging.Handler):
def __init__(self):
@@ -222,12 +238,18 @@
return log
_memhandler = MemoryListHandler()
+
+
_currentcat = None
+
def capture_log(category):
- """Category can either be a single category (a string like 'foo.bar')
- or a list of them. You <em>must</em> call print_log() to reset when
- you're done."""
+ """Capture log for one category.
+
+ The category can either be a single category (a string like 'foo.bar')
+ or a list of them. You *must* call print_log() to reset when you're done.
+
+ """
global _currentcat
assert not _currentcat
if not isinstance(category, list) and not isinstance(category, tuple):
@@ -238,8 +260,9 @@
log.setLevel(logging.DEBUG)
log.addHandler(_memhandler)
+
def _reset_logging():
- """Manages the resetting of the loggers"""
+ """Manage the resetting of the loggers."""
global _currentcat
if not _currentcat:
return
@@ -248,26 +271,39 @@
log.removeHandler(_memhandler)
_currentcat = None
+
def print_log():
- """Prints the log captured by capture_log to stdout, resets that log
- and resets the temporarily added handlers."""
+ """Print the log captured by capture_log to stdout.
+
+ Resets that log and resets the temporarily added handlers.
+
+ """
_reset_logging()
_memhandler.print_log()
+
def get_log():
- """Returns the list of log messages captured by capture_log,
- resets that log and resets the temporarily added handlers."""
+ """Return the list of log messages captured by capture_log.
+
+ Resets that log and resets the temporarily added handlers.
+
+ """
_reset_logging()
return _memhandler.get_log()
+
def sqlalchemy_cleanup():
- database._engine = None
- sqlalchemy.orm.clear_mappers()
database.metadata.clear()
- try: # if ThreadLocalMetaData is used
+ try:
database.metadata.dispose()
- except AttributeError:
- pass
+ except AttributeError: # not threadlocal
+ if database.metadata.bind:
+ database.metadata.bind.dispose()
+ database._engine = None
+ if database.mapper == database.session.mapper:
+ # the following does not work for SA < 0.4
+ sqlalchemy.orm.clear_mappers()
+
__all__ = ["create_request", "call", "DBTest", "createRequest",
"attach_identity", "set_identity_user",
Index: TurboGears.spec
===================================================================
RCS file: /cvs/pkgs/rpms/TurboGears/devel/TurboGears.spec,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- TurboGears.spec 1 Feb 2008 07:07:52 -0000 1.31
+++ TurboGears.spec 22 Feb 2008 18:38:13 -0000 1.32
@@ -3,7 +3,7 @@
Name: TurboGears
Version: 1.0.4.3
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Back-to-front web development in Python
Group: Development/Languages
@@ -11,6 +11,8 @@
URL: http://www.turbogears.org
Source0: http://files.turbogears.org/eggs/%{name}-%{version}.tar.gz
Patch0: %{name}-%{version}-setuptools.patch
+# Upstream fixes for sqlalchemy
+Patch1: %{name}-1.0.4.3-sqlalchemy-backport.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildArch: noarch
@@ -65,6 +67,7 @@
%prep
%setup -q
%patch0 -b .setuptools
+%patch1 -p1 -b .sa
%build
@@ -72,13 +75,14 @@
%install
rm -rf %{buildroot}
-%{__python} setup.py install -O1 --skip-build --root %{buildroot}
+%{__python} setup.py install --skip-build --root %{buildroot}
+%find_lang
%clean
rm -rf %{buildroot}
-%files
+%files -f TurboGears.lang
%defattr(0644,root,root,0755)
%doc CHANGELOG.txt LICENSE.txt
%attr(0755,root,root) %{_bindir}/tg-admin
@@ -86,6 +90,9 @@
%{python_sitelib}/turbogears/
%changelog
+* Thu Feb 21 2008 Toshio Kuratomi <tkuratom at redhat.com> 1.0.4.3-2
+- Fixes for SQLAlchemy-0.4 and exceptions. Upstream Bug #1721.
+
* Fri Feb 1 2008 Luke Macken <lmacken at redhat.com> 1.0.4.3-1
- 1.0.4.3
- Previous message (by thread): rpms/xorg-x11-drv-mga/devel .cvsignore, 1.10, 1.11 sources, 1.10, 1.11 xorg-x11-drv-mga.spec, 1.26, 1.27
- Next message (by thread): rpms/ocaml-fileutils/F-8 ocaml-fileutils.spec, NONE, 1.1 .cvsignore, 1.1, 1.2 sources, 1.1, 1.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the fedora-extras-commits
mailing list