You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2019/03/27 21:03:13 UTC

[allura] 02/08: [#8273] Upgrade TG 2.3.0 Webob 1.3.1: pylons imports, some registry stuff, etc

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8273
in repository https://gitbox.apache.org/repos/asf/allura.git

commit cbe6b8b8799cf9d339eb5ea7d318b8533b7408de
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Wed Mar 20 15:31:52 2019 -0400

    [#8273] Upgrade TG 2.3.0 Webob 1.3.1: pylons imports, some registry stuff, etc
---
 Allura/allura/__init__.py                          |  2 +-
 Allura/allura/app.py                               |  2 +-
 Allura/allura/command/base.py                      | 21 ++++----
 Allura/allura/command/reclone_repo.py              |  2 +-
 Allura/allura/command/script.py                    |  6 +--
 Allura/allura/command/show_models.py               |  2 +-
 Allura/allura/command/taskd.py                     |  3 +-
 Allura/allura/config/app_cfg.py                    |  9 ++--
 Allura/allura/config/environment.py                |  4 --
 Allura/allura/config/middleware.py                 | 16 +++---
 Allura/allura/controllers/auth.py                  |  4 +-
 Allura/allura/controllers/base.py                  |  2 +-
 Allura/allura/controllers/basetest_project_root.py |  7 +--
 Allura/allura/controllers/discuss.py               |  2 +-
 Allura/allura/controllers/feed.py                  |  2 +-
 Allura/allura/controllers/project.py               |  2 +-
 Allura/allura/controllers/repository.py            |  4 +-
 Allura/allura/controllers/rest.py                  |  4 +-
 Allura/allura/controllers/root.py                  |  7 +--
 Allura/allura/controllers/search.py                |  2 +-
 Allura/allura/controllers/site_admin.py            |  6 +--
 Allura/allura/controllers/static.py                |  2 +-
 Allura/allura/controllers/trovecategories.py       |  4 +-
 Allura/allura/ext/admin/admin_main.py              |  4 +-
 Allura/allura/ext/admin/widgets.py                 |  2 +-
 .../ext/personal_dashboard/dashboard_main.py       |  2 +-
 Allura/allura/ext/project_home/project_main.py     |  2 +-
 Allura/allura/ext/search/search_main.py            |  2 +-
 Allura/allura/ext/user_profile/user_main.py        |  4 +-
 Allura/allura/lib/app_globals.py                   |  4 +-
 Allura/allura/lib/base.py                          | 19 +-------
 Allura/allura/lib/custom_middleware.py             |  4 +-
 Allura/allura/lib/decorators.py                    |  4 +-
 Allura/allura/lib/helpers.py                       |  4 +-
 Allura/allura/lib/macro.py                         |  4 +-
 Allura/allura/lib/mail_util.py                     |  4 +-
 Allura/allura/lib/multifactor.py                   |  2 +-
 Allura/allura/lib/patches.py                       |  2 +-
 Allura/allura/lib/plugin.py                        |  4 +-
 Allura/allura/lib/repository.py                    |  4 +-
 Allura/allura/lib/search.py                        |  4 +-
 Allura/allura/lib/security.py                      |  4 +-
 Allura/allura/lib/spam/akismetfilter.py            |  4 +-
 Allura/allura/lib/spam/mollomfilter.py             |  4 +-
 Allura/allura/lib/spam/stopforumspamfilter.py      |  2 +-
 Allura/allura/lib/stats.py                         |  2 +-
 Allura/allura/lib/utils.py                         | 31 ++++++------
 Allura/allura/lib/validators.py                    |  2 +-
 Allura/allura/lib/widgets/auth_widgets.py          |  4 +-
 Allura/allura/lib/widgets/discuss.py               |  2 +-
 Allura/allura/lib/widgets/form_fields.py           |  2 +-
 Allura/allura/lib/widgets/forms.py                 |  2 +-
 Allura/allura/lib/widgets/project_list.py          |  2 +-
 Allura/allura/lib/widgets/subscriptions.py         |  2 +-
 Allura/allura/lib/widgets/user_profile.py          |  6 +--
 Allura/allura/model/artifact.py                    |  4 +-
 Allura/allura/model/attachments.py                 |  4 +-
 Allura/allura/model/auth.py                        |  4 +-
 Allura/allura/model/discuss.py                     |  2 +-
 Allura/allura/model/index.py                       |  2 +-
 Allura/allura/model/monq_model.py                  |  2 +-
 Allura/allura/model/neighborhood.py                |  4 +-
 Allura/allura/model/notification.py                |  2 +-
 Allura/allura/model/oauth.py                       |  2 +-
 Allura/allura/model/project.py                     |  4 +-
 Allura/allura/model/repo_refresh.py                |  2 +-
 Allura/allura/model/repository.py                  |  4 +-
 Allura/allura/model/session.py                     |  2 +-
 Allura/allura/model/timeline.py                    |  2 +-
 Allura/allura/scripts/create_deleted_comments.py   |  2 +-
 Allura/allura/scripts/create_sitemap_files.py      |  8 +--
 Allura/allura/scripts/refresh_last_commits.py      |  2 +-
 Allura/allura/scripts/refreshrepo.py               |  2 +-
 Allura/allura/scripts/reindex_projects.py          |  2 +-
 Allura/allura/tasks/activity_tasks.py              |  2 +-
 Allura/allura/tasks/admin_tasks.py                 |  2 +-
 Allura/allura/tasks/export_tasks.py                |  2 +-
 Allura/allura/tasks/index_tasks.py                 |  4 +-
 Allura/allura/tasks/mail_tasks.py                  |  2 +-
 Allura/allura/tasks/repo_tasks.py                  |  2 +-
 Allura/allura/tests/decorators.py                  |  2 +-
 Allura/allura/tests/functional/test_admin.py       |  2 +-
 Allura/allura/tests/functional/test_auth.py        |  2 +-
 Allura/allura/tests/functional/test_home.py        |  2 +-
 Allura/allura/tests/functional/test_nav.py         |  2 +-
 .../allura/tests/functional/test_neighborhood.py   |  4 +-
 .../tests/functional/test_personal_dashboard.py    |  2 +-
 Allura/allura/tests/functional/test_rest.py        |  2 +-
 Allura/allura/tests/functional/test_root.py        |  2 +-
 Allura/allura/tests/functional/test_site_admin.py  |  2 +-
 Allura/allura/tests/model/test_artifact.py         |  2 +-
 Allura/allura/tests/model/test_auth.py             |  2 +-
 Allura/allura/tests/model/test_discussion.py       |  2 +-
 Allura/allura/tests/model/test_filesystem.py       |  6 +--
 Allura/allura/tests/model/test_notification.py     |  2 +-
 Allura/allura/tests/model/test_project.py          |  2 +-
 Allura/allura/tests/model/test_repo.py             |  2 +-
 .../tests/scripts/test_create_sitemap_files.py     |  2 +-
 .../allura/tests/scripts/test_delete_projects.py   | 10 ++--
 .../tests/templates/jinja_master/test_lib.py       |  2 +-
 Allura/allura/tests/test_app.py                    |  2 +-
 Allura/allura/tests/test_globals.py                |  2 +-
 Allura/allura/tests/test_helpers.py                |  2 +-
 Allura/allura/tests/test_plugin.py                 | 57 +++++++++++-----------
 Allura/allura/tests/test_security.py               |  2 +-
 Allura/allura/tests/test_tasks.py                  |  2 +-
 Allura/allura/tests/test_webhooks.py               |  2 +-
 Allura/allura/tests/unit/patches.py                |  2 +-
 .../tests/unit/test_helpers/test_set_context.py    |  2 +-
 Allura/allura/tests/unit/test_post_model.py        |  2 +-
 Allura/allura/tests/unit/test_repo.py              |  2 +-
 Allura/allura/webhooks.py                          |  4 +-
 Allura/allura/websetup/bootstrap.py                |  2 +-
 Allura/allura/websetup/schema.py                   | 14 ++++--
 Allura/docs/development/testing.rst                |  2 +-
 AlluraTest/alluratest/controller.py                | 23 +++++----
 ForgeActivity/forgeactivity/main.py                |  4 +-
 .../forgeactivity/tests/functional/test_root.py    |  2 +-
 ForgeActivity/forgeactivity/widgets/follow.py      |  2 +-
 ForgeBlog/forgeblog/command/rssfeeds.py            |  6 +--
 ForgeBlog/forgeblog/main.py                        |  6 +--
 ForgeBlog/forgeblog/model/blog.py                  |  2 +-
 ForgeBlog/forgeblog/tests/functional/test_feeds.py |  2 +-
 ForgeBlog/forgeblog/tests/test_app.py              |  2 +-
 ForgeBlog/forgeblog/tests/test_commands.py         |  2 +-
 ForgeBlog/forgeblog/tests/test_roles.py            |  2 +-
 ForgeBlog/forgeblog/tests/unit/__init__.py         |  2 +-
 ForgeBlog/forgeblog/tests/unit/test_blog_post.py   |  2 +-
 ForgeChat/forgechat/main.py                        |  2 +-
 .../forgediscussion/controllers/forum.py           |  2 +-
 .../forgediscussion/controllers/root.py            |  4 +-
 ForgeDiscussion/forgediscussion/forum_main.py      |  4 +-
 ForgeDiscussion/forgediscussion/import_support.py  |  2 +-
 ForgeDiscussion/forgediscussion/model/forum.py     |  2 +-
 ForgeDiscussion/forgediscussion/tasks.py           |  2 +-
 .../forgediscussion/tests/functional/test_forum.py |  2 +-
 .../tests/functional/test_import.py                |  2 +-
 ForgeDiscussion/forgediscussion/tests/test_app.py  |  2 +-
 .../forgediscussion/tests/test_forum_roles.py      |  2 +-
 .../forgediscussion/widgets/forum_widgets.py       |  2 +-
 ForgeGit/forgegit/controllers.py                   |  2 +-
 ForgeGit/forgegit/git_main.py                      |  2 +-
 ForgeGit/forgegit/model/git_repo.py                |  2 +-
 .../forgegit/tests/functional/test_controllers.py  |  2 +-
 ForgeGit/forgegit/tests/model/test_repository.py   |  2 +-
 ForgeGit/forgegit/tests/test_git_app.py            |  2 +-
 ForgeGit/forgegit/tests/test_tasks.py              |  2 +-
 ForgeImporters/forgeimporters/base.py              |  4 +-
 ForgeImporters/forgeimporters/forge/tracker.py     |  4 +-
 ForgeImporters/forgeimporters/github/__init__.py   |  2 +-
 ForgeImporters/forgeimporters/github/code.py       |  4 +-
 ForgeImporters/forgeimporters/github/tasks.py      |  4 +-
 .../forgeimporters/github/tests/test_oauth.py      |  2 +-
 ForgeImporters/forgeimporters/github/tracker.py    |  4 +-
 ForgeImporters/forgeimporters/github/wiki.py       |  4 +-
 .../forgeimporters/trac/tests/test_tickets.py      |  2 +-
 ForgeImporters/forgeimporters/trac/tickets.py      |  4 +-
 ForgeLink/forgelink/link_main.py                   |  4 +-
 ForgeLink/forgelink/tests/test_app.py              |  2 +-
 ForgeSVN/forgesvn/controllers.py                   |  2 +-
 ForgeSVN/forgesvn/model/svn.py                     |  2 +-
 ForgeSVN/forgesvn/svn_main.py                      |  2 +-
 .../forgesvn/tests/functional/test_controllers.py  |  2 +-
 ForgeSVN/forgesvn/tests/model/test_repository.py   |  2 +-
 .../forgesvn/tests/model/test_svnimplementation.py |  2 +-
 ForgeSVN/forgesvn/tests/test_svn_app.py            |  2 +-
 ForgeSVN/forgesvn/tests/test_tasks.py              |  2 +-
 ForgeShortUrl/forgeshorturl/main.py                |  2 +-
 ForgeShortUrl/forgeshorturl/model/shorturl.py      |  2 +-
 .../forgeshorturl/tests/functional/test.py         |  2 +-
 .../forgetracker/command/fix_discussion.py         |  2 +-
 ForgeTracker/forgetracker/import_support.py        |  2 +-
 ForgeTracker/forgetracker/model/ticket.py          |  2 +-
 ForgeTracker/forgetracker/plugins.py               |  2 +-
 ForgeTracker/forgetracker/search.py                |  2 +-
 ForgeTracker/forgetracker/tasks.py                 |  2 +-
 .../forgetracker/tests/functional/test_rest.py     |  2 +-
 .../forgetracker/tests/functional/test_root.py     |  4 +-
 ForgeTracker/forgetracker/tests/test_app.py        |  2 +-
 .../forgetracker/tests/test_tracker_roles.py       |  2 +-
 ForgeTracker/forgetracker/tests/unit/__init__.py   |  7 ++-
 .../forgetracker/tests/unit/test_globals_model.py  |  2 +-
 .../tests/unit/test_milestone_controller.py        |  2 +-
 .../tests/unit/test_root_controller.py             |  2 +-
 .../tests/unit/test_ticket_custom_fields_form.py   |  2 +-
 .../forgetracker/tests/unit/test_ticket_form.py    |  2 +-
 .../forgetracker/tests/unit/test_ticket_model.py   |  2 +-
 ForgeTracker/forgetracker/tracker_main.py          |  4 +-
 ForgeTracker/forgetracker/widgets/ticket_form.py   |  2 +-
 .../forgeuserstats/controllers/userstats.py        |  2 +-
 ForgeUserStats/forgeuserstats/main.py              |  2 +-
 ForgeUserStats/forgeuserstats/model/stats.py       |  2 +-
 ForgeUserStats/forgeuserstats/tests/test_model.py  |  2 +-
 ForgeUserStats/forgeuserstats/tests/test_stats.py  |  2 +-
 ForgeWiki/forgewiki/model/wiki.py                  |  4 +-
 ForgeWiki/forgewiki/tests/test_app.py              |  2 +-
 ForgeWiki/forgewiki/tests/test_models.py           |  2 +-
 ForgeWiki/forgewiki/tests/test_wiki_roles.py       |  2 +-
 ForgeWiki/forgewiki/wiki_main.py                   |  4 +-
 requirements.txt                                   |  5 +-
 scripts/migrations/000-fix-tracker-fields.py       |  2 +-
 scripts/migrations/001-restore-labels.py           |  2 +-
 .../migrations/002-fix-tracker-thread-subjects.py  |  2 +-
 scripts/migrations/007-update-acls.py              |  2 +-
 scripts/migrations/010-fix-home-permissions.py     |  2 +-
 scripts/migrations/012-uninstall-home.py           |  2 +-
 scripts/migrations/013-update-ordinals.py          |  2 +-
 .../015-add-neighborhood_id-to-blog-posts.py       |  2 +-
 .../migrations/020-remove-wiki-title-slashes.py    |  2 +-
 .../migrations/024-migrate-custom-profile-text.py  |  2 +-
 .../033-change-comment-anon-permissions.py         |  2 +-
 ...34-update_subscriptions_ticket_and_mr_titles.py |  2 +-
 scripts/perf/call_count.py                         |  2 +-
 scripts/perf/load-up-forum.py                      |  2 +-
 scripts/perf/md_perf.py                            |  2 +-
 scripts/project-import.py                          |  2 +-
 scripts/publicize-neighborhood.py                  |  2 +-
 scripts/rethumb.py                                 |  2 +-
 scripts/scrub-allura-data.py                       |  2 +-
 scripts/teamforge-import.py                        |  2 +-
 220 files changed, 371 insertions(+), 388 deletions(-)

diff --git a/Allura/allura/__init__.py b/Allura/allura/__init__.py
index ebf903b..15c3ab2 100644
--- a/Allura/allura/__init__.py
+++ b/Allura/allura/__init__.py
@@ -18,6 +18,6 @@
 #       under the License.
 
 """The allura package"""
-from paste.registry import StackedObjectProxy
+from tg.support.registry import StackedObjectProxy
 
 credentials = StackedObjectProxy(name='credentials')
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index 9481eed..82a550b 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -27,7 +27,7 @@ import pkg_resources
 from tg import expose, redirect, flash, validate
 from tg.decorators import without_trailing_slash
 from tg import config as tg_config
-from pylons import request, app_globals as g, tmpl_context as c
+from tg import request, app_globals as g, tmpl_context as c
 from paste.deploy.converters import asbool, asint
 from bson import ObjectId
 from bson.errors import InvalidId
diff --git a/Allura/allura/command/base.py b/Allura/allura/command/base.py
index 66b46d5..9a7689a 100644
--- a/Allura/allura/command/base.py
+++ b/Allura/allura/command/base.py
@@ -19,11 +19,12 @@ import os
 import logging
 import shlex
 
-import pylons
+import tg
 from paste.script import command
 from paste.deploy import appconfig
 from paste.deploy.converters import asbool
-from paste.registry import Registry
+from tg.support.registry import Registry
+from tg.wsgiapp import RequestLocals
 
 import activitystream
 import ming
@@ -104,12 +105,12 @@ class Command(command.Command):
             ming.configure(**conf)
             if asbool(conf.get('activitystream.recording.enabled', False)):
                 activitystream.configure(**h.convert_bools(conf, prefix='activitystream.'))
-            pylons.tmpl_context.user = M.User.anonymous()
+            tg.tmpl_context.user = M.User.anonymous()
         else:
             # Probably being called from another script (websetup, perhaps?)
             log = logging.getLogger('allura.command')
-            conf = pylons.config
-        self.tools = pylons.app_globals.entry_points['tool'].values()
+            conf = tg.config
+        self.tools = tg.app_globals.entry_points['tool'].values()
         for ep in h.iter_entry_points('allura.command_init'):
             log.info('Running command_init for %s', ep.name)
             ep.load()(conf)
@@ -118,10 +119,12 @@ class Command(command.Command):
     def setup_globals(self):
         import allura.lib.app_globals
         self.registry.prepare()
-        self.registry.register(pylons.tmpl_context, EmptyClass())
-        self.registry.register(pylons.app_globals, self.globals)
-        self.registry.register(
-            allura.credentials, allura.lib.security.Credentials())
+        self.registry.register(allura.credentials, allura.lib.security.Credentials())
+        # turbogears has its own special magic wired up for its globals, can't use a regular Registry
+        tgl = RequestLocals()
+        tgl.tmpl_context = EmptyClass()
+        tgl.app_globals = self.globals
+        tg.request_local.context._push_object(tgl)
 
     def teardown_globals(self):
         self.registry.cleanup()
diff --git a/Allura/allura/command/reclone_repo.py b/Allura/allura/command/reclone_repo.py
index d401b0b..51e5ca6 100644
--- a/Allura/allura/command/reclone_repo.py
+++ b/Allura/allura/command/reclone_repo.py
@@ -17,7 +17,7 @@
 
 import warnings
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura import model as M
 
diff --git a/Allura/allura/command/script.py b/Allura/allura/command/script.py
index 1f2c93a..7bc3b8c 100644
--- a/Allura/allura/command/script.py
+++ b/Allura/allura/command/script.py
@@ -20,8 +20,8 @@ import os.path
 import cProfile
 import warnings
 
-from pylons import tmpl_context as c
-import pylons
+from tg import tmpl_context as c
+import tg
 import webob
 
 from ming.orm import session
@@ -52,7 +52,7 @@ class ScriptCommand(base.Command):
             self.basic_setup()
             request = webob.Request.blank('--script--', environ={
                 'paste.registry': self.registry})
-            self.registry.register(pylons.request, request)
+            tg.request_local.context.request = request
             if self.options.pdb:
                 base.log.info('Installing exception hook')
                 sys.excepthook = utils.postmortem_hook
diff --git a/Allura/allura/command/show_models.py b/Allura/allura/command/show_models.py
index 6de6035..ac2ef86 100644
--- a/Allura/allura/command/show_models.py
+++ b/Allura/allura/command/show_models.py
@@ -21,7 +21,7 @@ from contextlib import contextmanager
 from itertools import groupby
 
 from paste.deploy.converters import asbool
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from pymongo.errors import DuplicateKeyError, InvalidDocument, OperationFailure
 
 from ming.orm import mapper, session, Mapper
diff --git a/Allura/allura/command/taskd.py b/Allura/allura/command/taskd.py
index 409e701..d305c74 100644
--- a/Allura/allura/command/taskd.py
+++ b/Allura/allura/command/taskd.py
@@ -25,7 +25,6 @@ import signal
 import sys
 
 import faulthandler
-import pylons
 from setproctitle import setproctitle, getproctitle
 import tg
 from paste.deploy import loadapp
@@ -103,7 +102,7 @@ class TaskdCommand(base.Command):
         name = '%s pid %s' % (os.uname()[1], os.getpid())
         wsgi_app = loadapp('config:%s#task' %
                            self.args[0], relative_to=os.getcwd())
-        poll_interval = asint(pylons.config.get('monq.poll_interval', 10))
+        poll_interval = asint(tg.config.get('monq.poll_interval', 10))
         only = self.options.only
         if only:
             only = only.split(',')
diff --git a/Allura/allura/config/app_cfg.py b/Allura/allura/config/app_cfg.py
index 50028c1..c21af19 100644
--- a/Allura/allura/config/app_cfg.py
+++ b/Allura/allura/config/app_cfg.py
@@ -65,9 +65,8 @@ class ForgeConfig(AppConfig):
         self.disable_request_extensions = True
 
     def after_init_config(self):
-        config['pylons.strict_c'] = True
+        config['tg.strict_tmpl_context'] = True
 
-    def setup_routes(self):
         map = Mapper()
         # Setup a default route for the root of object dispatch
         map.connect('*url', controller=self.root_controller,
@@ -106,9 +105,9 @@ class ForgeConfig(AppConfig):
         jinja2_env.filters['filter'] = lambda s,t=None: filter(t and jinja2_env.tests[t], s)
         jinja2_env.filters['nl2br'] = helpers.nl2br_jinja_filter
         jinja2_env.globals.update({'hasattr': hasattr})
-        config['pylons.app_globals'].jinja2_env = jinja2_env
+        config['tg.app_globals'].jinja2_env = jinja2_env
         # Jinja's unable to request c's attributes without strict_c
-        config['pylons.strict_c'] = True
+        config['tg.strict_tmpl_context'] = True
         self.render_functions.jinja = tg.render.render_jinja
 
 
@@ -116,7 +115,7 @@ class JinjaEngine(ew.TemplateEngine):
 
     @property
     def _environ(self):
-        return config['pylons.app_globals'].jinja2_env
+        return config['tg.app_globals'].jinja2_env
 
     def load(self, template_name):
         try:
diff --git a/Allura/allura/config/environment.py b/Allura/allura/config/environment.py
index 35676fd..bf0f5b6 100644
--- a/Allura/allura/config/environment.py
+++ b/Allura/allura/config/environment.py
@@ -19,10 +19,6 @@
 
 """WSGI environment setup for allura."""
 
-import pylons.middleware
-import tg
-import tg.error
-
 from allura.config.app_cfg import base_config
 
 __all__ = ['load_environment']
diff --git a/Allura/allura/config/middleware.py b/Allura/allura/config/middleware.py
index 99f9329..decce40 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -20,13 +20,12 @@
 """WSGI middleware initialization for the allura application."""
 import mimetypes
 
-import pylons.middleware  # needed within tg.error :(
 import tg
 import tg.error
 import pkg_resources
 from tg import config
 from paste.deploy.converters import asbool, aslist, asint
-from paste.registry import RegistryManager
+from tg.support.registry import RegistryManager
 from routes.middleware import RoutesMiddleware
 from pylons.middleware import StatusCodeRedirect
 from beaker.middleware import SessionMiddleware
@@ -178,7 +177,7 @@ def _make_core_app(root, global_conf, full_stack=True, **app_conf):
         # Converts exceptions to HTTP errors, shows traceback in debug mode
         # don't use TG footer with extra CSS & images that take time to load
         tg.error.footer_html = '<!-- %s %s -->'
-        app = tg.error.ErrorHandler(app, global_conf, **config['pylons.errorware'])
+        app = tg.error.ErrorHandler(app, global_conf, **config['tg.errorware'])
 
         app = SetRequestHostFromConfig(app, config)
 
@@ -209,16 +208,15 @@ def allura_globals_middleware(app):
 
 
 def get_tg_vars(context):
-    import pylons
     import tg
     from allura.lib import helpers as h
     from urllib import quote, quote_plus
-    context.setdefault('g', pylons.app_globals)
-    context.setdefault('c', pylons.tmpl_context)
+    context.setdefault('g', tg.app_globals)
+    context.setdefault('c', tg.tmpl_context)
     context.setdefault('h', h)
-    context.setdefault('request', pylons.request)
-    context.setdefault('response', pylons.response)
-    context.setdefault('url', pylons.url)
+    context.setdefault('request', tg.request)
+    context.setdefault('response', tg.response)
+    context.setdefault('url', tg.url)
     context.setdefault('tg', dict(
         config=tg.config,
         flash_obj=tg.flash,
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index 3333b66..e10fdd0 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -25,8 +25,8 @@ import bson
 import tg
 from tg import expose, flash, redirect, validate, config, session
 from tg.decorators import with_trailing_slash, without_trailing_slash
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request, response
+from tg import tmpl_context as c, app_globals as g
+from tg import request, response
 from webob import exc as wexc
 from paste.deploy.converters import asbool
 from cryptography.hazmat.primitives.twofactor import InvalidToken
diff --git a/Allura/allura/controllers/base.py b/Allura/allura/controllers/base.py
index 6a6ab28..ef91a32 100644
--- a/Allura/allura/controllers/base.py
+++ b/Allura/allura/controllers/base.py
@@ -21,7 +21,7 @@ from tg import expose
 from webob import exc
 from crank.objectdispatcher import ObjectDispatcher
 from tg import redirect, flash
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 
 log = logging.getLogger(__name__)
diff --git a/Allura/allura/controllers/basetest_project_root.py b/Allura/allura/controllers/basetest_project_root.py
index b80d94d..0a5047d 100644
--- a/Allura/allura/controllers/basetest_project_root.py
+++ b/Allura/allura/controllers/basetest_project_root.py
@@ -21,8 +21,8 @@
 import logging
 from urllib import unquote
 
-from pylons import tmpl_context as c
-from pylons import request
+from tg import tmpl_context as c
+from tg import request
 from webob import exc
 from tg import expose
 from paste.deploy.converters import asbool
@@ -88,9 +88,6 @@ class BasetestProjectRootController(WsgiDispatchController, ProjectController):
             count -= 1
             assert count > 0, 'Timeout waiting for test project to appear'
 
-    def _cleanup_request(self):
-        pass
-
     @expose()
     def _lookup(self, name, *remainder):
         if not h.re_project_name.match(name):
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 34f085d..9aec747 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -24,7 +24,7 @@ from tg import expose, redirect, validate, request, flash, response
 from tg.decorators import with_trailing_slash, without_trailing_slash, before_render, before_validate
 from decorator import decorator
 
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from webob import exc
 
 from ming.base import Object
diff --git a/Allura/allura/controllers/feed.py b/Allura/allura/controllers/feed.py
index 2fef9f3..9a9c2ae 100644
--- a/Allura/allura/controllers/feed.py
+++ b/Allura/allura/controllers/feed.py
@@ -18,7 +18,7 @@
 from tg import expose, validate, request, response
 from tg.decorators import without_trailing_slash
 from formencode import validators as V
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from webob import exc
 
 from allura import model as M
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index d7c2d3d..5c7e253 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -23,7 +23,7 @@ from urllib import unquote
 from bson import ObjectId
 from tg import expose, flash, redirect, validate, request, config, session
 from tg.decorators import with_trailing_slash, without_trailing_slash
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from paste.deploy.converters import asbool
 from webob import exc
 import jinja2
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 650065c..8cae021 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -24,8 +24,8 @@ from collections import defaultdict, OrderedDict
 
 from ming.utils import LazyProperty
 from paste.deploy.converters import asbool
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request, response
+from tg import tmpl_context as c, app_globals as g
+from tg import request, response
 from webob import exc
 import tg
 from tg import redirect, expose, flash, validate
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index 2913bee..6e9f78b 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -25,8 +25,8 @@ import oauth2 as oauth
 from paste.util.converters import asbool
 from webob import exc
 from tg import expose, flash, redirect, config
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request, response
+from tg import tmpl_context as c, app_globals as g
+from tg import request, response
 
 from ming.orm import session
 from ming.utils import LazyProperty
diff --git a/Allura/allura/controllers/root.py b/Allura/allura/controllers/root.py
index 76987e9..7a6bee2 100644
--- a/Allura/allura/controllers/root.py
+++ b/Allura/allura/controllers/root.py
@@ -23,8 +23,8 @@ import logging
 from tg import expose, request, config, session, redirect
 from tg.decorators import with_trailing_slash
 from tg.flash import TGFlash
-from pylons import tmpl_context as c
-from pylons import response
+from tg import tmpl_context as c
+from tg import response
 from paste.deploy.converters import asbool
 
 from allura.app import SitemapEntry
@@ -108,9 +108,6 @@ class RootController(WsgiDispatchController):
             # https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=en#defining_optimal_cache-control_policy
             response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate'
 
-    def _cleanup_request(self):
-        pass
-
     @expose()
     @with_trailing_slash
     def index(self, **kw):
diff --git a/Allura/allura/controllers/search.py b/Allura/allura/controllers/search.py
index eaf8446..3fe6f8a 100644
--- a/Allura/allura/controllers/search.py
+++ b/Allura/allura/controllers/search.py
@@ -18,7 +18,7 @@
 from tg import expose, validate, request
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from formencode import validators as V
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from webob import exc
 import pymongo
 
diff --git a/Allura/allura/controllers/site_admin.py b/Allura/allura/controllers/site_admin.py
index d5d91f1..d173800 100644
--- a/Allura/allura/controllers/site_admin.py
+++ b/Allura/allura/controllers/site_admin.py
@@ -25,9 +25,9 @@ from tg.decorators import with_trailing_slash, without_trailing_slash
 import bson
 import tg
 from paste.deploy.converters import aslist
-from pylons import app_globals as g
-from pylons import tmpl_context as c
-from pylons import request
+from tg import app_globals as g
+from tg import tmpl_context as c
+from tg import request
 from formencode import validators, Invalid
 from webob.exc import HTTPNotFound, HTTPFound
 from ming.odm import ThreadLocalORMSession
diff --git a/Allura/allura/controllers/static.py b/Allura/allura/controllers/static.py
index 89a94ab..15b638c 100644
--- a/Allura/allura/controllers/static.py
+++ b/Allura/allura/controllers/static.py
@@ -21,7 +21,7 @@ from tg import expose
 from tg.decorators import without_trailing_slash
 from webob import exc
 
-from pylons import app_globals as g
+from tg import app_globals as g
 from allura.lib import helpers as h
 from allura.lib import utils
 
diff --git a/Allura/allura/controllers/trovecategories.py b/Allura/allura/controllers/trovecategories.py
index 392de1c..149b1bc 100644
--- a/Allura/allura/controllers/trovecategories.py
+++ b/Allura/allura/controllers/trovecategories.py
@@ -18,11 +18,11 @@ import re
 from collections import OrderedDict
 
 from tg import expose, flash, redirect, validate, config
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from string import digits, lowercase
 from tg.decorators import without_trailing_slash
 from webob.exc import HTTPForbidden, HTTPNotFound
-from pylons import app_globals as g
+from tg import app_globals as g
 
 from allura import model as M
 from allura.controllers import BaseController
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 4b7ec42..6e49e6d 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -26,8 +26,8 @@ import json
 from operator import itemgetter, attrgetter
 import pkg_resources
 
-from pylons import tmpl_context as c, app_globals as g, response
-from pylons import request
+from tg import tmpl_context as c, app_globals as g, response
+from tg import request
 from paste.deploy.converters import asbool, aslist
 from tg import expose, redirect, flash, validate, config, jsonify
 from tg.decorators import with_trailing_slash, without_trailing_slash
diff --git a/Allura/allura/ext/admin/widgets.py b/Allura/allura/ext/admin/widgets.py
index 547092e..6fed753 100644
--- a/Allura/allura/ext/admin/widgets.py
+++ b/Allura/allura/ext/admin/widgets.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 import ew as ew_core
 from ew import jinja2_ew as ew
diff --git a/Allura/allura/ext/personal_dashboard/dashboard_main.py b/Allura/allura/ext/personal_dashboard/dashboard_main.py
index f3fb479..fb83cb7 100644
--- a/Allura/allura/ext/personal_dashboard/dashboard_main.py
+++ b/Allura/allura/ext/personal_dashboard/dashboard_main.py
@@ -17,7 +17,7 @@
 
 import logging
 
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from tg import expose, redirect, config
 from itertools import islice, ifilter
 from ming.orm import session
diff --git a/Allura/allura/ext/project_home/project_main.py b/Allura/allura/ext/project_home/project_main.py
index a02b807..0710ea6 100644
--- a/Allura/allura/ext/project_home/project_main.py
+++ b/Allura/allura/ext/project_home/project_main.py
@@ -18,7 +18,7 @@
 import logging
 
 import pkg_resources
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from tg import expose, redirect
 from tg.decorators import with_trailing_slash
 
diff --git a/Allura/allura/ext/search/search_main.py b/Allura/allura/ext/search/search_main.py
index 9f8a92b..91bb1da 100644
--- a/Allura/allura/ext/search/search_main.py
+++ b/Allura/allura/ext/search/search_main.py
@@ -18,7 +18,7 @@
 import logging
 
 import pkg_resources
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from tg import expose, validate
 from tg.decorators import with_trailing_slash
 from formencode import validators as V
diff --git a/Allura/allura/ext/user_profile/user_main.py b/Allura/allura/ext/user_profile/user_main.py
index 50bd64a..a6f218f 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -21,8 +21,8 @@ import pkg_resources
 from datetime import datetime
 
 from formencode import validators
-from pylons import request
-from pylons import tmpl_context as c, app_globals as g
+from tg import request
+from tg import tmpl_context as c, app_globals as g
 from pytz import timezone
 from tg import expose, redirect, validate, flash
 from webob import exc
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 1e63594..4b0a282 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -39,8 +39,8 @@ import pygments.lexers
 import pygments.formatters
 import pygments.util
 from tg import config
-from pylons import request
-from pylons import tmpl_context as c
+from tg import request
+from tg import tmpl_context as c
 from paste.deploy.converters import asbool, asint, aslist
 from pypeline.markup import markup as pypeline_markup
 from ming.odm import session
diff --git a/Allura/allura/lib/base.py b/Allura/allura/lib/base.py
index 8000e88..148c3e8 100644
--- a/Allura/allura/lib/base.py
+++ b/Allura/allura/lib/base.py
@@ -18,8 +18,6 @@
 #       under the License.
 
 """The base Controller API."""
-from webob import exc
-import pylons
 from tg import TGController
 
 __all__ = ['WsgiDispatchController']
@@ -39,19 +37,6 @@ class WsgiDispatchController(TGController):
         '''Responsible for setting all the values we need to be set on pylons.tmpl_context'''
         raise NotImplementedError, '_setup_request'
 
-    def _cleanup_request(self):
-        raise NotImplementedError, '_cleanup_request'
-
     def __call__(self, environ, start_response):
-        try:
-            self._setup_request()
-            response = super(WsgiDispatchController, self).__call__(
-                environ, start_response)
-            return self.cleanup_iterator(response)
-        except exc.HTTPException, err:
-            return err(environ, start_response)
-
-    def cleanup_iterator(self, response):
-        for chunk in response:
-            yield chunk
-        self._cleanup_request()
+        self._setup_request()
+        return super(WsgiDispatchController, self).__call__(environ, start_response)
diff --git a/Allura/allura/lib/custom_middleware.py b/Allura/allura/lib/custom_middleware.py
index e558080..bd27868 100644
--- a/Allura/allura/lib/custom_middleware.py
+++ b/Allura/allura/lib/custom_middleware.py
@@ -23,7 +23,7 @@ import tg
 import pkg_resources
 from paste import fileapp
 from paste.deploy.converters import aslist
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from pylons.util import call_wsgi_application
 from timermiddleware import Timer, TimerMiddleware
 from webob import exc, Request
@@ -189,7 +189,7 @@ class CSRFMiddleware(object):
         if cookie is None:
             cookie = h.cryptographic_nonce()
         if req.method == 'POST':
-            param = req.str_POST.pop(self._param_name, None)
+            param = req.POST.pop(self._param_name, None)
             if cookie != param:
                 log.warning('CSRF attempt detected, %r != %r', cookie, param)
                 environ.pop('HTTP_COOKIE', None)  # effectively kill the existing session
diff --git a/Allura/allura/lib/decorators.py b/Allura/allura/lib/decorators.py
index 5f37daf..589b327 100644
--- a/Allura/allura/lib/decorators.py
+++ b/Allura/allura/lib/decorators.py
@@ -32,8 +32,8 @@ from tg.decorators import before_validate
 from tg import request, redirect, session, config
 from tg.render import render
 from webob import exc
-from pylons import tmpl_context as c
-from pylons import response
+from tg import tmpl_context as c
+from tg import response
 from webob.exc import HTTPFound, WSGIHTTPException
 
 from allura.lib import helpers as h
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 70c768f..57f200d 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -53,8 +53,8 @@ from bson import ObjectId
 from paste.deploy import appconfig
 from pymongo.errors import InvalidId
 from contextlib import contextmanager
-from pylons import tmpl_context as c, app_globals as g
-from pylons import response, request
+from tg import tmpl_context as c, app_globals as g
+from tg import response, request
 from tg.decorators import before_validate
 from formencode.variabledecode import variable_decode
 import formencode
diff --git a/Allura/allura/lib/macro.py b/Allura/allura/lib/macro.py
index 191a413..3996826 100644
--- a/Allura/allura/lib/macro.py
+++ b/Allura/allura/lib/macro.py
@@ -26,8 +26,8 @@ from operator import attrgetter
 from urlparse import urlparse, urlunparse
 
 import pymongo
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
+from tg import tmpl_context as c, app_globals as g
+from tg import request
 from paste.deploy.converters import asint
 from BeautifulSoup import BeautifulSoup
 
diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py
index ae72f93..ea906bf 100644
--- a/Allura/allura/lib/mail_util.py
+++ b/Allura/allura/lib/mail_util.py
@@ -26,8 +26,8 @@ from email import header
 import tg
 from paste.deploy.converters import asbool, asint, aslist
 from formencode import validators as fev
-from pylons import tmpl_context as c
-from pylons import app_globals as g
+from tg import tmpl_context as c
+from tg import app_globals as g
 
 from allura.lib.utils import ConfigProxy
 from allura.lib import exceptions as exc
diff --git a/Allura/allura/lib/multifactor.py b/Allura/allura/lib/multifactor.py
index a617392..ec0249d 100644
--- a/Allura/allura/lib/multifactor.py
+++ b/Allura/allura/lib/multifactor.py
@@ -28,7 +28,7 @@ import errno
 import bson
 from allura.lib.exceptions import InvalidRecoveryCode, MultifactorRateLimitError
 from tg import config
-from pylons import app_globals as g
+from tg import app_globals as g
 from paste.deploy.converters import asint
 from cryptography.hazmat.backends import default_backend
 from cryptography.hazmat.primitives.twofactor import InvalidToken
diff --git a/Allura/allura/lib/patches.py b/Allura/allura/lib/patches.py
index 67ba105..8e0dcf8 100644
--- a/Allura/allura/lib/patches.py
+++ b/Allura/allura/lib/patches.py
@@ -20,7 +20,7 @@ import re
 import webob
 import tg.decorators
 from decorator import decorator
-from pylons import request
+from tg import request
 import mock
 import simplejson
 
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 921d989..f64c8ca 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -42,7 +42,7 @@ except ImportError:
 import pkg_resources
 import tg
 from tg import config, request, redirect, response
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from webob import exc, Request
 from paste.deploy.converters import asbool, asint
 
@@ -1376,7 +1376,7 @@ class ThemeProvider(object):
         return note, set_cookie
 
     def get_site_notification(self):
-        from pylons import request, response
+        from tg import request, response
         tool_name = c.app.config.tool_name if c.app else ''
         r = self._get_site_notification(
             request.path_qs,
diff --git a/Allura/allura/lib/repository.py b/Allura/allura/lib/repository.py
index 82d09c4..6250026 100644
--- a/Allura/allura/lib/repository.py
+++ b/Allura/allura/lib/repository.py
@@ -18,8 +18,8 @@
 import logging
 from urllib import quote
 
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
+from tg import tmpl_context as c, app_globals as g
+from tg import request
 from tg import expose, redirect, flash, validate, config
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from webob import exc
diff --git a/Allura/allura/lib/search.py b/Allura/allura/lib/search.py
index 53669eb..370cef6 100644
--- a/Allura/allura/lib/search.py
+++ b/Allura/allura/lib/search.py
@@ -25,8 +25,8 @@ import bson
 import markdown
 import jinja2
 from tg import redirect, url
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
+from tg import tmpl_context as c, app_globals as g
+from tg import request
 from pysolr import SolrError
 
 from allura.lib import helpers as h
diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index 41691f4..544bc76 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -21,8 +21,8 @@ This module provides the security predicates used in decorating various models.
 import logging
 from collections import defaultdict
 
-from pylons import tmpl_context as c
-from pylons import request
+from tg import tmpl_context as c
+from tg import request
 from webob import exc
 from itertools import chain
 from ming.utils import LazyProperty
diff --git a/Allura/allura/lib/spam/akismetfilter.py b/Allura/allura/lib/spam/akismetfilter.py
index 26cccbd..2ea4c13 100644
--- a/Allura/allura/lib/spam/akismetfilter.py
+++ b/Allura/allura/lib/spam/akismetfilter.py
@@ -17,8 +17,8 @@
 
 import logging
 
-from pylons import request
-from pylons import tmpl_context as c
+from tg import request
+from tg import tmpl_context as c
 
 from allura.lib import helpers as h
 from allura.lib import utils
diff --git a/Allura/allura/lib/spam/mollomfilter.py b/Allura/allura/lib/spam/mollomfilter.py
index f2d6b68..ddd2e86 100644
--- a/Allura/allura/lib/spam/mollomfilter.py
+++ b/Allura/allura/lib/spam/mollomfilter.py
@@ -17,8 +17,8 @@
 
 import logging
 
-from pylons import request
-from pylons import tmpl_context as c
+from tg import request
+from tg import tmpl_context as c
 
 from allura.lib import helpers as h
 from allura.lib import utils
diff --git a/Allura/allura/lib/spam/stopforumspamfilter.py b/Allura/allura/lib/spam/stopforumspamfilter.py
index 0e263be..4e7a497 100644
--- a/Allura/allura/lib/spam/stopforumspamfilter.py
+++ b/Allura/allura/lib/spam/stopforumspamfilter.py
@@ -20,7 +20,7 @@ import csv
 from sys import getsizeof
 
 import ipaddress
-from pylons import request
+from tg import request
 
 from allura.lib import utils
 from allura.lib.spam import SpamFilter
diff --git a/Allura/allura/lib/stats.py b/Allura/allura/lib/stats.py
index 9864e30..d5244b1 100644
--- a/Allura/allura/lib/stats.py
+++ b/Allura/allura/lib/stats.py
@@ -18,7 +18,7 @@
 from __future__ import with_statement
 from time import time
 from contextlib import contextmanager
-from pylons import request
+from tg import request
 
 
 class StatsRecord(object):
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index 7198386..971d53c 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -34,7 +34,6 @@ from urlparse import urlparse
 
 import tg
 import emoji
-import pylons
 import json
 from formencode import Invalid
 from collections import OrderedDict
@@ -248,7 +247,7 @@ class AntiSpam(object):
     def __init__(self, request=None, num_honey=2, timestamp=None, spinner=None):
         self.num_honey = num_honey
         if request is None or request.method == 'GET':
-            self.request = pylons.request
+            self.request = tg.request
             self.timestamp = timestamp if timestamp else int(time.time())
             self.spinner = spinner if spinner else self.make_spinner()
             self.timestamp_text = str(self.timestamp)
@@ -348,13 +347,13 @@ class AntiSpam(object):
         octets = self.client_ip.split('.')
         ip_chunk = '.'.join(octets[0:3])
         plain = '%d:%s:%s' % (
-            timestamp, ip_chunk, pylons.config.get('spinner_secret', 'abcdef'))
+            timestamp, ip_chunk, tg.config.get('spinner_secret', 'abcdef'))
         return hashlib.sha1(plain).digest()
 
     @classmethod
     def validate_request(cls, request=None, now=None, params=None):
         if request is None:
-            request = pylons.request
+            request = tg.request
         if params is None:
             params = request.params
         new_params = dict(params)
@@ -369,7 +368,7 @@ class AntiSpam(object):
                     now = time.time()
                 if obj.timestamp > now + 5:
                     raise ValueError('Post from the future')
-                if now - obj.timestamp > int(pylons.config.get('spam.form_post_expiration', 24 * 60 * 60)):
+                if now - obj.timestamp > int(tg.config.get('spam.form_post_expiration', 24 * 60 * 60)):
                     raise ValueError('Post from the distant past')
                 if obj.spinner != expected_spinner:
                     raise ValueError('Bad spinner value')
@@ -403,7 +402,7 @@ class AntiSpam(object):
                     # request.params is immutable, but will reflect changes to request.POST
                     tg.request.POST.update(new_params)
             except (ValueError, TypeError, binascii.Error):
-                testing = pylons.request.environ.get('paste.testing', False)
+                testing = tg.request.environ.get('paste.testing', False)
                 if testing:
                     # re-raise so we can see problems more easily
                     raise
@@ -545,19 +544,19 @@ def serve_file(fp, filename, content_type, last_modified=None,
         etag = u'{0}?{1}'.format(filename, last_modified).encode('utf-8')
     if etag:
         etag_cache(etag)
-    pylons.response.headers['Content-Type'] = ''
-    pylons.response.content_type = content_type.encode('utf-8')
-    pylons.response.cache_expires = cache_expires or asint(
+    tg.response.headers['Content-Type'] = ''
+    tg.response.content_type = content_type.encode('utf-8')
+    tg.response.cache_expires = cache_expires or asint(
         tg.config.get('files_expires_header_secs', 60 * 60))
-    pylons.response.last_modified = last_modified
+    tg.response.last_modified = last_modified
     if size:
-        pylons.response.content_length = size
-    if 'Pragma' in pylons.response.headers:
-        del pylons.response.headers['Pragma']
-    if 'Cache-Control' in pylons.response.headers:
-        del pylons.response.headers['Cache-Control']
+        tg.response.content_length = size
+    if 'Pragma' in tg.response.headers:
+        del tg.response.headers['Pragma']
+    if 'Cache-Control' in tg.response.headers:
+        del tg.response.headers['Cache-Control']
     if not embed:
-        pylons.response.headers.add(
+        tg.response.headers.add(
             'Content-Disposition',
             'attachment;filename="%s"' % filename.encode('utf-8'))
     # http://code.google.com/p/modwsgi/wiki/FileWrapperExtension
diff --git a/Allura/allura/lib/validators.py b/Allura/allura/lib/validators.py
index 1a38905..d78947f 100644
--- a/Allura/allura/lib/validators.py
+++ b/Allura/allura/lib/validators.py
@@ -20,7 +20,7 @@ import re
 from bson import ObjectId
 import formencode as fe
 from formencode import validators as fev
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from . import helpers as h
 from datetime import datetime
 
diff --git a/Allura/allura/lib/widgets/auth_widgets.py b/Allura/allura/lib/widgets/auth_widgets.py
index b7772ab..3233015 100644
--- a/Allura/allura/lib/widgets/auth_widgets.py
+++ b/Allura/allura/lib/widgets/auth_widgets.py
@@ -19,12 +19,12 @@ import ew as ew_core
 import ew.jinja2_ew as ew
 from ew.core import validator
 
-from pylons import request, tmpl_context as c
+from tg import request, tmpl_context as c
 from formencode import Invalid
 from webob import exc
 
 from .forms import ForgeForm
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from allura.lib import plugin
 from allura import model as M
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index e07e73c..6918196 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -20,7 +20,7 @@ from formencode import validators as fev
 import json
 import ew as ew_core
 import ew.jinja2_ew as ew
-from pylons import app_globals as g
+from tg import app_globals as g
 from  tg import config
 
 from allura.lib import utils
diff --git a/Allura/allura/lib/widgets/form_fields.py b/Allura/allura/lib/widgets/form_fields.py
index 900e46e..68badf6 100644
--- a/Allura/allura/lib/widgets/form_fields.py
+++ b/Allura/allura/lib/widgets/form_fields.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from tg import request, url
 import json
 import logging
diff --git a/Allura/allura/lib/widgets/forms.py b/Allura/allura/lib/widgets/forms.py
index ac49ce3..7820157 100644
--- a/Allura/allura/lib/widgets/forms.py
+++ b/Allura/allura/lib/widgets/forms.py
@@ -18,7 +18,7 @@
 import logging
 import warnings
 
-from pylons import app_globals as g, tmpl_context as c
+from tg import app_globals as g, tmpl_context as c
 from formencode import validators as fev
 import formencode
 import ew as ew_core
diff --git a/Allura/allura/lib/widgets/project_list.py b/Allura/allura/lib/widgets/project_list.py
index 9c60781..1d511b5 100644
--- a/Allura/allura/lib/widgets/project_list.py
+++ b/Allura/allura/lib/widgets/project_list.py
@@ -18,7 +18,7 @@
 import ew as ew_core
 import ew.jinja2_ew as ew
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from paste.deploy.converters import asbool
 
 from allura import model as M
diff --git a/Allura/allura/lib/widgets/subscriptions.py b/Allura/allura/lib/widgets/subscriptions.py
index 142463d..83d3037 100644
--- a/Allura/allura/lib/widgets/subscriptions.py
+++ b/Allura/allura/lib/widgets/subscriptions.py
@@ -17,7 +17,7 @@
 
 import ew as ew_core
 import ew.jinja2_ew as ew
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.lib import validators as V
 from allura.lib.widgets import form_fields as ffw
diff --git a/Allura/allura/lib/widgets/user_profile.py b/Allura/allura/lib/widgets/user_profile.py
index c37cde9..3c51f94 100644
--- a/Allura/allura/lib/widgets/user_profile.py
+++ b/Allura/allura/lib/widgets/user_profile.py
@@ -24,9 +24,9 @@ from jinja2 import Markup
 from paste.deploy.converters import asbool
 import tg
 from formencode import validators as fev
-from pylons import app_globals as g
-from pylons import request
-from pylons import tmpl_context as c
+from tg import app_globals as g
+from tg import request
+from tg import tmpl_context as c
 from allura.lib import helpers as h
 from allura.lib.plugin import AuthenticationProvider
 from .forms import ForgeForm
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index bf0716c..4df6cd3 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -20,8 +20,8 @@ from collections import defaultdict
 from datetime import datetime
 
 import pymongo
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
+from tg import tmpl_context as c, app_globals as g
+from tg import request
 from ming import schema as S
 from ming.orm import state, session
 from ming.orm import FieldProperty, ForeignIdProperty, RelationProperty
diff --git a/Allura/allura/model/attachments.py b/Allura/allura/model/attachments.py
index 568f5b0..fa67134 100644
--- a/Allura/allura/model/attachments.py
+++ b/Allura/allura/model/attachments.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import FieldProperty
 from ming import schema as S
 
@@ -49,7 +49,7 @@ class BaseAttachment(File):
         return self.artifact.url() + 'attachment/' + h.urlquote(self.filename)
 
     def is_embedded(self):
-        from pylons import request
+        from tg import request
         return self.filename in request.environ.get('allura.macro.att_embedded', [])
 
     @classmethod
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index 8ebef71..6a2f999 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -28,8 +28,8 @@ import re
 from pytz import timezone
 import pymongo
 from tg import config
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
+from tg import tmpl_context as c, app_globals as g
+from tg import request
 from ming import schema as S
 from ming import Field, collection
 from ming.orm import session, state
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index c6cbc58..973d196 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -22,7 +22,7 @@ from datetime import datetime
 import jinja2
 import pymongo
 from pymongo.errors import DuplicateKeyError
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 import tg
 
 from ming import schema
diff --git a/Allura/allura/model/index.py b/Allura/allura/model/index.py
index 61a036a..300b9ba 100644
--- a/Allura/allura/model/index.py
+++ b/Allura/allura/model/index.py
@@ -24,7 +24,7 @@ from urllib import unquote
 
 import bson
 import pymongo
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from ming import collection, Field, Index
 from ming import schema as S
diff --git a/Allura/allura/model/monq_model.py b/Allura/allura/model/monq_model.py
index 7f25a4f..b28ca12 100644
--- a/Allura/allura/model/monq_model.py
+++ b/Allura/allura/model/monq_model.py
@@ -22,7 +22,7 @@ import logging
 from datetime import datetime, timedelta
 
 import pymongo
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from tg import config
 from paste.deploy.converters import asbool
 
diff --git a/Allura/allura/model/neighborhood.py b/Allura/allura/model/neighborhood.py
index 59b9075..789f5ea 100644
--- a/Allura/allura/model/neighborhood.py
+++ b/Allura/allura/model/neighborhood.py
@@ -25,8 +25,8 @@ from ming.orm import FieldProperty, RelationProperty
 from ming.orm.declarative import MappedClass
 from ming.utils import LazyProperty
 
-from pylons import request
-from pylons import tmpl_context as c, app_globals as g
+from tg import request
+from tg import tmpl_context as c, app_globals as g
 
 from allura.lib import plugin
 
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index c4e2c24..080ef05 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -39,7 +39,7 @@ from bson import ObjectId
 from datetime import datetime, timedelta
 from collections import defaultdict
 
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from tg import config
 import pymongo
 import jinja2
diff --git a/Allura/allura/model/oauth.py b/Allura/allura/model/oauth.py
index d467dc1..9d93d37 100644
--- a/Allura/allura/model/oauth.py
+++ b/Allura/allura/model/oauth.py
@@ -18,7 +18,7 @@
 import logging
 
 import oauth2 as oauth
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from paste.deploy.converters import aslist
 from tg import config
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 106f776..d4edf27 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -26,8 +26,8 @@ import re
 from xml.etree import ElementTree as ET
 
 from tg import config
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
+from tg import tmpl_context as c, app_globals as g
+from tg import request
 from paste.deploy.converters import asbool, aslist
 import formencode as fe
 from webob import exc
diff --git a/Allura/allura/model/repo_refresh.py b/Allura/allura/model/repo_refresh.py
index b6677b6..9712164 100644
--- a/Allura/allura/model/repo_refresh.py
+++ b/Allura/allura/model/repo_refresh.py
@@ -25,7 +25,7 @@ import bson
 import tg
 import jinja2
 from paste.deploy.converters import asint
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from ming.base import Object
 from ming.orm import mapper, session, ThreadLocalORMSession
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index dc97527..b4b6fa3 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -34,8 +34,8 @@ from difflib import SequenceMatcher
 
 import tg
 from paste.deploy.converters import asint, asbool
-from pylons import tmpl_context as c
-from pylons import app_globals as g
+from tg import tmpl_context as c
+from tg import app_globals as g
 import pymongo
 import pymongo.errors
 import bson
diff --git a/Allura/allura/model/session.py b/Allura/allura/model/session.py
index 3399456..2ab5961 100644
--- a/Allura/allura/model/session.py
+++ b/Allura/allura/model/session.py
@@ -115,7 +115,7 @@ class ArtifactSessionExtension(ManagedSessionExtension):
     def after_flush(self, obj=None):
         "Update artifact references, and add/update this artifact to solr"
         if not getattr(self.session, 'disable_index', False):
-            from pylons import app_globals as g
+            from tg import app_globals as g
             from .index import ArtifactReference, Shortlink
             from .session import main_orm_session
             # Ensure artifact references & shortlinks exist for new objects
diff --git a/Allura/allura/model/timeline.py b/Allura/allura/model/timeline.py
index 66ecdaf..ee50462 100644
--- a/Allura/allura/model/timeline.py
+++ b/Allura/allura/model/timeline.py
@@ -19,7 +19,7 @@ import bson
 import logging
 
 from ming.odm import Mapper
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from activitystream import ActivityDirector
 from activitystream.base import NodeBase, ActivityObjectBase
diff --git a/Allura/allura/scripts/create_deleted_comments.py b/Allura/allura/scripts/create_deleted_comments.py
index 509752c..7b3c455 100644
--- a/Allura/allura/scripts/create_deleted_comments.py
+++ b/Allura/allura/scripts/create_deleted_comments.py
@@ -20,7 +20,7 @@ import argparse
 import logging
 
 from ming.odm import session
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.scripts import ScriptTask
 from allura import model as M
diff --git a/Allura/allura/scripts/create_sitemap_files.py b/Allura/allura/scripts/create_sitemap_files.py
index 5bd3bb6..40e4642 100644
--- a/Allura/allura/scripts/create_sitemap_files.py
+++ b/Allura/allura/scripts/create_sitemap_files.py
@@ -33,9 +33,9 @@ from datetime import datetime
 import argparse
 
 from jinja2 import Template
-import pylons
+import tg
 import webob
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import ThreadLocalORMSession
 from tg import config
 
@@ -78,11 +78,11 @@ class CreateSitemapFiles(ScriptTask):
     def execute(cls, options):
         # This script will indirectly call app.sidebar_menu() for every app in
         # every project. Some of the sidebar_menu methods expect the
-        # pylons.request threadlocal object to be present. So, we're faking it.
+        # tg.request threadlocal object to be present. So, we're faking it.
         #
         # The fact that this isn't a 'real' request doesn't matter for the
         # purposes of the sitemap.
-        pylons.request._push_object(webob.Request.blank('/'))
+        tg.request_local.context.request = webob.Request.blank('/')
 
         output_path = options.output_dir
         if os.path.exists(output_path):
diff --git a/Allura/allura/scripts/refresh_last_commits.py b/Allura/allura/scripts/refresh_last_commits.py
index 0dd7235..49b2772 100644
--- a/Allura/allura/scripts/refresh_last_commits.py
+++ b/Allura/allura/scripts/refresh_last_commits.py
@@ -21,7 +21,7 @@ from datetime import datetime
 from contextlib import contextmanager
 
 import faulthandler
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import ThreadLocalORMSession, session
 
 from allura import model as M
diff --git a/Allura/allura/scripts/refreshrepo.py b/Allura/allura/scripts/refreshrepo.py
index 9050400..8556f87 100644
--- a/Allura/allura/scripts/refreshrepo.py
+++ b/Allura/allura/scripts/refreshrepo.py
@@ -21,7 +21,7 @@ import faulthandler
 from datetime import datetime
 
 from paste.util.converters import asbool
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import ThreadLocalORMSession
 
 from allura import model as M
diff --git a/Allura/allura/scripts/reindex_projects.py b/Allura/allura/scripts/reindex_projects.py
index 0f8f3be..37ff222 100644
--- a/Allura/allura/scripts/reindex_projects.py
+++ b/Allura/allura/scripts/reindex_projects.py
@@ -19,7 +19,7 @@ import argparse
 import logging
 
 from pymongo.errors import InvalidDocument
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from allura.scripts import ScriptTask
 from allura import model as M
diff --git a/Allura/allura/tasks/activity_tasks.py b/Allura/allura/tasks/activity_tasks.py
index 312d9ec..f6bf8b6 100644
--- a/Allura/allura/tasks/activity_tasks.py
+++ b/Allura/allura/tasks/activity_tasks.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import app_globals as g
+from tg import app_globals as g
 from activitystream.storage.mingstorage import Activity
 
 from allura.lib.decorators import task
diff --git a/Allura/allura/tasks/admin_tasks.py b/Allura/allura/tasks/admin_tasks.py
index 65f2775..7a71444 100644
--- a/Allura/allura/tasks/admin_tasks.py
+++ b/Allura/allura/tasks/admin_tasks.py
@@ -17,7 +17,7 @@
 
 import inspect
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura import model as M
 from allura.lib.decorators import task
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index d63c40f..49771ae 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -21,7 +21,7 @@ import logging
 import shutil
 
 import tg
-from pylons import app_globals as g, tmpl_context as c
+from tg import app_globals as g, tmpl_context as c
 
 from allura.tasks import mail_tasks
 from allura.lib.decorators import task
diff --git a/Allura/allura/tasks/index_tasks.py b/Allura/allura/tasks/index_tasks.py
index 792eeab..631ec14 100644
--- a/Allura/allura/tasks/index_tasks.py
+++ b/Allura/allura/tasks/index_tasks.py
@@ -19,8 +19,8 @@ import sys
 import logging
 from contextlib import contextmanager
 
-from pylons import app_globals as g
-from pylons import tmpl_context as c
+from tg import app_globals as g
+from tg import tmpl_context as c
 
 from allura.lib import helpers as h
 from allura.lib.decorators import task
diff --git a/Allura/allura/tasks/mail_tasks.py b/Allura/allura/tasks/mail_tasks.py
index 938f358..d60533f 100644
--- a/Allura/allura/tasks/mail_tasks.py
+++ b/Allura/allura/tasks/mail_tasks.py
@@ -19,7 +19,7 @@ import logging
 import HTMLParser
 import re
 
-from pylons import tmpl_context as c, app_globals as g, config
+from tg import tmpl_context as c, app_globals as g, config
 from bson import ObjectId
 import markupsafe
 
diff --git a/Allura/allura/tasks/repo_tasks.py b/Allura/allura/tasks/repo_tasks.py
index 41a1ba7..c84977f 100644
--- a/Allura/allura/tasks/repo_tasks.py
+++ b/Allura/allura/tasks/repo_tasks.py
@@ -19,7 +19,7 @@ import shutil
 import logging
 import traceback
 
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from ming.odm import session
 
 from allura.lib.decorators import task
diff --git a/Allura/allura/tests/decorators.py b/Allura/allura/tests/decorators.py
index d54a6c2..7c42206 100644
--- a/Allura/allura/tests/decorators.py
+++ b/Allura/allura/tests/decorators.py
@@ -21,7 +21,7 @@ from functools import wraps
 import contextlib
 
 from ming.orm.ormsession import ThreadLocalORMSession
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from mock import patch
 import tg
 from paste.deploy.converters import asbool
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 6f2bd96..3b8d90a 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -27,7 +27,7 @@ import PIL
 from nose.tools import assert_equals, assert_in, assert_not_in, assert_is_not_none, assert_greater
 from ming.orm.ormsession import ThreadLocalORMSession
 from tg import expose
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 import mock
 
 from allura.tests import TestController
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index b0ddf5e..02c7823 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -42,7 +42,7 @@ from nose.tools import (
     assert_false,
     assert_raises
 )
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from webob import exc
 
 from allura.tests import TestController
diff --git a/Allura/allura/tests/functional/test_home.py b/Allura/allura/tests/functional/test_home.py
index 0dee4c7..cc7ccc2 100644
--- a/Allura/allura/tests/functional/test_home.py
+++ b/Allura/allura/tests/functional/test_home.py
@@ -19,7 +19,7 @@ import json
 import re
 import os
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from nose.tools import assert_equal, assert_not_in, assert_in
 from ming.orm import ThreadLocalORMSession
 
diff --git a/Allura/allura/tests/functional/test_nav.py b/Allura/allura/tests/functional/test_nav.py
index 0945d09..8fb2f78 100644
--- a/Allura/allura/tests/functional/test_nav.py
+++ b/Allura/allura/tests/functional/test_nav.py
@@ -18,7 +18,7 @@
 import mock
 import json
 from tg import config
-from pylons import app_globals as g
+from tg import app_globals as g
 
 from allura.tests import TestController
 from allura.lib import helpers as h
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index 55a492c..dd22da4 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -27,7 +27,7 @@ from tg import config
 from nose.tools import assert_equal, assert_in, assert_not_equal
 from ming.orm.ormsession import ThreadLocalORMSession, session
 from paste.httpexceptions import HTTPFound
-from pylons import app_globals as g, tmpl_context as c
+from tg import app_globals as g, tmpl_context as c
 
 import allura
 from allura import model as M
@@ -908,7 +908,7 @@ class TestNeighborhood(TestController):
                       extra_environ=dict(username='root'))
 
     def test_add_a_project_link(self):
-        from pylons import tmpl_context as c
+        from tg import tmpl_context as c
         # Install Home tool for all neighborhoods
         for nb in M.Neighborhood.query.find().all():
             p = nb.neighborhood_project
diff --git a/Allura/allura/tests/functional/test_personal_dashboard.py b/Allura/allura/tests/functional/test_personal_dashboard.py
index 5e397fc..dc2685e 100644
--- a/Allura/allura/tests/functional/test_personal_dashboard.py
+++ b/Allura/allura/tests/functional/test_personal_dashboard.py
@@ -21,7 +21,7 @@ import tg
 
 from ming.orm import ThreadLocalORMSession, ThreadLocalODMSession
 from nose.tools import assert_equal, assert_in, assert_not_in
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura import model as M
 from allura.lib import helpers as h
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 306cdbc..8d12950 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -17,7 +17,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import app_globals as g
+from tg import app_globals as g
 import mock
 from nose.tools import assert_equal, assert_in, assert_not_in
 from ming.odm import ThreadLocalODMSession
diff --git a/Allura/allura/tests/functional/test_root.py b/Allura/allura/tests/functional/test_root.py
index be81292..dfb11f7 100644
--- a/Allura/allura/tests/functional/test_root.py
+++ b/Allura/allura/tests/functional/test_root.py
@@ -28,7 +28,7 @@ functional tests exercise the whole application and its WSGI stack.
 Please read http://pythonpaste.org/webtest/ for more information.
 
 """
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from nose.tools import assert_equal
 from ming.orm.ormsession import ThreadLocalORMSession
 import mock
diff --git a/Allura/allura/tests/functional/test_site_admin.py b/Allura/allura/tests/functional/test_site_admin.py
index c46e2b1..cb61e58 100644
--- a/Allura/allura/tests/functional/test_site_admin.py
+++ b/Allura/allura/tests/functional/test_site_admin.py
@@ -23,7 +23,7 @@ import bson
 from mock import patch, MagicMock
 from nose.tools import assert_equal, assert_in, assert_not_in
 from ming.odm import ThreadLocalORMSession
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from tg import config
 from bson import ObjectId
 
diff --git a/Allura/allura/tests/model/test_artifact.py b/Allura/allura/tests/model/test_artifact.py
index 017d0d3..1e63813 100644
--- a/Allura/allura/tests/model/test_artifact.py
+++ b/Allura/allura/tests/model/test_artifact.py
@@ -23,7 +23,7 @@ Model tests for artifact
 import re
 from datetime import datetime
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from nose.tools import assert_raises, assert_equal
 from nose import with_setup
 from mock import patch
diff --git a/Allura/allura/tests/model/test_auth.py b/Allura/allura/tests/model/test_auth.py
index 5d1841b..79234e2 100644
--- a/Allura/allura/tests/model/test_auth.py
+++ b/Allura/allura/tests/model/test_auth.py
@@ -29,7 +29,7 @@ from nose.tools import (
     assert_not_in,
     assert_in,
 )
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from webob import Request
 from mock import patch, Mock
 from datetime import datetime, timedelta
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 0258f38..d470c87 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -25,7 +25,7 @@ import time
 from datetime import datetime, timedelta
 from cgi import FieldStorage
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from nose.tools import assert_equals, with_setup
 import mock
 from mock import patch
diff --git a/Allura/allura/tests/model/test_filesystem.py b/Allura/allura/tests/model/test_filesystem.py
index 1f4c1da..30ab9e9 100644
--- a/Allura/allura/tests/model/test_filesystem.py
+++ b/Allura/allura/tests/model/test_filesystem.py
@@ -22,7 +22,7 @@ from unittest import TestCase
 from cStringIO import StringIO
 from io import BytesIO
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import session, Mapper
 from nose.tools import assert_equal
 from mock import patch
@@ -126,7 +126,7 @@ class TestFile(TestCase):
         f = File.from_data(u'te s\u0b6e1.txt', 'test1')
         self.session.flush()
         with patch('allura.lib.utils.tg.request', Request.blank('/')), \
-                patch('allura.lib.utils.pylons.response', Response()) as response, \
+                patch('allura.lib.utils.tg.response', Response()) as response, \
                 patch('allura.lib.utils.etag_cache') as etag_cache:
             response_body = list(f.serve())
             etag_cache.assert_called_once_with(u'{}?{}'.format(f.filename,
@@ -139,7 +139,7 @@ class TestFile(TestCase):
         f = File.from_data(u'te s\u0b6e1.txt', 'test1')
         self.session.flush()
         with patch('allura.lib.utils.tg.request', Request.blank('/')), \
-                patch('allura.lib.utils.pylons.response', Response()) as response, \
+                patch('allura.lib.utils.tg.response', Response()) as response, \
                 patch('allura.lib.utils.etag_cache') as etag_cache:
             response_body = list(f.serve(embed=False))
             etag_cache.assert_called_once_with(u'{}?{}'.format(f.filename,
diff --git a/Allura/allura/tests/model/test_notification.py b/Allura/allura/tests/model/test_notification.py
index f4ba56e..91f88d4 100644
--- a/Allura/allura/tests/model/test_notification.py
+++ b/Allura/allura/tests/model/test_notification.py
@@ -19,7 +19,7 @@ import unittest
 from datetime import timedelta
 import collections
 
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from nose.tools import assert_equal, assert_in
 from ming.orm import ThreadLocalORMSession
 import mock
diff --git a/Allura/allura/tests/model/test_project.py b/Allura/allura/tests/model/test_project.py
index 2fe3dc8..84eb0af 100644
--- a/Allura/allura/tests/model/test_project.py
+++ b/Allura/allura/tests/model/test_project.py
@@ -22,7 +22,7 @@ Model tests for project
 """
 from nose import with_setup
 from nose.tools import assert_equals, assert_in
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm.ormsession import ThreadLocalORMSession
 from formencode import validators as fev
 
diff --git a/Allura/allura/tests/model/test_repo.py b/Allura/allura/tests/model/test_repo.py
index 1020031..95263dc 100644
--- a/Allura/allura/tests/model/test_repo.py
+++ b/Allura/allura/tests/model/test_repo.py
@@ -21,7 +21,7 @@ from collections import defaultdict, OrderedDict
 import unittest
 import mock
 from nose.tools import assert_equal
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from bson import ObjectId
 from ming.orm import session
 from tg import config
diff --git a/Allura/allura/tests/scripts/test_create_sitemap_files.py b/Allura/allura/tests/scripts/test_create_sitemap_files.py
index df00e98..6f5f1b9 100644
--- a/Allura/allura/tests/scripts/test_create_sitemap_files.py
+++ b/Allura/allura/tests/scripts/test_create_sitemap_files.py
@@ -19,7 +19,7 @@ import os
 from shutil import rmtree
 import xml.etree.ElementTree as ET
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from nose.tools import assert_in
 from testfixtures import TempDirectory
 
diff --git a/Allura/allura/tests/scripts/test_delete_projects.py b/Allura/allura/tests/scripts/test_delete_projects.py
index d0f8620..c128f8c 100644
--- a/Allura/allura/tests/scripts/test_delete_projects.py
+++ b/Allura/allura/tests/scripts/test_delete_projects.py
@@ -17,7 +17,7 @@
 
 from ming.odm import session, Mapper, ThreadLocalODMSession
 from mock import patch
-from pylons import app_globals as g
+from tg import app_globals as g
 from nose.tools import assert_equal
 
 from alluratest.controller import TestController
@@ -100,8 +100,8 @@ class TestDeleteProjects(TestController):
         del_solr.post.assert_called_once_with(pid)
 
     @with_user_project('test-user')
-    @patch('allura.model.auth.request', autospec=True)
-    @patch('allura.lib.helpers.request', autospec=True)
+    @patch('allura.model.auth.request')
+    @patch('allura.lib.helpers.request')
     def test_userproject_does_disable(self, req, req2):
         req.remote_addr = None
         req.user_agent = 'MozFoo'
@@ -146,8 +146,8 @@ class TestDeleteProjects(TestController):
         assert admin.disabled is disable
         assert dev.disabled is disable
 
-    @patch('allura.model.auth.request', autospec=True)
-    @patch('allura.lib.helpers.request', autospec=True)
+    @patch('allura.model.auth.request')
+    @patch('allura.lib.helpers.request')
     def test_disable_users(self, req, req2):
         req.remote_addr = None
         req.user_agent = 'MozFoo'
diff --git a/Allura/allura/tests/templates/jinja_master/test_lib.py b/Allura/allura/tests/templates/jinja_master/test_lib.py
index 2fccafc..b818560 100644
--- a/Allura/allura/tests/templates/jinja_master/test_lib.py
+++ b/Allura/allura/tests/templates/jinja_master/test_lib.py
@@ -32,7 +32,7 @@ class TemplateTest(object):
         setup_config_test()
         forge_config = ForgeConfig()
         forge_config.setup_jinja_renderer()
-        self.jinja2_env = config['pylons.app_globals'].jinja2_env
+        self.jinja2_env = config['tg.app_globals'].jinja2_env
 
 
 class TestRelatedArtifacts(TemplateTest):
diff --git a/Allura/allura/tests/test_app.py b/Allura/allura/tests/test_app.py
index 926a71b..3ddbd04 100644
--- a/Allura/allura/tests/test_app.py
+++ b/Allura/allura/tests/test_app.py
@@ -17,7 +17,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 import mock
 from ming.base import Object
 from nose.tools import assert_equal, assert_raises
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 2b1cce2..b233479 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -28,7 +28,7 @@ from mock import patch, Mock
 
 from bson import ObjectId
 from nose.tools import with_setup, assert_equal, assert_in, assert_not_in
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 import tg
 
 from ming.orm import ThreadLocalORMSession
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index 65c44ac..bada67c 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -24,7 +24,7 @@ import time
 
 import PIL
 from mock import Mock, patch
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from nose.tools import eq_, assert_equals, assert_raises
 from IPython.testing.decorators import skipif, module_not_available
 from datadiff import tools as dd
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
index 20c6059..8ccf5d5 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -19,7 +19,7 @@ import datetime as dt
 import calendar
 
 import tg
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from webob import Request, exc
 from bson import ObjectId
 from ming.orm.ormsession import ThreadLocalORMSession
@@ -253,8 +253,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response')
-    @patch('pylons.request')
+    @patch('tg.response')
+    @patch('tg.request')
     def test_get_site_notification_no_note(self, request, response, SiteNotification):
         SiteNotification.current.return_value = None
         assert_is_none(ThemeProvider().get_site_notification())
@@ -262,8 +262,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response')
-    @patch('pylons.request')
+    @patch('tg.response')
+    @patch('tg.request')
     def test_get_site_notification_closed(self, request, response, SiteNotification):
         SiteNotification.current.return_value._id = 'deadbeef'
         SiteNotification.current.return_value.user_role = None
@@ -275,8 +275,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response')
-    @patch('pylons.request')
+    @patch('tg.response')
+    @patch('tg.request')
     def test_get_site_notification_impressions_over(self, request, response, SiteNotification):
         note = SiteNotification.current.return_value
         note._id = 'deadbeef'
@@ -290,8 +290,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response')
-    @patch('pylons.request')
+    @patch('tg.response')
+    @patch('tg.request')
     def test_get_site_notification_impressions_under(self, request, response, SiteNotification):
         note = SiteNotification.current.return_value
         note._id = 'deadbeef'
@@ -306,8 +306,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response')
-    @patch('pylons.request')
+    @patch('tg.response')
+    @patch('tg.request')
     def test_get_site_notification_impressions_persistent(self, request, response, SiteNotification):
         note = SiteNotification.current.return_value
         note._id = 'deadbeef'
@@ -320,8 +320,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response')
-    @patch('pylons.request')
+    @patch('tg.response')
+    @patch('tg.request')
     def test_get_site_notification_new_notification(self, request, response, SiteNotification):
         note = SiteNotification.current.return_value
         note._id = 'deadbeef'
@@ -336,8 +336,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response')
-    @patch('pylons.request')
+    @patch('tg.response')
+    @patch('tg.request')
     def test_get_site_notification_no_cookie(self, request, response, SiteNotification):
         note = SiteNotification.current.return_value
         note._id = 'deadbeef'
@@ -352,8 +352,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response')
-    @patch('pylons.request')
+    @patch('tg.response')
+    @patch('tg.request')
     def test_get_site_notification_bad_cookie(self, request, response, SiteNotification):
         note = SiteNotification.current.return_value
         note._id = 'deadbeef'
@@ -397,8 +397,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c')
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response', MagicMock())
-    @patch('pylons.request', MagicMock())
+    @patch('tg.response', MagicMock())
+    @patch('tg.request', MagicMock())
     def test_get_site_notification_with_role(self, SiteNotification, c):
         note = SiteNotification.current.return_value
         note.user_role = 'Test'
@@ -425,8 +425,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response', MagicMock())
-    @patch('pylons.request', MagicMock())
+    @patch('tg.response', MagicMock())
+    @patch('tg.request', MagicMock())
     def test_get_site_notification_without_role(self, SiteNotification):
         note = SiteNotification.current.return_value
         note.user_role = None
@@ -437,8 +437,8 @@ class TestThemeProvider(object):
     @patch('allura.lib.plugin.c', MagicMock())
     @patch('re.search')
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response', MagicMock())
-    @patch('pylons.request', MagicMock())
+    @patch('tg.response', MagicMock())
+    @patch('tg.request', MagicMock())
     def test_get_site_notification_with_page_regex(self, SiteNotification, search):
         note = SiteNotification.current.return_value
         note.user_role = None
@@ -453,8 +453,8 @@ class TestThemeProvider(object):
 
     @patch('allura.lib.plugin.c')
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response', MagicMock())
-    @patch('pylons.request', MagicMock())
+    @patch('tg.response', MagicMock())
+    @patch('tg.request', MagicMock())
     def test_get_site_notification_with_page_tool_type(self, SiteNotification, c):
         note = SiteNotification.current.return_value
         note.user_role = None
@@ -472,10 +472,9 @@ class TestThemeProvider(object):
         assert_is(ThemeProvider().get_site_notification(), None)
 
     @patch('allura.lib.plugin.c')
-    @patch('pylons.request')
+    @patch('tg.request')
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.response', MagicMock())
-    @patch('pylons.request', MagicMock())
+    @patch('tg.response', MagicMock())
     def test_get_site_notification_with_page_tool_type_page_regex(self, SiteNotification, request, c):
         note = SiteNotification.current.return_value
         note.user_role = None
@@ -518,7 +517,7 @@ class TestThemeProvider(object):
         assert get_note[1] == 'test_id-1-False'
 
     @patch('allura.model.notification.SiteNotification')
-    @patch('pylons.request')
+    @patch('tg.request')
     def test_get_site_notifications_with_api_cookie(self, request, SiteNotification):
         note = SiteNotification.current.return_value
         note._id = 'test_id'
diff --git a/Allura/allura/tests/test_security.py b/Allura/allura/tests/test_security.py
index 44b2831..940388c 100644
--- a/Allura/allura/tests/test_security.py
+++ b/Allura/allura/tests/test_security.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from nose.tools import assert_equal
 
 from ming.odm import ThreadLocalODMSession
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 2d27256..274a291 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -26,7 +26,7 @@ import logging
 
 import tg
 import mock
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from datadiff.tools import assert_equal
 from nose.tools import assert_in, assert_less
 from ming.orm import FieldProperty, Mapper
diff --git a/Allura/allura/tests/test_webhooks.py b/Allura/allura/tests/test_webhooks.py
index 5b8df07..3b5a004 100644
--- a/Allura/allura/tests/test_webhooks.py
+++ b/Allura/allura/tests/test_webhooks.py
@@ -30,7 +30,7 @@ from nose.tools import (
 from datadiff import tools as dd
 from formencode import Invalid
 from ming.odm import session
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from tg import config
 
 from allura import model as M
diff --git a/Allura/allura/tests/unit/patches.py b/Allura/allura/tests/unit/patches.py
index afd5758..eaa6404 100644
--- a/Allura/allura/tests/unit/patches.py
+++ b/Allura/allura/tests/unit/patches.py
@@ -16,7 +16,7 @@
 #       under the License.
 
 from mock import Mock, patch
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.tests.unit.factories import (
     create_project,
diff --git a/Allura/allura/tests/unit/test_helpers/test_set_context.py b/Allura/allura/tests/unit/test_helpers/test_set_context.py
index 8b56a0f..89e5977 100644
--- a/Allura/allura/tests/unit/test_helpers/test_set_context.py
+++ b/Allura/allura/tests/unit/test_helpers/test_set_context.py
@@ -16,7 +16,7 @@
 #       under the License.
 
 from nose.tools import assert_raises
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from bson import ObjectId
 
 from allura.lib.helpers import set_context
diff --git a/Allura/allura/tests/unit/test_post_model.py b/Allura/allura/tests/unit/test_post_model.py
index f972688..2f9a4d3 100644
--- a/Allura/allura/tests/unit/test_post_model.py
+++ b/Allura/allura/tests/unit/test_post_model.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.lib import helpers as h
 from allura import model as M
diff --git a/Allura/allura/tests/unit/test_repo.py b/Allura/allura/tests/unit/test_repo.py
index 33c10d3..786d413 100644
--- a/Allura/allura/tests/unit/test_repo.py
+++ b/Allura/allura/tests/unit/test_repo.py
@@ -21,7 +21,7 @@ from mock import patch, Mock, MagicMock, call
 from nose.tools import assert_equal
 from datadiff import tools as dd
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura import model as M
 from allura.controllers.repository import topo_sort
diff --git a/Allura/allura/webhooks.py b/Allura/allura/webhooks.py
index d902e71..57871e6 100644
--- a/Allura/allura/webhooks.py
+++ b/Allura/allura/webhooks.py
@@ -27,8 +27,8 @@ import requests
 from bson import ObjectId
 from tg import expose, validate, redirect, flash, config
 from tg.decorators import with_trailing_slash, without_trailing_slash
-from pylons import tmpl_context as c
-from pylons import response, request
+from tg import tmpl_context as c
+from tg import response, request
 from formencode import validators as fev, schema, Invalid
 from ming.odm import session
 from webob import exc
diff --git a/Allura/allura/websetup/bootstrap.py b/Allura/allura/websetup/bootstrap.py
index fbbc211..d282b5d 100644
--- a/Allura/allura/websetup/bootstrap.py
+++ b/Allura/allura/websetup/bootstrap.py
@@ -25,7 +25,7 @@ import shutil
 from textwrap import dedent
 
 import tg
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from paste.deploy.converters import asbool
 import ew
 
diff --git a/Allura/allura/websetup/schema.py b/Allura/allura/websetup/schema.py
index 88c57a4..86b0f39 100644
--- a/Allura/allura/websetup/schema.py
+++ b/Allura/allura/websetup/schema.py
@@ -22,10 +22,11 @@
 import logging
 
 import activitystream
+import tg
 from tg import config
-import pylons
 from paste.deploy.converters import asbool
-from paste.registry import Registry
+from tg.support.registry import Registry
+from tg.wsgiapp import RequestLocals
 
 from allura.lib import helpers as h
 
@@ -38,10 +39,15 @@ def setup_schema(command, conf, vars):
     import ming
     import allura
 
+    # turbogears has its own special magic wired up for its globals, can't use a regular Registry
+    tgl = RequestLocals()
+    tgl.tmpl_context = EmptyClass()
+    tgl.app_globals = config['tg.app_globals']
+    tg.request_local.context._push_object(tgl)
+
     REGISTRY.prepare()
-    REGISTRY.register(pylons.tmpl_context, EmptyClass())
-    REGISTRY.register(pylons.app_globals, config['pylons.app_globals'])
     REGISTRY.register(allura.credentials, allura.lib.security.Credentials())
+
     ming.configure(**conf)
     if asbool(conf.get('activitystream.recording.enabled', False)):
         activitystream.configure(**h.convert_bools(conf, prefix='activitystream.'))
diff --git a/Allura/docs/development/testing.rst b/Allura/docs/development/testing.rst
index bcff43f..69e9c97 100644
--- a/Allura/docs/development/testing.rst
+++ b/Allura/docs/development/testing.rst
@@ -60,7 +60,7 @@ fully-loaded wsgi app, you can do something like this:
 
 .. code-block:: python
 
-    from pylons import tmpl_context as c
+    from tg import tmpl_context as c
 
     from alluratest.controller import setup_unit_test
     from allura.lib import helpers a h
diff --git a/AlluraTest/alluratest/controller.py b/AlluraTest/alluratest/controller.py
index b28af46..4ce4e31 100644
--- a/AlluraTest/alluratest/controller.py
+++ b/AlluraTest/alluratest/controller.py
@@ -26,10 +26,10 @@ from formencode import variabledecode
 from paste.deploy import loadapp
 from paste.deploy.converters import asbool
 from paste.script.appinstall import SetupCommand
-from pylons import tmpl_context as c, app_globals as g
-from pylons import url, request, response, session
-import pylons
+from tg import tmpl_context as c, app_globals as g
+from tg import url, request, response, session
 import tg
+from tg.wsgiapp import RequestLocals
 from webob import Response, Request
 import ew
 from ming.orm import ThreadLocalORMSession
@@ -84,7 +84,7 @@ def setup_config_test(config_file=None, force=False):
     '''
     if not config_file:
         config_file = get_config_file()
-    already_loaded = pylons.config.get('pylons.app_globals')
+    already_loaded = tg.config.get('tg.app_globals')
     if not already_loaded or force:
         loadapp('config:' + config_file)
 setup_config_test.__test__ = False
@@ -132,12 +132,17 @@ def setup_unit_test():
     REGISTRY.prepare()
     REGISTRY.register(ew.widget_context,
                       ew.core.WidgetContext('http', ew.ResourceManager()))
-    REGISTRY.register(g, Globals())
-    REGISTRY.register(c, mock.Mock())
-    REGISTRY.register(url, lambda: None)
-    REGISTRY.register(request, Request.blank('/', remote_addr='127.0.0.1'))
-    REGISTRY.register(response, Response())
     REGISTRY.register(allura.credentials, allura.lib.security.Credentials())
+
+    # turbogears has its own special magic wired up for its globals, can't use a regular Registry
+    tgl = RequestLocals()
+    tgl.app_globals = Globals()
+    tgl.tmpl_context = mock.Mock()
+    tgl.url = lambda: None
+    tgl.request = Request.blank('/', remote_addr='127.0.0.1')
+    tgl.response = Response()
+    tg.request_local.context._push_object(tgl)
+
     c.model_cache = None
     ThreadLocalORMSession.close_all()
 setup_unit_test.__test__ = False  # sometimes __test__ above isn't sufficient
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index 0786db6..d66a9b2 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -22,8 +22,8 @@ from itertools import islice, ifilter
 
 from bson import ObjectId
 from ming.orm import session
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request, response
+from tg import tmpl_context as c, app_globals as g
+from tg import request, response
 from tg import expose, validate, config
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from paste.deploy.converters import asbool, asint
diff --git a/ForgeActivity/forgeactivity/tests/functional/test_root.py b/ForgeActivity/forgeactivity/tests/functional/test_root.py
index a2a812e..e41f7fc 100644
--- a/ForgeActivity/forgeactivity/tests/functional/test_root.py
+++ b/ForgeActivity/forgeactivity/tests/functional/test_root.py
@@ -22,7 +22,7 @@ from tg import config
 from bson import ObjectId
 import dateutil.parser
 from nose.tools import assert_equal
-from pylons import app_globals as g
+from tg import app_globals as g
 from activitystream.storage.mingstorage import Activity
 from ming.odm import ThreadLocalODMSession
 
diff --git a/ForgeActivity/forgeactivity/widgets/follow.py b/ForgeActivity/forgeactivity/widgets/follow.py
index 1aed295..97e2f97 100644
--- a/ForgeActivity/forgeactivity/widgets/follow.py
+++ b/ForgeActivity/forgeactivity/widgets/follow.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from formencode import validators as fev
 import ew as ew_core
 import ew.jinja2_ew as ew
diff --git a/ForgeBlog/forgeblog/command/rssfeeds.py b/ForgeBlog/forgeblog/command/rssfeeds.py
index 42b5edd..3cce7f3 100644
--- a/ForgeBlog/forgeblog/command/rssfeeds.py
+++ b/ForgeBlog/forgeblog/command/rssfeeds.py
@@ -25,7 +25,7 @@ import base
 from allura.command import base as allura_base
 
 from ming.orm import session
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura import model as M
 from forgeblog import model as BM
@@ -59,9 +59,9 @@ class RssFeedsCommand(base.BlogCommand):
         # activity, User.url() will be called. This method defers to an
         # AuthenticationProvider, which depends on a request being setup in
         # the current thread. So, we set one up here.
-        import pylons
+        import tg
         import webob
-        pylons.request._push_object(webob.Request.blank('/'))
+        tg.request_local.context.request = webob.Request.blank('/')
 
         self.basic_setup()
         self.process_feed = exceptionless(
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 407e435..1cf9099 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -24,9 +24,9 @@ import json
 import pymongo
 from tg import config, expose, validate, redirect, flash, jsonify
 from tg.decorators import with_trailing_slash, without_trailing_slash
-from pylons import tmpl_context as c
-from pylons import app_globals as g
-from pylons import request
+from tg import tmpl_context as c
+from tg import app_globals as g
+from tg import request
 from paste.deploy.converters import asbool
 import formencode
 from formencode import validators
diff --git a/ForgeBlog/forgeblog/model/blog.py b/ForgeBlog/forgeblog/model/blog.py
index 0cbd8df..5fafd43 100644
--- a/ForgeBlog/forgeblog/model/blog.py
+++ b/ForgeBlog/forgeblog/model/blog.py
@@ -21,7 +21,7 @@ import re
 from datetime import datetime
 from random import randint
 
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from tg import config as tg_config
 from pymongo.errors import DuplicateKeyError
 
diff --git a/ForgeBlog/forgeblog/tests/functional/test_feeds.py b/ForgeBlog/forgeblog/tests/functional/test_feeds.py
index d5f29e8..39a090c 100644
--- a/ForgeBlog/forgeblog/tests/functional/test_feeds.py
+++ b/ForgeBlog/forgeblog/tests/functional/test_feeds.py
@@ -20,7 +20,7 @@ import datetime
 
 from nose.tools import assert_in, assert_not_in
 from ming.orm.ormsession import ThreadLocalORMSession
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from alluratest.controller import TestController
 from allura import model as M
diff --git a/ForgeBlog/forgeblog/tests/test_app.py b/ForgeBlog/forgeblog/tests/test_app.py
index e043929..ac50f8b 100644
--- a/ForgeBlog/forgeblog/tests/test_app.py
+++ b/ForgeBlog/forgeblog/tests/test_app.py
@@ -22,7 +22,7 @@ import json
 import os
 
 from nose.tools import assert_equal
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from cStringIO import StringIO
 from ming.orm import ThreadLocalORMSession
 
diff --git a/ForgeBlog/forgeblog/tests/test_commands.py b/ForgeBlog/forgeblog/tests/test_commands.py
index 7f2d0f7..6fb32fe 100644
--- a/ForgeBlog/forgeblog/tests/test_commands.py
+++ b/ForgeBlog/forgeblog/tests/test_commands.py
@@ -16,7 +16,7 @@
 #       under the License.
 
 from datetime import datetime, timedelta
-from pylons import app_globals as g
+from tg import app_globals as g
 from datadiff.tools import assert_equal
 from IPython.testing.decorators import module_not_available, skipif
 import pkg_resources
diff --git a/ForgeBlog/forgeblog/tests/test_roles.py b/ForgeBlog/forgeblog/tests/test_roles.py
index e270bec..3fe6a64 100644
--- a/ForgeBlog/forgeblog/tests/test_roles.py
+++ b/ForgeBlog/forgeblog/tests/test_roles.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from alluratest.controller import setup_basic_test, setup_global_objects
 from allura import model as M
diff --git a/ForgeBlog/forgeblog/tests/unit/__init__.py b/ForgeBlog/forgeblog/tests/unit/__init__.py
index dbef2b5..565758a 100644
--- a/ForgeBlog/forgeblog/tests/unit/__init__.py
+++ b/ForgeBlog/forgeblog/tests/unit/__init__.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm.ormsession import ThreadLocalORMSession
 
 from allura.websetup import bootstrap
diff --git a/ForgeBlog/forgeblog/tests/unit/test_blog_post.py b/ForgeBlog/forgeblog/tests/unit/test_blog_post.py
index fadfcf0..b62447e 100644
--- a/ForgeBlog/forgeblog/tests/unit/test_blog_post.py
+++ b/ForgeBlog/forgeblog/tests/unit/test_blog_post.py
@@ -17,7 +17,7 @@
 
 from datetime import datetime
 from nose.tools import assert_equal, assert_true
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from forgeblog import model as M
 from forgeblog.tests.unit import BlogTestWithModel
diff --git a/ForgeChat/forgechat/main.py b/ForgeChat/forgechat/main.py
index 8e01426..981af26 100644
--- a/ForgeChat/forgechat/main.py
+++ b/ForgeChat/forgechat/main.py
@@ -24,7 +24,7 @@ from datetime import date, time, datetime, timedelta
 # Non-stdlib imports
 from tg import expose, validate, redirect, flash
 from tg.decorators import with_trailing_slash
-from pylons import tmpl_context as c, request
+from tg import tmpl_context as c, request
 from formencode import validators
 
 # Pyforge-specific imports
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index 338764d..8fc2d6b 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -23,7 +23,7 @@ from allura.lib.search import mapped_artifacts_from_index_ids
 
 from tg import expose, validate, redirect
 from tg import request
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from webob import exc
 from formencode import validators
 
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index 7ba008c..0a12864 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -25,8 +25,8 @@ from collections import OrderedDict
 
 from tg import expose, validate, redirect, flash
 from tg.decorators import with_trailing_slash, without_trailing_slash
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
+from tg import tmpl_context as c, app_globals as g
+from tg import request
 from formencode import validators
 from webob import exc
 import pymongo
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index 7e957a3..311886f 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -22,8 +22,8 @@ import json
 import os
 
 # Non-stdlib imports
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
+from tg import tmpl_context as c, app_globals as g
+from tg import request
 from tg import expose, redirect, flash, validate, jsonify
 from tg.decorators import with_trailing_slash
 from bson import ObjectId
diff --git a/ForgeDiscussion/forgediscussion/import_support.py b/ForgeDiscussion/forgediscussion/import_support.py
index 5318ec5..a5a3cc0 100644
--- a/ForgeDiscussion/forgediscussion/import_support.py
+++ b/ForgeDiscussion/forgediscussion/import_support.py
@@ -22,7 +22,7 @@ from datetime import datetime
 from ming import schema as S
 from ming.orm import ThreadLocalORMSession, session
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura import model as M
 
diff --git a/ForgeDiscussion/forgediscussion/model/forum.py b/ForgeDiscussion/forgediscussion/model/forum.py
index 481fe92..5bc91f4 100644
--- a/ForgeDiscussion/forgediscussion/model/forum.py
+++ b/ForgeDiscussion/forgediscussion/model/forum.py
@@ -20,7 +20,7 @@ import logging
 from itertools import chain
 
 import pymongo
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming import schema
 from ming.utils import LazyProperty
 from ming.orm import FieldProperty, RelationProperty, ForeignIdProperty, Mapper
diff --git a/ForgeDiscussion/forgediscussion/tasks.py b/ForgeDiscussion/forgediscussion/tasks.py
index 9566818..cfd5320 100644
--- a/ForgeDiscussion/forgediscussion/tasks.py
+++ b/ForgeDiscussion/forgediscussion/tasks.py
@@ -17,7 +17,7 @@
 
 import logging
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from allura.lib.decorators import task
 
 log = logging.getLogger(__name__)
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index 421f49a..44cc42f 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -29,7 +29,7 @@ import pymongo
 import webtest
 
 from ming.odm import ThreadLocalORMSession
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from tg import config
 
 from nose.tools import assert_equal, assert_in, assert_not_in, assert_true, assert_false, assert_raises
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_import.py b/ForgeDiscussion/forgediscussion/tests/functional/test_import.py
index 38290e8..879b21c 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_import.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_import.py
@@ -22,7 +22,7 @@ from nose.tools import assert_equal
 
 import ming
 from tg import config
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura import model as M
 from allura.lib import helpers as h
diff --git a/ForgeDiscussion/forgediscussion/tests/test_app.py b/ForgeDiscussion/forgediscussion/tests/test_app.py
index 90f83bf..4e23cfa 100644
--- a/ForgeDiscussion/forgediscussion/tests/test_app.py
+++ b/ForgeDiscussion/forgediscussion/tests/test_app.py
@@ -25,7 +25,7 @@ import os
 from operator import attrgetter
 
 from nose.tools import assert_equal
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from cStringIO import StringIO
 from ming.orm import ThreadLocalORMSession
 from cgi import FieldStorage
diff --git a/ForgeDiscussion/forgediscussion/tests/test_forum_roles.py b/ForgeDiscussion/forgediscussion/tests/test_forum_roles.py
index 44d6989..4bc0eef 100644
--- a/ForgeDiscussion/forgediscussion/tests/test_forum_roles.py
+++ b/ForgeDiscussion/forgediscussion/tests/test_forum_roles.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from alluratest.controller import setup_basic_test, setup_global_objects
 from allura import model as M
diff --git a/ForgeDiscussion/forgediscussion/widgets/forum_widgets.py b/ForgeDiscussion/forgediscussion/widgets/forum_widgets.py
index 3dbe2c7..5dba9f2 100644
--- a/ForgeDiscussion/forgediscussion/widgets/forum_widgets.py
+++ b/ForgeDiscussion/forgediscussion/widgets/forum_widgets.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from formencode import validators as fev
 
 import ew as ew_core
diff --git a/ForgeGit/forgegit/controllers.py b/ForgeGit/forgegit/controllers.py
index 93e9364..d939576 100644
--- a/ForgeGit/forgegit/controllers.py
+++ b/ForgeGit/forgegit/controllers.py
@@ -17,7 +17,7 @@
 
 from tg import expose, redirect
 from tg.decorators import with_trailing_slash
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.controllers import repository
 
diff --git a/ForgeGit/forgegit/git_main.py b/ForgeGit/forgegit/git_main.py
index cfdb7b0..27abc42 100644
--- a/ForgeGit/forgegit/git_main.py
+++ b/ForgeGit/forgegit/git_main.py
@@ -19,7 +19,7 @@
 import logging
 
 # Non-stdlib imports
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from ming.utils import LazyProperty
 from ming.orm.ormsession import ThreadLocalORMSession
diff --git a/ForgeGit/forgegit/model/git_repo.py b/ForgeGit/forgegit/model/git_repo.py
index f75e21f..3b4d237 100644
--- a/ForgeGit/forgegit/model/git_repo.py
+++ b/ForgeGit/forgegit/model/git_repo.py
@@ -27,7 +27,7 @@ from time import time
 import tg
 import git
 import gitdb
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from pymongo.errors import DuplicateKeyError
 from paste.deploy.converters import asbool
 
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 4bcffce..a4db828 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -28,7 +28,7 @@ from nose.tools import assert_equal, assert_in, assert_not_in, assert_not_equal,
 import tg
 import pkg_resources
 from nose.tools import assert_regexp_matches
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import ThreadLocalORMSession
 from mock import patch, PropertyMock
 
diff --git a/ForgeGit/forgegit/tests/model/test_repository.py b/ForgeGit/forgegit/tests/model/test_repository.py
index 9412cb4..e277ce0 100644
--- a/ForgeGit/forgegit/tests/model/test_repository.py
+++ b/ForgeGit/forgegit/tests/model/test_repository.py
@@ -26,7 +26,7 @@ import datetime
 import email.iterators
 
 import mock
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 import tg
 from ming.base import Object
 from ming.orm import ThreadLocalORMSession, session
diff --git a/ForgeGit/forgegit/tests/test_git_app.py b/ForgeGit/forgegit/tests/test_git_app.py
index 0566249..c03e242 100644
--- a/ForgeGit/forgegit/tests/test_git_app.py
+++ b/ForgeGit/forgegit/tests/test_git_app.py
@@ -18,7 +18,7 @@
 import unittest
 from nose.tools import assert_equals
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import ThreadLocalORMSession
 
 from alluratest.controller import setup_basic_test, setup_global_objects
diff --git a/ForgeGit/forgegit/tests/test_tasks.py b/ForgeGit/forgegit/tests/test_tasks.py
index 3f003d6..26d1ee5 100644
--- a/ForgeGit/forgegit/tests/test_tasks.py
+++ b/ForgeGit/forgegit/tests/test_tasks.py
@@ -19,7 +19,7 @@ import unittest
 import mock
 
 from ming.orm import ThreadLocalORMSession
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from alluratest.controller import setup_basic_test, setup_global_objects
 from allura.lib import helpers as h
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index fb2fa21..e6a64b9 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -32,8 +32,8 @@ except ImportError:
 from BeautifulSoup import BeautifulSoup
 from tg import expose, validate, flash, redirect, config
 from tg.decorators import with_trailing_slash
-from pylons import app_globals as g
-from pylons import tmpl_context as c
+from tg import app_globals as g
+from tg import tmpl_context as c
 from formencode import validators as fev, schema
 from webob import exc
 
diff --git a/ForgeImporters/forgeimporters/forge/tracker.py b/ForgeImporters/forgeimporters/forge/tracker.py
index 2937b63..32ec0eb 100644
--- a/ForgeImporters/forgeimporters/forge/tracker.py
+++ b/ForgeImporters/forgeimporters/forge/tracker.py
@@ -19,8 +19,8 @@ import os
 import json
 
 import dateutil.parser
-from pylons import tmpl_context as c
-from pylons import app_globals as g
+from tg import tmpl_context as c
+from tg import app_globals as g
 from ming.orm import session, ThreadLocalORMSession
 
 from tg import (
diff --git a/ForgeImporters/forgeimporters/github/__init__.py b/ForgeImporters/forgeimporters/github/__init__.py
index 1dc4ca1..e294ee1 100644
--- a/ForgeImporters/forgeimporters/github/__init__.py
+++ b/ForgeImporters/forgeimporters/github/__init__.py
@@ -24,7 +24,7 @@ from datetime import datetime
 
 from tg import config, session, redirect, request, expose
 from tg.decorators import without_trailing_slash
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from requests_oauthlib import OAuth2Session
 import requests
 from formencode import validators as fev
diff --git a/ForgeImporters/forgeimporters/github/code.py b/ForgeImporters/forgeimporters/github/code.py
index 410b3bb..9d6e5f5 100644
--- a/ForgeImporters/forgeimporters/github/code.py
+++ b/ForgeImporters/forgeimporters/github/code.py
@@ -15,8 +15,8 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
-from pylons import app_globals as g
+from tg import tmpl_context as c
+from tg import app_globals as g
 from formencode import validators as fev
 from tg import (
     expose,
diff --git a/ForgeImporters/forgeimporters/github/tasks.py b/ForgeImporters/forgeimporters/github/tasks.py
index d74a9cd..db12c4d 100644
--- a/ForgeImporters/forgeimporters/github/tasks.py
+++ b/ForgeImporters/forgeimporters/github/tasks.py
@@ -15,8 +15,8 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
-from pylons import app_globals as g
+from tg import tmpl_context as c
+from tg import app_globals as g
 
 from ming.orm import ThreadLocalORMSession
 
diff --git a/ForgeImporters/forgeimporters/github/tests/test_oauth.py b/ForgeImporters/forgeimporters/github/tests/test_oauth.py
index 0bf8f4e..7656289 100644
--- a/ForgeImporters/forgeimporters/github/tests/test_oauth.py
+++ b/ForgeImporters/forgeimporters/github/tests/test_oauth.py
@@ -18,7 +18,7 @@
 from unittest import TestCase
 
 from mock import Mock, patch, MagicMock
-from pylons import tmpl_context as c, config
+from tg import tmpl_context as c, config
 from webob.exc import HTTPFound
 
 from allura.tests import TestController
diff --git a/ForgeImporters/forgeimporters/github/tracker.py b/ForgeImporters/forgeimporters/github/tracker.py
index 1f8d186..0c54f3f 100644
--- a/ForgeImporters/forgeimporters/github/tracker.py
+++ b/ForgeImporters/forgeimporters/github/tracker.py
@@ -41,8 +41,8 @@ from allura.lib import helpers as h
 from allura.lib.plugin import ImportIdConverter
 from allura.lib.decorators import require_post
 from ming.orm import session, ThreadLocalORMSession
-from pylons import tmpl_context as c
-from pylons import app_globals as g
+from tg import tmpl_context as c
+from tg import app_globals as g
 
 from forgetracker import model as TM
 from forgeimporters.base import (
diff --git a/ForgeImporters/forgeimporters/github/wiki.py b/ForgeImporters/forgeimporters/github/wiki.py
index 5b787d9..91c9594 100644
--- a/ForgeImporters/forgeimporters/github/wiki.py
+++ b/ForgeImporters/forgeimporters/github/wiki.py
@@ -25,8 +25,8 @@ from paste.deploy.converters import aslist
 
 from BeautifulSoup import BeautifulSoup
 import git
-from pylons import app_globals as g
-from pylons import tmpl_context as c
+from tg import app_globals as g
+from tg import tmpl_context as c
 from ming.orm import ThreadLocalORMSession
 from formencode import validators as fev
 from tg import (
diff --git a/ForgeImporters/forgeimporters/trac/tests/test_tickets.py b/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
index e3c8f7e..1e98584 100644
--- a/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
@@ -21,7 +21,7 @@ import os
 from unittest import TestCase
 from mock import Mock, patch
 from ming.orm import ThreadLocalORMSession
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from IPython.testing.decorators import module_not_available, skipif
 
 from allura.tests import TestController
diff --git a/ForgeImporters/forgeimporters/trac/tickets.py b/ForgeImporters/forgeimporters/trac/tickets.py
index 466b4f7..50c867a 100644
--- a/ForgeImporters/forgeimporters/trac/tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tickets.py
@@ -21,8 +21,8 @@ import re
 from formencode import validators as fev
 
 from ming.orm import session
-from pylons import tmpl_context as c
-from pylons import app_globals as g
+from tg import tmpl_context as c
+from tg import app_globals as g
 from tg import (
     expose,
     flash,
diff --git a/ForgeLink/forgelink/link_main.py b/ForgeLink/forgelink/link_main.py
index cece76e..cc00d00 100644
--- a/ForgeLink/forgelink/link_main.py
+++ b/ForgeLink/forgelink/link_main.py
@@ -21,8 +21,8 @@ import json
 
 # Non-stdlib imports
 from tg import expose, jsonify, redirect
-from pylons import tmpl_context as c
-from pylons import request
+from tg import tmpl_context as c
+from tg import request
 from formencode import validators as fev
 
 # Pyforge-specific imports
diff --git a/ForgeLink/forgelink/tests/test_app.py b/ForgeLink/forgelink/tests/test_app.py
index f4bbe84..2976341 100644
--- a/ForgeLink/forgelink/tests/test_app.py
+++ b/ForgeLink/forgelink/tests/test_app.py
@@ -19,7 +19,7 @@ import tempfile
 import json
 
 from nose.tools import assert_equal
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.tests import decorators as td
 from allura import model as M
diff --git a/ForgeSVN/forgesvn/controllers.py b/ForgeSVN/forgesvn/controllers.py
index 35af8e7..8a13c7a 100644
--- a/ForgeSVN/forgesvn/controllers.py
+++ b/ForgeSVN/forgesvn/controllers.py
@@ -17,7 +17,7 @@
 
 from tg import expose, redirect
 from tg.decorators import with_trailing_slash
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.controllers import repository
 from allura.controllers.feed import FeedController
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index afcdd12..1ded9e3 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -34,7 +34,7 @@ import tg
 import pysvn
 from paste.deploy.converters import asbool, asint
 from pymongo.errors import DuplicateKeyError
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from ming.base import Object
 from ming.orm import Mapper, FieldProperty
diff --git a/ForgeSVN/forgesvn/svn_main.py b/ForgeSVN/forgesvn/svn_main.py
index 60bb345..8c97630 100644
--- a/ForgeSVN/forgesvn/svn_main.py
+++ b/ForgeSVN/forgesvn/svn_main.py
@@ -17,7 +17,7 @@
 
 #-*- python -*-
 import logging
-from pylons import tmpl_context as c, request
+from tg import tmpl_context as c, request
 
 # Non-stdlib imports
 from ming.utils import LazyProperty
diff --git a/ForgeSVN/forgesvn/tests/functional/test_controllers.py b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
index 2154c6e..85f8e51 100644
--- a/ForgeSVN/forgesvn/tests/functional/test_controllers.py
+++ b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
@@ -21,7 +21,7 @@ import os
 
 import tg
 import pkg_resources
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import ThreadLocalORMSession
 from mock import patch
 from nose.tools import assert_equal
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index f4c49e8..d4323f0 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -25,7 +25,7 @@ from datetime import datetime
 from zipfile import ZipFile
 
 from collections import defaultdict
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 import mock
 from nose.tools import assert_equal, assert_in
 from datadiff.tools import assert_equals
diff --git a/ForgeSVN/forgesvn/tests/model/test_svnimplementation.py b/ForgeSVN/forgesvn/tests/model/test_svnimplementation.py
index 70cf129..99fed05 100644
--- a/ForgeSVN/forgesvn/tests/model/test_svnimplementation.py
+++ b/ForgeSVN/forgesvn/tests/model/test_svnimplementation.py
@@ -17,7 +17,7 @@
 
 from mock import Mock, patch
 from nose.tools import assert_equal
-from pylons import app_globals as g
+from tg import app_globals as g
 
 from alluratest.controller import setup_unit_test
 from allura.model.repository import Commit
diff --git a/ForgeSVN/forgesvn/tests/test_svn_app.py b/ForgeSVN/forgesvn/tests/test_svn_app.py
index 6ea576a..a962424 100644
--- a/ForgeSVN/forgesvn/tests/test_svn_app.py
+++ b/ForgeSVN/forgesvn/tests/test_svn_app.py
@@ -18,7 +18,7 @@
 import unittest
 from nose.tools import assert_equals
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import ThreadLocalORMSession
 
 from alluratest.controller import setup_basic_test, setup_global_objects
diff --git a/ForgeSVN/forgesvn/tests/test_tasks.py b/ForgeSVN/forgesvn/tests/test_tasks.py
index c928efb..2e0e99b 100644
--- a/ForgeSVN/forgesvn/tests/test_tasks.py
+++ b/ForgeSVN/forgesvn/tests/test_tasks.py
@@ -23,7 +23,7 @@ import os
 
 import tg
 import mock
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from paste.deploy.converters import asbool
 from nose.tools import assert_equal
 
diff --git a/ForgeShortUrl/forgeshorturl/main.py b/ForgeShortUrl/forgeshorturl/main.py
index 2be5b7f..66a5075 100644
--- a/ForgeShortUrl/forgeshorturl/main.py
+++ b/ForgeShortUrl/forgeshorturl/main.py
@@ -28,7 +28,7 @@ from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets.search import SearchResults, SearchHelp
 
 from webob import exc
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from datetime import datetime
 from formencode import validators
 from formencode.compound import All
diff --git a/ForgeShortUrl/forgeshorturl/model/shorturl.py b/ForgeShortUrl/forgeshorturl/model/shorturl.py
index 6682632..e8b0c29 100644
--- a/ForgeShortUrl/forgeshorturl/model/shorturl.py
+++ b/ForgeShortUrl/forgeshorturl/model/shorturl.py
@@ -17,7 +17,7 @@
 
 import pymongo
 from tg import config
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import FieldProperty, ForeignIdProperty, session
 from datetime import datetime
 from allura.model.auth import User
diff --git a/ForgeShortUrl/forgeshorturl/tests/functional/test.py b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
index f2c2e1c..d4aa712 100644
--- a/ForgeShortUrl/forgeshorturl/tests/functional/test.py
+++ b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from tg import config
 from nose.tools import assert_equal
 import mock
diff --git a/ForgeTracker/forgetracker/command/fix_discussion.py b/ForgeTracker/forgetracker/command/fix_discussion.py
index 95bddb4..a0d090d 100644
--- a/ForgeTracker/forgetracker/command/fix_discussion.py
+++ b/ForgeTracker/forgetracker/command/fix_discussion.py
@@ -18,7 +18,7 @@
 from bson import ObjectId
 from bson.errors import InvalidId
 from ming.orm import ThreadLocalORMSession
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.command import base
 from allura import model as M
diff --git a/ForgeTracker/forgetracker/import_support.py b/ForgeTracker/forgetracker/import_support.py
index affe94b..bc2aa73 100644
--- a/ForgeTracker/forgetracker/import_support.py
+++ b/ForgeTracker/forgetracker/import_support.py
@@ -22,7 +22,7 @@ from datetime import datetime
 from cStringIO import StringIO
 
 # Non-stdlib imports
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm.ormsession import ThreadLocalORMSession
 
 # Pyforge-specific imports
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 3e37ea6..9d5611c 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -25,7 +25,7 @@ import os
 
 import pymongo
 from pymongo.errors import OperationFailure
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 from pprint import pformat
 from paste.deploy.converters import aslist, asbool
 import jinja2
diff --git a/ForgeTracker/forgetracker/plugins.py b/ForgeTracker/forgetracker/plugins.py
index c610de8..676deb2 100644
--- a/ForgeTracker/forgetracker/plugins.py
+++ b/ForgeTracker/forgetracker/plugins.py
@@ -18,6 +18,6 @@
 import logging
 
 from tg import config
-from pylons import app_globals as g
+from tg import app_globals as g
 
 log = logging.getLogger(__name__)
diff --git a/ForgeTracker/forgetracker/search.py b/ForgeTracker/forgetracker/search.py
index 0225997..86e46b4 100644
--- a/ForgeTracker/forgetracker/search.py
+++ b/ForgeTracker/forgetracker/search.py
@@ -14,7 +14,7 @@
 #       KIND, either express or implied.  See the License for the
 #       specific language governing permissions and limitations
 #       under the License.
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.lib.search import search
 
diff --git a/ForgeTracker/forgetracker/tasks.py b/ForgeTracker/forgetracker/tasks.py
index 0fdebc5..5ad4214 100644
--- a/ForgeTracker/forgetracker/tasks.py
+++ b/ForgeTracker/forgetracker/tasks.py
@@ -18,7 +18,7 @@
 import logging
 from datetime import datetime
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from allura.lib.decorators import task
 from allura.lib import helpers as h
diff --git a/ForgeTracker/forgetracker/tests/functional/test_rest.py b/ForgeTracker/forgetracker/tests/functional/test_rest.py
index 46e5b9a..b44a881 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_rest.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_rest.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from datadiff.tools import assert_equal
 from nose.tools import assert_not_equal
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 8fd0144..5cdb2b1 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -40,8 +40,8 @@ from nose.tools import (
     assert_not_equal,
 )
 from formencode.variabledecode import variable_encode
-from pylons import tmpl_context as c
-from pylons import app_globals as g
+from tg import tmpl_context as c
+from tg import app_globals as g
 from tg import config
 
 from alluratest.controller import TestController, setup_basic_test
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
index 707a094..cfc0596 100644
--- a/ForgeTracker/forgetracker/tests/test_app.py
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -21,7 +21,7 @@ import operator
 import os
 
 from nose.tools import assert_equal, assert_true
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from cgi import FieldStorage
 from cStringIO import StringIO
 from ming.orm import ThreadLocalORMSession
diff --git a/ForgeTracker/forgetracker/tests/test_tracker_roles.py b/ForgeTracker/forgetracker/tests/test_tracker_roles.py
index 92bed3f..242646c 100644
--- a/ForgeTracker/forgetracker/tests/test_tracker_roles.py
+++ b/ForgeTracker/forgetracker/tests/test_tracker_roles.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from alluratest.controller import setup_basic_test, setup_global_objects
 from allura import model as M
diff --git a/ForgeTracker/forgetracker/tests/unit/__init__.py b/ForgeTracker/forgetracker/tests/unit/__init__.py
index ee9af84..1ef9b92 100644
--- a/ForgeTracker/forgetracker/tests/unit/__init__.py
+++ b/ForgeTracker/forgetracker/tests/unit/__init__.py
@@ -15,13 +15,12 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
-from pylons import request
+from tg import tmpl_context as c
+import tg
 from ming.orm.ormsession import ThreadLocalORMSession
 from webob import Request
 
 from allura.websetup import bootstrap
-from allura.websetup.schema import REGISTRY
 from allura.lib import helpers as h
 from allura.lib import plugin
 from allura import model as M
@@ -48,7 +47,7 @@ class TrackerTestWithModel(object):
         c.project.install_app('Tickets', 'bugs')
         ThreadLocalORMSession.flush_all()
         h.set_context('test', 'bugs', neighborhood='Projects')
-        REGISTRY.register(request, Request.blank('/'))  # borrowed from setup_unit_test but we need just this
+        tg.request_local.context.request = Request.blank('/')
 
     def tearDown(self):
         ThreadLocalORMSession.close_all()
diff --git a/ForgeTracker/forgetracker/tests/unit/test_globals_model.py b/ForgeTracker/forgetracker/tests/unit/test_globals_model.py
index 700a222..47b36ba 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_globals_model.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_globals_model.py
@@ -19,7 +19,7 @@ from datetime import datetime, timedelta
 
 import mock
 from nose.tools import assert_equal
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm.ormsession import ThreadLocalORMSession
 
 import forgetracker
diff --git a/ForgeTracker/forgetracker/tests/unit/test_milestone_controller.py b/ForgeTracker/forgetracker/tests/unit/test_milestone_controller.py
index b77cf74..e7c36c5 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_milestone_controller.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_milestone_controller.py
@@ -22,7 +22,7 @@ from mock import Mock
 from nose.tools import assert_equal
 
 from allura.lib import helpers as h
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from forgetracker.tracker_main import MilestoneController
 
 
diff --git a/ForgeTracker/forgetracker/tests/unit/test_root_controller.py b/ForgeTracker/forgetracker/tests/unit/test_root_controller.py
index 7a88f72..c7bef18 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_root_controller.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_root_controller.py
@@ -19,7 +19,7 @@ import unittest
 
 from mock import Mock, patch
 from ming.orm.ormsession import session
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from nose.tools import assert_equal
 
 from allura.lib import helpers as h
diff --git a/ForgeTracker/forgetracker/tests/unit/test_ticket_custom_fields_form.py b/ForgeTracker/forgetracker/tests/unit/test_ticket_custom_fields_form.py
index 3c8ea70..60576d1 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_ticket_custom_fields_form.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_ticket_custom_fields_form.py
@@ -18,7 +18,7 @@
 from ming.orm.ormsession import ThreadLocalORMSession
 from ming.base import Object
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from forgetracker.tests.unit import TrackerTestWithModel
 from forgetracker.widgets import ticket_form
diff --git a/ForgeTracker/forgetracker/tests/unit/test_ticket_form.py b/ForgeTracker/forgetracker/tests/unit/test_ticket_form.py
index a0743eb..a11a088 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_ticket_form.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_ticket_form.py
@@ -17,7 +17,7 @@
 
 from ming.orm.ormsession import ThreadLocalORMSession
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from forgetracker.tests.unit import TrackerTestWithModel
 from forgetracker.widgets import ticket_form
diff --git a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
index 3b6f318..99ba7de 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from datetime import datetime
 import urllib2
 
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 135df0e..1be5070 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -29,8 +29,8 @@ import pkg_resources
 from tg import expose, validate, redirect, flash, url, jsonify
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from paste.deploy.converters import aslist
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request, response
+from tg import tmpl_context as c, app_globals as g
+from tg import request, response
 from formencode import validators
 from bson import ObjectId
 from bson.son import SON
diff --git a/ForgeTracker/forgetracker/widgets/ticket_form.py b/ForgeTracker/forgetracker/widgets/ticket_form.py
index 5481eb2..64c0863 100644
--- a/ForgeTracker/forgetracker/widgets/ticket_form.py
+++ b/ForgeTracker/forgetracker/widgets/ticket_form.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from formencode import validators as fev
 from webhelpers.html.builder import literal
 
diff --git a/ForgeUserStats/forgeuserstats/controllers/userstats.py b/ForgeUserStats/forgeuserstats/controllers/userstats.py
index ffd2e58..8ab2db2 100644
--- a/ForgeUserStats/forgeuserstats/controllers/userstats.py
+++ b/ForgeUserStats/forgeuserstats/controllers/userstats.py
@@ -19,7 +19,7 @@ import re
 
 from tg import expose, validate, redirect
 from tg.decorators import with_trailing_slash
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from webob import exc
 
 from allura.controllers import BaseController
diff --git a/ForgeUserStats/forgeuserstats/main.py b/ForgeUserStats/forgeuserstats/main.py
index daa19ef..580b3a6 100644
--- a/ForgeUserStats/forgeuserstats/main.py
+++ b/ForgeUserStats/forgeuserstats/main.py
@@ -17,7 +17,7 @@
 
 #-*- python -*-
 import logging
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from datetime import datetime
 
 from allura.app import Application, SitemapEntry
diff --git a/ForgeUserStats/forgeuserstats/model/stats.py b/ForgeUserStats/forgeuserstats/model/stats.py
index 2da4618..340f857 100644
--- a/ForgeUserStats/forgeuserstats/model/stats.py
+++ b/ForgeUserStats/forgeuserstats/model/stats.py
@@ -19,7 +19,7 @@ from ming.orm import FieldProperty
 from ming import schema as S
 from datetime import datetime, timedelta
 from ming.orm import Mapper
-from pylons import request
+from tg import request
 
 from allura.lib import plugin
 from allura.model.session import main_orm_session
diff --git a/ForgeUserStats/forgeuserstats/tests/test_model.py b/ForgeUserStats/forgeuserstats/tests/test_model.py
index 3804063..b9eff67 100644
--- a/ForgeUserStats/forgeuserstats/tests/test_model.py
+++ b/ForgeUserStats/forgeuserstats/tests/test_model.py
@@ -19,7 +19,7 @@ import pkg_resources
 import unittest
 from datetime import datetime, timedelta
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from tg import config
 import mock
 
diff --git a/ForgeUserStats/forgeuserstats/tests/test_stats.py b/ForgeUserStats/forgeuserstats/tests/test_stats.py
index fda1bc7..aa08385 100644
--- a/ForgeUserStats/forgeuserstats/tests/test_stats.py
+++ b/ForgeUserStats/forgeuserstats/tests/test_stats.py
@@ -18,7 +18,7 @@
 import pkg_resources
 import unittest
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from alluratest.controller import TestController, setup_basic_test, setup_global_objects
 from allura.tests import decorators as td
diff --git a/ForgeWiki/forgewiki/model/wiki.py b/ForgeWiki/forgewiki/model/wiki.py
index e55d464..edd1685 100644
--- a/ForgeWiki/forgewiki/model/wiki.py
+++ b/ForgeWiki/forgewiki/model/wiki.py
@@ -20,8 +20,8 @@ import difflib
 import os
 
 # g is a namespace for globally accessable app helpers
-from pylons import app_globals as g
-from pylons import tmpl_context as context
+from tg import app_globals as g
+from tg import tmpl_context as context
 
 from ming import schema
 from ming.orm import FieldProperty, ForeignIdProperty, Mapper, session
diff --git a/ForgeWiki/forgewiki/tests/test_app.py b/ForgeWiki/forgewiki/tests/test_app.py
index 086d258..7934540 100644
--- a/ForgeWiki/forgewiki/tests/test_app.py
+++ b/ForgeWiki/forgewiki/tests/test_app.py
@@ -23,7 +23,7 @@ import os
 
 from cStringIO import StringIO
 from nose.tools import assert_equal
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import ThreadLocalORMSession
 
 from allura import model as M
diff --git a/ForgeWiki/forgewiki/tests/test_models.py b/ForgeWiki/forgewiki/tests/test_models.py
index 2ab2f00..3c6c7ef 100644
--- a/ForgeWiki/forgewiki/tests/test_models.py
+++ b/ForgeWiki/forgewiki/tests/test_models.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import session
 
 from allura.tests import TestController
diff --git a/ForgeWiki/forgewiki/tests/test_wiki_roles.py b/ForgeWiki/forgewiki/tests/test_wiki_roles.py
index 64b5f03..9750f0d 100644
--- a/ForgeWiki/forgewiki/tests/test_wiki_roles.py
+++ b/ForgeWiki/forgewiki/tests/test_wiki_roles.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from nose.tools import assert_equal
 
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 5e7b4f5..ac60545 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -25,8 +25,8 @@ from urllib import unquote
 # Non-stdlib imports
 from tg import expose, validate, redirect, flash, jsonify
 from tg.decorators import with_trailing_slash, without_trailing_slash
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
+from tg import tmpl_context as c, app_globals as g
+from tg import request
 from formencode import validators
 from webob import exc
 from ming.orm import session
diff --git a/requirements.txt b/requirements.txt
index 1a6b730..6c6de7d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -49,10 +49,10 @@ textile==2.1.5
 # dep of colander
 translationstring==0.4
 TimerMiddleware==0.4.4
-TurboGears2==2.2.2
+TurboGears2==2.3.0
 # dep of html5lib
 webencodings==0.5.1
-WebOb==1.1.1
+WebOb==1.3.1
 
 # dependencies for cryptography
 cryptography==2.6.1
@@ -66,6 +66,7 @@ asn1crypto==0.24.0
 
 # tg2 deps (not used directly)
 Babel==1.3
+backlash==0.1.4
 crank==0.8.1
 Mako==0.9.1
 MarkupSafe==1.0
diff --git a/scripts/migrations/000-fix-tracker-fields.py b/scripts/migrations/000-fix-tracker-fields.py
index 5d2b6b1..072aeb9 100644
--- a/scripts/migrations/000-fix-tracker-fields.py
+++ b/scripts/migrations/000-fix-tracker-fields.py
@@ -18,7 +18,7 @@
 import sys
 import logging
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from ming.orm import session
 
diff --git a/scripts/migrations/001-restore-labels.py b/scripts/migrations/001-restore-labels.py
index ef68c09..2e33da7 100644
--- a/scripts/migrations/001-restore-labels.py
+++ b/scripts/migrations/001-restore-labels.py
@@ -19,7 +19,7 @@ import sys
 import json
 import logging
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from ming.orm import session, MappedClass
 
diff --git a/scripts/migrations/002-fix-tracker-thread-subjects.py b/scripts/migrations/002-fix-tracker-thread-subjects.py
index 81861a0..df42446 100644
--- a/scripts/migrations/002-fix-tracker-thread-subjects.py
+++ b/scripts/migrations/002-fix-tracker-thread-subjects.py
@@ -18,7 +18,7 @@
 import sys
 import logging
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from ming.orm import session
 
diff --git a/scripts/migrations/007-update-acls.py b/scripts/migrations/007-update-acls.py
index 0f97ee1..1cc8f3b 100644
--- a/scripts/migrations/007-update-acls.py
+++ b/scripts/migrations/007-update-acls.py
@@ -20,7 +20,7 @@ from optparse import OptionParser
 from pprint import pformat
 
 import bson
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.base import Object
 
 from allura import model as M
diff --git a/scripts/migrations/010-fix-home-permissions.py b/scripts/migrations/010-fix-home-permissions.py
index 4506a17..1b669d5 100644
--- a/scripts/migrations/010-fix-home-permissions.py
+++ b/scripts/migrations/010-fix-home-permissions.py
@@ -19,7 +19,7 @@ import sys
 import logging
 from collections import OrderedDict
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import session
 from bson import ObjectId
 
diff --git a/scripts/migrations/012-uninstall-home.py b/scripts/migrations/012-uninstall-home.py
index c59fdb2..9c5bd79 100644
--- a/scripts/migrations/012-uninstall-home.py
+++ b/scripts/migrations/012-uninstall-home.py
@@ -18,7 +18,7 @@
 import sys
 import logging
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import session
 from bson import ObjectId
 from mock import Mock, patch
diff --git a/scripts/migrations/013-update-ordinals.py b/scripts/migrations/013-update-ordinals.py
index f26f112..0568fa0 100644
--- a/scripts/migrations/013-update-ordinals.py
+++ b/scripts/migrations/013-update-ordinals.py
@@ -18,7 +18,7 @@
 import sys
 import logging
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm import session
 from ming.orm.ormsession import ThreadLocalORMSession
 
diff --git a/scripts/migrations/015-add-neighborhood_id-to-blog-posts.py b/scripts/migrations/015-add-neighborhood_id-to-blog-posts.py
index 8c4abd9..1fa8542 100644
--- a/scripts/migrations/015-add-neighborhood_id-to-blog-posts.py
+++ b/scripts/migrations/015-add-neighborhood_id-to-blog-posts.py
@@ -17,7 +17,7 @@
 
 import logging
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from ming.orm.ormsession import ThreadLocalORMSession
 
 from forgeblog import model as BM
diff --git a/scripts/migrations/020-remove-wiki-title-slashes.py b/scripts/migrations/020-remove-wiki-title-slashes.py
index 34db4ce..0df73f7 100644
--- a/scripts/migrations/020-remove-wiki-title-slashes.py
+++ b/scripts/migrations/020-remove-wiki-title-slashes.py
@@ -17,7 +17,7 @@
 
 import logging
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from ming.orm import ThreadLocalORMSession
 
diff --git a/scripts/migrations/024-migrate-custom-profile-text.py b/scripts/migrations/024-migrate-custom-profile-text.py
index 18a82da..060b70e 100644
--- a/scripts/migrations/024-migrate-custom-profile-text.py
+++ b/scripts/migrations/024-migrate-custom-profile-text.py
@@ -18,7 +18,7 @@
 import logging
 import re
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from ming.orm import ThreadLocalORMSession
 
diff --git a/scripts/migrations/033-change-comment-anon-permissions.py b/scripts/migrations/033-change-comment-anon-permissions.py
index b5a710c..f0b7da8 100644
--- a/scripts/migrations/033-change-comment-anon-permissions.py
+++ b/scripts/migrations/033-change-comment-anon-permissions.py
@@ -18,7 +18,7 @@
 import sys
 import logging
 from ming.orm import ThreadLocalORMSession, session
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from allura import model as M
 from forgediscussion.model import ForumPost
 from allura.lib import utils, security
diff --git a/scripts/migrations/034-update_subscriptions_ticket_and_mr_titles.py b/scripts/migrations/034-update_subscriptions_ticket_and_mr_titles.py
index 4ca1cf8..94904c8 100644
--- a/scripts/migrations/034-update_subscriptions_ticket_and_mr_titles.py
+++ b/scripts/migrations/034-update_subscriptions_ticket_and_mr_titles.py
@@ -18,7 +18,7 @@
 import logging
 import re
 import sys
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from bson import ObjectId
 
 from ming.odm import session
diff --git a/scripts/perf/call_count.py b/scripts/perf/call_count.py
index 671e6f2..e94c238 100755
--- a/scripts/perf/call_count.py
+++ b/scripts/perf/call_count.py
@@ -24,7 +24,7 @@ import random
 import string
 import csv
 
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from testfixtures import LogCapture
 from mock import patch
 from ming.odm import ThreadLocalODMSession
diff --git a/scripts/perf/load-up-forum.py b/scripts/perf/load-up-forum.py
index 2184411..ee8f93d 100644
--- a/scripts/perf/load-up-forum.py
+++ b/scripts/perf/load-up-forum.py
@@ -19,7 +19,7 @@
 import logging
 import uuid
 from ming.orm import ThreadLocalORMSession, session
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 from allura import model as M
 from forgediscussion.model import ForumPost, Forum
 from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, ArgumentTypeError
diff --git a/scripts/perf/md_perf.py b/scripts/perf/md_perf.py
index e8d0f70..d4511da 100644
--- a/scripts/perf/md_perf.py
+++ b/scripts/perf/md_perf.py
@@ -56,7 +56,7 @@ try:
 except ImportError:
     RE2_INSTALLED = False
 
-from pylons import app_globals as g
+from tg import app_globals as g
 
 MAX_OUTPUT = 99999
 DUMMYTEXT = None
diff --git a/scripts/project-import.py b/scripts/project-import.py
index 462c4d6..9833bc2 100644
--- a/scripts/project-import.py
+++ b/scripts/project-import.py
@@ -26,7 +26,7 @@ import sys
 
 import colander as col
 from ming.orm import session, ThreadLocalORMSession
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from allura import model as M
 from allura.lib import helpers as h
diff --git a/scripts/publicize-neighborhood.py b/scripts/publicize-neighborhood.py
index 9cc6494..b2d208c 100644
--- a/scripts/publicize-neighborhood.py
+++ b/scripts/publicize-neighborhood.py
@@ -19,7 +19,7 @@ import logging
 import sys
 
 from ming.orm import ThreadLocalORMSession
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from allura import model as M
 from allura.lib import helpers as h
diff --git a/scripts/rethumb.py b/scripts/rethumb.py
index fa27f32..4dbfc04 100644
--- a/scripts/rethumb.py
+++ b/scripts/rethumb.py
@@ -18,7 +18,7 @@
 import sys
 
 import PIL
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 
 from ming.orm import ThreadLocalORMSession, state, Mapper
 
diff --git a/scripts/scrub-allura-data.py b/scripts/scrub-allura-data.py
index 211cfdc..226ea13 100644
--- a/scripts/scrub-allura-data.py
+++ b/scripts/scrub-allura-data.py
@@ -20,7 +20,7 @@ import sys
 
 from ming.orm import ThreadLocalORMSession
 import mock
-from pylons import tmpl_context as c, app_globals as g
+from tg import tmpl_context as c, app_globals as g
 
 from allura import model as M
 from forgediscussion import model as DM
diff --git a/scripts/teamforge-import.py b/scripts/teamforge-import.py
index b668128..aed92cd 100644
--- a/scripts/teamforge-import.py
+++ b/scripts/teamforge-import.py
@@ -18,7 +18,7 @@
 import logging
 from getpass import getpass
 from optparse import OptionParser
-from pylons import tmpl_context as c
+from tg import tmpl_context as c
 import re
 import os
 from time import mktime