Пример #1
0
    def __call__(self, *args, **kwargs):
        '''
        Calls every registered function with the given args and kwargs.
        '''
        # Note: There's a copy of this code in the _CalculateToCall method below. It's a copy
        # because we don't want a function call overhead here.
        # ------------------------------------------------------------------------------------------
        if not hasattr(self, '_callbacks'):
            return  # No callbacks registered
        callbacks = self._callbacks

        to_call = []

        for id_, info_and_extra_args in callbacks.items():  # iterate in a copy

            info = info_and_extra_args[0]
            func_obj = info[self.INFO_POS_FUNC_OBJ]
            if func_obj is not None:
                # Ok, we have a self.
                func_obj = func_obj()
                if func_obj is None:
                    # self is dead
                    del callbacks[id_]
                else:
                    func_func = info[self.INFO_POS_FUNC_FUNC]
                    to_call.append(
                        (
                            new.instancemethod(func_func, func_obj, info[self.INFO_POS_FUNC_CLASS]),
                            info_and_extra_args[1]
                        )
                    )
            else:
                func_func = info[self.INFO_POS_FUNC_FUNC]
                if func_func.__class__ == _CallbackWrapper:
                    # The instance of the _CallbackWrapper already died! (func_obj is None)
                    original_method = func_func.OriginalMethod()
                    if original_method is None:
                        del callbacks[id_]
                        continue

                # No self: either classmethod or just callable
                to_call.append((func_func, info_and_extra_args[1]))
        # ------------------------------------------------------------------------------------------

        # let's keep the 'if' outside of the iteration...
        if self._handle_errors:
            for func, extra_args in to_call:
                try:
                    func(*extra_args + args, **kwargs)
                except Exception, e:
                    # Note that if some error shouldn't really be handled here, clients can raise
                    # a subclass of ErrorNotHandledInCallback
                    if isinstance(e, ErrorNotHandledInCallback):
                        Reraise(e, 'Error while trying to call %r' % func)
                    else:
                        HandleErrorOnCallback(func, *extra_args + args, **kwargs)
Пример #2
0
def IsImplementation(class_or_instance, interface):
    '''
    :type class_or_instance: type or classobj or object

    :type interface: Interface

    :rtype: bool

    :see: :py:func:`.AssertImplements`
    '''
    try:
        is_interface = issubclass(interface, Interface)
    except TypeError, e:
        Reraise(e, "interface=%s (type %s)" % (interface, type(interface)))
Пример #3
0
def ImportModule(p_import_path):
    '''
        Import the module in the given import path.

        * Returns the "final" module, so importing "coilib50.subject.visu" return the "visu"
        module, not the "coilib50" as returned by __import__
    '''
    try:
        result = __import__(p_import_path)
        for i in p_import_path.split('.')[1:]:
            result = getattr(result, i)
        return result
    except ImportError, e:
        from ben10.foundation.reraise import Reraise
        Reraise(e, 'Error importing module %s' % p_import_path)
Пример #4
0
def ExecuteNoWait(command_line, cwd=None, ignore_output=False):
    '''
    Execute the given command line without waiting for the process to finish its execution.

    :return:
        Returns the resulting of subprocess.Popen.
        Use result.pid for process-id.
    '''
    with Cwd(cwd):
        try:
            if ignore_output:
                process = subprocess.Popen(command_line,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.STDOUT)
            else:
                process = subprocess.Popen(command_line)

            return process
        except Exception, e:
            Reraise(
                e, 'SystemSharedScript.ExecuteNoWait:\n'
                '  command_line: %s\n'
                '  cwd: %s\n' % (command_line, cwd))
Пример #5
0
def _AssertImplementsFullChecking(class_or_instance,
                                  interface,
                                  check_attr=True):
    '''
    Used internally.

    This method will check each member of the given instance (or class) comparing them against the
    ones declared in the interface, making sure that it actually implements it even if it does not
    declare it so using ImplementsInterface.

    .. note:: Slow
        This method is *slow*, so make sure to never use it in hot-spots.

    :raises BadImplementationError:
        If :arg class_or_instance: doesn't implement this interface.
    '''
    # Moved from the file to avoid cyclic import:
    from ben10.foundation.types_ import Null

    try:
        is_interface = issubclass(interface, Interface)
    except TypeError, e:
        Reraise(e, "interface=%s (type %s)" % (interface, type(interface)))
Пример #6
0
            host.stat('~')
        except Exception, e:
            if e.errno in [425, 500]:
                # 425 = Errno raised when trying to a server without active ftp
                # 500 = Illegal PORT command. In this case we also want to try passive mode.
                host = create_host(session_factory=DefaultFTP)

        return host
    except FTPOSError, e:
        if e.args[0] in [11004, -3]:
            from ben10.foundation.reraise import Reraise
            Reraise(
                e,
                'Could not connect to host "%s"\n'
                'Make sure that:\n'
                '- You have a working network connection\n'
                '- This hostname is valid\n'
                '- This hostname is not being blocked by a firewall\n' %
                url.hostname,
            )
        raise


