Skip to content

Commit 8531736

Browse files
authored
Merge pull request #128 from fundakol/ruff-code
Fix code by ruff
2 parents 623c206 + a22b857 commit 8531736

16 files changed

Lines changed: 330 additions & 453 deletions

.pre-commit-config.yaml

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,10 @@
11
repos:
2-
- repo: https://github.com/PYCQA/isort
3-
rev: 6.1.0
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: "v0.13.3"
44
hooks:
5-
- id: isort
6-
files: ^(src/|tests/)
7-
stages: [pre-commit]
8-
args: ["--profile", "black", "--filter-files", "--line-length=88"]
9-
10-
- repo: https://github.com/hhatto/autopep8
11-
rev: v2.3.2
12-
hooks:
13-
- id: autopep8
14-
files: ^(src/|tests/)
15-
stages: [pre-commit]
16-
17-
- repo: https://github.com/PYCQA/flake8
18-
rev: 7.3.0
19-
hooks:
20-
- id: flake8
21-
files: ^(src/|tests/)
22-
stages: [pre-commit]
5+
- id: ruff-check
6+
args: ["--fix"]
7+
- id: ruff-format
238

249
- repo: https://github.com/pre-commit/mirrors-mypy
2510
rev: v1.18.2

pyproject.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,31 @@ include_trailing_comma = true
5555
force_grid_wrap = 0
5656
use_parentheses = true
5757
line_length = 88
58+
59+
[tool.ruff]
60+
target-version = "py39"
61+
line-length = 120
62+
src = [
63+
"src",
64+
"tests",
65+
]
66+
67+
[tool.ruff.lint]
68+
select = [
69+
# pycodestyle
70+
"E",
71+
# Pyflakes
72+
"F",
73+
# pyupgrade
74+
"UP",
75+
# flake8-bugbear
76+
"B",
77+
# flake8-simplify
78+
"SIM",
79+
# isort
80+
"I",
81+
]
82+
ignore = ["SIM108"]
83+
84+
[tool.ruff.format]
85+
quote-style = "single"

requirements-dev.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
flake8==4.0.0
2-
Flask==2.0.2
3-
isort
41
mypy==0.910
52
pre-commit
63
pytest>=7.0.1
74
pytest-cov>=3.0.0
85
requests==2.27.0
6+
ruff
97
tox
10-
types-flask==1.1.6
118
types-requests==2.28.11.1
129
Werkzeug==2.0.2

setup.py

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/pytest_xray/evidence.py

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import base64
2-
from typing import AnyStr, Dict
2+
from typing import AnyStr
33

44
from pytest_xray.exceptions import XrayError
55

@@ -12,40 +12,36 @@
1212
APP_ZIP: str = 'application/zip'
1313

1414

15-
def evidence(data: AnyStr, filename: str, content_type: str) -> Dict[str, str]:
15+
def evidence(data: AnyStr, filename: str, content_type: str) -> dict[str, str]:
1616
if isinstance(data, bytes):
1717
data_base64: str = base64.b64encode(data).decode('utf-8')
1818
elif isinstance(data, str):
1919
data_base64 = base64.b64encode(data.encode('utf-8')).decode('utf-8')
2020
else:
2121
raise XrayError('data must be string or bytes')
2222

23-
return {
24-
'data': data_base64,
25-
'filename': filename,
26-
'contentType': content_type
27-
}
23+
return {'data': data_base64, 'filename': filename, 'contentType': content_type}
2824

2925

30-
def jpeg(data: AnyStr, filename: str) -> Dict[str, str]:
26+
def jpeg(data: AnyStr, filename: str) -> dict[str, str]:
3127
return evidence(data, filename, IMAGE_JPEG)
3228

3329

34-
def png(data: AnyStr, filename: str) -> Dict[str, str]:
30+
def png(data: AnyStr, filename: str) -> dict[str, str]:
3531
return evidence(data, filename, IMAGE_PNG)
3632

