# Path: twiggy/lib/validators.py
# def _import_module(module_name):
#     # Python 2.6 compatibility
#     fromlist = []
#     try:
#         fromlist.append(module_name[:module_name.rindex('.')])
#     except ValueError:
#         pass
# 
#     return __import__(module_name, fromlist=fromlist)
# 
# def _string_to_attribute(value, type_='attribute'):
#     """
#     Tests whether a string is an importable attribute and returns the attribute
# 
#     :arg value: The string naming the attribute
#     :returns: The attribute
#     :raises ValueError: if the string is not an importable attribute
#     """
#     # For exception messages
#     if type_[0] in ('a', 'e', 'i', 'o', 'u'):
#         article = 'an'
#     else:
#         article = 'a'
# 
#     if not isinstance(value, string_types):
#         raise ValueError('This value must be a string naming {0} {1}, not {2} of'
#                          ' type {3}'.format(article, type_, value, type(value)))
#     parts = value.split('.')
# 
#     # Test for an attribute in builtins named value
#     if len(parts) == 1:
#         try:
#             attribute = getattr(builtins, value)
#         except AttributeError:
#             raise ValueError('Could not find {0} {1} named {2}'.format(article, type_, value))
# 
#         return attribute
# 
#     # Find a module that we can import
#     module = None
#     for idx in range(len(parts) - 1, 0, -1):
#         try:
#             module = import_module('.'.join(parts[:idx]))
#         except Exception:
#             pass
#         else:
#             remainder = parts[idx:]
#             break
#     else:  # For-else
#         raise ValueError('Could not import a module with {0} {1} named'
#                          ' {2}'.format(article, type_, value))
# 
#     # Handle both Staticmethod (ClassName.staticmethod) and module global
#     # attribute (attributename)
#     prev_part = module
#     for next_part in remainder:
#         try:
#             prev_part = getattr(prev_part, next_part)
#         except AttributeError:
#             raise ValueError('Could not find {0} {1} named {2} in module'
#                              ' {3}'.format(article, type_, '.'.join(remainder),
#                                            '.'.join(parts[:idx])))
#     attribute = prev_part
#     return attribute
# 
# def _parse_external(value, function=False):
#     """
#     Check whether a string is marked as being an external resource and return the resource
# 
#     This function checks whether a string begins with ``ext://`` and if so it removes the ``ext://``
#     and tries to import an attribute with that name.
# 
#     :arg value: The string to process
#     :kwarg function: If True, make sure that the attribute found is a callable.  This will convert
#         a string into a function or fail validation regardless of whether the string starts with
#         ``ext://``. (Default False)
#     :returns: If ``ext://`` was present or always is True then the imported attribute is returned.
#         If not, then ``value`` is returned.
#     :raises ValueError: if the string is not importable
#     """
#     external = False
#     if isinstance(value, string_types):
#         if value.startswith('ext://'):
#             value = value[6:]
#             external = True
# 
#     if not (external or function):
#         return value
# 
#     if isinstance(value, string_types):
#         attribute = _string_to_attribute(value, type_='function' if function else 'attribute')
#     else:
#         attribute = value
# 
#     if function:
#         # Finally check that it is a callable
#         if not callable(attribute):
#             raise ValueError('Identifier named {0} is not a function'.format(value))
#     return attribute


import re
import sys
import pytest
    import os
    import os.path
        import itertools
        import itertools
        import itertools
from twiggy.lib.validators import (_import_module, _string_to_attribute, _parse_external)
        from os import F_OK
        from os import F_OK
        from itertools import chain
        from itertools import chain
        from tarfile import TarInfo
        from tarfile import TarInfo

INVALID_FUNCTIONS = INVALID_ATTRIBUTES[1:] + (
    (5, "Identifier named 5 is not a function"),
    ('os.F_OK', 'Identifier named os.F_OK is not a function'),
)


def function_for_testing(value):
    pass


def test_import_module_backport():
    os_via_import_module = _import_module('os')
    assert os_via_import_module == os

    os_path_via_import_module = _import_module('os.path')
    assert os_path_via_import_module == os.path


class TestStringToAttribute(object):
    def test_valid_builtin(self):

        # A toplevel function
        assert _string_to_attribute('dir', type_='function') == dir

    def test_valid_attribute_pre_import(self):
        f_ok_via_validator = _string_to_attribute('os.F_OK')
        assert f_ok_via_validator == F_OK

    def test_valid_attribute_post_import(self):

