Skip to content

Commit

Permalink
Drop Python 3.5
Browse files Browse the repository at this point in the history
  • Loading branch information
asvetlov committed Sep 17, 2019
1 parent 5d88cb0 commit 7b4cca0
Show file tree
Hide file tree
Showing 14 changed files with 29 additions and 112 deletions.
2 changes: 0 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ environment:
PYTHONIOENCODING: "utf8:backslashreplace"
PYTHONLEGACYWINDOWSSTDIO: "1"
matrix:
- PYTHON: "C:\\Python35"
- PYTHON: "C:\\Python35-x64"
- PYTHON: "C:\\Python36"
- PYTHON: "C:\\Python36-x64"
- PYTHON: "C:\\Python37"
Expand Down
25 changes: 1 addition & 24 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ sudo: required
language: python

python:
- &py35 3.5
- &py36 3.6
- &py37 3.7
- nightly
- &pypy3 pypy3.5-6.0.0
- &pypy3 pypy3

install:
- &upgrade_python_toolset pip install --upgrade pip wheel setuptools
Expand Down Expand Up @@ -312,14 +311,6 @@ jobs:
deploy:
<<: *deploy_step

# Build and deploy MacOS binary wheels for each OSX+Python combo possible
# OS X 10.10, Python 3.5
- <<: *osx_pypi_deploy_base_1010
name: *env_os1010_msg
python: *py35
env:
<<: *env_osx_base
PYTHON_VERSION: *py35
# OS X 10.10, Python 3.6
- <<: *osx_pypi_deploy_base_1010
name: *env_os1010_msg
Expand All @@ -334,13 +325,6 @@ jobs:
env:
<<: *env_osx_base
PYTHON_VERSION: *py37
# OS X 10.11, Python 3.5
- <<: *osx_pypi_deploy_base_1011
name: *env_os1011_msg
python: *py35
env:
<<: *env_osx_base
PYTHON_VERSION: *py35
# OS X 10.11, Python 3.6
- <<: *osx_pypi_deploy_base_1011
name: *env_os1011_msg
Expand All @@ -355,13 +339,6 @@ jobs:
env:
<<: *env_osx_base
PYTHON_VERSION: *py37
# OS X 10.12, Python 3.5
- <<: *osx_pypi_deploy_base_1012
name: *env_os1012_msg
python: *py35
env:
<<: *env_osx_base
PYTHON_VERSION: *py35
# OS X 10.12, Python 3.6
- <<: *osx_pypi_deploy_base_1012
name: *env_os1012_msg
Expand Down
6 changes: 0 additions & 6 deletions docs/client_quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -354,12 +354,6 @@ can chain get and post requests together::
await session.post('http://httpbin.org/post',
data=resp.content)

.. note::

Python 3.5 has no native support for asynchronous generators, use
``async_generator`` library as workaround.


.. _aiohttp-client-websockets:


Expand Down
25 changes: 0 additions & 25 deletions docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,31 +77,6 @@ other resource you want to share between handlers.
return app


Why is Python 3.5.3 the lowest supported version?
-------------------------------------------------

Python 3.5.2 fixes the protocol for async iterators: ``__aiter__()`` is
not a coroutine but a regular function.

Python 3.5.3 has a more important change: :func:`asyncio.get_event_loop`
returns the running loop instance if called from a coroutine.
Previously it returned a *default* loop, set by
:func:`asyncio.set_event_loop`.

Previous to Python 3.5.3,
:func:`asyncio.get_event_loop` was not reliable, so users were
forced to explicitly pass the event loop instance everywhere.
If a future object were created for one event loop
(e.g. the default loop) but a coroutine was run by another loop, the coroutine
was never awaited. As a result, the task would hang.

Keep in mind that every internal ``await`` expression either passed
instantly or paused, waiting for a future.

It's extremely important that all tasks (coroutine runners) and
futures use the same event loop.


How can middleware store data for web handlers to use?
------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ Continuous Integration.
Dependencies
============

