<commit_before>"""
Load a shared library.
"""
import os
import sys
import ctypes
import ctypes.util
import logging
import subprocess

from . import utils, DEFAULT_EXTENSION, IS_PYTHON2

logger = logging.getLogger(__name__)

_encoding = sys.getfilesystemencoding()

class LoadLibrary(object):

    def __init__(self, path, libtype=None, **kwargs):
        """Load a shared library.

        For example, a C/C++, FORTRAN, C#, Java, Delphi, LabVIEW, ActiveX, ... library.

        Based on the value of `libtype` this class will load the shared library as a:

            * :class:`~ctypes.CDLL` if `libtype` is ``'cdll'``,
            * :class:`~ctypes.WinDLL` if `libtype` is ``'windll'``,
            * :class:`~ctypes.OleDLL` if `libtype` is ``'oledll'``,
            * `System.Reflection.Assembly <Assembly_>`_ if `libtype` is ``'net'``,
            * :class:`~.py4j.java_gateway.JavaGateway` if `libtype` is ``'java'``, or
            * comtypes.CreateObject_ if `libtype` is ``'com'``.

        .. _Assembly: https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx
        .. _comtypes.CreateObject: https://pythonhosted.org/comtypes/#creating-and-accessing-com-objects
        .. _COM: https://en.wikipedia.org/wiki/Component_Object_Model

        Parameters
        ----------
        path : :class:`str`
            The path to the shared library.

            The search order for finding the shared library is:

                1. assume that a full or a relative (to the current working directory)
                   path is specified,
                2. use :func:`ctypes.util.find_library` to find the shared library file,
                3. search :data:`sys.path`, then
                4. search :data:`os.environ['PATH'] <os.environ>` to find the shared library.

            If loading a COM_ library then `path` represents the `progid <comtypes.CreateObject_>`_
            argument.

        libtype : :class:`str`, optional
            The library type. The following values are currently supported:

            * ``'cdll'`` -- for a library that uses the __cdecl calling convention
            * ``'windll'`` or ``'oledll'`` -- for a __stdcall calling convention
            * ``'net'`` -- for Microsoft's .NET Framework (Common Language Runtime)
            * ``'java'`` -- for a Java archive, ``.jar``, or Java byte code, ``.class``, file
            * ``'com'`` -- for a COM_ library.

            Default is ``'cdll'``.

            .. tip::
               Since the ``.jar`` or ``.class`` extension uniquely defines a Java library,
               the `libtype` will be automatically set to ``'java'`` if `path` ends with
               ``.jar`` or ``.class``. If `path` starts with ``'{'`` and ends with ``'}'``
               then this uniquely defines the Class ID for a COM_ library and so `libtype`
               will be automatically set to ``'com'``.

        **kwargs
            Keyword arguments that are passed to the object that loads the library.

        Raises
        ------
        IOError
            If the shared library cannot be loaded.
        TypeError
            If `libtype` is not a supported library type.
        """

        # a reference to the shared library
        self._lib = None

        # a reference to the .NET Runtime Assembly
        self._assembly = None

        # a reference to the Py4J JavaGateway
        self._gateway = None

        # fixes Issue #8, if `path` is a <class 'pathlib.Path'> object
        if hasattr(path, 'as_posix'):
            path = path.as_posix()

        # try to automatically determine the libtype
        if libtype is None:
            if path.startswith('{') and path.endswith('}'):
                libtype = 'com'
            elif path.endswith('.jar') or path.endswith('.class'):
                libtype = 'java'
            else:
                libtype = 'cdll'
        else:
            libtype = libtype.lower()

        # create a new reference to `path` just in case the
        # DEFAULT_EXTENSION is appended below so that the
        # ctypes.util.find_library function call will use the
        # unmodified value of `path`
        _path = path

        # assume a default extension if no extension was provided
        ext = os.path.splitext(path)[1]
        if libtype != 'java' and libtype != 'com' and not ext:
            _path += DEFAULT_EXTENSION

        if IS_PYTHON2:
            _path = _path.encode(_encoding)

        if libtype != 'com':
            self._path = os.path.abspath(_path)
            if not os.path.isfile(self._path):
                # for find_library use the original 'path' value since it may be a library name
                # without any prefix like 'lib', suffix like '.so', '.dylib' or version number
                self._path = ctypes.util.find_library(path)
                if self._path is None:  # then search sys.path and os.environ['PATH']
                    success = False
                    search_dirs = sys.path + os.environ['PATH'].split(os.pathsep)
                    for directory in search_dirs:
                        p = os.path.join(directory, _path)
                        if os.path.isfile(p):
                            self._path = p
                            success = True
                            break
                    if not success:
                        raise IOError('Cannot find the shared library {!r}'.format(path))
        else:
            self._path = _path

        if libtype == 'cdll':
            self._lib = ctypes.CDLL(self._path, **kwargs)
        elif libtype == 'windll':
            self._lib = ctypes.WinDLL(self._path, **kwargs)
        elif libtype == 'oledll':
            self._lib = ctypes.OleDLL(self._path, **kwargs)
        elif libtype == 'com':
            if not utils.is_comtypes_installed():
                raise IOError('Cannot load a COM library because comtypes is not installed.\n'
                              'To install comtypes run: pip install comtypes')
            from comtypes.client import CreateObject
            self._lib = CreateObject(self._path, **kwargs)
        elif libtype == 'java':
            if not utils.is_py4j_installed():
                raise IOError('Cannot load a Java file because Py4J is not installed.\n'
                              'To install Py4J run: pip install py4j')

            from py4j.version import __version__
            from py4j.java_gateway import JavaGateway, GatewayParameters

            # the address and port to use to host the py4j.GatewayServer
            address = kwargs.pop('address', '127.0.0.1')
            port = kwargs.pop('port', utils.get_available_port())

            # find the py4j JAR (needed to import py4j.GatewayServer on the Java side)
            root = os.path.dirname(sys.executable)
            filename = 'py4j'+__version__+'.jar'
            py4j_jar = os.path.join(root, 'share', 'py4j', filename)
            if not os.path.isfile(py4j_jar):
                root = os.path.dirname(root)  # then check one folder up (for unix or venv)
                py4j_jar = os.path.join(root, 'share', 'py4j', filename)
                if not os.path.isfile(py4j_jar):
                    py4j_jar = os.environ.get('PY4J_JAR', '')  # then check the environment variable
                    if not os.path.isfile(py4j_jar):
                        raise IOError('Cannot find {0}\nCreate a PY4J_JAR environment '
                                      'variable to be equal to the full path to {0}'.format(filename))

            # build the java command
            wrapper = os.path.join(os.path.dirname(__file__), 'py4j-wrapper.jar')
            cmd = ['java', '-cp', py4j_jar + os.pathsep + wrapper, 'Py4JWrapper', str(port)]

            # from the URLClassLoader documentation:
            #   Any URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL
            #   is assumed to refer to a JAR file which will be downloaded and opened as needed.
            if ext == '.jar':
                cmd.append(self._path)
            else:  # it is a .class file
                cmd.append(os.path.dirname(self._path) + '/')

            try:
                # start the py4j.GatewayServer, cannot use subprocess.call() because it blocks
                subprocess.Popen(cmd, stderr=sys.stderr, stdout=sys.stdout)
                err = None
            except IOError as e:
                err = str(e) + '\nYou must have a Java Runtime Environment installed and available on PATH'

            if err:
                raise IOError(err)

            utils.wait_for_server(address, port, 5.0)

            self._gateway = JavaGateway(
                gateway_parameters=GatewayParameters(address=address, port=port, **kwargs)
            )

            self._lib = self._gateway.jvm

        elif libtype == 'net':
            if not utils.is_pythonnet_installed():
                raise IOError('Cannot load a .NET Assembly because pythonnet is not installed.\n'
                              'To install pythonnet run: pip install pythonnet')

            import clr
            try:
                # By default, pythonnet can only load libraries that are for .NET 4.0+.
                #
                # In order to allow pythonnet to load a library from .NET <4.0 the
                # useLegacyV2RuntimeActivationPolicy property needs to be enabled
                # in a <python-executable>.config file. If the following statement
                # raises a FileLoadException then attempt to create the configuration
                # file that has the property enabled and then notify the user why
                # loading the library failed and ask them to re-run their Python
                # script to load the .NET library.
                self._assembly = clr.System.Reflection.Assembly.LoadFile(self._path)

            except clr.System.IO.FileLoadException as err:
                # Example error message that can occur if the library is for .NET <4.0,
                # and the useLegacyV2RuntimeActivationPolicy is not enabled:
                #
                # " Mixed mode assembly is built against version 'v2.0.50727' of the
                #  runtime and cannot be loaded in the 4.0 runtime without additional
                #  configuration information. "
                if str(err).startswith('Mixed mode assembly'):
                    status, msg = utils.check_dot_net_config(sys.executable)
                    if not status == 0:
                        raise IOError(msg)
                    else:
                        update_msg = 'Checking .NET config returned "{}" '.format(msg)
                        update_msg += 'and still cannot load library.\n'
                        update_msg += str(err)
                        raise IOError(update_msg)
                raise IOError('The above "System.IO.FileLoadException" is not handled.\n')

            # the shared library must be available in sys.path
            head, tail = os.path.split(self._path)
            if IS_PYTHON2:
                head = head.decode(_encoding)
            sys.path.append(head)

            # don't include the library extension
            clr.AddReference(os.path.splitext(tail)[0])

            # import namespaces, create instances of classes or reference a System.Type[] object
            try:
                types = self._assembly.GetTypes()
            except Exception as e:
                logger.error(e)
                logger.error('The LoaderExceptions are:')
                for item in e.LoaderExceptions:
                    logger.error('  ' + item.Message)
            else:
                dotnet = dict()
                for t in types:
                    if t.Namespace is not None:
                        mod = __import__(t.Namespace)
                        if mod.__name__ not in dotnet:
                            dotnet[mod.__name__] = mod
                    else:
                        try:
                            dotnet[t.Name] = self._assembly.CreateInstance(t.FullName)
                        except:
                            if t.Name not in dotnet:
                                dotnet[t.Name] = t
                self._lib = DotNet(dotnet, self._path)

        else:
            raise TypeError('Cannot load libtype={}'.format(libtype))

        if IS_PYTHON2:
            self._path = self._path.decode(_encoding)

        logger.debug('Loaded ' + self._path)

    def __repr__(self):
        path = self._path.encode(_encoding) if IS_PYTHON2 else self._path
        return '<LoadLibrary libtype={} path={}>'.format(self._lib.__class__.__name__, path)

    def __del__(self):
        if self._gateway is not None:
            self._gateway.shutdown()
            logger.debug('shutdown py4j.GatewayServer')

    @property
    def assembly(self):
        """
        Returns a reference to the `.NET Runtime Assembly <Assembly_>`_ object, only if
        the shared library is a .NET Framework, otherwise returns :data:`None`.

        .. tip::
           The `JetBrains dotPeek`_ program can be used to reliably decompile any
           .NET Assembly in to the equivalent source code.

        .. _JetBrains dotPeek: https://www.jetbrains.com/decompiler/
        """
        return self._assembly

    @property
    def gateway(self):
        """
        Returns the :class:`~py4j.java_gateway.JavaGateway` object, only if
        the shared library is a Java archive, otherwise returns :data:`None`.
        """
        return self._gateway

    @property
    def lib(self):
        """Returns the reference to the loaded library object.

        For example, if `libtype` is

            * ``'cdll'`` then a :class:`~ctypes.CDLL` object
            * ``'windll'`` then a :class:`~ctypes.WinDLL` object
            * ``'oledll'`` then a :class:`~ctypes.OleDLL` object
            * ``'net'`` then a :class:`~.load_library.DotNet` object
            * ``'java'`` then a :class:`~py4j.java_gateway.JVMView` object
            * ``'com'`` then the interface pointer returned by comtypes.CreateObject_
        """
        return self._lib

    @property
    def path(self):
        """:class:`str`: The path to the shared library file."""
        return self._path