# Path: twiggy/lib/validators.py
# def _import_module(module_name):
#     # Python 2.6 compatibility
#     fromlist = []
#     try:
#         fromlist.append(module_name[:module_name.rindex('.')])
#     except ValueError:
#         pass
# 
#     return __import__(module_name, fromlist=fromlist)
# 
# def _string_to_attribute(value, type_='attribute'):
#     """
#     Tests whether a string is an importable attribute and returns the attribute
# 
#     :arg value: The string naming the attribute
#     :returns: The attribute
#     :raises ValueError: if the string is not an importable attribute
#     """
#     # For exception messages
#     if type_[0] in ('a', 'e', 'i', 'o', 'u'):
#         article = 'an'
#     else:
#         article = 'a'
# 
#     if not isinstance(value, string_types):
#         raise ValueError('This value must be a string naming {0} {1}, not {2} of'
#                          ' type {3}'.format(article, type_, value, type(value)))
#     parts = value.split('.')
# 
#     # Test for an attribute in builtins named value
#     if len(parts) == 1:
#         try:
#             attribute = getattr(builtins, value)
#         except AttributeError:
#             raise ValueError('Could not find {0} {1} named {2}'.format(article, type_, value))
# 
#         return attribute
# 
#     # Find a module that we can import
#     module = None
#     for idx in range(len(parts) - 1, 0, -1):
#         try:
#             module = import_module('.'.join(parts[:idx]))
#         except Exception:
#             pass
#         else:
#             remainder = parts[idx:]
#             break
#     else:  # For-else
#         raise ValueError('Could not import a module with {0} {1} named'
#                          ' {2}'.format(article, type_, value))
# 
#     # Handle both Staticmethod (ClassName.staticmethod) and module global
#     # attribute (attributename)
#     prev_part = module
#     for next_part in remainder:
#         try:
#             prev_part = getattr(prev_part, next_part)
#         except AttributeError:
#             raise ValueError('Could not find {0} {1} named {2} in module'
#                              ' {3}'.format(article, type_, '.'.join(remainder),
#                                            '.'.join(parts[:idx])))
#     attribute = prev_part
#     return attribute
# 
# def _parse_external(value, function=False):
#     """
#     Check whether a string is marked as being an external resource and return the resource
# 
#     This function checks whether a string begins with ``ext://`` and if so it removes the ``ext://``
#     and tries to import an attribute with that name.
# 
#     :arg value: The string to process
#     :kwarg function: If True, make sure that the attribute found is a callable.  This will convert
#         a string into a function or fail validation regardless of whether the string starts with
#         ``ext://``. (Default False)
#     :returns: If ``ext://`` was present or always is True then the imported attribute is returned.
#         If not, then ``value`` is returned.
#     :raises ValueError: if the string is not importable
#     """
#     external = False
#     if isinstance(value, string_types):
#         if value.startswith('ext://'):
#             value = value[6:]
#             external = True
# 
#     if not (external or function):
#         return value
# 
#     if isinstance(value, string_types):
#         attribute = _string_to_attribute(value, type_='function' if function else 'attribute')
#     else:
#         attribute = value
# 
#     if function:
#         # Finally check that it is a callable
#         if not callable(attribute):
#             raise ValueError('Identifier named {0} is not a function'.format(value))
#     return attribute


# Path: tests/test_lib_validators.py
import re
import sys
import pytest
    import os
    import os.path
        import itertools
        import itertools
        import itertools
from twiggy.lib.validators import (_import_module, _string_to_attribute, _parse_external)
        from os import F_OK
        from os import F_OK
        from itertools import chain
        from itertools import chain
        from tarfile import TarInfo
        from tarfile import TarInfo


INVALID_FUNCTIONS = INVALID_ATTRIBUTES[1:] + (
    (5, "Identifier named 5 is not a function"),
    ('os.F_OK', 'Identifier named os.F_OK is not a function'),
)


def function_for_testing(value):
    pass


def test_import_module_backport():
    os_via_import_module = _import_module('os')
    assert os_via_import_module == os

    os_path_via_import_module = _import_module('os.path')
    assert os_path_via_import_module == os.path


class TestStringToAttribute(object):
    def test_valid_builtin(self):

        # A toplevel function
        assert _string_to_attribute('dir', type_='function') == dir

    def test_valid_attribute_pre_import(self):
        f_ok_via_validator = _string_to_attribute('os.F_OK')
        assert f_ok_via_validator == F_OK

    def test_valid_attribute_post_import(self):

        f_ok_via_validator = _string_to_attribute('os.F_OK')