Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update pydantic requirement from 1.10.9 to 2.0.2 #263

Merged
merged 4 commits into from
Jul 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/source/overview/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ A full list of available settings and their defaults is provided below.


.. important:: The top level ``file_systems`` field is a nested field and entries
should adhere to the :ref:`#/definitions/FileSystemSchema` schema outlined below.
should adhere to the :ref:`#/$defs/filesystemschema` schema outlined below.

.. pydantic:: quota_notifier.settings.SettingsSchema

.. _#/definitions/FileSystemSchema:
.. _#/$defs/filesystemschema:
.. pydantic:: quota_notifier.settings.FileSystemSchema
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ notifier = "quota_notifier.cli:Application.execute"

[tool.poetry.dependencies]
python = ">=3.8"
pydantic = "1.10.9"
pydantic-settings = "2.0.1"
sqlalchemy = "2.0.17"

[tool.poetry.group.tests]
Expand Down
15 changes: 10 additions & 5 deletions quota_notifier/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
from tempfile import NamedTemporaryFile
from typing import Any, List, Literal, Optional, Set, Tuple, Union

from pydantic import BaseSettings, Field, validator
from pydantic import field_validator, Field
from pydantic_settings import BaseSettings

DEFAULT_DB_PATH = Path.cwd().resolve() / 'notifier_data.db'

Expand Down Expand Up @@ -42,7 +43,8 @@ class FileSystemSchema(BaseSettings):
title='Notification Thresholds',
description='Usage percentages to issue notifications for.')

@validator('name')
@field_validator('name')
@classmethod
def validate_name(cls, value: str) -> str:
"""Ensure the given name is not blank

Expand All @@ -59,7 +61,8 @@ def validate_name(cls, value: str) -> str:

return stripped

@validator('path')
@field_validator('path')
@classmethod
def validate_path(cls, value: Path) -> Path:
"""Ensure the given system path exists

Expand All @@ -78,7 +81,8 @@ def validate_path(cls, value: Path) -> Path:

return value

@validator('thresholds')
@field_validator('thresholds')
@classmethod
def validate_thresholds(cls, value: list) -> list:
"""Validate threshold values are between 0 and 100 (exclusive)

Expand Down Expand Up @@ -188,7 +192,8 @@ class SettingsSchema(BaseSettings):
default=False,
description='Disable database commits and email notifications. Useful for development and testing.')

@validator('file_systems')
@field_validator('file_systems')
@classmethod
def validate_unique_file_systems(cls, value: List[FileSystemSchema]) -> List[FileSystemSchema]:
"""Ensure file systems have unique names/paths

Expand Down
2 changes: 1 addition & 1 deletion tests/settings/test_applicationsettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_invalid_file(self) -> None:
with path_obj.open('w') as io:
json.dump(settings, io)

with self.assertRaisesRegex(ValidationError, 'extra fields not permitted'):
with self.assertRaisesRegex(Exception, 'Extra inputs are not permitted'):
ApplicationSettings.set_from_file(path_obj)


Expand Down
16 changes: 8 additions & 8 deletions tests/settings/test_filesystemschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ class NameValidation(DefaultSetupTeardown, TestCase):
def test_blank_name_error(self) -> None:
"""Test a ``ValueError`` is raised for empty/blank names"""

with self.assertRaisesRegex(ValueError, 'File system name cannot be blank'):
with self.assertRaisesRegex(Exception, 'File system name cannot be blank'):
FileSystemSchema(name='')

for char in string.whitespace:
with self.assertRaisesRegex(ValueError, 'File system name cannot be blank'):
with self.assertRaisesRegex(Exception, 'File system name cannot be blank'):
FileSystemSchema(name=char)

def test_whitespace_is_stripped(self) -> None:
Expand Down Expand Up @@ -61,7 +61,7 @@ def test_valid_types_pass() -> None:
def test_invalid_type_error(self) -> None:
"""Test a ``ValueError`` is raised for invalid types"""

with self.assertRaisesRegex(ValidationError, 'type\n unexpected value;'):
with self.assertRaisesRegex(Exception, 'type\n Input should be '):
FileSystemSchema(type='fake_type')


Expand All @@ -78,29 +78,29 @@ def test_intermediate_values_pass(self) -> None:
def test_empty_list_fails(self) -> None:
"""Test an empty collection of thresholds fails validation"""

with self.assertRaisesRegex(ValidationError, 'At least one threshold must be specified'):
with self.assertRaisesRegex(Exception, 'At least one threshold must be specified'):
FileSystemSchema(thresholds=[])

def test_zero_percent(self) -> None:
"""Test the value ``0`` fails validation"""

with self.assertRaisesRegex(ValidationError, 'must be greater than 0 and less than 100'):
with self.assertRaisesRegex(Exception, 'must be greater than 0 and less than 100'):
FileSystemSchema(thresholds=[0, 50])

def test_100_percent(self) -> None:
"""Test the value ``100`` fails validation"""

with self.assertRaisesRegex(ValidationError, 'must be greater than 0 and less than 100'):
with self.assertRaisesRegex(Exception, 'must be greater than 0 and less than 100'):
FileSystemSchema(thresholds=[50, 100])

def test_negative_percent(self) -> None:
"""Test negative values fail validation"""

with self.assertRaisesRegex(ValidationError, 'must be greater than 0 and less than 100'):
with self.assertRaisesRegex(Exception, 'must be greater than 0 and less than 100'):
FileSystemSchema(thresholds=[-1, 50])

def test_over_100_percent(self) -> None:
"""Test values over ``100`` fail validation"""

with self.assertRaisesRegex(ValidationError, 'must be greater than 0 and less than 100'):
with self.assertRaisesRegex(Exception, 'must be greater than 0 and less than 100'):
FileSystemSchema(thresholds=[50, 101])
31 changes: 0 additions & 31 deletions tests/settings/test_settingsschema.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,6 @@
from tests.base import DefaultSetupTeardown


class BlacklistValidation(DefaultSetupTeardown, TestCase):
"""Test validation for the ``uid_blacklist`` and ``gid_blacklist`` fields"""

def test_error_on_id_range_len_1(self) -> None:
"""Test a ``ValueError`` is raised for UID and GID ranges with 1 element"""

with self.assertRaisesRegex(ValueError, 'actual_length=1; expected_length=2'):
SettingsSchema(uid_blacklist=[[1], ])

with self.assertRaisesRegex(ValueError, 'actual_length=1; expected_length=2'):
SettingsSchema(gid_blacklist=[[1], ])

def test_error_on_id_range_len_3(self) -> None:
"""Test a ``ValueError`` is raised for UID and GID ranges with 3 elements"""

with self.assertRaisesRegex(ValueError, 'actual_length=3; expected_length=2'):
SettingsSchema(uid_blacklist=[[1, 2, 3], ])

with self.assertRaisesRegex(ValueError, 'actual_length=3; expected_length=2'):
SettingsSchema(gid_blacklist=[[1, 2, 3], ])

def test_error_on_account_names(self) -> None:
"""Test a useful error message is raised when users provide account names instead of IDs"""

with self.assertRaisesRegex(ValueError, 'value is not a valid integer'):
SettingsSchema(uid_blacklist=['root', ])

with self.assertRaisesRegex(ValueError, 'value is not a valid integer'):
SettingsSchema(gid_blacklist=['root', ])


class FileSystemValidation(DefaultSetupTeardown, TestCase):
"""Test validation for the ``file_systems`` field"""

Expand Down