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 3.5 #4046

Merged
merged 6 commits into from
Oct 2, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
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
asvetlov marked this conversation as resolved.
Show resolved Hide resolved
# 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):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's okay to just remove this check since setuptools that supports python_requires is shipped with Python 3.6.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to fail loudly even on Python 3.5

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