Skip to content

Commit

Permalink
Explicitly re-export imports using __all__
Browse files Browse the repository at this point in the history
This is necessary to avoid errors from the no-implicit-reexport rule both in the library and in projects using the library. It's also cleaner to have explicit exports.
  • Loading branch information
binaryDiv committed Aug 7, 2024
1 parent 779710c commit 1694bbb
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Install dependencies
run: pip install --upgrade pip tox

- name: Run unit tests with tox
- name: Run test suite with tox
# Run tox using the version of Python in `PATH`
run: tox run -e clean,py,report,flake8,mypy -- --junit-xml=reports/pytest_${{ matrix.python-version }}.xml

Expand Down
3 changes: 0 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ explicit_package_bases = true
# Enable strict type checking
strict = true

# Ignore errors like `Module "validataclass.exceptions" does not explicitly export attribute "..."`
no_implicit_reexport = false

[[tool.mypy.overrides]]
module = 'tests.*'

Expand Down
10 changes: 10 additions & 0 deletions src/validataclass/dataclasses/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@
from .validataclass import validataclass
from .validataclass_field import validataclass_field
from .validataclass_mixin import ValidataclassMixin

__all__ = [
'Default',
'DefaultFactory',
'DefaultUnset',
'NoDefault',
'ValidataclassMixin',
'validataclass',
'validataclass_field',
]
71 changes: 56 additions & 15 deletions src/validataclass/exceptions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,34 @@
Use of this source code is governed by an MIT-style license that can be found in the LICENSE file.
"""

# "Meta exceptions" (no validation errors, but logic errors in the validators, e.g. when specifying invalid options for
# a validator)
from .base_exceptions import ValidationError
from .common_exceptions import (
FieldNotAllowedError,
InvalidTypeError,
RequiredValueError,
)
from .dataclass_exceptions import DataclassPostValidationError
from .datetime_exceptions import (
DateTimeRangeError,
InvalidDateError,
InvalidDateTimeError,
InvalidTimeError,
)
from .dict_exceptions import (
DictFieldsValidationError,
DictInvalidKeyTypeError,
DictRequiredFieldError,
)
from .email_exceptions import InvalidEmailError
from .list_exceptions import (
ListItemsValidationError,
ListLengthError,
)
from .meta_exceptions import (
DataclassInvalidPreValidateSignatureException,
DataclassValidatorFieldException,
InvalidValidatorOptionException,
)

# Base exception classes for validation errors
from .base_exceptions import ValidationError

# Common validation errors used throughout the library
from .common_exceptions import RequiredValueError, FieldNotAllowedError, InvalidTypeError

# More specific validation errors
from .dataclass_exceptions import DataclassPostValidationError
from .datetime_exceptions import InvalidDateError, InvalidTimeError, InvalidDateTimeError, DateTimeRangeError
from .dict_exceptions import DictFieldsValidationError, DictInvalidKeyTypeError, DictRequiredFieldError
from .email_exceptions import InvalidEmailError
from .list_exceptions import ListItemsValidationError, ListLengthError
from .misc_exceptions import ValueNotAllowedError
from .number_exceptions import (
DecimalPlacesError,
Expand All @@ -40,3 +48,36 @@
StringTooShortError,
)
from .url_exceptions import InvalidUrlError

__all__ = [
'DataclassInvalidPreValidateSignatureException',
'DataclassPostValidationError',
'DataclassValidatorFieldException',
'DateTimeRangeError',
'DecimalPlacesError',
'DictFieldsValidationError',
'DictInvalidKeyTypeError',
'DictRequiredFieldError',
'FieldNotAllowedError',
'InvalidDateError',
'InvalidDateTimeError',
'InvalidDecimalError',
'InvalidEmailError',
'InvalidIntegerError',
'InvalidTimeError',
'InvalidTypeError',
'InvalidUrlError',
'InvalidValidatorOptionException',
'ListItemsValidationError',
'ListLengthError',
'NonFiniteNumberError',
'NumberRangeError',
'RegexMatchError',
'RequiredValueError',
'StringInvalidCharactersError',
'StringInvalidLengthError',
'StringTooLongError',
'StringTooShortError',
'ValidationError',
'ValueNotAllowedError',
]
27 changes: 22 additions & 5 deletions src/validataclass/helpers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,34 @@
Use of this source code is governed by an MIT-style license that can be found in the LICENSE file.
"""

# Requirements for the __getattr__ definition below
import importlib
import warnings
from typing import Any

from .datetime_range import BaseDateTimeRange, DateTimeRange, DateTimeOffsetRange
from .unset_value import UnsetValue, UnsetValueType, OptionalUnset, OptionalUnsetNone, unset_to_none
# Re-export symbols from modules
from .datetime_range import (
BaseDateTimeRange,
DateTimeOffsetRange,
DateTimeRange,
)
from .unset_value import (
OptionalUnset,
OptionalUnsetNone,
UnsetValue,
UnsetValueType,
unset_to_none,
)

# Defining __all__ is necessary here because of the definition of __getattr__() below.
__all__ = [
'BaseDateTimeRange', 'DateTimeRange', 'DateTimeOffsetRange',
'UnsetValue', 'UnsetValueType', 'OptionalUnset', 'OptionalUnsetNone', 'unset_to_none',
'BaseDateTimeRange',
'DateTimeOffsetRange',
'DateTimeRange',
'OptionalUnset',
'OptionalUnsetNone',
'UnsetValue',
'UnsetValueType',
'unset_to_none',
]


Expand Down
39 changes: 35 additions & 4 deletions src/validataclass/validators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
Use of this source code is governed by an MIT-style license that can be found in the LICENSE file.
"""

# Abstract base class
from .validator import Validator

# Validators
from .allow_empty_string import AllowEmptyString
from .any_of_validator import AnyOfValidator
from .anything_validator import AnythingValidator
Expand All @@ -33,3 +29,38 @@
from .string_validator import StringValidator
from .time_validator import TimeValidator, TimeFormat
from .url_validator import UrlValidator
from .validator import Validator

__all__ = [
'AllowEmptyString',
'AnyOfValidator',
'AnythingValidator',
'BigIntegerValidator',
'BooleanValidator',
'DataclassValidator',
'DateTimeFormat',
'DateTimeValidator',
'DateValidator',
'DecimalValidator',
'DictValidator',
'DiscardValidator',
'EmailValidator',
'EnumValidator',
'FloatToDecimalValidator',
'FloatValidator',
'IntegerValidator',
'ListValidator',
'NoneToUnsetValue',
'Noneable',
'NumericValidator',
'RegexValidator',
'RejectValidator',
'StringValidator',
'T_Dataclass',
'T_Enum',
'T_ListItem',
'TimeFormat',
'TimeValidator',
'UrlValidator',
'Validator',
]
2 changes: 2 additions & 0 deletions tests/dataclasses/validataclass_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
Copyright (c) 2021, binary butterfly GmbH and contributors
Use of this source code is governed by an MIT-style license that can be found in the LICENSE file.
"""
# (Ignore comparison-overlap errors, which happen in comparisons like `assert fields['baz'].type is Optional[str]`)
# mypy: no-strict-equality

import dataclasses
from typing import Dict, List, Optional, Union
Expand Down

0 comments on commit 1694bbb

Please sign in to comment.