class DotNet(object):

    def __init__(self, dot_net_dict, path):
        """Contains the namespace_ modules, classes and `System.Type`_ objects of a .NET Assembly.

        Do not instantiate this class directly.

        .. _namespace: https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx
        .. _System.Type: https://msdn.microsoft.com/en-us/library/system.type(v=vs.110).aspx
        """
        self.__dict__.update(dot_net_dict)
        self._path = path

    def __repr__(self):
        return '<{} path={}>'.format(self.__class__.__name__, self._path)
<commit_msg>raise ValueError "if not path"<commit_after>"""
Load a shared library.
"""
import os
import sys
import ctypes
import ctypes.util
import logging
import subprocess

from . import utils, DEFAULT_EXTENSION, IS_PYTHON2

logger = logging.getLogger(__name__)

_encoding = sys.getfilesystemencoding()

class LoadLibrary(object):

    def __init__(self, path, libtype=None, **kwargs):
        """Load a shared library.

        For example, a C/C++, FORTRAN, C#, Java, Delphi, LabVIEW, ActiveX, ... library.

        Based on the value of `libtype` this class will load the shared library as a:

            * :class:`~ctypes.CDLL` if `libtype` is ``'cdll'``,
            * :class:`~ctypes.WinDLL` if `libtype` is ``'windll'``,
            * :class:`~ctypes.OleDLL` if `libtype` is ``'oledll'``,
            * `System.Reflection.Assembly <Assembly_>`_ if `libtype` is ``'net'``,
            * :class:`~.py4j.java_gateway.JavaGateway` if `libtype` is ``'java'``, or
            * comtypes.CreateObject_ if `libtype` is ``'com'``.

        .. _Assembly: https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx
        .. _comtypes.CreateObject: https://pythonhosted.org/comtypes/#creating-and-accessing-com-objects
        .. _COM: https://en.wikipedia.org/wiki/Component_Object_Model

        Parameters
        ----------
        path : :class:`str`
            The path to the shared library.

            The search order for finding the shared library is:

                1. assume that a full or a relative (to the current working directory)
                   path is specified,
                2. use :func:`ctypes.util.find_library` to find the shared library file,
                3. search :data:`sys.path`, then
                4. search :data:`os.environ['PATH'] <os.environ>` to find the shared library.

            If loading a COM_ library then `path` represents the `progid <comtypes.CreateObject_>`_
            argument.

        libtype : :class:`str`, optional
            The library type. The following values are currently supported:

            * ``'cdll'`` -- for a library that uses the __cdecl calling convention
            * ``'windll'`` or ``'oledll'`` -- for a __stdcall calling convention
            * ``'net'`` -- for Microsoft's .NET Framework (Common Language Runtime)
            * ``'java'`` -- for a Java archive, ``.jar``, or Java byte code, ``.class``, file
            * ``'com'`` -- for a COM_ library.

            Default is ``'cdll'``.

            .. tip::
               Since the ``.jar`` or ``.class`` extension uniquely defines a Java library,
               the `libtype` will be automatically set to ``'java'`` if `path` ends with
               ``.jar`` or ``.class``. If `path` starts with ``'{'`` and ends with ``'}'``
               then this uniquely defines the Class ID for a COM_ library and so `libtype`
               will be automatically set to ``'com'``.

        **kwargs
            Keyword arguments that are passed to the object that loads the library.

        Raises
        ------
        IOError
            If the shared library cannot be loaded.
        TypeError
            If `libtype` is not a supported library type.
        """
        # a reference to the shared library
        self._lib = None

        # a reference to the .NET Runtime Assembly
        self._assembly = None

        # a reference to the Py4J JavaGateway
        self._gateway = None

        if not path:
            raise ValueError('You must specify the path, got {!r}'.format(path))

        # fixes Issue #8, if `path` is a <class 'pathlib.Path'> object
        if hasattr(path, 'as_posix'):
            path = path.as_posix()

        # try to automatically determine the libtype
        if libtype is None:
            if path.startswith('{') and path.endswith('}'):
                libtype = 'com'
            elif path.endswith('.jar') or path.endswith('.class'):
                libtype = 'java'
            else:
                libtype = 'cdll'
        else:
            libtype = libtype.lower()

        # create a new reference to `path` just in case the
        # DEFAULT_EXTENSION is appended below so that the
        # ctypes.util.find_library function call will use the
        # unmodified value of `path`
        _path = path

        # assume a default extension if no extension was provided
        ext = os.path.splitext(path)[1]
        if libtype != 'java' and libtype != 'com' and not ext:
            _path += DEFAULT_EXTENSION

        if IS_PYTHON2:
            _path = _path.encode(_encoding)

        if libtype != 'com':
            self._path = os.path.abspath(_path)
            if not os.path.isfile(self._path):
                # for find_library use the original 'path' value since it may be a library name
                # without any prefix like 'lib', suffix like '.so', '.dylib' or version number
                self._path = ctypes.util.find_library(path)
                if self._path is None:  # then search sys.path and os.environ['PATH']
                    success = False
                    search_dirs = sys.path + os.environ['PATH'].split(os.pathsep)
                    for directory in search_dirs:
                        p = os.path.join(directory, _path)
                        if os.path.isfile(p):
                            self._path = p
                            success = True
                            break
                    if not success:
                        raise IOError('Cannot find the shared library {!r}'.format(path))
        else:
            self._path = _path

        if libtype == 'cdll':
            self._lib = ctypes.CDLL(self._path, **kwargs)
        elif libtype == 'windll':
            self._lib = ctypes.WinDLL(self._path, **kwargs)
        elif libtype == 'oledll':
            self._lib = ctypes.OleDLL(self._path, **kwargs)
        elif libtype == 'com':
            if not utils.is_comtypes_installed():
                raise IOError('Cannot load a COM library because comtypes is not installed.\n'
                              'To install comtypes run: pip install comtypes')
            from comtypes.client import CreateObject
            self._lib = CreateObject(self._path, **kwargs)
        elif libtype == 'java':
            if not utils.is_py4j_installed():
                raise IOError('Cannot load a Java file because Py4J is not installed.\n'
                              'To install Py4J run: pip install py4j')

            from py4j.version import __version__
            from py4j.java_gateway import JavaGateway, GatewayParameters

            # the address and port to use to host the py4j.GatewayServer
            address = kwargs.pop('address', '127.0.0.1')
            port = kwargs.pop('port', utils.get_available_port())

            # find the py4j JAR (needed to import py4j.GatewayServer on the Java side)
            root = os.path.dirname(sys.executable)
            filename = 'py4j'+__version__+'.jar'
            py4j_jar = os.path.join(root, 'share', 'py4j', filename)
            if not os.path.isfile(py4j_jar):
                root = os.path.dirname(root)  # then check one folder up (for unix or venv)
                py4j_jar = os.path.join(root, 'share', 'py4j', filename)
                if not os.path.isfile(py4j_jar):
                    py4j_jar = os.environ.get('PY4J_JAR', '')  # then check the environment variable
                    if not os.path.isfile(py4j_jar):
                        raise IOError('Cannot find {0}\nCreate a PY4J_JAR environment '
                                      'variable to be equal to the full path to {0}'.format(filename))

            # build the java command
            wrapper = os.path.join(os.path.dirname(__file__), 'py4j-wrapper.jar')
            cmd = ['java', '-cp', py4j_jar + os.pathsep + wrapper, 'Py4JWrapper', str(port)]

            # from the URLClassLoader documentation:
            #   Any URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL
            #   is assumed to refer to a JAR file which will be downloaded and opened as needed.
            if ext == '.jar':
                cmd.append(self._path)
            else:  # it is a .class file
                cmd.append(os.path.dirname(self._path) + '/')

            try:
                # start the py4j.GatewayServer, cannot use subprocess.call() because it blocks
                subprocess.Popen(cmd, stderr=sys.stderr, stdout=sys.stdout)
                err = None
            except IOError as e:
                err = str(e) + '\nYou must have a Java Runtime Environment installed and available on PATH'

            if err:
                raise IOError(err)

            utils.wait_for_server(address, port, 5.0)

            self._gateway = JavaGateway(
                gateway_parameters=GatewayParameters(address=address, port=port, **kwargs)
            )

            self._lib = self._gateway.jvm

        elif libtype == 'net':
            if not utils.is_pythonnet_installed():
                raise IOError('Cannot load a .NET Assembly because pythonnet is not installed.\n'
                              'To install pythonnet run: pip install pythonnet')

            import clr
            try:
                # By default, pythonnet can only load libraries that are for .NET 4.0+.
                #
                # In order to allow pythonnet to load a library from .NET <4.0 the
                # useLegacyV2RuntimeActivationPolicy property needs to be enabled
                # in a <python-executable>.config file. If the following statement
                # raises a FileLoadException then attempt to create the configuration
                # file that has the property enabled and then notify the user why
                # loading the library failed and ask them to re-run their Python
                # script to load the .NET library.
                self._assembly = clr.System.Reflection.Assembly.LoadFile(self._path)

            except clr.System.IO.FileLoadException as err:
                # Example error message that can occur if the library is for .NET <4.0,
                # and the useLegacyV2RuntimeActivationPolicy is not enabled:
                #
                # " Mixed mode assembly is built against version 'v2.0.50727' of the
                #  runtime and cannot be loaded in the 4.0 runtime without additional
                #  configuration information. "
                if str(err).startswith('Mixed mode assembly'):
                    status, msg = utils.check_dot_net_config(sys.executable)
                    if not status == 0:
                        raise IOError(msg)
                    else:
                        update_msg = 'Checking .NET config returned "{}" '.format(msg)
                        update_msg += 'and still cannot load library.\n'
                        update_msg += str(err)
                        raise IOError(update_msg)
                raise IOError('The above "System.IO.FileLoadException" is not handled.\n')

            # the shared library must be available in sys.path
            head, tail = os.path.split(self._path)
            if IS_PYTHON2:
                head = head.decode(_encoding)
            sys.path.append(head)

            # don't include the library extension
            clr.AddReference(os.path.splitext(tail)[0])

            # import namespaces, create instances of classes or reference a System.Type[] object
            try:
                types = self._assembly.GetTypes()
            except Exception as e:
                logger.error(e)
                logger.error('The LoaderExceptions are:')
                for item in e.LoaderExceptions:
                    logger.error('  ' + item.Message)
            else:
                dotnet = dict()
                for t in types:
                    if t.Namespace is not None:
                        mod = __import__(t.Namespace)
                        if mod.__name__ not in dotnet:
                            dotnet[mod.__name__] = mod
                    else:
                        try:
                            dotnet[t.Name] = self._assembly.CreateInstance(t.FullName)
                        except:
                            if t.Name not in dotnet:
                                dotnet[t.Name] = t
                self._lib = DotNet(dotnet, self._path)

        else:
            raise TypeError('Cannot load libtype={}'.format(libtype))

        if IS_PYTHON2:
            self._path = self._path.decode(_encoding)

        logger.debug('Loaded ' + self._path)

    def __repr__(self):
        path = self._path.encode(_encoding) if IS_PYTHON2 else self._path
        return '<LoadLibrary libtype={} path={}>'.format(self._lib.__class__.__name__, path)

    def __del__(self):
        if self._gateway is not None:
            self._gateway.shutdown()
            logger.debug('shutdown py4j.GatewayServer')

    @property
    def assembly(self):
        """
        Returns a reference to the `.NET Runtime Assembly <Assembly_>`_ object, only if
        the shared library is a .NET Framework, otherwise returns :data:`None`.

        .. tip::
           The `JetBrains dotPeek`_ program can be used to reliably decompile any
           .NET Assembly in to the equivalent source code.

        .. _JetBrains dotPeek: https://www.jetbrains.com/decompiler/
        """
        return self._assembly

    @property
    def gateway(self):
        """
        Returns the :class:`~py4j.java_gateway.JavaGateway` object, only if
        the shared library is a Java archive, otherwise returns :data:`None`.
        """
        return self._gateway

    @property
    def lib(self):
        """Returns the reference to the loaded library object.

        For example, if `libtype` is

            * ``'cdll'`` then a :class:`~ctypes.CDLL` object
            * ``'windll'`` then a :class:`~ctypes.WinDLL` object
            * ``'oledll'`` then a :class:`~ctypes.OleDLL` object
            * ``'net'`` then a :class:`~.load_library.DotNet` object
            * ``'java'`` then a :class:`~py4j.java_gateway.JVMView` object
            * ``'com'`` then the interface pointer returned by comtypes.CreateObject_
        """
        return self._lib

    @property
    def path(self):
        """:class:`str`: The path to the shared library file."""
        return self._path

