Skip to content

Commit

Permalink
Drop Python 3.7 support
Browse files Browse the repository at this point in the history
  • Loading branch information
HardNorth committed Nov 29, 2024
1 parent 2d1e5d4 commit 39fa31c
Show file tree
Hide file tree
Showing 14 changed files with 15 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13' ]
python-version: [ '3.8', '3.9', '3.10', '3.11', '3.12', '3.13' ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Changelog

## [Unreleased]
### Removed
- `Python 3.7` support, by @HardNorth

## [5.5.10]
### Added
Expand Down
6 changes: 1 addition & 5 deletions reportportal_client/aio/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
"""This module contains customized asynchronous Tasks and Task Factories for the ReportPortal client."""

import asyncio
import sys
from abc import abstractmethod
from asyncio import Future
from typing import TypeVar, Generic, Union, Generator, Awaitable, Optional
Expand Down Expand Up @@ -54,10 +53,7 @@ def __init__(
:param name: the name of the task
"""
self.name = name
if sys.version_info < (3, 8):
super().__init__(coro, loop=loop)
else:
super().__init__(coro, loop=loop, name=name)
super().__init__(coro, loop=loop, name=name)

@abstractmethod
def blocking_result(self) -> _T:
Expand Down
27 changes: 7 additions & 20 deletions reportportal_client/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import asyncio
import inspect
import logging
import sys
import threading
import time
import uuid
Expand Down Expand Up @@ -203,25 +202,13 @@ def get_package_parameters(package_name: str, parameters: List[str] = None) -> L
if not parameters:
return result

if sys.version_info < (3, 8):
from pkg_resources import get_distribution, DistributionNotFound
try:
package_info = get_distribution(package_name)
except DistributionNotFound:
return [None] * len(parameters)
for param in parameters:
if param.lower() == 'name':
param = 'project_name'
result.append(getattr(package_info, param, None))
else:
# noinspection PyCompatibility
from importlib.metadata import distribution, PackageNotFoundError
try:
package_info = distribution(package_name)
except PackageNotFoundError:
return [None] * len(parameters)
for param in parameters:
result.append(package_info.metadata[param.lower()[:1].upper() + param.lower()[1:]])
from importlib.metadata import distribution, PackageNotFoundError
try:
package_info = distribution(package_name)
except PackageNotFoundError:
return [None] * len(parameters)
for param in parameters:
result.append(package_info.metadata[param.lower()[:1].upper() + param.lower()[1:]])
return result


Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
aenum
requests>=2.31.0
aiohttp>=3.8.6
requests>=2.32.3
aiohttp>=3.10.11
certifi>=2024.8.30
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from setuptools import setup, find_packages

__version__ = '5.5.11'
__version__ = '5.6.0'

TYPE_STUBS = ['*.pyi']

Expand Down Expand Up @@ -40,7 +40,6 @@ def read_file(fname):
license='Apache 2.0.',
keywords=['testing', 'reporting', 'reportportal', 'client'],
classifiers=[
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
Expand Down
7 changes: 1 addition & 6 deletions tests/_internal/services/test_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
# limitations under the License

import re
import sys
from unittest import mock

# noinspection PyPackageRequirements
Expand Down Expand Up @@ -107,13 +106,9 @@ def test_same_client_id(mocked_requests):
assert result1 == result2


MOCKED_AIOHTTP = None
if not sys.version_info < (3, 8):
MOCKED_AIOHTTP = mock.AsyncMock()
MOCKED_AIOHTTP = mock.AsyncMock()


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="the test requires AsyncMock which was introduced in Python 3.8")
@mock.patch('reportportal_client._internal.services.statistics.get_client_id',
mock.Mock(return_value='555'))
@mock.patch('reportportal_client._internal.services.statistics.aiohttp.ClientSession.post', MOCKED_AIOHTTP)
Expand Down
55 changes: 0 additions & 55 deletions tests/aio/test_aio_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ async def test_retries_param(retry_num, expected_class, expected_param):
assert getattr(session, '_RetryingClientSession__retry_number') == expected_param


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="For some reasons this does not work on Python 3.7 on Ubuntu, "
"but works on my Mac. Unfortunately GHA use Python 3.7 on Ubuntu.")
@pytest.mark.parametrize(
'timeout_param, expected_connect_param, expected_sock_read_param',
[
Expand Down Expand Up @@ -134,8 +131,6 @@ def test_clone():
EXPECTED_DEBUG_URL = f'http://endpoint/ui/#project/userdebug/all/{LAUNCH_ID}'


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="the test requires AsyncMock which was introduced in Python 3.8")
@pytest.mark.parametrize(
'launch_mode, project_name, expected_url',
[
Expand All @@ -160,9 +155,6 @@ async def get_call(*args, **kwargs):
assert await (aio_client.get_launch_ui_url('test_launch_uuid')) == expected_url


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="For some reasons this does not work on Python 3.7 on Ubuntu, "
"but works on my Mac. Unfortunately GHA use Python 3.7 on Ubuntu.")
@pytest.mark.parametrize('default', [True, False])
@mock.patch('reportportal_client.aio.client.aiohttp.TCPConnector')
@pytest.mark.asyncio
Expand All @@ -179,9 +171,6 @@ async def test_verify_ssl_default(connector_mock: mock.Mock, default: bool):
assert len(ssl_context.get_ca_certs()) > 0


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="For some reasons this does not work on Python 3.7 on Ubuntu, "
"but works on my Mac. Unfortunately GHA use Python 3.7 on Ubuntu.")
@pytest.mark.parametrize('param_value', [False, None])
@mock.patch('reportportal_client.aio.client.aiohttp.TCPConnector')
@pytest.mark.asyncio
Expand All @@ -194,9 +183,6 @@ async def test_verify_ssl_off(connector_mock: mock.Mock, param_value):
assert ssl_context is not None and isinstance(ssl_context, bool) and not ssl_context


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="For some reasons this does not work on Python 3.7 on Ubuntu, "
"but works on my Mac. Unfortunately GHA use Python 3.7 on Ubuntu.")
@mock.patch('reportportal_client.aio.client.aiohttp.TCPConnector')
@pytest.mark.asyncio
async def test_verify_ssl_str(connector_mock: mock.Mock):
Expand All @@ -213,9 +199,6 @@ async def test_verify_ssl_str(connector_mock: mock.Mock):
assert certificate['notAfter'] == 'Jun 4 11:04:38 2035 GMT'


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="For some reasons this does not work on Python 3.7 on Ubuntu, "
"but works on my Mac. Unfortunately GHA use Python 3.7 on Ubuntu.")
@mock.patch('reportportal_client.aio.client.aiohttp.TCPConnector')
@pytest.mark.asyncio
async def test_keepalive_timeout(connector_mock: mock.Mock):
Expand All @@ -229,8 +212,6 @@ async def test_keepalive_timeout(connector_mock: mock.Mock):
assert timeout is not None and timeout == keepalive_timeout


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="the test requires AsyncMock which was introduced in Python 3.8")
@pytest.mark.asyncio
async def test_close(aio_client: Client):
# noinspection PyTypeChecker
Expand Down Expand Up @@ -260,8 +241,6 @@ def verify_attributes(expected_attributes: Optional[dict], actual_attributes: Op
assert attribute.get('system') == hidden


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_start_launch(aio_client: Client):
# noinspection PyTypeChecker
Expand Down Expand Up @@ -292,8 +271,6 @@ async def test_start_launch(aio_client: Client):
verify_attributes(attributes, actual_attributes)


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@mock.patch('reportportal_client.aio.client.async_send_event')
@pytest.mark.asyncio
async def test_start_launch_statistics_send(async_send_event):
Expand Down Expand Up @@ -321,8 +298,6 @@ async def test_start_launch_statistics_send(async_send_event):
assert len(kwargs.items()) == 0


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@mock.patch('reportportal_client.aio.client.getenv')
@mock.patch('reportportal_client.aio.client.async_send_event')
@pytest.mark.asyncio
Expand All @@ -343,8 +318,6 @@ async def test_start_launch_no_statistics_send(async_send_event, getenv):
async_send_event.assert_not_called()


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="the test requires AsyncMock which was introduced in Python 3.8")
@pytest.mark.asyncio
async def test_launch_uuid_print():
str_io = StringIO()
Expand All @@ -358,8 +331,6 @@ async def test_launch_uuid_print():
assert 'ReportPortal Launch UUID: ' in str_io.getvalue()


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="the test requires AsyncMock which was introduced in Python 3.8")
@pytest.mark.asyncio
async def test_no_launch_uuid_print():
str_io = StringIO()
Expand All @@ -373,8 +344,6 @@ async def test_no_launch_uuid_print():
assert 'ReportPortal Launch UUID: ' not in str_io.getvalue()


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="the test requires AsyncMock which was introduced in Python 3.8")
@pytest.mark.asyncio
@mock.patch('reportportal_client.client.sys.stdout', new_callable=StringIO)
async def test_launch_uuid_print_default_io(mock_stdout):
Expand All @@ -386,8 +355,6 @@ async def test_launch_uuid_print_default_io(mock_stdout):
assert 'ReportPortal Launch UUID: ' in mock_stdout.getvalue()


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="the test requires AsyncMock which was introduced in Python 3.8")
@pytest.mark.asyncio
@mock.patch('reportportal_client.client.sys.stdout', new_callable=StringIO)
async def test_launch_uuid_print_default_print(mock_stdout):
Expand Down Expand Up @@ -427,8 +394,6 @@ def request_error(*args, **kwargs):
raise ValueError()


@pytest.mark.skipif(sys.version_info < (3, 8),
reason="the test requires AsyncMock which was introduced in Python 3.8")
@pytest.mark.parametrize(
'requests_method, client_method, client_params',
[
Expand Down Expand Up @@ -479,8 +444,6 @@ def verify_parameters(expected_parameters: dict, actual_parameters: List[dict]):
assert expected_parameters.get(attribute.get('key')) == attribute.get('value')


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.parametrize(
'parent_id, expected_uri',
[
Expand Down Expand Up @@ -533,8 +496,6 @@ async def test_start_test_item(aio_client: Client, parent_id, expected_uri):
verify_parameters(parameters, actual_parameters)


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_start_test_item_default_values(aio_client: Client):
# noinspection PyTypeChecker
Expand Down Expand Up @@ -576,8 +537,6 @@ def mock_basic_put_response(session):
session.put.return_value = return_object


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_finish_test_item(aio_client: Client):
# noinspection PyTypeChecker
Expand Down Expand Up @@ -618,8 +577,6 @@ async def test_finish_test_item(aio_client: Client):
assert entry[1] == expected_issue[entry[0]]


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_finish_test_item_default_values(aio_client: Client):
# noinspection PyTypeChecker
Expand Down Expand Up @@ -649,8 +606,6 @@ async def test_finish_test_item_default_values(aio_client: Client):
assert actual_json.get('issue') is None


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_finish_launch(aio_client: Client):
# noinspection PyTypeChecker
Expand Down Expand Up @@ -678,8 +633,6 @@ async def test_finish_launch(aio_client: Client):
verify_attributes(attributes, actual_attributes)


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_finish_launch_default_values(aio_client: Client):
# noinspection PyTypeChecker
Expand Down Expand Up @@ -711,8 +664,6 @@ def mock_basic_get_response(session):
session.get.return_value = return_object


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_update_item(aio_client: Client):
# noinspection PyTypeChecker
Expand All @@ -738,8 +689,6 @@ async def test_update_item(aio_client: Client):
verify_attributes(attributes, actual_attributes)


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_get_item_id_by_uuid(aio_client: Client):
# noinspection PyTypeChecker
Expand All @@ -756,8 +705,6 @@ async def test_get_item_id_by_uuid(aio_client: Client):
assert expected_uri == call_args[0][0]


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_get_launch_ui_url(aio_client: Client):
# noinspection PyTypeChecker
Expand All @@ -774,8 +721,6 @@ async def test_get_launch_ui_url(aio_client: Client):
assert expected_uri == call_args[0][0]


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.parametrize(
'method, mock_method, call_method, arguments',
[
Expand Down
8 changes: 0 additions & 8 deletions tests/aio/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ def test_clone():
and async_client.current_item() == cloned.current_item()


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_start_launch():
aio_client = mock.AsyncMock()
Expand All @@ -92,8 +90,6 @@ async def test_start_launch():
assert kwargs.get('rerun_of') == rerun_of


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.parametrize(
'launch_uuid, method, params',
[
Expand Down Expand Up @@ -154,8 +150,6 @@ async def test_launch_uuid_usage(launch_uuid, method, params):
assert args[i + 1] == param


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_start_item_tracking(async_client: AsyncRPClient):
aio_client = async_client.client
Expand All @@ -174,8 +168,6 @@ async def test_start_item_tracking(async_client: AsyncRPClient):
assert async_client.current_item() is None


@pytest.mark.skipif(sys.version_info < (3, 8),
reason='the test requires AsyncMock which was introduced in Python 3.8')
@pytest.mark.asyncio
async def test_logs_flush_on_close(async_client: AsyncRPClient):
# noinspection PyTypeChecker
Expand Down
Loading

0 comments on commit 39fa31c

Please sign in to comment.