#===================================================================================================
# FTPUploadFileToUrl
#===================================================================================================
def FTPUploadFileToUrl(source_filename, target_url):
    '''
    Uploads the given LOCAL file to the given ftp url.

    :param str source_filename:
Пример #7
0
    def __enter__(self):
        '''
        Copies the current environment and sets the given environment

        :param dict(str:str) environ:
            A dictionary of environment variables names and values
        '''
        self._old_environ = os.environ.copy()
        self._old_sys_path = sys.path[:]

        if not self._update:
            os.environ.clear()
            if self._change_sys_path:
                new_sys_path = sys.path[:]
                new_sys_path = map(CanonicalPath, new_sys_path)

                # Keeping python_home paths so this instance of Python continues to work.
                python_home = CanonicalPath(GetExecutableDir())
                new_sys_path = [
                    i for i in new_sys_path if i.startswith(python_home)
                ]

                sys.path = new_sys_path

        if self._update:
            # Merge some list variables to include new stuff
            def SetMerged(variable):
                merged_values = []

                new_value = self._new_environ.get(variable)
                if new_value is not None:
                    merged_values += new_value.split(os.pathsep)

                current_value = os.environ.get(variable)
                if current_value is not None:
                    merged_values += [
                        i for i in current_value.split(os.pathsep)
                        if i not in merged_values
                    ]

                merged = os.pathsep.join(merged_values)
                if len(merged) > 0:
                    self._new_environ[variable] = merged

            SetMerged('PATH')
            SetMerged('PYTHONPATH')
            SetMerged('LD_LIBRARY_PATH')

        try:
            # Update environment variables
            os.environ.update(self._new_environ)

            if self._change_sys_path:
                sys.path += os.environ.get('PYTHONPATH', '').split(os.pathsep)

        except Exception, e:
            stream = StringIO()
            oss = TextOutput(stream)
            PrintEnvironment(self._new_environ, oss)
            Reraise(
                e, 'While entering an EnvironmentContextManager with:%s' %
                stream.getvalue())
Пример #8
0
def Execute(
    command_line,
    cwd=None,
    environ=None,
    extra_environ=None,
    input=None,  # @ReservedAssignment
    output_callback=None,
    return_code_callback=None,
    shell=False,
    ignore_auto_quote=False,
    clean_eol=True,
    pipe_stdout=True,
):
    '''
    Executes a shell command

    :type command_line: list(str) or str
    :param command_line:
        List of command - line to execute, including the executable as the first element in the
        list.

    :param str cwd:
        The current working directory for the execution.

    :type environ: dict(str, str)
    :param environ:
        The environment variables available for the subprocess. This will replace the current
        environment.
        If a value is "COPY_FROM_ENVIRON" the value is replaced by the current environment
        value before executing the command - line.
        This dictionary will be modified by the Execute, so make sure that this is a copy of
        your actual data, not the original.

    :param dict(str:str) extra_environ:
        Environment variables (name, value) to add to the execution environment.

    :type input: str | None
    :param input:
        Text to send as input to the process.

    :param callback(str) output_callback:
        A optional callback called with the process output as it is generated.

    :param callback(int) return_code_callback:
        A optional callback called with the execution return -code.
        The returned value is ignored.
        Because our return value is an iterator, the only way (I found) to give the user access
        to the return -code is via callback.

    :param bool shell:
        From subprocess.py:

        If shell is True, the specified command will be executed through the shell.

        On UNIX, with shell=False (default): In this case, the Popen class uses os.execvp() to
        execute the child program.  'command_line' should normally be a sequence.  A string will
        be treated as a sequence with the string as the only item (the program to execute).

        On UNIX, with shell=True: If 'command_line' is a string, it specifies the command string
        to execute through the shell.  If 'command_line' is a sequence, the first item specifies
        the command string, and any additional items will be treated as additional shell
        arguments.

    :param bool ignore_auto_quote:
        If True, passes the entire command line to subprocess as a single string, instead of
        a list of strings.

        This is useful when we want to avoid subprocess' algorithm that tries to handle quoting
        on its own when receiving a list of arguments.

        This way, we are able to use quotes as we wish, without having them escaped by subprocess.

    :param bool clean_eol:
        If True, output returned and passed to callback will be stripped of eols (\r \n)

    :param bool pipe_stdout:
        If True, pipe stdout so that it can be returned as a string and passed to the output
        callback. If False, stdout will be dumped directly to the console (preserving color),
        and the callback will not be called.

    :rtype: list(str)
    :returns:
        Returns the process execution output as a list of strings.
    '''
    def CmdLineStr(cmd_line):
        return '    ' + '\n    '.join(cmd_line)

    def EnvStr(env):
        result = ''
        for i, j in sorted(env.items()):
            if os.sep in j:
                j = '\n    * ' + '\n    * '.join(sorted(j.split(os.pathsep)))
            result += '  - %s = %s\n' % (i, j)
        return result

    # We accept strings as the command_line.
    is_string_command_line = isinstance(command_line, str)

    # Handle string/list command_list
    if ignore_auto_quote and not is_string_command_line:
        # ... with ignore_auto_quote we want a string command_line... but it came as a list
        #     NOTE: This simple join may cause problems since we can have spaces in a argument. The correct way of
        #           doing would be something like "shlex.join" (that does not exists, by the way).
        command_line = ' '.join(command_line)

    elif not ignore_auto_quote and is_string_command_line:
        # ... without ignore_auto_quote we want a list command_line... but it came as a string
        if sys.platform == 'win32':
            command, arguments = SafeSplit(command_line, ' ', 1)
            assert command.count(
                '"'
            ) != 1, 'Command may have spaces in it. Use list instead of string.'

            # Always use normpath for command, because Windows does not like posix slashes
            command = StandardizePath(command)
            command = os.path.normpath(command)
            command_line = [command] + shlex.split(arguments)
        else:
            command_line = shlex.split(command_line)

    if cwd is None:
        cwd = '.'

    with Cwd(cwd):
        if environ is None:
            environ = os.environ.copy()

        if extra_environ:
            environ.update(extra_environ)

        replace_environ = {}
        for i_name, i_value in environ.iteritems():
            if i_value is COPY_FROM_ENVIRONMENT and i_name in os.environ:
                replace_environ[i_name] = os.environ[i_name]
        environ.update(replace_environ)

        try:
            with EnvironmentContextManager(environ):
                popen = subprocess.Popen(
                    command_line,
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE if pipe_stdout else None,
                    stderr=subprocess.STDOUT,
                    env=environ,
                    bufsize=0,
                    shell=shell,
                )
        except Exception, e:
            Reraise(
                e, 'While executing "System.Execute":\n'
                '  environment::\n'
                '%s\n'
                '  current working dir::\n'
                '    %s\n\n'
                '  command_line::\n'
                '%s\n' %
                (EnvStr(environ), os.getcwd(), CmdLineStr(command_line)))

        try:
            result = []
            if popen.stdin:
                if input:
                    try:
                        popen.stdin.write(input)
                    except IOError, e:
                        import errno
                        if e.errno != errno.EPIPE and e.errno != errno.EINVAL:
                            raise
                popen.stdin.close()

            if popen.stdout:
                # TODO: EDEN-245: Refactor System.Execute and derivates (git, scons, etc)
                if clean_eol:  # Read one line at the time, and remove EOLs
                    for line in iter(popen.stdout.readline, ""):
                        line = line.rstrip('\n\r')
                        if output_callback:
                            output_callback(line)
                        result.append(line)
                else:  # Read one char at a time, to keep \r and \n
                    current_line = ''
                    carriage = False
                    for char in iter(lambda: popen.stdout.read(1), ""):

                        # Check if last line was \r, if not, print what we have
                        if char != '\n' and carriage:
                            carriage = False
                            if output_callback:
                                output_callback(current_line)
                            result.append(current_line)
                            current_line = ''

                        current_line += char

                        if char == '\r':
                            carriage = True

                        if char == '\n':
                            if output_callback:
                                output_callback(current_line)
                            result.append(current_line)
                            carriage = False
                            current_line = ''
Пример #9
0
            for func, extra_args in to_call:
                try:
                    func(*extra_args + args, **kwargs)
                except Exception, e:
                    # Note that if some error shouldn't really be handled here, clients can raise
                    # a subclass of ErrorNotHandledInCallback
                    if isinstance(e, ErrorNotHandledInCallback):
                        Reraise(e, 'Error while trying to call %r' % func)
                    else:
                        HandleErrorOnCallback(func, *extra_args + args, **kwargs)
        else:
            for func, extra_args in to_call:
                try:
                    func(*extra_args + args, **kwargs)
                except Exception, e:
                    Reraise(e, 'Error while trying to call %r' % func)


    def _CalculateToCall(self):
        '''
        Copy of the code above so that subclasses can use it (we don't want the overhead in the
        call above).
        '''
        if not hasattr(self, '_callbacks'):
            return []  # No callbacks registered
        callbacks = self._callbacks

        to_call = []

        for _id, info_and_extra_args in callbacks.items():  # iterate in a copy