Skip to content

Commit

Permalink
Config with pure python template (#11)
Browse files Browse the repository at this point in the history
* Drop support for Python 2.7, 3.5, 3.6.
* Add support for Python 3.11.
  • Loading branch information
Michael Howitz committed Jan 17, 2023
1 parent 2fe2fa1 commit eea9a63
Show file tree
Hide file tree
Showing 19 changed files with 70 additions and 121 deletions.
17 changes: 7 additions & 10 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,29 @@ jobs:
fail-fast: false
matrix:
os:
- ubuntu
- ["ubuntu", "ubuntu-20.04"]
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"]
- ["pypy-2.7", "pypy"]
- ["3.11", "py311"]
- ["pypy-3.7", "pypy3"]
- ["3.9", "coverage"]

runs-on: ${{ matrix.os }}-latest
runs-on: ${{ matrix.os[1] }}
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
name: ${{ matrix.config[1] }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.config[0] }}
- name: Pip cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ matrix.config[0] }}-${{ hashFiles('setup.*', 'tox.ini') }}
Expand All @@ -58,7 +55,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 }}
4 changes: 2 additions & 2 deletions .meta.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
# https://github.com/zopefoundation/meta/tree/master/config/pure-python
[meta]
template = "pure-python"
commit-id = "ae61f414cfef4e129d275679c6a76dc67b1a2c11"
commit-id = "4f0f7596"

[python]
with-pypy = true
with-legacy-python = true
with-sphinx-doctests = false
with-windows = false
with-future-python = false
with-macos = false

[tox]
use-flake8 = true
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
=========

1.2.1 (unreleased)
==================
2.0 (unreleased)
================

- Drop support for Python 2.7, 3.5, 3.6.

- Add support for Python 3.9, 3.10.
- Add support for Python 3.9, 3.10, 3.11.


1.2.0 (2020-03-06)
Expand Down
2 changes: 1 addition & 1 deletion 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 Down
7 changes: 2 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def read(*rnames):
return f.read()


version = '1.2.1.dev0'
version = '2.0.dev0'

