Skip to content

Commit d4e20db

Browse files
authored
Open up pydantic version to allow both v1 and v2 (#422)
* Open up pydantic version * LOCK, STOCK, TWO SMOKING BARRELLS - (lock, changelog and bump) * Fix mypy/pylint errors * Ignore mypy error
1 parent 164a63b commit d4e20db

File tree

12 files changed

+994
-771
lines changed

12 files changed

+994
-771
lines changed

.pylintrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ disable=
1818
C0114,
1919
C0111,
2020
C0103,
21-
R0904
21+
R0904,
22+
wrong-import-position
2223

2324
[tool.pylint.REPORTS]
2425
reports=no

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ All notable changes to the [Nucleus Python Client](https://github.com/scaleapi/n
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.16.14](https://github.com/scaleapi/nucleus-python-client/releases/tag/v0.16.14) - 2024-01-03
9+
10+
### Fixes
11+
- Open up Pydantic version requirements as was fixed in 0.16.11
12+
813
## [0.16.13](https://github.com/scaleapi/nucleus-python-client/releases/tag/v0.16.13) - 2023-12-13
914

1015
### Added

nucleus/__init__.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,17 @@
4545
import datetime
4646
import os
4747
import warnings
48-
from typing import Any, Dict, List, Optional, Tuple, Union
49-
50-
try:
51-
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
52-
import pydantic.v1 as pydantic
53-
except ImportError:
54-
import pydantic
48+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
49+
50+
if TYPE_CHECKING:
51+
# Backwards compatibility is even uglier with mypy
52+
from pydantic.v1 import parse_obj_as
53+
else:
54+
try:
55+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
56+
from pydantic.v1 import parse_obj_as
57+
except ImportError:
58+
from pydantic import parse_obj_as
5559

5660
import requests
5761
import tqdm
@@ -216,7 +220,11 @@ def datasets(self) -> List[Dataset]:
216220
List of all datasets accessible to user
217221
"""
218222
response = self.make_request({}, "dataset/details", requests.get)
219-
dataset_details = pydantic.parse_obj_as(List[DatasetDetails], response)
223+
dataset_details = (
224+
parse_obj_as( # pylint: disable=used-before-assignment
225+
List[DatasetDetails], response
226+
)
227+
)
220228
return [
221229
Dataset(d.id, client=self, name=d.name) for d in dataset_details
222230
]

nucleus/data_transfer_object/job_status.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
# pylint: disable=E0213
22

33
from datetime import datetime
4-
from typing import List, Optional, Union
4+
from typing import TYPE_CHECKING, List, Optional, Union
55

66
from dateutil.parser import ParserError, parse
77

8-
try:
9-
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
8+
if TYPE_CHECKING:
9+
# Backwards compatibility is even uglier with mypy
1010
from pydantic.v1 import validator
11-
except ImportError:
12-
from pydantic import validator
11+
else:
12+
try:
13+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
14+
from pydantic.v1 import validator
15+
except ImportError:
16+
from pydantic import validator
1317

1418
from nucleus.constants import JOB_REQ_LIMIT
1519
from nucleus.job import CustomerJobTypes
@@ -24,7 +28,9 @@ class JobInfoRequestPayload(ImmutableModel):
2428
limit: Optional[int]
2529
show_completed: bool
2630

27-
@validator("from_date", "to_date")
31+
@validator( # pylint: disable=used-before-assignment
32+
"from_date", "to_date"
33+
)
2834
def ensure_date_format(cls, date):
2935
if date is None:
3036
return None

nucleus/pydantic_base.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@
44
As a library we want to support v1 and v2 such that we're not causing downstream problems for our users.
55
This means we have to do some import shenanigans to support both v1 and v2.
66
"""
7-
try:
8-
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
9-
from pydantic.v1 import BaseModel # pylint: disable=no-name-in-module
10-
except ImportError:
11-
from pydantic import BaseModel
7+
from typing import TYPE_CHECKING
128

9+
if TYPE_CHECKING:
10+
# Backwards compatibility is even uglier with mypy
11+
from pydantic.v1 import BaseModel, Extra, ValidationError
12+
else:
13+
try:
14+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
15+
from pydantic.v1 import BaseModel # pylint: disable=no-name-in-module
16+
except ImportError:
17+
from pydantic import BaseModel
1318

14-
class ImmutableModel(BaseModel):
19+
20+
class ImmutableModel(BaseModel): # pylint: disable=used-before-assignment
1521
class Config:
1622
allow_mutation = False
1723

nucleus/test_launch_integration.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,28 @@
11
import io
2-
from typing import Any, Callable, Dict, List, Optional, Type
2+
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Type
33

44
from PIL import Image, ImageDraw
55

6-
try:
7-
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
6+
if TYPE_CHECKING:
7+
# Backwards compatibility is even uglier with mypy
88
from pydantic.v1 import BaseModel, Extra, ValidationError
9-
except ImportError:
10-
from pydantic import BaseModel, Extra, ValidationError
9+
else:
10+
try:
11+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
12+
from pydantic.v1 import BaseModel, Extra, ValidationError
13+
except ImportError:
14+
from pydantic import BaseModel, Extra, ValidationError
1115

1216
# From scaleapi/server/src/lib/select/api/types.ts
1317
# These classes specify how user models must pass output to Launch + Nucleus.
1418

1519

16-
class PointModel(BaseModel):
20+
class PointModel(BaseModel): # pylint: disable=used-before-assignment
1721
x: float
1822
y: float
1923

2024
class Config:
21-
extra = Extra.forbid
25+
extra = Extra.forbid # pylint: disable=used-before-assignment
2226

2327

2428
class BoxGeometryModel(BaseModel):
@@ -106,7 +110,7 @@ def verify_output(
106110
for annotation in annotation_list:
107111
try:
108112
model.parse_obj(annotation)
109-
except ValidationError as e:
113+
except ValidationError as e: # pylint: disable=used-before-assignment
110114
raise ValueError("Failed validation") from e
111115
if annotation["type"] != annotation_type:
112116
raise ValueError(

nucleus/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ def upload_to_presigned_url(presigned_url: str, file_pointer: IO):
363363
# TODO optimize this further to deal with truly huge files and flaky internet connection.
364364
upload_response = requests.put(presigned_url, file_pointer)
365365
if not upload_response.ok:
366-
raise HTTPError(
366+
raise HTTPError( # type: ignore
367367
f"Tried to put a file to url, but failed with status {upload_response.status_code}. The detailed error was: {upload_response.text}"
368368
)
369369

nucleus/validate/data_transfer_objects/eval_function.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
from typing import Any, Dict, List, Optional
1+
from typing import TYPE_CHECKING, Any, Dict, List, Optional
22

3-
try:
4-
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
3+
if TYPE_CHECKING:
4+
# Backwards compatibility is even uglier with mypy
55
from pydantic.v1 import validator
6-
except ImportError:
7-
from pydantic import validator
6+
else:
7+
try:
8+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
9+
from pydantic.v1 import validator
10+
except ImportError:
11+
from pydantic import validator
812

913
from ...pydantic_base import ImmutableModel
1014
from ..constants import ThresholdComparison
@@ -63,7 +67,7 @@ class EvaluationCriterion(ImmutableModel):
6367
threshold: float
6468
eval_func_arguments: Dict[str, Any]
6569

66-
@validator("eval_function_id")
70+
@validator("eval_function_id") # pylint: disable=used-before-assignment
6771
def valid_eval_function_id(cls, v): # pylint: disable=no-self-argument
6872
if not v.startswith("ef_"):
6973
raise ValueError(f"Expected field to start with 'ef_', got '{v}'")

nucleus/validate/data_transfer_objects/scenario_test.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
from typing import List
1+
from typing import TYPE_CHECKING, List
22

3-
try:
4-
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
3+
if TYPE_CHECKING:
4+
# Backwards compatibility is even uglier with mypy
55
from pydantic.v1 import validator
6-
except ImportError:
7-
from pydantic import validator
6+
else:
7+
try:
8+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
9+
from pydantic.v1 import validator
10+
except ImportError:
11+
from pydantic import validator
812

913
from nucleus.pydantic_base import ImmutableModel
1014

@@ -19,7 +23,7 @@ class CreateScenarioTestRequest(ImmutableModel):
1923
slice_id: str
2024
evaluation_functions: List[EvalFunctionListEntry]
2125

22-
@validator("slice_id")
26+
@validator("slice_id") # pylint: disable=used-before-assignment
2327
def startswith_slice_indicator(cls, v): # pylint: disable=no-self-argument
2428
if not v.startswith("slc_"):
2529
raise ValueError(f"Expected field to start with 'slc_', got '{v}'")

nucleus/validate/data_transfer_objects/scenario_test_evaluations.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
from typing import Optional
1+
from typing import TYPE_CHECKING, Optional
22

3-
try:
4-
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
3+
if TYPE_CHECKING:
4+
# Backwards compatibility is even uglier with mypy
55
from pydantic.v1 import root_validator, validator
6-
except ImportError:
7-
from pydantic import root_validator, validator
6+
else:
7+
try:
8+
# NOTE: we always use pydantic v1 but have to do these shenanigans to support both v1 and v2
9+
from pydantic.v1 import root_validator, validator
10+
except ImportError:
11+
from pydantic import root_validator, validator
812

913
from nucleus.pydantic_base import ImmutableModel
1014

@@ -16,7 +20,7 @@ class EvaluationResult(ImmutableModel):
1620
score: float = 0
1721
weight: float = 1
1822

19-
@root_validator()
23+
@root_validator() # pylint: disable=used-before-assignment
2024
def is_item_or_scene_provided(
2125
cls, values
2226
): # pylint: disable=no-self-argument
@@ -31,7 +35,7 @@ def is_item_or_scene_provided(
3135
)
3236
return values
3337

34-
@validator("weight")
38+
@validator("weight") # pylint: disable=used-before-assignment
3539
def is_normalized(cls, v): # pylint: disable=no-self-argument
3640
if 0 <= v <= 1:
3741
return v

0 commit comments

Comments
 (0)