Skip to content

Commit a19bac3

Browse files
authored
Merge pull request #1380 from hkad98/jkd/attrs
refactor(gooddata-sdk): migrate @attr.s to @define
2 parents 1ca5699 + 5fd3de0 commit a19bac3

File tree

82 files changed

+979
-1032
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+979
-1032
lines changed

packages/gooddata-sdk/src/gooddata_sdk/catalog/base.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
from __future__ import annotations
33

44
import builtins
5-
from typing import Any, Optional, TypeVar
5+
from typing import Any, TypeVar
66

7-
import attr
7+
from attrs import Attribute, asdict, define, field
88
from cattrs import structure
99

1010
from gooddata_sdk.utils import AllPagedEntities
@@ -13,9 +13,7 @@
1313
U = TypeVar("U", bound="JsonApiEntityBase")
1414

1515

16-
def value_in_allowed(
17-
instance: type[Base], attribute: attr.Attribute, value: str, client_class: Optional[Any] = None
18-
) -> None:
16+
def value_in_allowed(instance: type[Base], attribute: Attribute, value: str, client_class: Any | None = None) -> None:
1917
if client_class is None:
2018
client_class = instance.client_class()
2119
allowed_values = client_class.allowed_values.get((attribute.name,))
@@ -26,7 +24,7 @@ def value_in_allowed(
2624
)
2725

2826

29-
@attr.s
27+
@define
3028
class Base:
3129
@classmethod
3230
def from_api(cls: type[T], entity: dict[str, Any]) -> T:
@@ -55,11 +53,11 @@ def to_dict(self, camel_case: bool = True) -> dict[str, Any]:
5553
return self.to_api().to_dict(camel_case)
5654

5755
@staticmethod
58-
def _is_attribute_private(attribute: attr.Attribute) -> bool:
56+
def _is_attribute_private(attribute: Attribute) -> bool:
5957
return attribute.name.startswith("_")
6058

