Skip to content

Commit

Permalink
Drop support for EOL Python 3.7 (#105)
Browse files Browse the repository at this point in the history
https://devguide.python.org/versions/

---------

Co-authored-by: Serge Matveenko <[email protected]>
  • Loading branch information
atugushev and lig authored Jul 11, 2023
1 parent 04293bb commit 7f51e74
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 67 deletions.
1 change: 0 additions & 1 deletion .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ jobs:
os:
- Ubuntu
python-version:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ repos:
rev: v3.8.0
hooks:
- id: pyupgrade
args: [--py37-plus]
args: [--py38-plus]
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
Expand Down
4 changes: 2 additions & 2 deletions ansq/tcp/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

if TYPE_CHECKING:
from ansq.tcp.connection import NSQConnection
from ansq.tcp.types import NSQMessage
from ansq.tcp.types import NSQMessage, TCPConnection


class Reader(Client):
Expand Down Expand Up @@ -302,7 +302,7 @@ def _get_producer_addresses(response: Dict[str, Any]) -> List["Address"]:

return addresses

def _on_close_connection(self, connection: "NSQConnection") -> None:
def _on_close_connection(self, connection: "TCPConnection") -> None:
"""A callback to be called after a connection being closed."""
# Remove the connection from the reader so that lookupd could add it later
self._reader.remove_connection(connection)
Expand Down
3 changes: 2 additions & 1 deletion ansq/tcp/types/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

if TYPE_CHECKING:
from ansq.tcp.connection import NSQConnection
from ansq.tcp.types import TCPConnection


class Client:
Expand Down Expand Up @@ -62,7 +63,7 @@ def add_connection(self, connection: "NSQConnection") -> None:
"""Add connection to connections pool."""
self._connections[connection.id] = connection

def remove_connection(self, connection: "NSQConnection") -> None:
def remove_connection(self, connection: "TCPConnection") -> None:
"""Remove connection from connections pool."""
if connection.id in self._connections:
del self._connections[connection.id]
Expand Down
7 changes: 2 additions & 5 deletions ansq/tcp/types/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import functools
import logging
import socket
import sys
import warnings
from asyncio.events import AbstractEventLoop
from asyncio.streams import StreamReader, StreamWriter
Expand Down Expand Up @@ -32,10 +31,8 @@

@functools.lru_cache(maxsize=None)
def _get_version() -> str:
if sys.version_info >= (3, 8):
from importlib import metadata
else:
import importlib_metadata as metadata
from importlib import metadata

return metadata.version("ansq")


Expand Down
17 changes: 6 additions & 11 deletions ansq/utils.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import json
import logging
import re
from dataclasses import asdict, is_dataclass
from datetime import datetime
from decimal import Decimal
from enum import Enum
from functools import singledispatch
from sys import version_info
from typing import Any, Optional, Tuple, Union
from urllib.parse import urlsplit

PY37 = version_info >= (3, 7)


class JSONEncoder(json.JSONEncoder):
def default(self, obj: Any) -> str:
Expand Down Expand Up @@ -46,11 +44,10 @@ def convert_to_bytes(value: Any) -> bytes:
:raises TypeError:
"""
if PY37:
from dataclasses import asdict, is_dataclass

if is_dataclass(value) and not isinstance(value, type):
return convert_to_bytes(asdict(value))
if is_dataclass(value) and not isinstance(value, type):
return convert_to_bytes(asdict(value))

raise TypeError(
"Argument {} expected to be type of "
"bytes, bytearray, str, int, float, dict, Decimal, datetime "
Expand Down Expand Up @@ -106,11 +103,9 @@ def convert_to_str(value: Any) -> str:
:raises TypeError:
"""
if PY37:
from dataclasses import asdict, is_dataclass
if is_dataclass(value) and not isinstance(value, type):
return convert_to_str(asdict(value))

if is_dataclass(value) and not isinstance(value, type):
return convert_to_str(asdict(value))
raise TypeError(
"Argument {} expected to be type of "
"bytes, bytearray, str, int, float, dict, Decimal, datetime "
Expand Down
3 changes: 1 addition & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ packages = find:
install_requires =
aiohttp>=1.0.0
attrs>=20.1
importlib-metadata;python_version<"3.8"
python_requires = >=3.7
python_requires = >=3.8
include_package_data = True

[options.packages.find]
Expand Down
81 changes: 39 additions & 42 deletions tests/test_convert_to_bytes.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
from dataclasses import dataclass
from datetime import datetime
from decimal import Decimal
from enum import Enum
from sys import version_info
from typing import Optional

import pytest

from ansq.utils import convert_to_bytes

PY37 = version_info >= (3, 7)


class Color(Enum):
RED = 1
Expand Down Expand Up @@ -63,51 +61,50 @@ def test_convert_to_bytes(value, expected):
assert convert_to_bytes(value) == expected


if PY37:
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
color: Color = Color.BLUE
name: Optional[str] = None


@dataclass
class Point:
x: int
y: int
color: Color = Color.BLUE
name: Optional[str] = None
@dataclass
class DataclassWithDictPayload:
name: str
payload: dict

@dataclass
class DataclassWithDictPayload:
name: str
payload: dict

@pytest.mark.parametrize(
"value, expected",
@pytest.mark.parametrize(
"value, expected",
(
(Point(10, 20), b'{"x":10,"y":20,"color":"BLUE","name":null}'),
(
(Point(10, 20), b'{"x":10,"y":20,"color":"BLUE","name":null}'),
(
Point(10, 20, Color.RED, "A point"),
b'{"x":10,"y":20,"color":"RED","name":"A point"}',
),
(
DataclassWithDictPayload(
"Some str here",
{
"int": 123,
"float": 123.123,
"str": "str",
"list": [1, 2, 3],
"dict": {"a": 1, "b": 2},
"color": Color.GREEN,
"dataclass": Point(10, 20),
},
),
b'{"name":"Some str here","payload":{"int":123,'
b'"float":123.123,"str":"str","list":[1,2,3],'
b'"dict":{"a":1,"b":2},"color":"GREEN","dataclass":'
b'{"x":10,"y":20,"color":"BLUE","name":null}}}',
Point(10, 20, Color.RED, "A point"),
b'{"x":10,"y":20,"color":"RED","name":"A point"}',
),
(
DataclassWithDictPayload(
"Some str here",
{
"int": 123,
"float": 123.123,
"str": "str",
"list": [1, 2, 3],
"dict": {"a": 1, "b": 2},
"color": Color.GREEN,
"dataclass": Point(10, 20),
},
),
b'{"name":"Some str here","payload":{"int":123,'
b'"float":123.123,"str":"str","list":[1,2,3],'
b'"dict":{"a":1,"b":2},"color":"GREEN","dataclass":'
b'{"x":10,"y":20,"color":"BLUE","name":null}}}',
),
)
def test_convert_dataclass_to_bytes(value, expected):
assert convert_to_bytes(value) == expected
),
)
def test_convert_dataclass_to_bytes(value, expected):
assert convert_to_bytes(value) == expected


@pytest.mark.parametrize("value", (None, [1, 2, 3], (1, 2), ["str_in_list"]))
Expand Down
3 changes: 1 addition & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tox]
envlist =
py3{7,8,9,10,11,12}-cov
py3{8,9,10,11,12}-cov
cov
lint
skip_missing_interpreters = True
Expand All @@ -22,7 +22,6 @@ commands = pre-commit run --all-files --show-diff-on-failure

[gh-actions]
python =
3.7: py37
3.8: py38
3.9: py39
3.10: py310
Expand Down

0 comments on commit 7f51e74

Please sign in to comment.