Skip to content
This repository has been archived by the owner on May 4, 2021. It is now read-only.

Commit

Permalink
Merge pull request #34 from herczy/f/typing-error-fix
Browse files Browse the repository at this point in the history
typing_inspect removed, use own inspect methods for now
  • Loading branch information
attilammagyar authored Mar 6, 2018
2 parents 162acec + 361a9e3 commit 452242d
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 6 deletions.
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
are valid.
""",
license="LGPLv2+",
version="2.1.1",
version="2.1.2",
author="Viktor Hercinger",
author_email="[email protected]",
maintainer="Viktor Hercinger",
Expand Down Expand Up @@ -68,6 +68,5 @@
install_requires=[
'nose',
'sphinx',
'typing_inspect',
]
)
1 change: 0 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ deps=
behave

coverage
typing_inspect
py34: typing

commands=
Expand Down
37 changes: 37 additions & 0 deletions typesafety/tests/test_typing_inspect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#
# Copyright (c) 2013-2018 Balabit
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#

import typing
import unittest

from typesafety.typing_inspect import is_union_type, get_union_args


class TestTypingInspect(unittest.TestCase):
def test_inspect_union_type(self):
self.assertTrue(is_union_type(typing.Union))
self.assertTrue(is_union_type(typing.Union[int, str]))
self.assertTrue(is_union_type(typing.Optional[int]))
self.assertFalse(is_union_type(typing.List[int]))
self.assertFalse(is_union_type(typing.Any))

def test_get_union_args(self):
self.assertEqual((), get_union_args(typing.Union))
self.assertEqual((int, str), get_union_args(typing.Union[int, str]))
self.assertEqual((int, type(None)), get_union_args(typing.Optional[int]))
self.assertRaises(TypeError, get_union_args, typing.List[int])
self.assertRaises(TypeError, get_union_args, typing.Any)
51 changes: 51 additions & 0 deletions typesafety/typing_inspect.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#
# Copyright (c) 2013-2018 Balabit
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#

'''
This module contains helper methods for dealing with the contents of the typing module. This
module is not really stable so there are differences even between minor versions. See:
https://docs.python.org/3.6/library/typing.html
Note that this module is flaky and very hacky, but hopefully later we can use some external
tool for this.
'''

# There is no good, idiomatic way to determine if an annotation is a union or not,
# so we're saddled with this hacky solution.
# pylint: disable=unidiomatic-typecheck,protected-access
import typing


def is_union_type(cls):
if hasattr(typing, '_Union'):
return type(cls) is typing._Union

return type(cls) is typing.UnionMeta


def get_union_args(cls):
if not is_union_type(cls):
raise TypeError('expected union type')

if hasattr(cls, '__args__'):
res = cls.__args__

else:
res = cls.__union_params__

return res if res is not None else ()
9 changes: 6 additions & 3 deletions typesafety/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import inspect
import warnings

from typing_inspect import is_union_type, get_args
from typesafety.typing_inspect import is_union_type, get_union_args


class TypesafetyError(Exception):
Expand Down Expand Up @@ -174,6 +174,9 @@ def validate_arguments(self, locals_dict):
raise TypesafetyError(message)

def __format_expectation(self, annotation):
if is_union_type(annotation):
return 'typing.Union[{}]'.format(', '.join(entry.__name__ for entry in get_union_args(annotation)))

if isinstance(annotation, tuple):
return "({})".format(
", ".join(self.__format_expectation(a) for a in annotation)
Expand Down Expand Up @@ -278,7 +281,7 @@ def __is_valid(self, value, validator):
if is_union_type(validator):
return any(
self.__is_valid(value, subvalidator)
for subvalidator in get_args(validator)
for subvalidator in get_union_args(validator)
)

if isinstance(validator, type):
Expand Down Expand Up @@ -307,7 +310,7 @@ def __is_valid_typecheck_annotation(self, validator):
if is_union_type(validator):
return all(
self.__is_valid_typecheck_annotation(subvalidator)
for subvalidator in get_args(validator)
for subvalidator in get_union_args(validator)
)

if isinstance(validator, type):
Expand Down

0 comments on commit 452242d

Please sign in to comment.