- Python 3.5.3+
- Python 3.6+
- *async_timeout*
- *attrs*
- *chardet*
Expand Down
4 changes: 0 additions & 4 deletions docs/web_advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -699,10 +699,6 @@ one ``yield``.
*aiohttp* guarantees that *cleanup code* is called if and only if
*startup code* was successfully finished.

Asynchronous generators are supported by Python 3.6+, on Python 3.5
please use `async_generator <https://pypi.org/project/async_generator/>`_
library.

.. versionadded:: 3.1

.. _aiohttp-web-nested-applications:
Expand Down
1 change: 0 additions & 1 deletion requirements/ci-wheel.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
-r flake.txt
attrs==19.1.0
async-generator==1.10
async-timeout==3.0.1
Brotli==1.0.7
cchardet==2.1.4
Expand Down
4 changes: 0 additions & 4 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ ignore_missing_imports = true
ignore_missing_imports = true


[mypy-async_generator]
ignore_missing_imports = true


[mypy-aiodns]
ignore_missing_imports = true

Expand Down
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
from setuptools import Extension, setup


if sys.version_info < (3, 5, 3):
raise RuntimeError("aiohttp 3.x requires Python 3.5.3+")
if sys.version_info < (3, 6):
raise RuntimeError("aiohttp 4.x requires Python 3.6+")