class DotNet(object):

    def __init__(self, dot_net_dict, path):
        """Contains the namespace_ modules, classes and `System.Type`_ objects of a .NET Assembly.

        Do not instantiate this class directly.

        .. _namespace: https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx
        .. _System.Type: https://msdn.microsoft.com/en-us/library/system.type(v=vs.110).aspx
        """
        self.__dict__.update(dot_net_dict)
        self._path = path

    def __repr__(self):
        return '<{} path={}>'.format(self.__class__.__name__, self._path)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django.utils.timezone

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='File',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(unique=True, max_length=255, db_index=True)),
                ('size', models.PositiveIntegerField(db_index=True)),
                ('_content', models.TextField(db_column=b'content')),
                ('created_datetime', models.DateTimeField(default=django.utils.timezone.now, verbose_name=b'Created datetime', db_index=True)),
                ('_content_hash', models.CharField(db_index=True, max_length=128, null=True, db_column=b'content_hash', blank=True)),
            ],
            options={
                'db_table': 'database_files_file',
            },
        ),
    ]
<commit_msg>Make Django 1.7 migrations compatible with Python3<commit_after># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations
import django.utils.timezone

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='File',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('name', models.CharField(unique=True, max_length=255, db_index=True)),
                ('size', models.PositiveIntegerField(db_index=True)),
                ('_content', models.TextField(db_column='content')),
                ('created_datetime', models.DateTimeField(default=django.utils.timezone.now, verbose_name='Created datetime', db_index=True)),
                ('_content_hash', models.CharField(db_index=True, max_length=128, null=True, db_column='content_hash', blank=True)),
            ],
            options={
                'db_table': 'database_files_file',
            },
        ),
    ]
<|endoftext|>


<commit_before># Copyright 2014, 2015 Holger Kohr, Jonas Adler
#
# This file is part of RL.
#
# RL is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RL 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with RL.  If not, see <http://www.gnu.org/licenses/>.

# Imports for common Python 2/3 codebase
from __future__ import (unicode_literals, print_function, division,
                        absolute_import)
try:
    from builtins import str, zip, range, super
except ImportError:  # Versions < 0.14 of python-future
    from future.builtins import str, zip, range, super
from future import standard_library

#
from itertools import repeat

# RL imports
from RL.space.space import HilbertSpace, NormedSpace, LinearSpace
from RL.utility.utility import errfmt

standard_library.install_aliases()

class ProductSpace(LinearSpace):
    """Product space (X1 x X2 x ... x Xn)
    Creates a Cartesian product of an arbitrary set of spaces.

    For example:

    `ProductSpace(Reals(), Reals())` is mathematically equivalent to `RN(2)`

    Note that the later is obviously more efficient.

    Args:
        spaces    (multiple) LinearSpace     One or more instances of linear spaces
    """

    def __init__(self, *spaces):
        if len(spaces) == 0:
            raise TypeError("Empty product not allowed")

        if not all(spaces[0].field == y.field for y in spaces):
            raise TypeError("All spaces must have the same field")

        self.spaces = spaces
        self._nProducts = len(self.spaces)
        self._field = spaces[0].field  # X_n has same field

    def zero(self):
        """ Create a vector whose components is the zero vectors in the underlying spaces
        """
        return self.makeVector(*[space.zero() for space in self.spaces])

    def empty(self):
        """ Create a vector whose components is arbitrary vectors in the underlying spaces
        """
        return self.makeVector(*[space.empty() for space in self.spaces])

    def linCombImpl(self, z, a, x, b, y):
        """ Applies linComb to each component
        """
        for space, zp, xp, yp in zip(self.spaces, z.parts, x.parts, y.parts):
            space.linCombImpl(zp, a, xp, b, yp)

    @property
    def field(self):
        """ Get the underlying field of this product space.
        The field is the same for each underlying space.
        """
        return self._field

    def equals(self, other):
        """ Tests two objects for equality.

        Returns true if other is a ProductSpace with the same subspaces as this space.
        """
        return (isinstance(other, ProductSpace) and
                self._nProducts == other._nProducts and
                all(x.equals(y) for x, y in zip(self.spaces, other.spaces)))

    def makeVector(self, *args):
        """ Creates an element in the product space

        Parameters
        ----------
        The method has two call patter, the first is:

        *args : tuple of LinearSpace.Vector's
                A tuple of vectors in the underlying space.
                This will simply wrap the Vectors (not copy).

        The second pattern is to create a new Vector from scratch, in this case

        *args : Argument for i:th vector

        Returns
        -------
        ProductSpace.Vector instance

        Examples
        --------

        >>> rn = RN(2)
        >>> rm = RN(3)
        >>> prod = ProductSpace(rn,rm)
        >>> x = rn.makeVector([1,2])
        >>> y = rm.makeVector([1,2,3])
        >>> z = prod.makeVector(x, y)
        >>> z
        {[ 1.  2.], [ 1.  2.  3.]}

        """

        if not isinstance(args[0], LinearSpace.Vector):
            # Delegate constructors
            return self.makeVector(*(space.makeVector(arg)
                                   for arg, space in zip(args, self.spaces)))
        else:  # Construct from existing tuple
            if any(part.space != space
                    for part, space in zip(args, self.spaces)):
                raise TypeError(errfmt('''
                The spaces of all parts must correspond to this
                space's parts'''))

            #Use class to allow subclassing
            return self.__class__.Vector(self, *args)

    def __len__(self):
        """ Get the number of parts of this product space
        """
        return self._nProducts

    def __getitem__(self, index):
        """ Access the index:th subspace of this space

        Parameters
        ----------

        index : int
                The position that should be accessed

        Returns
        -------
        LinearSpace, the index:th subspace

        Examples
        --------

        >>> rn = RN(2)
        >>> rm = RN(3)
        >>> prod = ProductSpace(rn, rm)
        >>> prod[0]
        RN(2)
        >>> prod[1]
        RN(3)

        """
        return self.spaces[index]

    def __str__(self):
        return ' x '.join(str(space) for space in self.spaces)

    def __repr__(self):
        return ('ProductSpace(' +
                ', '.join(str(space) for space in self.spaces) + ')')

    class Vector(LinearSpace.Vector):
        def __init__(self, space, *args):
            super().__init__(space)
            self.parts = args

        def __len__(self):
            """ The number of components of this vector
            """
            return self.space._nProducts

        def __getitem__(self, index):
            """ Access the index:th component of this vector

            Parameters
            ----------

            index : int
                    The position that should be accessed

            Returns
            -------
            LinearSpace.Vector of type self.space[index], the index:th sub-vector

            Examples
            --------

            >>> rn = RN(2)
            >>> rm = RN(3)
            >>> prod = ProductSpace(rn, rm)
            >>> z = prod.makeVector([1, 2], [1, 2, 3])
            >>> z[0]
            [1.0, 2.0]
            >>> z[1]
            [1.0, 2.0, 3.0]

            """
            return self.parts[index]

        def __str__(self):
            return ('{' + ', '.join(str(part) for part in self.parts) +
                    '}')

        def __repr__(self):
            return (self.space.__repr__() + '.Vector(' +
                    ', '.join(part.__repr__() for part in self.parts) + ')')

