Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop Python < 3.7 #116

Merged
merged 4 commits into from
Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,12 @@ jobs:
config:
# [Python version, tox env]
- ["3.9", "lint"]
- ["2.7", "py27"]
- ["3.5", "py35"]
- ["3.6", "py36"]
- ["3.7", "py37"]
- ["3.8", "py38"]
- ["3.9", "py39"]
- ["3.10", "py310"]
- ["3.11", "py311"]
- ["pypy-2.7", "pypy"]
- ["pypy-3.7", "pypy3"]
- ["pypy-3.9", "pypy3"]
- ["3.9", "docs"]
- ["3.9", "coverage"]

Expand Down Expand Up @@ -60,7 +56,7 @@ jobs:
- name: Coverage
if: matrix.config[1] == 'coverage'
run: |
pip install coveralls coverage-python-version
pip install coveralls
coveralls --service=github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 1 addition & 2 deletions .meta.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
[meta]
template = "pure-python"
commit-id = "200573eb414d2228d463da3de7d71a6d6335a704"
commit-id = "fe63cb4c"

[python]
with-pypy = true
with-legacy-python = true
with-docs = true
with-sphinx-doctests = true
with-windows = false
Expand Down
8 changes: 5 additions & 3 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
Changes
=========

3.1.1 (unreleased)
==================
4.0 (unreleased)
================

- Drop support for Python 2.7, 3.5, 3.6.

- Nothing changed yet.
- Drop support for deprecated ``python setup.py test.``.


3.1.0 (2023-03-17)
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Generated from:
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
[bdist_wheel]
universal = 1
universal = 0

[flake8]
doctests = 1
Expand All @@ -18,7 +18,7 @@ ignore =
force_single_line = True
combine_as_imports = True
sections = FUTURE,STDLIB,THIRDPARTY,ZOPE,FIRSTPARTY,LOCALFOLDER
known_third_party = six, docutils, pkg_resources
known_third_party = docutils, pkg_resources, pytz
known_zope =
known_first_party =
default_section = ZOPE
Expand Down
18 changes: 5 additions & 13 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from setuptools import setup


version = '3.1.1.dev0'
version = '4.0.dev0'
here = os.path.abspath(os.path.dirname(__file__))


