diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml
index c07d20d7..138f4524 100644
--- a/.github/workflows/run-tests.yml
+++ b/.github/workflows/run-tests.yml
@@ -1,12 +1,19 @@
name: run-tests
-on: [push, pull_request, workflow_dispatch]
+on:
+ push:
+ branches:
+ - main
+ - master
+ - development
+ pull_request:
+ workflow_dispatch:
jobs:
build:
name: Run tests
strategy:
matrix:
os: [ubuntu-latest]
- python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
diff --git a/devtools/gearbox/quickstart/command.py b/devtools/gearbox/quickstart/command.py
index 794467ec..9bfd5328 100644
--- a/devtools/gearbox/quickstart/command.py
+++ b/devtools/gearbox/quickstart/command.py
@@ -1,5 +1,3 @@
-from __future__ import print_function
-
import re
import os
import shutil
@@ -244,4 +242,4 @@ def safe_name(name: str) -> str:
from setuptools.pkg_resources.safe_name
"""
- return re.sub('[^A-Za-z0-9.]+', '-', name)
\ No newline at end of file
+ return re.sub('[^A-Za-z0-9.]+', '-', name)
diff --git a/devtools/gearbox/quickstart/template/+package+/controllers/root.py_tmpl b/devtools/gearbox/quickstart/template/+package+/controllers/root.py_tmpl
index b7b42ca3..758d5ba8 100644
--- a/devtools/gearbox/quickstart/template/+package+/controllers/root.py_tmpl
+++ b/devtools/gearbox/quickstart/template/+package+/controllers/root.py_tmpl
@@ -115,7 +115,7 @@ class RootController(BaseController):
redirect('/login',
params=dict(came_from=came_from, __logins=login_counter))
userid = request.identity['repoze.who.userid']
- flash(_('Welcome back, %s!') % userid)
+ flash(_('Welcome back, {}!').format(userid))
# Do not use tg.redirect with tg.url as it will add the mountpoint
# of the application twice.
diff --git a/devtools/gearbox/quickstart/template/+package+/lib/helpers.py_tmpl b/devtools/gearbox/quickstart/template/+package+/lib/helpers.py_tmpl
index f9f6bf7d..d3526873 100644
--- a/devtools/gearbox/quickstart/template/+package+/lib/helpers.py_tmpl
+++ b/devtools/gearbox/quickstart/template/+package+/lib/helpers.py_tmpl
@@ -13,7 +13,7 @@ def current_year():
def icon(icon_name):
- return Markup('' % icon_name)
+ return Markup(f'')
# Import commonly used helpers from WebHelpers2 and TG
diff --git a/devtools/gearbox/quickstart/template/+package+/model/auth.py_tmpl b/devtools/gearbox/quickstart/template/+package+/model/auth.py_tmpl
index e2f111f4..ac90da70 100644
--- a/devtools/gearbox/quickstart/template/+package+/model/auth.py_tmpl
+++ b/devtools/gearbox/quickstart/template/+package+/model/auth.py_tmpl
@@ -72,7 +72,7 @@ class Group(DeclarativeBase):
users = relationship('User', secondary=user_group_table, backref='groups')
def __repr__(self):
- return '' % repr(self.group_name)
+ return f''
def __unicode__(self):
return self.group_name
@@ -96,11 +96,7 @@ class User(DeclarativeBase):
created = Column(DateTime, default=datetime.now)
def __repr__(self):
- return '' % (
- repr(self.user_name),
- repr(self.email_address),
- repr(self.display_name)
- )
+ return f''
def __unicode__(self):
return self.display_name or self.user_name
@@ -185,7 +181,7 @@ class Permission(DeclarativeBase):
backref='permissions')
def __repr__(self):
- return '' % repr(self.permission_name)
+ return f''
def __unicode__(self):
return self.permission_name
diff --git a/devtools/gearbox/quickstart/template/+package+/tests/__init__.py_tmpl b/devtools/gearbox/quickstart/template/+package+/tests/__init__.py_tmpl
index ed348547..b0d85e14 100644
--- a/devtools/gearbox/quickstart/template/+package+/tests/__init__.py_tmpl
+++ b/devtools/gearbox/quickstart/template/+package+/tests/__init__.py_tmpl
@@ -17,7 +17,7 @@ application_name = 'main_without_authn'
def load_app(name=application_name):
"""Load the test application."""
- return TestApp(loadapp('config:test.ini#%s' % name, relative_to=getcwd()))
+ return TestApp(loadapp(f'config:test.ini#{name}', relative_to=getcwd()))
def setup_app():
diff --git a/devtools/gearbox/quickstart/template/+package+/tests/functional/test_authentication.py_tmpl b/devtools/gearbox/quickstart/template/+package+/tests/functional/test_authentication.py_tmpl
index e5533ac0..26e6b8b5 100644
--- a/devtools/gearbox/quickstart/template/+package+/tests/functional/test_authentication.py_tmpl
+++ b/devtools/gearbox/quickstart/template/+package+/tests/functional/test_authentication.py_tmpl
@@ -7,8 +7,6 @@ As {{project}} grows and the authentication method changes, only these tests
should be updated.
"""
-from __future__ import unicode_literals
-
from {{package}}.tests import TestController
@@ -36,7 +34,7 @@ class TestAuthentication(TestController):
home_page = post_login.follow(status=302)
assert (
'authtkt' in home_page.request.cookies
- ), 'Session cookie was not defined: %s' % home_page.request.cookies
+ ), f'Session cookie was not defined: {home_page.request.cookies}'
assert home_page.location, 'http://localhost/'
def test_logout(self):
@@ -47,7 +45,7 @@ class TestAuthentication(TestController):
resp = resp.follow(status=302)
assert (
'authtkt' in resp.request.cookies
- ), 'Session cookie was not defined: %s' % resp.request.cookies
+ ), f'Session cookie was not defined: {resp.request.cookies}'
# Logging out:
resp = self.app.get('/logout_handler', status=302)
assert resp.location.startswith('http://localhost/post_logout')
@@ -56,7 +54,7 @@ class TestAuthentication(TestController):
authtkt = home_page.request.cookies.get('authtkt')
assert (
not authtkt or authtkt == 'INVALID'
- ), 'Session cookie was not deleted: %s' % home_page.request.cookies
+ ), f'Session cookie was not deleted: {home_page.request.cookies}'
assert home_page.location == 'http://localhost/'
def test_failed_login_keeps_username(self):
diff --git a/devtools/gearbox/quickstart/template/+package+/tests/functional/test_root.py_tmpl b/devtools/gearbox/quickstart/template/+package+/tests/functional/test_root.py_tmpl
index 7192c7ed..9de9ab00 100644
--- a/devtools/gearbox/quickstart/template/+package+/tests/functional/test_root.py_tmpl
+++ b/devtools/gearbox/quickstart/template/+package+/tests/functional/test_root.py_tmpl
@@ -25,7 +25,7 @@ class TestRootController(TestController):
assert msg in response
# You can also access a BeautifulSoup'ed response in your tests
- # (First run $ easy_install BeautifulSoup
+ # (First run `pip install beautifulsoup4`
# and then uncomment the next two lines)
# links = response.html.findAll('a')
diff --git a/devtools/gearbox/quickstart/template/+package+/tests/models/test_auth.py_tmpl b/devtools/gearbox/quickstart/template/+package+/tests/models/test_auth.py_tmpl
index 61069678..162739b2 100644
--- a/devtools/gearbox/quickstart/template/+package+/tests/models/test_auth.py_tmpl
+++ b/devtools/gearbox/quickstart/template/+package+/tests/models/test_auth.py_tmpl
@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
"""Test suite for the TG app's models"""
-from __future__ import unicode_literals
-
from {{package}} import model
from {{package}}.tests.models import ModelTest
diff --git a/devtools/gearbox/quickstart/template/+package+/websetup/bootstrap.py_tmpl b/devtools/gearbox/quickstart/template/+package+/websetup/bootstrap.py_tmpl
index 37d86ecd..4a2c4b6d 100644
--- a/devtools/gearbox/quickstart/template/+package+/websetup/bootstrap.py_tmpl
+++ b/devtools/gearbox/quickstart/template/+package+/websetup/bootstrap.py_tmpl
@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
"""Setup the {{project}} application"""
-from __future__ import print_function, unicode_literals
-
{{if sqlalchemy}}
import transaction
{{endif}}
diff --git a/devtools/gearbox/quickstart/template/+package+/websetup/schema.py_tmpl b/devtools/gearbox/quickstart/template/+package+/websetup/schema.py_tmpl
index d7e5e192..1a9a8554 100644
--- a/devtools/gearbox/quickstart/template/+package+/websetup/schema.py_tmpl
+++ b/devtools/gearbox/quickstart/template/+package+/websetup/schema.py_tmpl
@@ -1,7 +1,5 @@
# -*- coding: utf-8 -*-
"""Setup the {{project}} application"""
-from __future__ import print_function
-
from tg import config
{{if sqlalchemy}}
import transaction
@@ -32,4 +30,4 @@ def setup_schema(command, conf, vars):
alembic_cfg.set_main_option("sqlalchemy.url", config['sqlalchemy.url'])
import alembic.command
alembic.command.stamp(alembic_cfg, "head")
- {{endif}}
\ No newline at end of file
+ {{endif}}
diff --git a/devtools/gearbox/quickstart/template/migration/env.py_tmpl b/devtools/gearbox/quickstart/template/migration/env.py_tmpl
index 06d1ac93..5df5faa6 100644
--- a/devtools/gearbox/quickstart/template/migration/env.py_tmpl
+++ b/devtools/gearbox/quickstart/template/migration/env.py_tmpl
@@ -1,4 +1,3 @@
-from __future__ import with_statement
from alembic import context
from sqlalchemy import engine_from_config, pool
diff --git a/devtools/gearbox/quickstart/template/setup.py_tmpl b/devtools/gearbox/quickstart/template/setup.py_tmpl
deleted file mode 100755
index 57c026bf..00000000
--- a/devtools/gearbox/quickstart/template/setup.py_tmpl
+++ /dev/null
@@ -1,4 +0,0 @@
-from setuptools import setup
-
-if __name__ == "__main__":
- setup()
\ No newline at end of file
diff --git a/devtools/gearbox/sqlamigrate.py b/devtools/gearbox/sqlamigrate.py
index fca6f369..202205e0 100644
--- a/devtools/gearbox/sqlamigrate.py
+++ b/devtools/gearbox/sqlamigrate.py
@@ -37,14 +37,9 @@
check http://code.google.com/p/sqlalchemy-migrate/wiki/MigrateVersioning for detail.
"""
-from __future__ import print_function
+from configparser import ConfigParser
from gearbox.command import Command
-try:
- from configparser import ConfigParser
-except ImportError:
- from ConfigParser import ConfigParser
-
import sys, os
class MigrateCommand(Command):
diff --git a/devtools/gearbox/tgext/command.py b/devtools/gearbox/tgext/command.py
index b93451ca..3b207516 100644
--- a/devtools/gearbox/tgext/command.py
+++ b/devtools/gearbox/tgext/command.py
@@ -1,5 +1,3 @@
-from __future__ import print_function
-
from gearbox.command import TemplateCommand
import re, getpass
diff --git a/devtools/gearbox/tgext/template/pyproject.toml_tmpl b/devtools/gearbox/tgext/template/pyproject.toml_tmpl
index e7aeb986..240865c1 100644
--- a/devtools/gearbox/tgext/template/pyproject.toml_tmpl
+++ b/devtools/gearbox/tgext/template/pyproject.toml_tmpl
@@ -7,8 +7,9 @@ name = {{repr(package)}}
version = "{{version}}"
description = "{{description or ''}}"
readme = { file = "README.rst", content-type = "text/x-rst" }
+requires-python = ">=3.8"
classifiers = [] # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
-keywords = {{repr(keywords or '')}}
+keywords = [{{repr(keywords or '')}}]
authors = [
{ name = {{repr(author or '')}}, email = {{repr(author_email or '')}} }
]
@@ -24,4 +25,3 @@ exclude = ["ez_setup", "examples", "tests"]
[tool.setuptools]
include-package-data = true
zip-safe = false
-namespace_packages = ["tgext"]
diff --git a/devtools/gearbox/tgext/template/tgext/__init__.py b/devtools/gearbox/tgext/template/tgext/__init__.py
deleted file mode 100644
index 5761d9e1..00000000
--- a/devtools/gearbox/tgext/template/tgext/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
-try:
- __import__('pkg_resources').declare_namespace(__name__)
-except ImportError:
- from pkgutil import extend_path
- __path__ = extend_path(__path__, __name__)
-
diff --git a/devtools/gearbox/tgshell.py b/devtools/gearbox/tgshell.py
index a26e159b..7c9b539b 100644
--- a/devtools/gearbox/tgshell.py
+++ b/devtools/gearbox/tgshell.py
@@ -1,5 +1,3 @@
-from __future__ import print_function
-
import os, sys
import tg
@@ -71,9 +69,9 @@ def take_action(self, opts):
if self._can_import(helpers_module):
locs['h'] = sys.modules[helpers_module]
- exec ('import tg') in locs
- exec ('from tg import app_globals, config, request, response, '
- 'session, tmpl_context, url') in locs
+ exec('import tg', locs)
+ exec('from tg import app_globals, config, request, response, '
+ 'session, tmpl_context, url', locs)
locs.pop('__builtins__', None)
# Import all objects from the base module
diff --git a/devtools/tests/test_quickstart.py b/devtools/tests/test_quickstart.py
index 0f69a3bd..ac09d243 100644
--- a/devtools/tests/test_quickstart.py
+++ b/devtools/tests/test_quickstart.py
@@ -15,7 +15,6 @@
PY_VERSION = sys.version_info[:2]
-PY2 = sys.version_info[0] == 2
PROJECT_NAME = 'TGTest-%02d'
ENV_NAME = 'TESTENV'
CLEANUP = True
diff --git a/pyproject.toml b/pyproject.toml
index 340a354e..96570f1b 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -6,6 +6,7 @@ build-backend = "setuptools.build_meta"
name = "tg.devtools"
version = "2.5.1dev1"
description = "TurboGears 2 DevTools is a command-line toolkit that streamlines TurboGears2 development."
+requires-python = ">=3.10"
readme = { file = "README.rst", content-type = "text/x-rst" }
keywords = ["turbogears", "devtools", "cli", "scaffold", "gearbox"]
classifiers = []