class NormedProductSpace(ProductSpace,NormedSpace):
    """ A product space of Normed Spaces (X1 x X2 x ... x Xn)

    Creates a Cartesian product of an arbitrary set of spaces.

    For example:

    `NormedProductSpace(Reals(), Reals())` is mathematically equivalent to `RN(2)` ##TODO MAKE NORMED RN SPACE

    Note that the later is obviously more efficient.

    Parameters
    ----------

    *spaces : NormedSpace's
                A set of normed spaces
    **kwargs : {'ord'}
                'ord' : string
                        The order of the norm.

    The following values for `ord` can be specified.
    Note that any value of ord < 1 only gives a pseudonorm

    =====  ==========================
    ord    Definition
    =====  ==========================
    inf    max(norm(x[0]), ..., norm(x[n-1]))
    -inf   min(norm(x[0]), ..., norm(x[n-1]))
    0      (norm(x[0]) != 0 + ... + norm(x[n-1]) != 0)
    other  (norm(x[0])**ord + ... + norm(x[n-1])**ord)**(1/ord)
    =====  ==========================
    """

    def __init__(self, *spaces, **kwargs):
        self.ord = kwargs.pop('ord',2)

        super().__init__(*spaces)

    def normImpl(self, x):
        if self.ord == float('inf'):
            return max(space.normImpl(xp) for space, xp in zip(self.spaces, x.parts))
        elif self.ord == -float('inf'):
            return min(space.normImpl(xp) for space, xp in zip(self.spaces, x.parts))
        elif self.ord == 0:
            return sum(space.normImpl(xp) != 0 for space, xp in zip(self.spaces, x.parts))
        else:
            return sum(space.normImpl(xp)**self.ord for space, xp in zip(self.spaces, x.parts))**(1/self.ord)

    class Vector(ProductSpace.Vector,NormedSpace.Vector):
        pass

class HilbertProductSpace(HilbertSpace,NormedProductSpace):
    """ A product space of HilbertSpaces (X1 x X2 x ... x Xn)

    Creates a Cartesian product of an arbitrary set of spaces.

    For example:

    `HilbertProductSpace(Reals(), Reals())` is mathematically equivalent to `EuclideanSpace(2)`

    Note that the later is obviously more efficient.

    Parameters
    ----------

    *spaces : HilbertSpace's
              A set of HilbertSpace's
    **kwargs : {'weights'}
                'weights' : Array-Like
                            List of weights, same size as spaces

    The inner product in the HilbertProductSpace is per default defined as

    inner(x, y) = x[0]*y[0] + ... + x[n-1]*y[n-1]

    The optional parameter `weights` changes this behaviour to

    inner(x, y) = weights[0]*x[0]*y[0] + ... + weights[n-1]*x[n-1]*y[n-1]
    """

    def __init__(self, *spaces, **kwargs):
        self.weights = kwargs.pop('weights', None)

        super().__init__(*spaces)

    def innerImpl(self, x, y):
        if self.weights:
            return sum(space.innerImpl(xp, yp)
                       for space, weight, xp, yp in zip(self.spaces, self.weights, x.parts, y.parts))
        else:
            return sum(space.innerImpl(xp, yp)
                       for space, xp, yp in zip(self.spaces, x.parts, y.parts))

    class Vector(ProductSpace.Vector,HilbertSpace.Vector):
        pass

def makeProductSpace(*spaces):
    """ Creates an appropriate ProductSpace

    Selects the type of product space that has the most structure (Inner product, norm)
    given a set of spaces

    Parameters
    ----------

    *spaces : LinearSpace's
              A set of LinearSpace's

    Returns
    -------
    ProductSpace, NormedProductSpace or HilbertProductSpace depending on the lowest common denominator in spaces.

    """
    if all(isinstance(space, HilbertSpace) for space in spaces):
        return HilbertProductSpace(*spaces)
    elif all(isinstance(space, NormedSpace) for space in spaces):
        return NormedProductSpace(*spaces)
    else:
        return ProductSpace(*spaces)

def makePowerSpace(underlying_space, nProducts):
    """ Creates a Cartesian "power" of a space. For example,

    `PowerSpace(Reals(),3)` is mathematically the same as `RN(3)` or `R x R x R`
    Note that the later is more efficient.

    Selects the type of product space that has the most structure (Inner product, norm)
    given a set of spaces

    Parameters
    ----------

    underlying_space : LinearSpace
                       The underlying space that should be repeated
    nProduct         : Int
                       Number of products in the result

    Returns
    -------
    ProductSpace, NormedProductSpace or HilbertProductSpace depending on the lowest common denominator in spaces.

    """
    return makeProductSpace(*([underlying_space]*nProducts))<commit_msg>Replaced make... functions with classes<commit_after># Copyright 2014, 2015 Holger Kohr, Jonas Adler
#
# This file is part of RL.
#
# RL is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# RL 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with RL.  If not, see <http://www.gnu.org/licenses/>.

# Imports for common Python 2/3 codebase
from __future__ import (unicode_literals, print_function, division,
                        absolute_import)
try:
    from builtins import str, zip, range, super
except ImportError:  # Versions < 0.14 of python-future
    from future.builtins import str, zip, range, super
from future import standard_library

# RL imports
from RL.space.space import HilbertSpace, NormedSpace, LinearSpace
from RL.utility.utility import errfmt

standard_library.install_aliases()

class ProductSpace(LinearSpace):
    """Product space (X1 x X2 x ... x Xn)
    Creates a Cartesian product of an arbitrary set of spaces.

    For example:

    `ProductSpace(Reals(), Reals())` is mathematically equivalent to `RN(2)`

    Note that the later is obviously more efficient.

    Args:
        spaces    (multiple) LinearSpace     One or more instances of linear spaces
    """

    def __new__(cls, *spaces, **kwargs):

        if not all(spaces[0].field == spc.field for spc in spaces):
            raise TypeError('All spaces must have the same field')

        if all(isinstance(spc, HilbertSpace) for spc in spaces):
            cls = HilbertProductSpace
        elif all(isinstance(spc, NormedSpace) for spc in spaces):
            cls = NormedProductSpace
        else:
            cls = LinearProductSpace

        return super().__new__(cls, *spaces, **kwargs)

class LinearProductSpace(ProductSpace):

    def __init__(self, *spaces, **kwargs):

        if not all(isinstance(spc, LinearSpace) for spc in spaces):
            wrong_spc = filter(lambda spc: not isinstance(spc, LinearSpace),
                               spaces)
            raise TypeError('{} not LinearSpace instance(s)'.format(wrong_spc))

        self.spaces = spaces
        self._nfactors = len(self.spaces)
        self._field = spaces[0].field  # X_n has same field
        super().__init__(**kwargs)

    def zero(self):
        """ Create a vector whose components is the zero vectors in the underlying spaces
        """
        return self.makeVector(*[space.zero() for space in self.spaces])

    def empty(self):
        """ Create a vector whose components is arbitrary vectors in the underlying spaces
        """
        return self.makeVector(*[space.empty() for space in self.spaces])

    def linCombImpl(self, z, a, x, b, y):
        """ Applies linComb to each component
        """
        for space, zp, xp, yp in zip(self.spaces, z.parts, x.parts, y.parts):
            space.linCombImpl(zp, a, xp, b, yp)

    @property
    def field(self):
        """ Get the underlying field of this product space.
        The field is the same for each underlying space.
        """
        return self._field

    def equals(self, other):
        """ Tests two objects for equality.

        Returns true if other is a ProductSpace with the same subspaces as this space.
        """
        return (isinstance(other, ProductSpace) and
                self._nfactors == other._nfactors and
                all(x.equals(y) for x, y in zip(self.spaces, other.spaces)))

    def makeVector(self, *args):
        """ Creates an element in the product space

        Parameters
        ----------
        The method has two call patter, the first is:

        *args : tuple of LinearSpace.Vector's
                A tuple of vectors in the underlying space.
                This will simply wrap the Vectors (not copy).

        The second pattern is to create a new Vector from scratch, in this case

        *args : Argument for i:th vector

        Returns
        -------
        ProductSpace.Vector instance

        Examples
        --------

        >>> rn = RN(2)
        >>> rm = RN(3)
        >>> prod = ProductSpace(rn,rm)
        >>> x = rn.makeVector([1,2])
        >>> y = rm.makeVector([1,2,3])
        >>> z = prod.makeVector(x, y)
        >>> z
        {[ 1.  2.], [ 1.  2.  3.]}

        """

        if not isinstance(args[0], LinearSpace.Vector):
            # Delegate constructors
            return self.makeVector(*(space.makeVector(arg)
                                   for arg, space in zip(args, self.spaces)))
        else:  # Construct from existing tuple
            if any(part.space != space
                    for part, space in zip(args, self.spaces)):
                raise TypeError(errfmt('''
                The spaces of all parts must correspond to this
                space's parts'''))

            # Use __class__ to allow subclassing
            return self.__class__.Vector(self, *args)

    def __len__(self):
        """ Get the number of parts of this product space
        """
        return self._nfactors

    def __getitem__(self, index):
        """ Access the index:th subspace of this space

        Parameters
        ----------

        index : int
                The position that should be accessed

        Returns
        -------
        LinearSpace, the index:th subspace

        Examples
        --------

        >>> rn = RN(2)
        >>> rm = RN(3)
        >>> prod = ProductSpace(rn, rm)
        >>> prod[0]
        RN(2)
        >>> prod[1]
        RN(3)

        """
        return self.spaces[index]

    def __str__(self):
        return ' x '.join(str(space) for space in self.spaces)

    def __repr__(self):
        return ('ProductSpace(' +
                ', '.join(str(space) for space in self.spaces) + ')')

    class Vector(LinearSpace.Vector):
        def __init__(self, space, *args):
            super().__init__(space)
            self.parts = args

        def __len__(self):
            """ The number of components of this vector
            """
            return self.space._nfactors

        def __getitem__(self, index):
            """ Access the index:th component of this vector

            Parameters
            ----------

            index : int
                    The position that should be accessed

            Returns
            -------
            LinearSpace.Vector of type self.space[index], the index:th sub-vector

            Examples
            --------

            >>> rn = RN(2)
            >>> rm = RN(3)
            >>> prod = ProductSpace(rn, rm)
            >>> z = prod.makeVector([1, 2], [1, 2, 3])
            >>> z[0]
            [1.0, 2.0]
            >>> z[1]
            [1.0, 2.0, 3.0]

            """
            return self.parts[index]

        def __str__(self):
            return ('{' + ', '.join(str(part) for part in self.parts) +
                    '}')

        def __repr__(self):
            return (self.space.__repr__() + '.Vector(' +
                    ', '.join(part.__repr__() for part in self.parts) + ')')