NO_EXTENSIONS = bool(os.environ.get('AIOHTTP_NO_EXTENSIONS')) # type: bool
Expand Down Expand Up @@ -101,9 +101,9 @@ def read(f):
'Intended Audience :: Developers',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Development Status :: 5 - Production/Stable',
'Operating System :: POSIX',
'Operating System :: MacOS :: MacOS X',
Expand All @@ -130,7 +130,7 @@ def read(f):
},
license='Apache 2',
packages=['aiohttp'],
python_requires='>=3.5.3',
python_requires='>=3.6',
install_requires=install_requires,
extras_require={
'speedups': [
Expand Down
7 changes: 2 additions & 5 deletions tests/test_client_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from unittest import mock

import pytest
from async_generator import async_generator, yield_
from multidict import MultiDict

import aiohttp
Expand Down Expand Up @@ -1517,12 +1516,11 @@ async def handler(request):
with fname.open('rb') as f:
data_size = len(f.read())

@async_generator
async def gen(fname):
with fname.open('rb') as f:
data = f.read(100)
while data:
await yield_(data)
yield data
data = f.read(100)

resp = await client.post(
Expand Down Expand Up @@ -2734,10 +2732,9 @@ async def handler(request):

client = await aiohttp_client(app)

@async_generator
async def gen():
for i in range(100):
await yield_(b'1234567890')
yield b'1234567890'

resp = await client.post('/', data=gen())
assert resp.status == 200
Expand Down
20 changes: 8 additions & 12 deletions tests/test_client_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from unittest import mock

import pytest
from async_generator import async_generator, yield_
from multidict import CIMultiDict, CIMultiDictProxy, istr
from yarl import URL

Expand Down Expand Up @@ -866,10 +865,9 @@ async def test_expect_100_continue_header(loop, conn) -> None:


async def test_data_stream(loop, buf, conn) -> None:
@async_generator
async def gen():
await yield_(b'binary data')
await yield_(b' result')
yield b'binary data'
yield b' result'

req = ClientRequest(
'POST', URL('http://python.org/'), data=gen(), loop=loop)
Expand Down Expand Up @@ -906,9 +904,8 @@ async def test_data_file(loop, buf, conn) -> None:
async def test_data_stream_exc(loop, conn) -> None:
fut = loop.create_future()

@async_generator
async def gen():
await yield_(b'binary data')
yield b'binary data'
await fut

req = ClientRequest(
Expand All @@ -932,9 +929,10 @@ async def throw_exc():
async def test_data_stream_exc_chain(loop, conn) -> None:
fut = loop.create_future()

@async_generator
async def gen():
await fut
return
yield

req = ClientRequest('POST', URL('http://python.org/'),
data=gen(), loop=loop)
Expand All @@ -959,10 +957,9 @@ async def throw_exc():


async def test_data_stream_continue(loop, buf, conn) -> None:
@async_generator
async def gen():
await yield_(b'binary data')
await yield_(b' result')
yield b'binary data'
yield b' result'

req = ClientRequest(
'POST', URL('http://python.org/'), data=gen(),
Expand Down Expand Up @@ -1003,10 +1000,9 @@ async def coro():


async def test_close(loop, buf, conn) -> None:
@async_generator
async def gen():
await asyncio.sleep(0.00001)
await yield_(b'result')
yield b'result'

req = ClientRequest(
'POST', URL('http://python.org/'), data=gen(), loop=loop)
Expand Down
9 changes: 4 additions & 5 deletions tests/test_payload.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from io import StringIO

import pytest
from async_generator import async_generator

from aiohttp import payload

Expand Down Expand Up @@ -90,18 +89,18 @@ def test_string_io_payload() -> None:


def test_async_iterable_payload_default_content_type() -> None:
@async_generator
async def gen():
pass
return
yield

p = payload.AsyncIterablePayload(gen())
assert p.content_type == 'application/octet-stream'


def test_async_iterable_payload_explicit_content_type() -> None:
@async_generator
async def gen():
pass
return
yield

p = payload.AsyncIterablePayload(gen(), content_type='application/custom')
assert p.content_type == 'application/custom'
Expand Down
21 changes: 7 additions & 14 deletions tests/test_web_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from unittest import mock

import pytest
from async_generator import async_generator, yield_

from aiohttp import log, web
from aiohttp.helpers import PY_36
Expand Down Expand Up @@ -182,10 +181,9 @@ async def test_cleanup_ctx() -> None:
out = []

def f(num):
@async_generator
async def inner(app):
out.append('pre_' + str(num))
await yield_(None)
yield None
out.append('post_' + str(num))
return inner

Expand All @@ -205,12 +203,11 @@ async def test_cleanup_ctx_exception_on_startup() -> None:
exc = Exception('fail')

def f(num, fail=False):
@async_generator
async def inner(app):
out.append('pre_' + str(num))
if fail:
raise exc
await yield_(None)
yield None
out.append('post_' + str(num))
return inner

Expand All @@ -233,10 +230,9 @@ async def test_cleanup_ctx_exception_on_cleanup() -> None:
exc = Exception('fail')

def f(num, fail=False):
@async_generator
async def inner(app):
out.append('pre_' + str(num))
await yield_(None)
yield None
out.append('post_' + str(num))
if fail:
raise exc
Expand All @@ -259,10 +255,9 @@ async def test_cleanup_ctx_exception_on_cleanup_multiple() -> None:
out = []

def f(num, fail=False):
@async_generator
async def inner(app):
out.append('pre_' + str(num))
await yield_(None)
yield None
out.append('post_' + str(num))
if fail:
raise Exception('fail_' + str(num))
Expand All @@ -288,12 +283,11 @@ async def test_cleanup_ctx_multiple_yields() -> None:
out = []

def f(num):
@async_generator
async def inner(app):
out.append('pre_' + str(num))
await yield_(None)
yield None
out.append('post_' + str(num))
await yield_(None)
yield None
return inner

app.cleanup_ctx.append(f(1))
Expand Down Expand Up @@ -378,12 +372,11 @@ async def on_startup(app):
ctx_pre_called = False
ctx_post_called = False

@async_generator
async def cleanup_ctx(app):
nonlocal ctx_pre_called, ctx_post_called
ctx_pre_called = True
app['cleanup'] = True
await yield_(None)
yield None
ctx_post_called = True

subapp.cleanup_ctx.append(cleanup_ctx)
Expand Down
Loading

0 comments on commit 7b4cca0

Please sign in to comment.