Expand All @@ -43,11 +43,7 @@ def _read_file(filename):
"Operating System :: Microsoft :: Windows",
"Operating System :: Unix",
"Programming Language :: Python",
"Programming Language :: Python :: 2",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
Expand All @@ -57,8 +53,8 @@ def _read_file(filename):
"Programming Language :: Python :: Implementation :: PyPy",
"Framework :: ZODB",
],
author="Zope Corporation",
author_email="zodb-dev@zope.org",
author="Zope Foundation and Contributors",
author_email="zodb-dev@zope.dev",
url="https://github.com/zopefoundation/transaction",
project_urls={
'Issue Tracker': ('https://github.com/zopefoundation/'
Expand All @@ -71,17 +67,13 @@ def _read_file(filename):
package_dir={'': 'src'},
include_package_data=True,
zip_safe=False,
test_suite="transaction.tests",
tests_require=tests_require,
python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*',
python_requires='>=3.7',
install_requires=[
'zope.interface',
],
extras_require={
'docs': ['Sphinx', 'repoze.sphinx.autointerface'],
'test': tests_require,
'testing': ['nose', 'coverage'] + tests_require,
'testing': ['coverage'] + tests_require,
},
entry_points="""\
"""
)
6 changes: 3 additions & 3 deletions src/transaction/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
#: A thread-safe `~ITransactionManager`
from transaction._manager import ThreadTransactionManager

# NB: "with transaction:" does not work under Python 3 because they worked
# NB: "with transaction:" does not work because they worked
# really hard to break looking up special methods like __enter__ and __exit__
# via getattr and getattribute; see http://bugs.python.org/issue12022. On
# Python 3, you must use ``with transaction.manager`` instead.
# via getattr and getattribute; see http://bugs.python.org/issue12022.
# You must use ``with transaction.manager`` instead.

#: The default transaction manager (a `~.ThreadTransactionManager`). All other
#: functions in this module refer to this object.
Expand Down
75 changes: 5 additions & 70 deletions src/transaction/_compat.py
Original file line number Diff line number Diff line change
@@ -1,75 +1,10 @@
import sys


PY3 = sys.version_info[0] == 3
JYTHON = sys.platform.startswith('java')

if PY3: # pragma: no cover
text_type = str
else: # pragma: no cover
# py2
text_type = unicode # noqa: F821 undefined name 'unicode'


def text_(s):
if not isinstance(s, text_type): # pragma: no cover
if not isinstance(s, str): # pragma: no cover
s = s.decode('utf-8')
return s


if PY3: # pragma: no cover
def native_(s, encoding='latin-1', errors='strict'):
if isinstance(s, text_type):
return s
return str(s, encoding, errors)
else: # pragma: no cover
def native_(s, encoding='latin-1', errors='strict'):
if isinstance(s, text_type):
return s.encode(encoding, errors)
return str(s)

if PY3: # pragma: no cover
from io import StringIO
else: # pragma: no cover
from io import BytesIO

# Prevent crashes in IPython when writing tracebacks if a commit fails
# ref:
# https://github.com/ipython/ipython/issues/9126#issuecomment-174966638

class StringIO(BytesIO):
def write(self, s):
s = native_(s, encoding='utf-8')
super(StringIO, self).write(s)


if PY3: # pragma: no cover
def reraise(tp, value, tb=None):
if value.__traceback__ is not tb: # pragma: no cover
raise value.with_traceback(tb)
raise value

else: # pragma: no cover
def exec_(code, globs=None, locs=None):
"""Execute code in a namespace."""
if globs is None:
frame = sys._getframe(1)
globs = frame.f_globals
if locs is None:
locs = frame.f_locals
del frame
elif locs is None:
locs = globs
exec("""exec code in globs, locs""")

exec_("""def reraise(tp, value, tb=None):
raise tp, value, tb
""")

# isort: off

try: # pragma: no cover
from threading import get_ident as get_thread_ident
except ImportError: # pragma: no cover
# PY2
from thread import get_ident as get_thread_ident # noqa: F401 unused
def native_(s, encoding='latin-1', errors='strict'):
if isinstance(s, str):
return s
return str(s, encoding, errors)
21 changes: 9 additions & 12 deletions src/transaction/_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

from zope.interface import implementer

from transaction._compat import reraise
from transaction._compat import text_
from transaction._transaction import Transaction
from transaction.interfaces import AlreadyInTransaction
Expand Down Expand Up @@ -60,7 +59,7 @@ def _new_transaction(txn, synchs):


@implementer(ITransactionManager)
class TransactionManager(object):
class TransactionManager:
"""Single-thread implementation of
`~transaction.interfaces.ITransactionManager`.
"""
Expand Down Expand Up @@ -183,20 +182,18 @@ def run(self, func=None, tries=3):
if tries <= 0:
raise ValueError("tries must be > 0")

# These are ordinarily native strings, but that's
# These are ordinarily strings, but that's
# not required. A callable class could override them
# to anything, and a Python 2.7 file could have
# imported `from __future__ import unicode_literals`
# which gets unicode docstrings.
# to anything.
name = func.__name__
doc = func.__doc__

name = text_(name) if name else u''
doc = text_(doc) if doc else u''
name = text_(name) if name else ''
doc = text_(doc) if doc else ''

if name and name != u'_':
if name and name != '_':
if doc:
doc = name + u'\n\n' + doc
doc = name + '\n\n' + doc
else:
doc = name

Expand Down Expand Up @@ -290,7 +287,7 @@ def run(self, func=None, tries=3):
return self.manager.run(func, tries)


class Attempt(object):
class Attempt:

success = False

Expand All @@ -302,7 +299,7 @@ def _retry_or_raise(self, t, v, tb):
self.manager.abort()
if retry:
return retry # suppress the exception if necessary
reraise(t, v, tb) # otherwise reraise the exception
raise v.with_traceback(tb) # otherwise reraise the exception

def __enter__(self):
return self.manager.__enter__()
Expand Down
Loading