class NormedProductSpace(LinearProductSpace, NormedSpace):
    """ A product space of Normed Spaces (X1 x X2 x ... x Xn)

    Creates a Cartesian product of an arbitrary set of spaces.

    For example:

    `NormedProductSpace(Reals(), Reals())` is mathematically equivalent to `RN(2)` ##TODO MAKE NORMED RN SPACE

    Note that the later is obviously more efficient.

    Parameters
    ----------

    *spaces : NormedSpace's
                A set of normed spaces
    **kwargs : {'ord'}
                'ord' : float, optional
                        The order of the norm.

    The following values for `ord` can be specified.
    Note that any value of ord < 1 only gives a pseudonorm

    =====  ==========================
    ord    Definition
    =====  ==========================
    inf    max(norm(x[0]), ..., norm(x[n-1]))
    -inf   min(norm(x[0]), ..., norm(x[n-1]))
    0      (norm(x[0]) != 0 + ... + norm(x[n-1]) != 0)
    other  (norm(x[0])**ord + ... + norm(x[n-1])**ord)**(1/ord)
    =====  ==========================
    """

    def __init__(self, *spaces, **kwargs):
        if not all(isinstance(spc, NormedSpace) for spc in spaces):
            wrong_spc = filter(lambda spc: not isinstance(spc, NormedSpace),
                               spaces)
            raise TypeError('{} not NormedSpace instance(s)'.format(wrong_spc))

        self.ord = kwargs.pop('ord', 2)
        super().__init__(*spaces, **kwargs)

    def normImpl(self, x):
        if self.ord == float('inf'):
            return max(space.normImpl(xp) for space, xp in zip(self.spaces, x.parts))
        elif self.ord == -float('inf'):
            return min(space.normImpl(xp) for space, xp in zip(self.spaces, x.parts))
        elif self.ord == 0:
            return sum(space.normImpl(xp) != 0 for space, xp in zip(self.spaces, x.parts))
        else:
            return sum(space.normImpl(xp)**self.ord for space, xp in zip(self.spaces, x.parts))**(1/self.ord)

    class Vector(LinearProductSpace.Vector, NormedSpace.Vector):
        pass

class HilbertProductSpace(NormedProductSpace, HilbertSpace):
    """ A product space of HilbertSpaces (X1 x X2 x ... x Xn)

    Creates a Cartesian product of an arbitrary set of spaces.

    For example:

    `HilbertProductSpace(Reals(), Reals())` is mathematically equivalent to `EuclideanSpace(2)`

    Note that the later is obviously more efficient.

    Parameters
    ----------

    *spaces : HilbertSpace's
              A set of HilbertSpace's
    **kwargs : {'weights'}
                'weights' : Array-Like
                            List of weights, same size as spaces

    The inner product in the HilbertProductSpace is per default defined as

    inner(x, y) = x[0]*y[0] + ... + x[n-1]*y[n-1]

    The optional parameter `weights` changes this behaviour to

    inner(x, y) = weights[0]*x[0]*y[0] + ... + weights[n-1]*x[n-1]*y[n-1]
    """

    def __init__(self, *spaces, **kwargs):
        self.weights = kwargs.pop('weights', None)

        if not all(isinstance(spc, HilbertSpace) for spc in spaces):
            wrong_spc = filter(lambda spc: not isinstance(spc, HilbertSpace),
                               spaces)
            raise TypeError('{} not HilbertSpace instance(s)'.format(wrong_spc))

        super().__init__(*spaces, **kwargs)

    def innerImpl(self, x, y):
        if self.weights:
            return sum(space.innerImpl(xp, yp)
                       for space, weight, xp, yp in zip(self.spaces, self.weights, x.parts, y.parts))
        else:
            return sum(space.innerImpl(xp, yp)
                       for space, xp, yp in zip(self.spaces, x.parts, y.parts))

    class Vector(NormedProductSpace.Vector, HilbertSpace.Vector):
        pass

class PowerSpace(ProductSpace):
    """ Creates a Cartesian "power" of a space. For example,

    `PowerSpace(Reals(),3)` is mathematically the same as `RN(3)` or `R x R x R`
    Note that the later is more efficient.

    Selects the type of product space that has the most structure (Inner product, norm)
    given a set of spaces

    Parameters
    ----------

    underlying_space : LinearSpace
                       The underlying space that should be repeated
    nProduct         : Int
                       Number of products in the result

    Returns
    -------
    ProductSpace, NormedProductSpace or HilbertProductSpace depending on the lowest common denominator in spaces.

    """

    def __new__(cls, base, nfactors, **kwargs):
        if nfactors <= 0:
            raise ValueError(errfmt('''
            'nfactors' must be a positive integer, got {}
            '''.format(nfactors)))

        spaces = [base] * nfactors
        # TODO: Figure out why tests fail without __init__
        instance = super().__new__(cls, *spaces, **kwargs)
        instance.__init__(*spaces, **kwargs)
        return instance
<|endoftext|>


<commit_before>"""
Load a :class:`~ctypes.CDLL`, :class:`~ctypes.WinDLL`, :class:`~ctypes.OleDLL`, or
a `.NET Framework <http://pythonnet.github.io/>`_ library.
"""
import os
import sys
import ctypes
import logging
import xml.etree.ElementTree as ET

from msl.loadlib import IS_WINDOWS, IS_LINUX, IS_MAC

log = logging.getLogger(__name__)

class LoadLibrary(object):
    """
    Loads the shared library.

    Based on the value of ``libtype`` this class will load the shared library as a:

        * :py:class:`ctypes.CDLL` object if ``libtype`` = **'cdll'**,
        * :class:`ctypes.WinDLL` object if ``libtype`` = **'windll'**,
        * :class:`ctypes.OleDLL` object if ``libtype`` = **'oledll'**, or a
        * `CLR <http://pythonnet.github.io/>`_-type object if ``libtype`` = **'net'**.

    Args:
        path (str): The path to the shared library.

        libtype (str, optional): The library type to use for the calling convention.

            The following values are allowed:

            * ``libtype`` = **'cdll'**, for a **__cdecl** library
            * ``libtype`` = **'windll'** or **'oledll'**, for a **__stdcall** library (Windows only)
            * ``libtype`` = **'net'**, for a **.NET** library

            Default is **'cdll'**.

    Raises:
        IOError: If the shared library cannot be loaded.
        TypeError: If the value of ``libtype`` is not supported.
    """
    def __init__(self, path, libtype='cdll'):

        # a reference to the .NET Runtime Assembly
        self._assembly = None

        #  assume a default extension if no extension was provided
        if not os.path.splitext(path)[1]:
            if IS_WINDOWS:
                path += '.dll'
            elif IS_LINUX:
                path += '.so'
            elif IS_MAC:
                path += '.dylib'

        self._path = os.path.abspath(path)
        if not os.path.isfile(self._path):
            raise IOError('Cannot find the shared library ' + self._path + '\n')

        if libtype == 'cdll':
            self._lib = ctypes.CDLL(self._path)
        elif libtype == 'windll':
            self._lib = ctypes.WinDLL(self._path)
        elif libtype == 'oledll':
            self._lib = ctypes.OleDLL(self._path)
        elif libtype == 'net' and self.is_pythonnet_installed():
            import clr
            try:
                # By default, pythonnet can only load libraries that are for .NET 4.0+.
                #
                # When MSL-LoadLib is installed, the useLegacyV2RuntimeActivationPolicy
                # property should have been enabled automatically to allow for loading
                # assemblies from previous .NET Framework versions.
                self._assembly = clr.System.Reflection.Assembly.LoadFile(self._path)

            except clr.System.IO.FileLoadException as err:
                # Example error message that can occur if the library is for .NET <4.0,
                # and the useLegacyV2RuntimeActivationPolicy is not enabled:
                #
                # " Mixed mode assembly is built against version 'v2.0.50727' of the
                #  runtime and cannot be loaded in the 4.0 runtime without additional
                #  configuration information. "
                #
                # To solve this problem, a <python-executable>.config file must exist and it must
                # contain a useLegacyV2RuntimeActivationPolicy property that is set to be "true".
                if "Mixed mode assembly" in str(err):
                    status, msg = self.check_dot_net_config(sys.executable)
                    if not status == 0:
                        raise IOError(msg)
                    else:
                        update_msg = 'Checking .NET config returned "{}" '.format(msg)
                        update_msg += 'and still cannot load library.\n'
                        update_msg += str(err)
                        raise IOError(update_msg)
                raise IOError('The above "System.IO.FileLoadException" is not handled.\n')

            # the shared library must be available in sys.path
            head, tail = os.path.split(self._path)
            sys.path.insert(0, head)

            # don't include the library extension
            clr.AddReference(os.path.splitext(tail)[0])

            # import namespaces, create instances of classes or reference a System.Type[] object
            dotnet = {}
            for t in self._assembly.GetTypes():
                if t.Namespace is not None:
                    if t.Namespace not in dotnet:
                        dotnet[t.Namespace] = __import__(t.Namespace)
                else:
                    try:
                        dotnet[t.Name] = self._assembly.CreateInstance(t.FullName)
                    except:
                        if t.Name not in dotnet:
                            dotnet[t.Name] = t
            self._lib = DotNetContainer(dotnet)

        else:
            raise TypeError('Cannot load libtype={}'.format(libtype))
        log.debug('Loaded ' + self._path)

    def __repr__(self):
        return '{} object at {}; libtype={}; path={}'.format(self.__class__.__name__,
                                                                hex(id(self)),
                                                                self.lib.__class__.__name__,
                                                                self._path)

    @property
    def path(self):
        """
        Returns:
            :py:class:`str`: The absolute path to the shared library file.
        """
        return self._path

    @property
    def lib(self):
        """
        Returns:
            The reference to the loaded-library object.

            For example:

            * if ``libtype`` = **'cdll'** then a :class:`ctypes.CDLL` object is returned
            * if ``libtype`` = **'windll'** then a :class:`ctypes.WinDLL` object is returned
            * if ``libtype`` = **'oledll'** then a :class:`ctypes.OleDLL` object is returned
            * if ``libtype`` = **'net'** then a :class:`~.load_library.DotNetContainer` containing
              the .NET namespaces_, classes and/or `System.Type`_ objects.

        .. _namespaces: https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx
        .. _System.Type: https://msdn.microsoft.com/en-us/library/system.type(v=vs.110).aspx
        """
        return self._lib

    @property
    def assembly(self):
        """
        Returns:
            The reference to the `.NET RuntimeAssembly
            <https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx>`_
            object -- *only if the shared library is a .NET library, otherwise returns*
            :py:data:`None`.
        """
        return self._assembly

    @staticmethod
    def is_pythonnet_installed():
        """
        Checks if `Python for .NET <http://pythonnet.github.io/>`_ is installed.

        Returns:
            :py:class:`bool`: :py:data:`True` if it is installed.

        .. note::
           For help getting Python for .NET working on a non-Windows operating system look at
           the :ref:`prerequisites`, the `Mono <http://www.mono-project.com/>`_ project and
           the `Python for .NET documentation <http://pythonnet.sourceforge.net/readme.html>`_.
        """
        try:
            import clr
        except ImportError:
            log.warning('Python for .NET <pythonnet> is not installed. Cannot load a .NET library.')
            return False
        return True

    @staticmethod
    def check_dot_net_config(py_exe_path):
        """
        Check if the **useLegacyV2RuntimeActivationPolicy** property is enabled.

        By default, `Python for .NET <http://pythonnet.github.io/>`_ only works with .NET
        4.0+ and therefore it cannot automatically load a shared library that was compiled
        with .NET <4.0. This method ensures that the **useLegacyV2RuntimeActivationPolicy**
        property exists in the **<python-executable>.config** file and that it is enabled.

        This `link <http://stackoverflow.com/questions/14508627/>`_ provides an overview
        explaining why the **useLegacyV2RuntimeActivationPolicy** property is required.

        The **<python-executable>.config** file should look like::

            <?xml version ="1.0"?>
            <configuration>
                <startup useLegacyV2RuntimeActivationPolicy="true">
                    <supportedRuntime version="v4.0" />
                    <supportedRuntime version="v2.0.50727" />
                </startup>
            </configuration>

        Args:
            py_exe_path (str): The path to the Python executable.

        Returns:
            :py:class:`tuple`: (:py:class:`int`, :py:class:`str`)
            Where the first index is one of the following status values:

            * -1 if there was a problem
            * 0 if the .NET property was already enabled, or
            * 1 if the property was created successfully.

            and the second index is a message describing the outcome.
        """

        config_path = py_exe_path + '.config'

        if os.path.isfile(config_path):

            with open(config_path, 'r') as fp:
                lines = fp.readlines()

            # use the ElementTree to parse the file
            try:
                tree = ET.parse(config_path)
            except ET.ParseError:
                msg = 'Invalid XML file ' + config_path
                msg += '\nCannot create useLegacyV2RuntimeActivationPolicy property.'
                log.warning(msg)
                return -1, msg

            root = tree.getroot()

            if not root.tag == 'configuration':
                msg = 'The root tag in {} is "{}".\n'.format(config_path, root.tag)
                msg += 'It must be "configuration" in order to create a .NET Framework config file '
                msg += 'to enable the useLegacyV2RuntimeActivationPolicy property.\n'
                msg += 'To load an assembly from a .NET Framework version <4.0 the '
                msg += 'following must be in {}:\n'.format(config_path)
                msg += '<configuration>' + NET_FRAMEWORK_FIX + '</configuration>\n'
                log.warning(msg)
                return -1, msg

            # check if the policy exists
            policy = root.find('startup/[@useLegacyV2RuntimeActivationPolicy]')
            if policy is None:
                lines.insert(-1, NET_FRAMEWORK_FIX)
                with open(config_path, 'w') as fp:
                    fp.writelines(lines)
                msg = 'Added the useLegacyV2RuntimeActivationPolicy property to ' + config_path
                msg += '\nTry again to see if Python can now load the .NET library.\n'
                return 1, msg
            else:
                if not policy.attrib['useLegacyV2RuntimeActivationPolicy'].lower() == 'true':
                    msg = 'The useLegacyV2RuntimeActivationPolicy in {} is False\n'.format(config_path)
                    msg += 'Cannot load an assembly from a .NET Framework version <4.0.'
                    log.warning(msg)
                    return -1, msg
                return 0, 'The useLegacyV2RuntimeActivationPolicy property is enabled'

        else:
            with open(config_path, 'w') as f:
                f.write('<?xml version ="1.0"?>')
                f.write(NET_FRAMEWORK_DESCRIPTION)
                f.write('<configuration>')
                f.write(NET_FRAMEWORK_FIX)
                f.write('</configuration>\n')
            msg = 'Added the useLegacyV2RuntimeActivationPolicy property to ' + config_path
            msg += '\nto fix the "System.IO.FileLoadException: Mixed mode assembly..." error.\n'
            msg += 'Try again to see if Python can now load the .NET library.\n'
            return 1, msg