BROWSER_REQUIRES = [
'zope.browser',
Expand Down Expand Up @@ -85,15 +85,12 @@ def read(*rnames):
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'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',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Natural Language :: English',
Expand Down
18 changes: 9 additions & 9 deletions src/zope/file/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ to specify how many bytes to read, or with a negative or omitted
argument to read to the end of the file:

>>> r.read(10)
''
b''
>>> r.read()
''
b''
>>> r.read(-1)
''
b''

Once the accessor has been closed, we can no longer read from it:

Expand Down Expand Up @@ -129,35 +129,35 @@ start of the file:

>>> _ = r.seek(20)
>>> r.read()
'still more'
b'still more'

That's equivalent to passing 0 as the `whence` argument:

>>> _ = r.seek(20, 0)
>>> r.read()
'still more'
b'still more'

We can skip backward and forward relative to the current position by
passing 1 for `whence`:

>>> _ = r.seek(-10, 1)
>>> r.read(5)
'still'
b'still'
>>> _ = r.seek(2, 1)
>>> r.read()
'ore'
b'ore'

We can skip to some position backward from the end of the file using
the value 2 for `whence`:

>>> _ = r.seek(-10, 2)
>>> r.read()
'still more'
b'still more'

>>> _ = r.seek(0)
>>> _ = r.seek(-4, 2)
>>> r.read()
'more'
b'more'

>>> r.close()

Expand Down
4 changes: 2 additions & 2 deletions src/zope/file/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

@component.adapter(interfaces.IFile)
@interface.implementer(zope.filerepresentation.interfaces.IReadFile)
class ReadFileAdapter(object):
class ReadFileAdapter:

def __init__(self, context):
self.context = context
Expand All @@ -34,7 +34,7 @@ def read(self):

@component.adapter(interfaces.IFile)
@interface.implementer(zope.filerepresentation.interfaces.IWriteFile)
class WriteFileAdapter(object):
class WriteFileAdapter:

def __init__(self, context):
self.context = context
Expand Down
2 changes: 1 addition & 1 deletion src/zope/file/adapters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ whose size we can get:
>>> from zope.filerepresentation.interfaces import IReadFile, IWriteFile
>>> r = IReadFile(f)
>>> r.read()
'hello'
b'hello'

>>> r.size()
5
Expand Down
2 changes: 1 addition & 1 deletion src/zope/file/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

@interface.implementer(zope.size.interfaces.ISized)
@component.adapter(zope.file.interfaces.IFile)
class Sized(object):
class Sized:

def __init__(self, context):
self.context = context
Expand Down
8 changes: 4 additions & 4 deletions src/zope/file/browser.rst
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Let's do some imports and create a new file object:
>>> s.sizeForSorting()
('byte', 0)
>>> s.sizeForDisplay()
u'0 KB'
'0 KB'

Let's add some content to the file:

Expand All @@ -37,7 +37,7 @@ The sized adapter now reflects the updated size:
>>> s.sizeForSorting()
('byte', 9)
>>> s.sizeForDisplay()
u'1 KB'
'1 KB'

Let's try again with a larger file size:

Expand All @@ -48,7 +48,7 @@ Let's try again with a larger file size:
('byte', 1048586)
>>> m = s.sizeForDisplay()
>>> m
u'${size} MB'
'${size} MB'
>>> m.mapping
{'size': '1.00'}

Expand All @@ -61,6 +61,6 @@ And still a bigger size:
('byte', 1572864)
>>> m = s.sizeForDisplay()
>>> m
u'${size} MB'
'${size} MB'
>>> m.mapping
{'size': '1.50'}
2 changes: 1 addition & 1 deletion src/zope/file/contenttype.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def setUpWidgets(self, ignore_request=False):
else:
self.have_encoded = False
self.form_fields = zope.formlib.form.Fields(*fields)
super(ContentTypeForm, self).setUpWidgets(
super().setUpWidgets(
ignore_request=ignore_request)

def save_validator(self, action, data):
Expand Down
20 changes: 7 additions & 13 deletions src/zope/file/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,12 @@ def getHeaders(context, contentType=None, downloadName=None,
downloadName = downloadName or context.__name__
if contentDisposition:
if downloadName:
# Headers must be native strings. Under Py2, we probably
# need to encode the name
if str is bytes:
if not isinstance(downloadName, bytes):
downloadName = downloadName.encode("utf-8")
else:
# Under Python 3, we need to pass the native string,
# but characters greater than 256 will fail to be encoded
# by the WSGI server, which should be using latin-1. The
# solution is to smuggle them through using double encoding,
# allowing the final recipient to decode its string using utf-8
downloadName = downloadName.encode('utf-8').decode('latin-1')
# Headers must be native strings,
# but characters greater than 256 will fail to be encoded
# by the WSGI server, which should be using latin-1. The
# solution is to smuggle them through using double encoding,
# allowing the final recipient to decode its string using utf-8
downloadName = downloadName.encode('utf-8').decode('latin-1')

contentDisposition += (
'; filename="%s"' % downloadName
Expand All @@ -83,7 +77,7 @@ def getHeaders(context, contentType=None, downloadName=None,


@zope.interface.implementer(zope.publisher.interfaces.http.IResult)
class DownloadResult(object):
class DownloadResult:
"""Result object for a download request."""

def __init__(self, context):
Expand Down
2 changes: 1 addition & 1 deletion src/zope/file/download.rst
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ expect:
>>> result = DownloadResult(f)
>>> L = list(result)
>>> b"".join(L)
'some text'
b'some text'

If the body content is really large, the iterator may provide more
than one chunk of data:
Expand Down
29 changes: 4 additions & 25 deletions src/zope/file/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
__docformat__ = "reStructuredText"

import doctest

from six.moves import urllib_parse as urllib
import urllib.parse

import zope.app.wsgi.testlayer
import zope.security.checker
Expand Down Expand Up @@ -46,26 +45,6 @@ class BrowserLayer(zope.testbrowser.wsgi.TestBrowserLayer,
ZopeFileLayer = BrowserLayer(zope.file, allowTearDown=True)


class _FakeResponse(FakeResponse):
if str is bytes:
# py2 has a bug, assuming headers are in unicode already, or
# are decodable implicitly to ascii
def getHeaders(self):
headers = super(_FakeResponse, self).getHeaders()
result = []
for key, value in headers:
assert isinstance(key, str)
assert isinstance(value, str)
result.append((key.decode('latin-1'),
value.decode('latin-1')))
return result

# we also need to ensure we get something that can be printed
# in ascii and produce the same output as Py3.
def __str__(self):
return self.getOutput().decode('latin-1').encode("utf-8")


def FunctionalBlobDocFileSuite(*paths, **kw):
globs = kw.setdefault('globs', {})
globs['getRootFolder'] = ZopeFileLayer.getRootFolder
Expand All @@ -80,7 +59,7 @@ def _http(query_str, *args, **kwargs):
# Strip leading \n
query_str = query_str.lstrip()
response = http(wsgi_app, query_str, *args, **kwargs)
response.__class__ = _FakeResponse
response.__class__ = FakeResponse
return response

test.globs['http'] = _http
Expand Down Expand Up @@ -153,7 +132,7 @@ def _extractContentInfo(self, item):
oid, obj = item
info['id'] = info['cb_id'] = oid
info['object'] = obj
info['url'] = urllib.quote(oid.encode('utf-8'))
info['url'] = urllib.parse.quote(oid.encode('utf-8'))
return info


Expand All @@ -176,7 +155,7 @@ def __call__(self):
redirect_url = item['action']
if not redirect_url.lower().startswith(('../', 'javascript:', '++')):
self.request.response.redirect(redirect_url)
return u''
return ''

# The zope.app.publication version would redirect to /
# with self.request.response.redirect('.) and return u''.
Expand Down

0 comments on commit eea9a63

Please sign in to comment.