6159
def _get_snake_dict(self) -> dict[str, Any]:
62-
return attr.asdict(
60+
return asdict(
6361
self, filter=lambda attribute, value: value is not None and not self._is_attribute_private(attribute)
6462
)
6563

@@ -72,24 +70,24 @@ def to_api(self) -> Any:
7270
return self.client_class().from_dict(dictionary, camel_case=False)
7371

7472

75-
@attr.s(auto_attribs=True)
73+
@define
7674
class JsonApiEntityBase:
7775
id: str
7876
type: str
79-
attributes: dict[str, Any] = attr.field(repr=False)
80-
relationships: Optional[dict[str, Any]] = attr.field(repr=False, default=None)
81-
meta: Optional[dict[str, Any]] = attr.field(repr=False, default=None)
82-
links: Optional[dict[str, Any]] = attr.field(repr=False, default=None)
83-
related_entities_data: list[dict[str, Any]] = attr.field(repr=False, factory=list)
84-
related_entities_side_loads: list[dict[str, Any]] = attr.field(repr=False, factory=list)
85-
side_loads: list[dict[str, Any]] = attr.field(repr=False, factory=list)
77+
attributes: dict[str, Any] = field(repr=False)
78+
relationships: dict[str, Any] | None = field(repr=False, default=None)
79+
meta: dict[str, Any] | None = field(repr=False, default=None)
80+
links: dict[str, Any] | None = field(repr=False, default=None)
81+
related_entities_data: list[dict[str, Any]] = field(repr=False, factory=list)
82+
related_entities_side_loads: list[dict[str, Any]] = field(repr=False, factory=list)
83+
side_loads: list[dict[str, Any]] = field(repr=False, factory=list)
8684

8785
@classmethod
8886
def from_api(
8987
cls,
9088
entity: dict[str, Any],
91-
side_loads: Optional[list[Any]] = None,
92-
related_entities: Optional[AllPagedEntities] = None,
89+
side_loads: list[Any] | None = None,
90+
related_entities: AllPagedEntities | None = None,
9391
) -> JsonApiEntityBase:
9492
"""
9593
Creates object from entity passed by client class, which represents it as dictionary.

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/ldm_request.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# (C) 2022 GoodData Corporation
22
from __future__ import annotations
33

4-
from typing import Optional
5-
6-
import attr
4+
from attrs import define
75
from gooddata_api_client.model.generate_ldm_request import GenerateLdmRequest
86
from gooddata_api_client.model.pdm_ldm_request import PdmLdmRequest
97
from gooddata_api_client.model.pdm_sql import PdmSql
@@ -13,7 +11,7 @@
1311
from gooddata_sdk.catalog.data_source.declarative_model.physical_model.table import CatalogDeclarativeTable
1412

1513

16-
@attr.s(auto_attribs=True, kw_only=True)
14+
@define(kw_only=True)
1715
class CatalogPdmSql(Base):
1816
statement: str
1917
title: str
@@ -24,34 +22,34 @@ def client_class() -> type[PdmSql]:
2422
return PdmSql
2523

2624

27-
@attr.s(auto_attribs=True, kw_only=True)
25+
@define(kw_only=True)
2826
class CatalogPdmLdmRequest(Base):
29-
sqls: Optional[list[CatalogPdmSql]] = None
30-
tables: Optional[list[CatalogDeclarativeTable]] = None
27+
sqls: list[CatalogPdmSql] | None = None
28+
tables: list[CatalogDeclarativeTable] | None = None
3129

3230
@staticmethod
3331
def client_class() -> type[PdmLdmRequest]:
3432
return PdmLdmRequest
3533

3634

37-
@attr.s(auto_attribs=True, kw_only=True)
35+
@define(kw_only=True)
3836
class CatalogGenerateLdmRequest(Base):
3937
separator: str = "__"
40-
generate_long_ids: Optional[bool] = None
41-
table_prefix: Optional[str] = None
42-
view_prefix: Optional[str] = None
43-
primary_label_prefix: Optional[str] = None
44-
secondary_label_prefix: Optional[str] = None
45-
fact_prefix: Optional[str] = None
46-
date_granularities: Optional[str] = None
47-
grain_prefix: Optional[str] = None
48-
reference_prefix: Optional[str] = None
49-
grain_reference_prefix: Optional[str] = None
50-
denorm_prefix: Optional[str] = None
51-
wdf_prefix: Optional[str] = None
52-
pdm: Optional[CatalogPdmLdmRequest] = None
53-
workspace_id: Optional[str] = None
54-
translation_prefix: Optional[str] = None
38+
generate_long_ids: bool | None = None
39+
table_prefix: str | None = None
40+
view_prefix: str | None = None
41+
primary_label_prefix: str | None = None
42+
secondary_label_prefix: str | None = None
43+
fact_prefix: str | None = None
44+
date_granularities: str | None = None
45+
grain_prefix: str | None = None
46+
reference_prefix: str | None = None
47+
grain_reference_prefix: str | None = None
48+
denorm_prefix: str | None = None
49+
wdf_prefix: str | None = None
50+
pdm: CatalogPdmLdmRequest | None = None
51+
workspace_id: str | None = None
52+
translation_prefix: str | None = None
5553

5654
@staticmethod
5755
def client_class() -> type[GenerateLdmRequest]:

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/scan_model_request.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# (C) 2022 GoodData Corporation
22
from __future__ import annotations
33

4-
from typing import Any, Optional
4+
from typing import Any
55

6-
import attr
7-
from attr import field
6+
from attrs import define, field
87
from gooddata_api_client.model.scan_request import ScanRequest
98

109
from gooddata_sdk.catalog.base import Base
@@ -15,14 +14,14 @@ def one_scan_true(instance: CatalogScanModelRequest, *args: Any) -> None:
1514
raise ValueError("Either scan_tables or scan_views must be True in CatalogScanModelRequest.")
1615

1716

18-
@attr.s(auto_attribs=True, kw_only=True)
17+
@define(kw_only=True)
1918
class CatalogScanModelRequest(Base):
2019
separator: str = "__"
2120
scan_tables: bool = field(default=True, validator=one_scan_true)
2221
scan_views: bool = field(default=False, validator=one_scan_true)
23-
table_prefix: Optional[str] = None
24-
view_prefix: Optional[str] = None
25-
schemata: Optional[list[str]] = None
22+
table_prefix: str | None = None
23+
view_prefix: str | None = None
24+
schemata: list[str] | None = None
2625

2726
@staticmethod
2827
def client_class() -> type[ScanRequest]:

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/requests/scan_sql_request.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# (C) 2023 GoodData Corporation
22
from __future__ import annotations
33

4-
import attr
4+
from attrs import define
55
from gooddata_api_client.model.scan_sql_request import ScanSqlRequest as ApiScanSqlRequest
66

77
from gooddata_sdk.catalog.base import Base
88

99

10-
@attr.s(auto_attribs=True, kw_only=True)
10+
@define(kw_only=True)
1111
class ScanSqlRequest(Base):
1212
sql: str
1313

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/responses/scan_sql_response.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
11
# (C) 2023 GoodData Corporation
22
from __future__ import annotations
33

4-
from typing import Optional
5-
6-
import attr
4+
from attrs import define
75
from gooddata_api_client.model.scan_sql_response import ScanSqlResponse as ApiScanSqlResponse
86

97
from gooddata_sdk.catalog.base import Base
108
from gooddata_sdk.catalog.data_source.action_model.sql_column import SqlColumn
119

1210

13-
@attr.s(auto_attribs=True, kw_only=True)
11+
@define(kw_only=True)
1412
class ScanSqlResponse(Base):
1513
columns: list[SqlColumn]
16-
data_preview: Optional[list[list[Optional[str]]]] = None
14+
data_preview: list[list[str | None]] | None = None
1715

1816
@staticmethod
1917
def client_class() -> type[ApiScanSqlResponse]:

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/action_model/sql_column.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# (C) 2023 GoodData Corporation
22
from __future__ import annotations
33

4-
import attr
4+
from attrs import define
55
from gooddata_api_client.model.sql_column import SqlColumn as ApiSqlColumn
66

77
from gooddata_sdk.catalog.base import Base
88

99

10-
@attr.s(auto_attribs=True, kw_only=True)
10+
@define(kw_only=True)
1111
class SqlColumn(Base):
1212
data_type: str
1313
name: str

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/data_source.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33

44
import builtins
55
from pathlib import Path
6-
from typing import Any, Optional, Union
6+
from typing import Any, Union
77
from warnings import warn
88

9-
import attr
9+
from attrs import define, field
1010
from gooddata_api_client.model.declarative_data_source import DeclarativeDataSource
1111
from gooddata_api_client.model.declarative_data_sources import DeclarativeDataSources
1212
from gooddata_api_client.model.test_definition_request import TestDefinitionRequest
@@ -25,7 +25,7 @@
2525
LAYOUT_DATA_SOURCES_DIR = "data_sources"
2626

2727

28-
@attr.s(auto_attribs=True, kw_only=True)
28+
@define(kw_only=True)
2929
class CatalogDeclarativeDataSources(Base):
3030
data_sources: list[CatalogDeclarativeDataSource]
3131

@@ -90,7 +90,7 @@ def _inject_credentials_aac(self, config_file: Union[str, Path]) -> DeclarativeD
9090
return self._inject_base(credentials)
9191

9292
def to_api(
93-
self, credentials: Optional[dict[str, Any]] = None, config_file: Optional[Union[str, Path]] = None
93+
self, credentials: dict[str, Any] | None = None, config_file: Union[str, Path] | None = None
9494
) -> DeclarativeDataSources:
9595
client_class = self.client_class()
9696
if credentials is not None and config_file is not None:
@@ -127,29 +127,29 @@ def load_from_disk(cls, layout_organization_folder: Path) -> CatalogDeclarativeD
127127
return cls(data_sources=data_sources)
128128

129129

130-
@attr.s(auto_attribs=True, kw_only=True)
130+
@define(kw_only=True)
131131
class CatalogDeclarativeDataSource(Base):
132132
id: str
133133
name: str
134-
type: str = attr.field(validator=value_in_allowed)
135-
url: Optional[str] = None
134+
type: str = field(validator=value_in_allowed)
135+
url: str | None = None
136136
schema: str
137-
cache_strategy: Optional[str] = None
138-
username: Optional[str] = None
139-
parameters: Optional[list[CatalogParameter]] = None
140-
decoded_parameters: Optional[list[CatalogParameter]] = None
141-
permissions: list[CatalogDeclarativeDataSourcePermission] = attr.field(factory=list)
142-
client_id: Optional[str] = None
143-
authentication_type: Optional[str] = None
144-
alternative_data_source_id: Optional[str] = None
137+
cache_strategy: str | None = None
138+
username: str | None = None
139+
parameters: list[CatalogParameter] | None = None
140+
decoded_parameters: list[CatalogParameter] | None = None
141+
permissions: list[CatalogDeclarativeDataSourcePermission] = field(factory=list)
142+
client_id: str | None = None
143+
authentication_type: str | None = None
144+
alternative_data_source_id: str | None = None
145145

146146
def to_test_request(
147147
self,
148-
password: Optional[str] = None,
149-
token: Optional[str] = None,
150-
private_key: Optional[str] = None,
151-
private_key_passphrase: Optional[str] = None,
152-
client_secret: Optional[str] = None,
148+
password: str | None = None,
149+
token: str | None = None,
150+
private_key: str | None = None,
151+
private_key_passphrase: str | None = None,
152+
client_secret: str | None = None,
153153
) -> TestDefinitionRequest:
154154
kwargs: dict[str, Any] = {"schema": self.schema}
155155
if password is not None:
@@ -183,11 +183,11 @@ def data_source_folder(data_sources_folder: Path, data_source_id: str) -> Path:
183183

184184
def to_api(
185185
self,
186-
password: Optional[str] = None,
187-
token: Optional[str] = None,
188-
private_key: Optional[str] = None,
189-
private_key_passphrase: Optional[str] = None,
190-
client_secret: Optional[str] = None,
186+
password: str | None = None,
187+
token: str | None = None,
188+
private_key: str | None = None,
189+
private_key_passphrase: str | None = None,
190+
client_secret: str | None = None,
191191
) -> DeclarativeDataSource:
192192
dictionary = self._get_snake_dict()
193193
if password is not None:

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/column.py

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
# (C) 2022 GoodData Corporation
22
from __future__ import annotations
33

4-
from typing import Optional
5-
6-
import attr
4+
from attrs import define
75
from gooddata_api_client.model.declarative_column import DeclarativeColumn
86

97
from gooddata_sdk.catalog.base import Base
108

119

12-
@attr.s(auto_attribs=True, kw_only=True)
10+
@define(kw_only=True)
1311
class CatalogDeclarativeColumn(Base):
1412
name: str
1513
data_type: str
16-
is_primary_key: Optional[bool] = None
17-
referenced_table_id: Optional[str] = None
18-
referenced_table_column: Optional[str] = None
19-
is_nullable: Optional[bool] = None
20-
null_value: Optional[str] = None
14+
is_primary_key: bool | None = None
15+
referenced_table_id: str | None = None
16+
referenced_table_column: str | None = None
17+
is_nullable: bool | None = None
18+
null_value: str | None = None
2119

2220
@staticmethod
2321
def client_class() -> type[DeclarativeColumn]:

packages/gooddata-sdk/src/gooddata_sdk/catalog/data_source/declarative_model/physical_model/pdm.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from pathlib import Path
55

6-
import attr
6+
from attrs import define, field
77
from gooddata_api_client.model.declarative_tables import DeclarativeTables
88

99
from gooddata_sdk.catalog.base import Base
@@ -17,9 +17,9 @@ def get_pdm_folder(data_source_folder: Path) -> Path:
1717
return data_source_folder / LAYOUT_PDM_DIR
1818

1919

20-
@attr.s(auto_attribs=True, kw_only=True)
20+
@define(kw_only=True)
2121
class CatalogDeclarativeTables(Base):
22-
tables: list[CatalogDeclarativeTable] = attr.field(factory=list)
22+
tables: list[CatalogDeclarativeTable] = field(factory=list)
2323

2424
@staticmethod
2525
def client_class() -> type[DeclarativeTables]:
@@ -39,8 +39,8 @@ def load_from_disk(cls, data_source_folder: Path) -> CatalogDeclarativeTables:
3939
return cls(tables=tables)
4040

4141

42-
@attr.s(auto_attribs=True, kw_only=True)
42+
@define(kw_only=True)
4343
class CatalogScanResultPdm(Base):
4444
pdm: CatalogDeclarativeTables = CatalogDeclarativeTables()
4545
# Just informative hints. Create appropriate classes later if needed.
46-
warnings: list[dict] = attr.field(factory=list)
46+
warnings: list[dict] = field(factory=list)

0 commit comments

Comments
 (0)