class DotNetContainer(object):
    """
    A container for the namespace_ modules, classes and `System.Type`_ objects
    of a .NET library.

    .. _namespace: https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx
    .. _System.Type: https://msdn.microsoft.com/en-us/library/system.type(v=vs.110).aspx
    """
    def __init__(self, dotnet_dict):
        self.__dict__.update(dotnet_dict)

NET_FRAMEWORK_DESCRIPTION = """
<!--
  Created by the MSL-LoadLib package.

  By default, applications that target the .NET Framework version 4.0+ cannot load assemblies from
  previous .NET Framework versions. You must add and modify the "app".config file and set the
  useLegacyV2RuntimeActivationPolicy property to be "true". For the Python executable this would be
  a python.exe.config (Windows) or python.config (Unix) configuration file.

  For example, Python for .NET (pythonnet, http://pythonnet.github.io/) only works with .NET 4.0+
  and therefore it cannot automatically load a shared library that was compiled with .NET <4.0. If
  you try to load the library and a System.IO.FileNotFoundException is raised then that might
  mean that the library is from .NET <4.0.

  Additionally, the System.IO.FileNotFoundException exception will also be raised if the folder
  that the DLL is located in is not within sys.path, so first make sure that the shared library
  is visible to the Python interpreter.

  See http://support.microsoft.com/kb/2572158 for an overview.

  NOTE: To install pythonnet, run:
  $ pip install pythonnet
-->
"""

NET_FRAMEWORK_FIX = """
    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" />
        <supportedRuntime version="v2.0.50727" />
    </startup>
"""
<commit_msg>include ctypes.util.find_library search<commit_after>"""
Load a :class:`~ctypes.CDLL`, :class:`~ctypes.WinDLL`, :class:`~ctypes.OleDLL`, or
a `.NET Framework <http://pythonnet.github.io/>`_ library.
"""
import os
import sys
import ctypes
import ctypes.util
import logging
import xml.etree.ElementTree as ET

from msl.loadlib import IS_WINDOWS, IS_LINUX, IS_MAC

log = logging.getLogger(__name__)

