Skip to content
Open
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: 0 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ RUN apt-get update && \
RUN add-apt-repository ppa:deadsnakes/ppa && \
apt-get update && \
apt-get install -y \
python2.7 \
python2.7-dev \
python3.4 \
python3.4-dev \
python3.5 \
python3.5-dev \
python3.6 \
Expand Down
5 changes: 0 additions & 5 deletions conformity/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
from __future__ import (
absolute_import,
unicode_literals,
)

from conformity.version import (
__version__,
__version_info__,
Expand Down
6 changes: 0 additions & 6 deletions conformity/constants.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
from __future__ import (
absolute_import,
unicode_literals,
)


# Error codes
ERROR_CODE_INVALID = 'INVALID'
ERROR_CODE_MISSING = 'MISSING'
Expand Down
28 changes: 28 additions & 0 deletions conformity/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from functools import wraps
import typing

from conformity.fields.base import BaseField


T = typing.TypeVar('T', bound=typing.Callable[..., typing.Any])


def validate(func: T) -> T:
type_hints = typing.get_type_hints(func)

# Collect Conformity fields from annotations
fields = {}
for arg, hint in type_hints.items():
if issubclass(hint, BaseField):
fields[arg] = hint

@wraps(func)
def wrapped(**kwargs):
# TODO: Add support for positional arguments
for key, value in kwargs.items():
field = fields.get(key)
if field is not None:
field.errors(value)
return func(**kwargs)

return typing.cast(T, wrapped)
46 changes: 4 additions & 42 deletions conformity/error.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,7 @@
from __future__ import (
absolute_import,
unicode_literals,
)

from typing import cast
import warnings

import six

# NOTE: The following have been moved to different modules, but are imported
# here for backwards compatibility. These aliases will be removed in
# Conformity 2.0.
from conformity.constants import (
ERROR_CODE_INVALID,
ERROR_CODE_MISSING,
ERROR_CODE_UNKNOWN,
)
from conformity.types import Error

__all__ = (
'ERROR_CODE_INVALID',
'ERROR_CODE_MISSING',
'ERROR_CODE_UNKNOWN',
'Error',
'KeywordError',
'PositionalError',
'ValidationError',
'update_error_pointer',
)


Expand All @@ -38,26 +13,13 @@ class ValidationError(ValueError):

class PositionalError(TypeError):
"""
Error raised when you pass positional arguments into a validated function that doesn't support them.
Error raised when you pass positional arguments into a validated function
that doesn't support them.
"""


class KeywordError(TypeError):
"""
Error raised when you pass keyword arguments into a validated function that doesn't support them.
Error raised when you pass keyword arguments into a validated function that
doesn't support them.
"""


# NOTE: update_error_pointer has been deprecated. Use utils.field:update_pointer
# instead. This alias has been added for backwards compatibility, but it
# will be removed in Conformity 2.0.
def update_error_pointer(error, pointer_or_prefix):
# type: (Error, six.text_type) -> Error
warnings.warn(
'update_error_pointer has been deprecated and will be removed in Conformity 2.0.',
DeprecationWarning,
stacklevel=2,
)

from conformity.fields.utils import update_pointer
return cast(Error, update_pointer(error, pointer_or_prefix))
102 changes: 67 additions & 35 deletions conformity/fields/__init__.py
Original file line number Diff line number Diff line change
@@ -1,52 +1,71 @@
from __future__ import (
absolute_import,
unicode_literals,
)

from conformity.fields.basic import (
Anything,
Base,
Boolean,
ByteString,
Constant,
Decimal,
Float,
Hashable,
Integer,
UnicodeDecimal,
UnicodeString,
from conformity.fields.base import (
BaseField,
BaseTypeField,
)
from conformity.fields.email import EmailAddress
from conformity.fields.geo import (
Latitude,
Longitude,
)
from conformity.fields.meta import (
All,
Any,
BooleanValidator,
ClassConfigurationSchema,
Deprecated,
from conformity.fields.legacy import (
Base,
ByteString,
Null,
Nullable,
ObjectInstance,
Polymorph,
PythonPath,
TypePath,
SchemalessDictionary,
TypeReference,
UnicodeDecimal,
UnicodeString,
)
from conformity.fields.meta import (
All,
Any,
Anything,
Chain,
Constant,
Instance,
Polymorph,
Type,
Validator,
)
from conformity.fields.modifiers import (
Deprecated,
Optional,
)
from conformity.fields.net import (
IPAddress,
IPv4Address,
IPv6Address,
)
from conformity.fields.protocols import (
Callable,
Collection,
Container,
Hashable,
Iterable,
Mapping,
Number,
Sequence,
Set,
Sized,
)
from conformity.fields.python import (
ClassConfigurationSchema,
PythonPath,
TypePath,
)
from conformity.fields.simple import (
Boolean,
Bytes,
Decimal,
Float,
Integer,
String,
)
from conformity.fields.structures import (
AdditionalCollectionValidator,
Dictionary,
List,
SchemalessDictionary,
Sequence,
Set,
Tuple,
)
from conformity.fields.temporal import (
Expand All @@ -57,18 +76,22 @@
TZInfo,
)


__all__ = (
'AdditionalCollectionValidator',
'All',
'Any',
'Anything',
'Base',
'BaseField',
'BaseTypeField',
'Boolean',
'BooleanValidator',
'ByteString',
'Bytes',
'Callable',
'Chain',
'ClassConfigurationSchema',
'Collection',
'Constant',
'Container',
'Date',
'DateTime',
'Decimal',
Expand All @@ -77,27 +100,36 @@
'EmailAddress',
'Float',
'Hashable',
'Integer',
'IPAddress',
'IPv4Address',
'IPv6Address',
'Instance',
'Integer',
'Iterable',
'Latitude',
'List',
'Longitude',
'Mapping',
'Null',
'Nullable',
'Number',
'ObjectInstance',
'Optional',
'Polymorph',
'PythonPath',
'SchemalessDictionary',
'Sequence',
'Set',
'Sized',
'String',
'TZInfo',
'Time',
'TimeDelta',
'Tuple',
'Type',
'TypePath',
'TypeReference',
'TZInfo',
'UnicodeDecimal',
'UnicodeString',
'Validator',
)
Loading