3733

38-
def text(data: AnyStr, filename: str) -> Dict[str, str]:
34+
def text(data: AnyStr, filename: str) -> dict[str, str]:
3935
return evidence(data, filename, PLAIN_TEXT)
4036

4137

42-
def html(data: AnyStr, filename: str) -> Dict[str, str]:
38+
def html(data: AnyStr, filename: str) -> dict[str, str]:
4339
return evidence(data, filename, TEXT_HTML)
4440

4541

46-
def json(data: AnyStr, filename: str) -> Dict[str, str]:
42+
def json(data: AnyStr, filename: str) -> dict[str, str]:
4743
return evidence(data, filename, APP_JSON)
4844

4945

50-
def zip(data: AnyStr, filename: str) -> Dict[str, str]:
46+
def zip(data: AnyStr, filename: str) -> dict[str, str]:
5147
return evidence(data, filename, APP_ZIP)

src/pytest_xray/helper.py

Lines changed: 33 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
import re
55
from os import environ
6-
from typing import Any, Dict, List, Optional, Union
6+
from typing import Any, Optional, Union
77

88
from pytest_xray import constant
99
from pytest_xray.constant import (
@@ -35,7 +35,7 @@ class Status(str, enum.Enum):
3535
# When merging two statuses, the highest will be picked.
3636
# For example, a PASS and a FAIL will result in a FAIL,
3737
# A TODO and an ABORTED in an ABORTED, A TODO and a PASS in a TODO.
38-
STATUS_HIERARCHY: List[Status] = [
38+
STATUS_HIERARCHY: list[Status] = [
3939
Status.PASS,
4040
Status.TODO,
4141
Status.EXECUTING,
@@ -47,7 +47,7 @@ class Status(str, enum.Enum):
4747

4848
# Maps the Status from the internal Status enum to the string representations
4949
# requested by either the Cloud Jira, or the on-site Jira
50-
STATUS_STR_MAPPER_CLOUD: Dict[Status, str] = {
50+
STATUS_STR_MAPPER_CLOUD: dict[Status, str] = {
5151
Status.TODO: 'TODO',
5252
Status.EXECUTING: 'EXECUTING',
5353
Status.PENDING: 'PENDING',
@@ -58,7 +58,7 @@ class Status(str, enum.Enum):
5858
}
5959

6060
# On-site jira uses the enum strings directly
61-
STATUS_STR_MAPPER_JIRA: Dict[Status, str] = {x: x.value for x in Status}
61+
STATUS_STR_MAPPER_JIRA: dict[Status, str] = {x: x.value for x in Status}
6262

6363

6464
class TestCase:
@@ -69,9 +69,9 @@ def __init__(
6969
test_key: str,
7070
status: Status,
7171
comment: Optional[str] = None,
72-
status_str_mapper: Optional[Dict[Status, str]] = None,
73-
evidences: Optional[List[Dict[str, str]]] = None,
74-
defects: Optional[List[str]] = None,
72+
status_str_mapper: Optional[dict[Status, str]] = None,
73+
evidences: Optional[list[dict[str, str]]] = None,
74+
defects: Optional[list[str]] = None,
7575
) -> None:
7676
self.test_key = test_key
7777
self.status = status
@@ -89,17 +89,14 @@ def merge(self, other: 'TestCase') -> None:
8989
"""
9090

9191
if self.test_key != other.test_key:
92-
raise ValueError(
93-
f'Cannot merge test with different test keys: '
94-
f'{self.test_key} {other.test_key}'
95-
)
92+
raise ValueError(f'Cannot merge test with different test keys: {self.test_key} {other.test_key}')
9693

9794
if self.comment == '':
9895
if other.comment != '':
9996
self.comment = other.comment
10097
else:
10198
if other.comment != '':
102-
self.comment += ('\n' + '-'*80 + '\n')
99+
self.comment += '\n' + '-' * 80 + '\n'
103100
self.comment += other.comment
104101

105102
self.status = _merge_status(self.status, other.status)
@@ -108,8 +105,8 @@ def merge(self, other: 'TestCase') -> None:
108105
if defect not in self.defects:
109106
self.defects.append(defect)
110107

111-
def as_dict(self) -> Dict[str, Any]:
112-
data: Dict[str, Any] = dict(
108+
def as_dict(self) -> dict[str, Any]:
109+
data: dict[str, Any] = dict(
113110
testKey=self.test_key,
114111
status=self.status_str_mapper[self.status],
115112
)
@@ -131,8 +128,8 @@ def __init__(
131128
test_plan_key: Optional[str] = None,
132129
user: Optional[str] = None,
133130
revision: Optional[str] = None,
134-
tests: Optional[List[TestCase]] = None,
135-
test_environments: Optional[List[str]] = None,
131+
tests: Optional[list[TestCase]] = None,
132+
test_environments: Optional[list[str]] = None,
136133
fix_version: Optional[str] = None,
137134
summary: Optional[str] = None,
138135
description: Optional[str] = None,
@@ -145,8 +142,7 @@ def __init__(
145142
self.finish_date = dt.datetime.now(tz=dt.timezone.utc)
146143
self.tests = tests or []
147144
self.test_environments = test_environments or _from_environ(
148-
constant.ENV_TEST_EXECUTION_TEST_ENVIRONMENTS,
149-
constant.ENV_MULTI_VALUE_SPLIT_PATTERN
145+
constant.ENV_TEST_EXECUTION_TEST_ENVIRONMENTS, constant.ENV_MULTI_VALUE_SPLIT_PATTERN
150146
)
151147
self.fix_version = fix_version or _first_from_environ(constant.ENV_TEST_EXECUTION_FIX_VERSION)
152148
self.summary = self._get_summery(summary)
@@ -179,10 +175,10 @@ def find_test_case(self, test_key: str) -> TestCase:
179175

180176
raise KeyError(test_key)
181177

182-
def as_dict(self) -> Dict[str, Any]:
178+
def as_dict(self) -> dict[str, Any]:
183179
"""Return test execution result as dictionary."""
184180
tests = [test.as_dict() for test in self.tests]
185-
info: Dict[str, Any] = dict(
181+
info: dict[str, Any] = dict(
186182
startDate=self.start_date.strftime(DATETIME_FORMAT),
187183
finishDate=self.finish_date.strftime(DATETIME_FORMAT), # type: ignore
188184
)
@@ -202,26 +198,21 @@ def as_dict(self) -> Dict[str, Any]:
202198
if self.revision is not None:
203199
info['revision'] = self.revision
204200

205-
data: Dict[str, Any] = dict(
206-
info=info,
207-
tests=tests
208-
)
201+
data: dict[str, Any] = dict(info=info, tests=tests)
209202
if self.test_plan_key:
210203
info['testPlanKey'] = self.test_plan_key
211204
if self.test_execution_key is not None:
212205
data['testExecutionKey'] = self.test_execution_key
213206
return data
214207

215208

216-
def get_base_options() -> Dict[str, Any]:
209+
def get_base_options() -> dict[str, Any]:
217210
"""Return authentication configuration from environment variables."""
218211
options = {}
219212
try:
220213
base_url = environ[ENV_XRAY_API_BASE_URL]
221-
except KeyError as e:
222-
raise XrayError(
223-
f'pytest-jira-xray plugin requires environment variable: {ENV_XRAY_API_BASE_URL}'
224-
) from e
214+
except KeyError:
215+
raise XrayError(f'pytest-jira-xray plugin requires environment variable: {ENV_XRAY_API_BASE_URL}') from None
225216

226217
verify = os.environ.get(ENV_XRAY_API_VERIFY_SSL, 'True')
227218

@@ -238,49 +229,45 @@ def get_base_options() -> Dict[str, Any]:
238229
return options
239230

240231

241-
def get_basic_auth() -> Dict[str, Any]:
232+
def get_basic_auth() -> dict[str, Any]:
242233
"""Return basic authentication setup with username and password."""
243234
options = get_base_options()
244235
try:
245236
user = environ[ENV_XRAY_API_USER]
246237
password = environ[ENV_XRAY_API_PASSWORD]
247-
except KeyError as e:
238+
except KeyError:
248239
raise XrayError(
249-
'Basic authentication requires environment variables: '
250-
f'{ENV_XRAY_API_USER}, {ENV_XRAY_API_PASSWORD}'
251-
) from e
240+
f'Basic authentication requires environment variables: {ENV_XRAY_API_USER}, {ENV_XRAY_API_PASSWORD}'
241+
) from None
252242

253243
options['USER'] = user
254244
options['PASSWORD'] = password
255245
return options
256246

257247

258-
def get_bearer_auth() -> Dict[str, Any]:
248+
def get_bearer_auth() -> dict[str, Any]:
259249
"""Return bearer authentication setup with Client ID and a Client Secret."""
260250
options = get_base_options()
261251
try:
262252
client_id = environ[ENV_XRAY_CLIENT_ID]
263253
client_secret = environ[ENV_XRAY_CLIENT_SECRET]
264-
except KeyError as e:
254+
except KeyError:
265255
raise XrayError(
266-
'Bearer authentication requires environment variables: '
267-
f'{ENV_XRAY_CLIENT_ID}, {ENV_XRAY_CLIENT_SECRET}'
268-
) from e
256+
f'Bearer authentication requires environment variables: {ENV_XRAY_CLIENT_ID}, {ENV_XRAY_CLIENT_SECRET}'
257+
) from None
269258

270259
options['CLIENT_ID'] = client_id
271260
options['CLIENT_SECRET'] = client_secret
272261
return options
273262

274263

275-
def get_api_key_auth() -> Dict[str, Any]:
264+
def get_api_key_auth() -> dict[str, Any]:
276265
"""Return personal access token authentication."""
277266
options = get_base_options()
278267
try:
279268
api_key = environ[ENV_XRAY_API_KEY]
280-
except KeyError as e:
281-
raise XrayError(
282-
f'API Key authentication requires environment variable: {ENV_XRAY_API_KEY}'
283-
) from e
269+
except KeyError:
270+
raise XrayError(f'API Key authentication requires environment variable: {ENV_XRAY_API_KEY}') from None
284271

285272
options['API_KEY'] = api_key
286273
return options
@@ -300,7 +287,7 @@ def _first_from_environ(name: str, separator: Optional[str] = None) -> Optional[
300287
return next(iter(_from_environ(name, separator)), None)
301288

302289

303-
def _from_environ(name: str, separator: Optional[str] = None) -> List[str]:
290+
def _from_environ(name: str, separator: Optional[str] = None) -> list[str]:
304291
if name not in environ:
305292
return []
306293

@@ -318,7 +305,4 @@ def _from_environ(name: str, separator: Optional[str] = None) -> List[str]:
318305
def _merge_status(status_1: Status, status_2: Status) -> Status:
319306
"""Merges the status of two tests."""
320307

321-
return STATUS_HIERARCHY[max(
322-
STATUS_HIERARCHY.index(status_1),
323-
STATUS_HIERARCHY.index(status_2)
324-
)]
308+
return STATUS_HIERARCHY[max(STATUS_HIERARCHY.index(status_1), STATUS_HIERARCHY.index(status_2))]

src/pytest_xray/hooks.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from typing import Any, Dict
1+
from typing import Any
22

33
import pytest
44

55

66
@pytest.hookspec
7-
def pytest_xray_results(results: Dict[str, Any], session: pytest.Session) -> None:
7+
def pytest_xray_results(results: dict[str, Any], session: pytest.Session) -> None:
88
"""
99
Called before uploading XRAY result to Jira server.
1010

0 commit comments

Comments
 (0)