class LoadLibrary(object):
    """
    Loads the shared library.

    Based on the value of ``libtype`` this class will load the shared library as a:

        * :py:class:`ctypes.CDLL` object if ``libtype`` = **'cdll'**,
        * :class:`ctypes.WinDLL` object if ``libtype`` = **'windll'**,
        * :class:`ctypes.OleDLL` object if ``libtype`` = **'oledll'**, or a
        * `CLR <http://pythonnet.github.io/>`_-type object if ``libtype`` = **'net'**.

    Args:
        path (str): The path to the shared library.

        libtype (str, optional): The library type to use for the calling convention.

            The following values are allowed:

            * ``libtype`` = **'cdll'**, for a **__cdecl** library
            * ``libtype`` = **'windll'** or **'oledll'**, for a **__stdcall** library (Windows only)
            * ``libtype`` = **'net'**, for a **.NET** library

            Default is **'cdll'**.

    Raises:
        IOError: If the shared library cannot be loaded.
        TypeError: If the value of ``libtype`` is not supported.
    """
    def __init__(self, path, libtype='cdll'):

        # a reference to the .NET Runtime Assembly
        self._assembly = None

        #  assume a default extension if no extension was provided
        if not os.path.splitext(path)[1]:
            if IS_WINDOWS:
                path += '.dll'
            elif IS_LINUX:
                path += '.so'
            elif IS_MAC:
                path += '.dylib'

        self._path = os.path.abspath(path)
        if not os.path.isfile(self._path):
            self._path = ctypes.util.find_library(path)
            if self._path is None:
                raise IOError('Cannot find the shared library ' + path + '\n')

        if libtype == 'cdll':
            self._lib = ctypes.CDLL(self._path)
        elif libtype == 'windll':
            self._lib = ctypes.WinDLL(self._path)
        elif libtype == 'oledll':
            self._lib = ctypes.OleDLL(self._path)
        elif libtype == 'net' and self.is_pythonnet_installed():
            import clr
            try:
                # By default, pythonnet can only load libraries that are for .NET 4.0+.
                #
                # When MSL-LoadLib is installed, the useLegacyV2RuntimeActivationPolicy
                # property should have been enabled automatically to allow for loading
                # assemblies from previous .NET Framework versions.
                self._assembly = clr.System.Reflection.Assembly.LoadFile(self._path)

            except clr.System.IO.FileLoadException as err:
                # Example error message that can occur if the library is for .NET <4.0,
                # and the useLegacyV2RuntimeActivationPolicy is not enabled:
                #
                # " Mixed mode assembly is built against version 'v2.0.50727' of the
                #  runtime and cannot be loaded in the 4.0 runtime without additional
                #  configuration information. "
                #
                # To solve this problem, a <python-executable>.config file must exist and it must
                # contain a useLegacyV2RuntimeActivationPolicy property that is set to be "true".
                if "Mixed mode assembly" in str(err):
                    status, msg = self.check_dot_net_config(sys.executable)
                    if not status == 0:
                        raise IOError(msg)
                    else:
                        update_msg = 'Checking .NET config returned "{}" '.format(msg)
                        update_msg += 'and still cannot load library.\n'
                        update_msg += str(err)
                        raise IOError(update_msg)
                raise IOError('The above "System.IO.FileLoadException" is not handled.\n')

            # the shared library must be available in sys.path
            head, tail = os.path.split(self._path)
            sys.path.insert(0, head)

            # don't include the library extension
            clr.AddReference(os.path.splitext(tail)[0])

            # import namespaces, create instances of classes or reference a System.Type[] object
            dotnet = {}
            for t in self._assembly.GetTypes():
                if t.Namespace is not None:
                    if t.Namespace not in dotnet:
                        dotnet[t.Namespace] = __import__(t.Namespace)
                else:
                    try:
                        dotnet[t.Name] = self._assembly.CreateInstance(t.FullName)
                    except:
                        if t.Name not in dotnet:
                            dotnet[t.Name] = t
            self._lib = DotNetContainer(dotnet)

        else:
            raise TypeError('Cannot load libtype={}'.format(libtype))
        log.debug('Loaded ' + self._path)

    def __repr__(self):
        return '{} object at {}; libtype={}; path={}'.format(self.__class__.__name__,
                                                                hex(id(self)),
                                                                self.lib.__class__.__name__,
                                                                self._path)

    @property
    def path(self):
        """
        Returns:
            :py:class:`str`: The absolute path to the shared library file.
        """
        return self._path

    @property
    def lib(self):
        """
        Returns:
            The reference to the loaded-library object.

            For example:

            * if ``libtype`` = **'cdll'** then a :class:`ctypes.CDLL` object is returned
            * if ``libtype`` = **'windll'** then a :class:`ctypes.WinDLL` object is returned
            * if ``libtype`` = **'oledll'** then a :class:`ctypes.OleDLL` object is returned
            * if ``libtype`` = **'net'** then a :class:`~.load_library.DotNetContainer` containing
              the .NET namespaces_, classes and/or `System.Type`_ objects.

        .. _namespaces: https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx
        .. _System.Type: https://msdn.microsoft.com/en-us/library/system.type(v=vs.110).aspx
        """
        return self._lib

    @property
    def assembly(self):
        """
        Returns:
            The reference to the `.NET RuntimeAssembly
            <https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx>`_
            object -- *only if the shared library is a .NET library, otherwise returns*
            :py:data:`None`.
        """
        return self._assembly

    @staticmethod
    def is_pythonnet_installed():
        """
        Checks if `Python for .NET <http://pythonnet.github.io/>`_ is installed.

        Returns:
            :py:class:`bool`: :py:data:`True` if it is installed.

        .. note::
           For help getting Python for .NET working on a non-Windows operating system look at
           the :ref:`prerequisites`, the `Mono <http://www.mono-project.com/>`_ project and
           the `Python for .NET documentation <http://pythonnet.sourceforge.net/readme.html>`_.
        """
        try:
            import clr
        except ImportError:
            log.warning('Python for .NET <pythonnet> is not installed. Cannot load a .NET library.')
            return False
        return True

    @staticmethod
    def check_dot_net_config(py_exe_path):
        """
        Check if the **useLegacyV2RuntimeActivationPolicy** property is enabled.

        By default, `Python for .NET <http://pythonnet.github.io/>`_ only works with .NET
        4.0+ and therefore it cannot automatically load a shared library that was compiled
        with .NET <4.0. This method ensures that the **useLegacyV2RuntimeActivationPolicy**
        property exists in the **<python-executable>.config** file and that it is enabled.

        This `link <http://stackoverflow.com/questions/14508627/>`_ provides an overview
        explaining why the **useLegacyV2RuntimeActivationPolicy** property is required.

        The **<python-executable>.config** file should look like::

            <?xml version ="1.0"?>
            <configuration>
                <startup useLegacyV2RuntimeActivationPolicy="true">
                    <supportedRuntime version="v4.0" />
                    <supportedRuntime version="v2.0.50727" />
                </startup>
            </configuration>

        Args:
            py_exe_path (str): The path to the Python executable.

        Returns:
            :py:class:`tuple`: (:py:class:`int`, :py:class:`str`)
            Where the first index is one of the following status values:

            * -1 if there was a problem
            * 0 if the .NET property was already enabled, or
            * 1 if the property was created successfully.

            and the second index is a message describing the outcome.
        """

        config_path = py_exe_path + '.config'

        if os.path.isfile(config_path):

            with open(config_path, 'r') as fp:
                lines = fp.readlines()

            # use the ElementTree to parse the file
            try:
                tree = ET.parse(config_path)
            except ET.ParseError:
                msg = 'Invalid XML file ' + config_path
                msg += '\nCannot create useLegacyV2RuntimeActivationPolicy property.'
                log.warning(msg)
                return -1, msg

            root = tree.getroot()

            if not root.tag == 'configuration':
                msg = 'The root tag in {} is "{}".\n'.format(config_path, root.tag)
                msg += 'It must be "configuration" in order to create a .NET Framework config file '
                msg += 'to enable the useLegacyV2RuntimeActivationPolicy property.\n'
                msg += 'To load an assembly from a .NET Framework version <4.0 the '
                msg += 'following must be in {}:\n'.format(config_path)
                msg += '<configuration>' + NET_FRAMEWORK_FIX + '</configuration>\n'
                log.warning(msg)
                return -1, msg

            # check if the policy exists
            policy = root.find('startup/[@useLegacyV2RuntimeActivationPolicy]')
            if policy is None:
                lines.insert(-1, NET_FRAMEWORK_FIX)
                with open(config_path, 'w') as fp:
                    fp.writelines(lines)
                msg = 'Added the useLegacyV2RuntimeActivationPolicy property to ' + config_path
                msg += '\nTry again to see if Python can now load the .NET library.\n'
                return 1, msg
            else:
                if not policy.attrib['useLegacyV2RuntimeActivationPolicy'].lower() == 'true':
                    msg = 'The useLegacyV2RuntimeActivationPolicy in {} is False\n'.format(config_path)
                    msg += 'Cannot load an assembly from a .NET Framework version <4.0.'
                    log.warning(msg)
                    return -1, msg
                return 0, 'The useLegacyV2RuntimeActivationPolicy property is enabled'

        else:
            with open(config_path, 'w') as f:
                f.write('<?xml version ="1.0"?>')
                f.write(NET_FRAMEWORK_DESCRIPTION)
                f.write('<configuration>')
                f.write(NET_FRAMEWORK_FIX)
                f.write('</configuration>\n')
            msg = 'Added the useLegacyV2RuntimeActivationPolicy property to ' + config_path
            msg += '\nto fix the "System.IO.FileLoadException: Mixed mode assembly..." error.\n'
            msg += 'Try again to see if Python can now load the .NET library.\n'
            return 1, msg

class DotNetContainer(object):
    """
    A container for the namespace_ modules, classes and `System.Type`_ objects
    of a .NET library.

    .. _namespace: https://msdn.microsoft.com/en-us/library/z2kcy19k.aspx
    .. _System.Type: https://msdn.microsoft.com/en-us/library/system.type(v=vs.110).aspx
    """
    def __init__(self, dotnet_dict):
        self.__dict__.update(dotnet_dict)

NET_FRAMEWORK_DESCRIPTION = """
<!--
  Created by the MSL-LoadLib package.

  By default, applications that target the .NET Framework version 4.0+ cannot load assemblies from
  previous .NET Framework versions. You must add and modify the "app".config file and set the
  useLegacyV2RuntimeActivationPolicy property to be "true". For the Python executable this would be
  a python.exe.config (Windows) or python.config (Unix) configuration file.

  For example, Python for .NET (pythonnet, http://pythonnet.github.io/) only works with .NET 4.0+
  and therefore it cannot automatically load a shared library that was compiled with .NET <4.0. If
  you try to load the library and a System.IO.FileNotFoundException is raised then that might
  mean that the library is from .NET <4.0.

  Additionally, the System.IO.FileNotFoundException exception will also be raised if the folder
  that the DLL is located in is not within sys.path, so first make sure that the shared library
  is visible to the Python interpreter.

  See http://support.microsoft.com/kb/2572158 for an overview.

  NOTE: To install pythonnet, run:
  $ pip install pythonnet
-->
"""

NET_FRAMEWORK_FIX = """
    <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" />
        <supportedRuntime version="v2.0.50727" />
    </startup>
"""
<|endoftext|>


<commit_before>from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, FileType
from importlib.util import find_spec
from .main_cross_validation import cross_validation_core
from .main_predict import predict_core
from .main_train import train_core
from ..version import version

def parse_args():
    parser = argparse.ArgumentParser(description="", epilog="", prog='naivemapper')
    parser.add_argument("--version", "-v", action="version", version="0.1", default=False)
    parser.add_argument("--input", "-i", default="input.rdf", type=str, help="RDF inputfile")
    parser.add_argument("--output", "-o", default="output.rdf", type=str, help="RDF outputfile")
    parser.add_argument("--output_rank", "-o2", default="rank/out_rank.txt", type=str,
                        help="the .txt-file with probability and mapping values ")
    parser.add_argument("--model", "-n", default="model.dat", type=str, help="Model file")
    parser.add_argument("--stage", "-s", type=int, default=2,
                        help="type of stage of the process: 0-learning, 1-prediction, 2-cross_validation")
    parser.add_argument("--f_type", "-ft", type=int, default=0, help="Method of fragmentation of a molecule")
    parser.add_argument("--min", "-m", type=int, default=1, help="minimal fragments length")
    parser.add_argument("--max", "-M", type=int, default=8, help="maximal fragments length")
    parser.add_argument("--deep", "-deep", type=int, default=3, help="maximal augmented-fragments length")
    parser.add_argument("--f_count", "-fc", type=int, default=0,
                        help="The way of accounting information on the number of fragments of each type in the set")
    parser.add_argument("--pairs", "-p", type=int, default=1,
                        help="type of united respective pairs: 0 - simple, 1 - equivalent")
    parser.add_argument("--duplicate", "-d", type=int, default=0,
                        help="duplicate availability:0-does all duplicate,1-has all duplicate,2-does 'False' duplicate")
    parser.add_argument("--bitstring", "-b", type=int, default=2,
                        help="type of united bitstring for atomic bitstrings A (substrats) and B (products): "
                             "0 - [A*B], 1 - [A+B+(A*B)], 2 - [(A!B)+(B!A)+(A*B)], 3 - [A+B], 4 - [(AxorB)+(A*B)], "
                             "5-Based on the pairwise (name_frag_in_sub_set, name_frag_in_prod_set)")
    parser.add_argument("--b_length", "-l", type=int, default=2048, help="lenght of bitstrings")
    parser.add_argument("--folds", "-N", type=int, default=5,
                        help="the number of partitions of the data: sets to training and test")
    parser.add_argument("--repeat", "-r", type=int, default=1,
                        help="the number of repetitions of the cross-validation procedure")
    parser.add_argument("--dfs", "-dfs", type=int, default=0,
                        help="Choice of method for reconsidering the assignment: "
                             "0-for symmetrically equivalent groups, 1-for the values of probabilities")
    parser.add_argument("--debug", action='store_true', help="debug mod")
    return parser

def train(subparsers):
    parser = subparsers.add_parser('train', help='reaction balanser',
                                   formatter_class=ArgumentDefaultsHelpFormatter)
    parser.add_argument("--input", "-i", default="input.rdf", type=FileType(),
                        help="RDF inputfile")
    parser.add_argument("--output", "-o", default="output.rdf", type=FileType('w'),
                        help="RDF outputfile")

    parser.set_defaults(func=train_core)

def predict(subparsers):
    parser = subparsers.add_parser('predict', help='reaction balanser',
                                   formatter_class=ArgumentDefaultsHelpFormatter)
    parser.set_defaults(func=predict_core)

def cross_validation(subparsers):
    parser = subparsers.add_parser('cross_validation', help='reaction balanser',
                                   formatter_class=ArgumentDefaultsHelpFormatter)
    parser.set_defaults(func=cross_validation_core)

def argparser():
    parser = ArgumentParser(description="CGRtools", epilog="(c) Dr. Ramil Nugmanov", prog='cgrtools')
    parser.add_argument("--version", "-v", action="version", version=version(), default=False)
    subparsers = parser.add_subparsers(title='subcommands', description='available utilities')

    train(subparsers)
    predict(subparsers)
    cross_validation(subparsers)

    if find_spec('argcomplete'):
        from argcomplete import autocomplete
        autocomplete(parser)

    return parser
<commit_msg>refactoring. part 2. CLI arguments refactoring<commit_after>from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, FileType
from importlib.util import find_spec
from .main_cross_validation import cross_validation_core
from .main_predict import predict_core
from .main_train import train_core
from ..version import version

def _common(parser):
    parser.add_argument("--fragment_type", "-ft", type=str, default="aug",
                        help="Method of fragmentation of a molecule: "
                             "'seq' - sequenced fragments,"
                             "'aug' - augmented fragments")
    parser.add_argument("--min", "-m", type=int, default=1,
                        help="The minimal sequenced fragments length")
    parser.add_argument("--max", "-M", type=int, default=8,
                        help="The maximal sequenced fragments length")
    parser.add_argument("--deep", "-deep", type=int, default=3,
                        help="The maximum number of levels of augmented fragments")
    parser.add_argument("--fragment_count", "-fc", type=bool, default=False,
                        help="Accounted for the number of fragments of each type:"
                             "False - to ignored,"
                             "True - to account.")
    parser.add_argument("--pairs", "-p", type=str, default="simple",
                        help="Type of union of atoms pairs: "
                             "'sim' - uniting atoms with the same name (in periodic table), "
                             "'eqv' - uniting same name with atoms symmetries refinement.")
    parser.add_argument("--bitstring", "-b", type=str, default="kron",
                        help="Type of union bit-strings the reagents (A) and the products (B): "
                             "'and' - intersection of information [A & B], "
                             "'xor' - United 'symmetric difference' and 'intersection' [(A ^ B) + (A & B)],"
                             "'kron' - Tensor product of information.")  # 1-[A+B+(A*B)],2-[(A!B)+(B!A)+(A*B)],3-[A+B],
    parser.add_argument("--length", "-l", type=int, default=2048, help="Length the bit-strings")
    parser.add_argument("--dfs", "-dfs", type=int, default=0,
                        help="Choice of the revision method (Depth-first search): "
                             "0 - by the symmetrically equivalent groups, "
                             "1 - by the values of probabilities")
    parser.add_argument("--debug", action='store_true', help="debug mod")

def train(subparsers):
    parser = subparsers.add_parser('train', help='The stage of the mapping learning on the reaction sets',
                                   formatter_class=ArgumentDefaultsHelpFormatter)
    parser.add_argument("--input", "-i", default="input.rdf", type=FileType(),
                        help="RDF inputfile on which to learn to create mapping")
    parser.add_argument("--model", "-n", default="model.dat", type=FileType('w'),
                        help="File with trained model")
    parser.add_argument("--duplicate", "-d", type=bool, default=True,
                        help="Accounted the atomic pairs information duplicates: "
                             "True - doesn't duplicate,"
                             "False - does all duplicate.")  # "2-does 'False' duplicate")
    _common(parser)
    parser.set_defaults(func=train_core)

def predict(subparsers):
    parser = subparsers.add_parser('predict', help='The stage of the mapping prediction on the new reaction  sets',
                                   formatter_class=ArgumentDefaultsHelpFormatter)
    parser.add_argument("--input", "-i", default="input.rdf", type=FileType(),
                        help="RDF inputfile to which want to create the mapping")
    parser.add_argument("--model", "-n", default="model.dat", type=FileType(),
                        help="File with trained model")
    parser.add_argument("--output", "-o", default="output.rdf", type=FileType('w'),
                        help="RDF outputfile")
    parser.add_argument("--rank", "-ro", default="rank/rank.txt", type=FileType('w'),
                        help="The debug file with average values of the mapping probability a reaction atoms "
                             "at the mappings value True/False")
    _common(parser)
    parser.set_defaults(func=predict_core)

def cross_validation(subparsers):
    parser = subparsers.add_parser('cross_validation', help='The stage of the process cross-validation',
                                   formatter_class=ArgumentDefaultsHelpFormatter)
    parser.add_argument("--input", "-i", default="input.rdf", type=FileType(),
                        help="RDF inputfile")
    parser.add_argument("--duplicate", "-d", type=bool, default=True,
                        help="Accounted the atomic pairs information duplicates: "
                             "True - doesn't duplicate,"
                             "False - does all duplicate.")  # "2-does 'False' duplicate")
    parser.add_argument("--fold", "-k", type=int, default=5,
                        help="Split the data into k consecutive folds.")
    parser.add_argument("--repeat", "-r", type=int, default=1,
                        help="The number of repetitions of the cross-validation procedure.")
    _common(parser)
    parser.set_defaults(func=cross_validation_core)

def argparser():
    parser = ArgumentParser(description="CGRtools", epilog="(c) Dr. Ramil Nugmanov", prog='cgrtools')
    parser.add_argument("--version", "-v", action="version", version=version(), default=False)
    subparsers = parser.add_subparsers(title='subcommands', description='available utilities')

    train(subparsers)
    predict(subparsers)
    cross_validation(subparsers)

    if find_spec('argcomplete'):
        from argcomplete import autocomplete
        autocomplete(parser)

    return parser
<|endoftext|>


<commit_before># Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals

import json
import os
import frappe
import frappe.translate
import frappe.modules.patch_handler
import frappe.model.sync
from frappe.utils.fixtures import sync_fixtures
from frappe.cache_manager import clear_global_cache
from frappe.desk.notifications import clear_notifications
from frappe.website import render
from frappe.core.doctype.language.language import sync_languages
from frappe.modules.utils import sync_customizations
from frappe.utils import global_search

def migrate(verbose=True, rebuild_website=False, skip_failing=False):
	'''Migrate all apps to the latest version, will:
	- run before migrate hooks
	- run patches
	- sync doctypes (schema)
	- sync fixtures
	- sync desktop icons
	- sync web pages (from /www)
	- sync web pages (from /www)
	- run after migrate hooks
	'''

	touched_tables_file = frappe.get_site_path('touched_tables.json')
	if os.path.exists(touched_tables_file):
		os.remove(touched_tables_file)

	try:
		frappe.flags.touched_tables = set()
		frappe.flags.in_migrate = True

		clear_global_cache()

		#run before_migrate hooks
		for app in frappe.get_installed_apps():
			for fn in frappe.get_hooks('before_migrate', app_name=app):
				frappe.get_attr(fn)()

		# run patches
		frappe.modules.patch_handler.run_all(skip_failing)
		# sync
		frappe.model.sync.sync_all(verbose=verbose)
		frappe.translate.clear_cache()
		sync_fixtures()
		sync_customizations()
		sync_languages()

		frappe.get_doc('Portal Settings', 'Portal Settings').sync_menu()

		# syncs statics
		render.clear_cache()

		# add static pages to global search
		global_search.update_global_search_for_all_web_pages()

		# updating installed applications data
		frappe.get_single('Installed Applications').update_versions()

		#run after_migrate hooks
		for app in frappe.get_installed_apps():
			for fn in frappe.get_hooks('after_migrate', app_name=app):
				frappe.get_attr(fn)()

		frappe.db.commit()

		clear_notifications()

		frappe.publish_realtime("version-update")
		frappe.flags.in_migrate = False
	finally:
		with open(touched_tables_file, 'w') as f:
			json.dump(list(frappe.flags.touched_tables), f, sort_keys=True, indent=4)
		frappe.flags.touched_tables.clear()
<commit_msg>fix: Docstring latest=>current<commit_after># Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt

from __future__ import unicode_literals

import json
import os
import frappe
import frappe.translate
import frappe.modules.patch_handler
import frappe.model.sync
from frappe.utils.fixtures import sync_fixtures
from frappe.cache_manager import clear_global_cache
from frappe.desk.notifications import clear_notifications
from frappe.website import render
from frappe.core.doctype.language.language import sync_languages
from frappe.modules.utils import sync_customizations
from frappe.utils import global_search

<<<<<<< HEAD
def migrate(verbose=True, rebuild_website=False, skip_failing=False):
	'''Migrate all apps to the latest version, will:
=======

def migrate(verbose=True, rebuild_website=False, skip_failing=False, skip_search_index=False):
	'''Migrate all apps to the current version, will:
>>>>>>> 2d96a2c4cc... fix: Docstring latest=>current
	- run before migrate hooks
	- run patches
	- sync doctypes (schema)
	- sync fixtures
	- sync desktop icons
	- sync web pages (from /www)
	- sync web pages (from /www)
	- run after migrate hooks
	'''

	touched_tables_file = frappe.get_site_path('touched_tables.json')
	if os.path.exists(touched_tables_file):
		os.remove(touched_tables_file)

	try:
		frappe.flags.touched_tables = set()
		frappe.flags.in_migrate = True

		clear_global_cache()

		#run before_migrate hooks
		for app in frappe.get_installed_apps():
			for fn in frappe.get_hooks('before_migrate', app_name=app):
				frappe.get_attr(fn)()

		# run patches
		frappe.modules.patch_handler.run_all(skip_failing)
		# sync
		frappe.model.sync.sync_all(verbose=verbose)
		frappe.translate.clear_cache()
		sync_fixtures()
		sync_customizations()
		sync_languages()

		frappe.get_doc('Portal Settings', 'Portal Settings').sync_menu()

		# syncs statics
		render.clear_cache()

		# add static pages to global search
		global_search.update_global_search_for_all_web_pages()

		# updating installed applications data
		frappe.get_single('Installed Applications').update_versions()

		#run after_migrate hooks
		for app in frappe.get_installed_apps():
			for fn in frappe.get_hooks('after_migrate', app_name=app):
				frappe.get_attr(fn)()

		frappe.db.commit()

		clear_notifications()

		frappe.publish_realtime("version-update")
		frappe.flags.in_migrate = False
	finally:
		with open(touched_tables_file, 'w') as f:
			json.dump(list(frappe.flags.touched_tables), f, sort_keys=True, indent=4)
		frappe.flags.touched_tables.clear()
<|endoftext|>