4 new revisions:

Revision: 0ac52913cf6a
Branch:   default
Author:   Pekka Klärck
Date:     Thu Jun 13 15:32:53 2013
Log: ConnectionCache: __getitem__ as sugar for get_connection. Process: use...
http://code.google.com/p/robotframework/source/detail?r=0ac52913cf6a

Revision: d5489af550f7
Branch:   default
Author:   Pekka Klärck
Date:     Thu Jun 13 15:44:34 2013
Log:      ConnectionCache: minor cleanup and doc enhancements
http://code.google.com/p/robotframework/source/detail?r=d5489af550f7

Revision: 0b4ef2a02bd0
Branch:   default
Author:   Pekka Klärck
Date:     Thu Jun 13 16:28:50 2013
Log: Process: atest cleanup. removed unnecessary skipping of tests with py/...
http://code.google.com/p/robotframework/source/detail?r=0b4ef2a02bd0

Revision: 43ea0b0f453b
Branch:   default
Author:   Pekka Klärck
Date:     Thu Jun 13 17:11:30 2013
Log: Collections: Create Dictionary and Set To Dictionary take items as **i...
http://code.google.com/p/robotframework/source/detail?r=43ea0b0f453b

==============================================================================
Revision: 0ac52913cf6a
Branch:   default
Author:   Pekka Klärck
Date:     Thu Jun 13 15:32:53 2013
Log: ConnectionCache: __getitem__ as sugar for get_connection. Process: use sugar.
http://code.google.com/p/robotframework/source/detail?r=0ac52913cf6a

Modified:
 /src/robot/libraries/Process.py
 /src/robot/utils/connectioncache.py
 /utest/utils/test_connectioncache.py

=======================================
--- /src/robot/libraries/Process.py     Thu Jun 13 14:29:24 2013
+++ /src/robot/libraries/Process.py     Thu Jun 13 15:32:53 2013
@@ -261,7 +261,7 @@
     ROBOT_LIBRARY_VERSION = get_version()

     def __init__(self):
-        self._started_processes = ConnectionCache('No active process.')
+        self._processes = ConnectionCache('No active process.')
         self._results = {}

     def run_process(self, command, *arguments, **configuration):
@@ -274,12 +274,12 @@

         This command does not change the `active process`.
         """
-        current_index = self._started_processes.current_index
+        current = self._processes.current
         try:
handle = self.start_process(command, *arguments, **configuration)
             return self.wait_for_process(handle)
         finally:
-            self._started_processes.current_index = current_index
+            self._processes.current = current

     def start_process(self, command, *arguments, **configuration):
         """Starts a new process on background.
@@ -305,7 +305,7 @@
         self._results[process] = ExecutionResult(process,
                                                  config.stdout_stream,
                                                  config.stderr_stream)
- return self._started_processes.register(process, alias=config.alias)
+        return self._processes.register(process, alias=config.alias)

     def _cmd(self, args, command, use_shell):
command = [encode_to_system(item) for item in [command] + list(args)]
@@ -322,7 +322,7 @@

Returns `True` if the process is still running and `False` otherwise.
         """
-        return self._process(handle).poll() is None
+        return self._processes[handle].poll() is None

     def process_should_be_running(self, handle=None,
                                   error_message='Process is not running.'):
@@ -353,7 +353,7 @@

Returns a `result object` containing information about the execution.
         """
-        process = self._process(handle)
+        process = self._processes[handle]
         result = self._results[process]
         logger.info('Waiting for process to complete.')
         result.rc = process.wait() or 0
@@ -367,7 +367,7 @@

         See `Stopping process` for more details.
         """
-        process = self._process(handle)
+        process = self._processes[handle]
         try:
             terminator = process.kill if kill else process.terminate
         except AttributeError:
@@ -386,7 +386,7 @@

         See `Stopping processes` for more details.
         """
-        for handle in range(1, len(self._started_processes) + 1):
+        for handle in range(1, len(self._processes) + 1):
             if self.is_process_running(handle):
                 self.terminate_process(handle, kill=kill)
         self.__init__()
@@ -403,14 +403,14 @@
         The pid is not the same as the identifier returned by
         `Start Process` that is used internally by this library.
         """
-        return self._process(handle).pid
+        return self._processes[handle].pid

     def get_process_object(self, handle=None):
         """Return the underlying `subprocess.Popen`  object.

         If `handle`is not given, uses the current `active process`.
         """
-        return self._process(handle)
+        return self._processes[handle]

     def switch_process(self, handle):
         """Makes the specified process the current `active process`.
@@ -425,10 +425,7 @@
         | `Switch Process` | process1 |
         | # now active process is process 1 |
         """
-        self._started_processes.switch(handle)
-
-    def _process(self, handle):
-        return self._started_processes.get_connection(handle)
+        self._processes.switch(handle)


 class ExecutionResult(object):
=======================================
--- /src/robot/utils/connectioncache.py Thu Jun 13 14:24:46 2013
+++ /src/robot/utils/connectioncache.py Thu Jun 13 15:32:53 2013
@@ -93,6 +93,8 @@
                                % index_or_alias)
         return self._connections[index-1]

+    __getitem__ = get_connection
+
     def close_all(self, closer_method='close'):
         """Closes connections using given closer method and empties cache.

=======================================
--- /utest/utils/test_connectioncache.py        Thu Jun 13 14:24:46 2013
+++ /utest/utils/test_connectioncache.py        Thu Jun 13 15:32:53 2013
@@ -130,18 +130,18 @@
         self._register('a', 'b')
         assert_equals(self.cache.get_connection(1).id, 'a')
         assert_equals(self.cache.current.id, 'b')
-        assert_equals(self.cache.get_connection(2).id, 'b')
+        assert_equals(self.cache[2].id, 'b')

     def test_get_connection_with_alias(self):
         self._register('a', 'b')
         assert_equals(self.cache.get_connection('a').id, 'a')
         assert_equals(self.cache.current.id, 'b')
-        assert_equals(self.cache.get_connection('b').id, 'b')
+        assert_equals(self.cache['b'].id, 'b')

     def test_get_connection_with_none_returns_current(self):
         self._register('a', 'b')
-        assert_equals(self.cache.get_connection(None).id, 'b')
         assert_equals(self.cache.get_connection().id, 'b')
+        assert_equals(self.cache[None].id, 'b')

     def test_get_connection_with_none_fails_if_no_current(self):
         assert_raises_with_msg(RuntimeError,

==============================================================================
Revision: d5489af550f7
Branch:   default
Author:   Pekka Klärck
Date:     Thu Jun 13 15:44:34 2013
Log:      ConnectionCache: minor cleanup and doc enhancements
http://code.google.com/p/robotframework/source/detail?r=d5489af550f7

Modified:
 /src/robot/utils/connectioncache.py

=======================================
--- /src/robot/utils/connectioncache.py Thu Jun 13 15:32:53 2013
+++ /src/robot/utils/connectioncache.py Thu Jun 13 15:44:34 2013
@@ -51,30 +51,33 @@
         If alias is given, it must be a string. Aliases are case and space
         insensitive.

-        The index of the first connection after initialization, or
+        The index of the first connection after initialization, and after
         :meth:`close_all` or :meth:`empty_cache`, is 1, second is 2, etc.
         """
         self.current = connection
         self._connections.append(connection)
+        index = len(self._connections)
         if isinstance(alias, basestring):
-            self._aliases[alias] = self.current_index
-        return self.current_index
+            self._aliases[alias] = index
+        return index

-    def switch(self, index_or_alias):
-        """Switches to the connection specified by given index or alias.
+    def switch(self, alias_or_index):
+ """Switches to the connection specified by the given alias or index.
+
+        Updates :attr:`current` and also returns its new value.

         Alias is whatever was given to :meth:`register` method and indices
         are returned by it. Index can be given either as an integer or
         as a string that can be converted to an integer. Raises an error
         if no connection with the given index or alias found.
         """
-        self.current = self.get_connection(index_or_alias)
+        self.current = self.get_connection(alias_or_index)
         return self.current

-    def get_connection(self, index_or_alias=None):
-        """Get the connection specified by given index or alias.
+    def get_connection(self, alias_or_index=None):
+        """Get the connection specified by the given alias or index..

-        If ``index_or_alias`` is ``None``, returns the current connection
+        If ``alias_or_index`` is ``None``, returns the current connection
         if it is active, or raises an error if it is not.

         Alias is whatever was given to :meth:`register` method and indices
@@ -82,15 +85,15 @@
         as a string that can be converted to an integer. Raises an error
         if no connection with the given index or alias found.
         """
-        if index_or_alias is None:
+        if alias_or_index is None:
             if not self:
                 self.current.raise_error()
             return self.current
         try:
-            index = self._resolve_index_or_alias(index_or_alias)
+            index = self._resolve_alias_or_index(alias_or_index)
         except ValueError:
             raise RuntimeError("Non-existing index or alias '%s'."
-                               % index_or_alias)
+                               % alias_or_index)
         return self._connections[index-1]

     __getitem__ = get_connection
@@ -100,7 +103,7 @@

         If simply calling the closer method is not adequate for closing
         connections, clients should close connections themselves and use
-        empty_cache afterwards.
+        :meth:`empty_cache` afterwards.
         """
         for conn in self._connections:
             getattr(conn, closer_method)()
@@ -125,11 +128,11 @@
     def __nonzero__(self):
         return self.current is not self._no_current

-    def _resolve_index_or_alias(self, index_or_alias):
+    def _resolve_alias_or_index(self, alias_or_index):
         try:
-            return self._resolve_alias(index_or_alias)
+            return self._resolve_alias(alias_or_index)
         except ValueError:
-            return self._resolve_index(index_or_alias)
+            return self._resolve_index(alias_or_index)

     def _resolve_alias(self, alias):
         if isinstance(alias, basestring):

==============================================================================
Revision: 0b4ef2a02bd0
Branch:   default
Author:   Pekka Klärck
Date:     Thu Jun 13 16:28:50 2013
Log: Process: atest cleanup. removed unnecessary skipping of tests with py/jy 2.5, added separate keywords for safe removal of files/dirs, etc.
http://code.google.com/p/robotframework/source/detail?r=0b4ef2a02bd0

Modified:
 /atest/robot/standard_libraries/process/is_process_alive.txt
 /atest/robot/standard_libraries/process/process_library.txt
 /atest/robot/standard_libraries/process/start_process_preferences.txt
 /atest/testdata/standard_libraries/process/is_process_alive.txt
 /atest/testdata/standard_libraries/process/newlines_and_encoding.txt
 /atest/testdata/standard_libraries/process/process_library.txt
 /atest/testdata/standard_libraries/process/resource.txt
 /atest/testdata/standard_libraries/process/start_process_preferences.txt
 /atest/testdata/standard_libraries/process/terminate_and_pid.txt

=======================================
--- /atest/robot/standard_libraries/process/is_process_alive.txt Mon May 6 00:29:42 2013 +++ /atest/robot/standard_libraries/process/is_process_alive.txt Thu Jun 13 16:28:50 2013
@@ -1,6 +1,5 @@
 *** Settings ***
Suite Setup Run Tests ${EMPTY} standard_libraries/process/is_process_alive.txt
-Test Setup       Check Preconditions
 Force Tags       regression    pybot    jybot
 Resource         atest_resource.txt

@@ -13,7 +12,3 @@

 Test Process Should Be Dead
     Check Test Case    ${TESTNAME}
-
-*** Keywords ***
-Check Preconditions
- Run Keyword If '${SUITE.metadata.get('info')}' == 'precondition_fail' Fail precondition fail -regression
=======================================
--- /atest/robot/standard_libraries/process/process_library.txt Tue Jun 11 04:18:12 2013 +++ /atest/robot/standard_libraries/process/process_library.txt Thu Jun 13 16:28:50 2013
@@ -1,7 +1,6 @@
 *** Settings ***
Suite Setup Run Tests ${EMPTY} standard_libraries/process/process_library.txt
 Force Tags       regression    pybot    jybot
-Test Setup       Check Preconditions
 Resource         atest_resource.txt

 *** Test Cases ***
@@ -73,7 +72,3 @@

Current working directory should not be used with stdout and stderr when absolute path in use
     Check Test Case    ${TESTNAME}
-
-*** Keywords ***
-Check Preconditions
- Run Keyword If '${SUITE.metadata.get('info')}' == 'precondition_fail' Fail precondition fail -regression
=======================================
--- /atest/robot/standard_libraries/process/start_process_preferences.txt Fri May 17 05:28:12 2013 +++ /atest/robot/standard_libraries/process/start_process_preferences.txt Thu Jun 13 16:28:50 2013
@@ -1,6 +1,5 @@
 *** Settings ***
Suite Setup Run Tests ${EMPTY} standard_libraries/process/start_process_preferences.txt
-Test Setup       Check Preconditions
 Force Tags       regression    pybot    jybot
 Resource         atest_resource.txt

@@ -23,7 +22,3 @@

 Process switch
     Check Test Case   ${TESTNAME}
-
-*** Keywords ***
-Check Preconditions
- Run Keyword If '${SUITE.metadata.get('info')}' == 'precondition_fail' Fail precondition fail -regression
=======================================
--- /atest/testdata/standard_libraries/process/is_process_alive.txt Tue Jun 11 04:28:34 2013 +++ /atest/testdata/standard_libraries/process/is_process_alive.txt Thu Jun 13 16:28:50 2013
@@ -1,6 +1,4 @@
 *** Settings ***
-#Suite Setup       Check Preconditions
-Library           Process
 Resource          resource.txt

 *** Test Cases ***
@@ -24,9 +22,3 @@
     Stop some process
     Wait For Process    ${handle}
     Process Should Be Stopped    ${handle}
-
-*** Keywords ***
-Check Preconditions
-    ${is_ok}=   Evaluate   sys.version_info >= (2,6)  sys
- Run Keyword If not ${is_ok} Set Suite Metadata info precondition_fail
-    Run Keyword If  not ${is_ok}    Fail
=======================================
--- /atest/testdata/standard_libraries/process/newlines_and_encoding.txt Tue Jun 11 04:28:34 2013 +++ /atest/testdata/standard_libraries/process/newlines_and_encoding.txt Thu Jun 13 16:28:50 2013
@@ -1,7 +1,5 @@
 *** Settings ***
-Suite Setup       Check Preconditions
-Library           Process
-Library           OperatingSystem
+Suite Setup       Check Precondition    sys.version_info >= (2,6)
 Resource          resource.txt

 *** Test Cases ***
@@ -14,9 +12,10 @@
     Result should equal    ${result}    stdout=ööåöåöå

 Non-ascii in the command with given stdout
- ${result}= Run Process python -c print "ööåöåöå" shell=True stdout=myfile.txt
+    ${path}=    Normalize Path    %{TEMPDIR}/process-stdout.txt
+ ${result}= Run Process python -c print "ööåöåöå" shell=True stdout=${path}
     Result should equal    ${result}    stdout=ööåöåöå
-    [Teardown]   Run Keyword And Ignore Error   Remove File   myfile.txt
+    [Teardown]   Safe Remove File    ${path}

 Newlines and trailing newline is removed
${result}= Run Process python -c "print 'first line\\nsecond line\\nthird line'" shell=True cwd=${CURDIR}
@@ -33,9 +32,3 @@
 Newline test using shell=False
     ${result}=   Run Process    python  -c   print "hello"
     Result should equal    ${result}    stdout=hello
-
-*** Keywords ***
-Check Preconditions
-    ${is_ok}=   Evaluate   sys.version_info >= (2,6)  sys
- Run Keyword If not ${is_ok} Set Suite Metadata info precondition_fail
-    Run Keyword If  not ${is_ok}    Fail
=======================================
--- /atest/testdata/standard_libraries/process/process_library.txt Tue Jun 11 05:45:43 2013 +++ /atest/testdata/standard_libraries/process/process_library.txt Thu Jun 13 16:28:50 2013
@@ -1,9 +1,7 @@
 *** Settings ***
-Suite Setup       Suite Setup
-Suite Teardown    Suite Teardown
-Test Teardown     Restart Suite Process If Needed
-Library           Process.py
-Library           OperatingSystem
+Suite Setup       Some process    suite_process
+Suite Teardown    Stop some process    suite_process
+Test Setup        Restart Suite Process If Needed
 Library           Collections
 Resource          resource.txt

@@ -46,14 +44,14 @@
     ${output}=    Get File    %{TEMPDIR}/myfile_1.txt
     Should Not Be Empty    ${output}
     Should Match  ${output}   ${result.stdout}*
- [Teardown] Run Keyword And Ignore Error Remove File %{TEMPDIR}/myfile_1.txt
+    [Teardown]    Safe Remove File    %{TEMPDIR}/myfile_1.txt

 Setting Stderr
${result}= Run Process python -c "1/0" shell=True stderr=%{TEMPDIR}/myfile.txt
     ${output}=    Get File    %{TEMPDIR}/myfile.txt
     Should Not Be Empty    ${output}
     Should Match   ${output}   ${result.stderr}*
- [Teardown] Run Keyword And Ignore Error Remove File %{TEMPDIR}/myfile.txt
+    [Teardown]    Safe Remove File    %{TEMPDIR}/myfile.txt

 Without Env Configuration the Environment Should Be As It Was
     Set Environment Variable  normalvar  normal
@@ -132,7 +130,7 @@
     Should Match    ${result.stderr}    *ZeroDivisionError*
     Should Be Equal    ${result.stdout_path}    ${path}
     Should Be Equal    ${result.stderr_path}    ${path}
-    [Teardown]    Run Keyword And Ignore Error   Remove File    ${path}
+    [Teardown]    Safe Remove File    ${path}

 Current working directory should be used with stdout and stderr
     Create Directory    %{TEMPDIR}/hc
@@ -142,7 +140,7 @@
     ${output2}=    Get File    %{TEMPDIR}/hc/myerr.txt
     Should Match    ${output}    *moon kuu*
     Should Match    ${output2}    *ZeroDivisionError*
- [Teardown] Run Keyword And Ignore Error Remove Directory %{TEMPDIR}/hc recursive=True
+    [Teardown]    Safe Remove Directory    %{TEMPDIR}/hc

Current working directory should not be used with stdout and stderr when absolute path in use
     Create Directory    %{TEMPDIR}/hc
@@ -156,29 +154,14 @@
     Should Match    ${stderr}    *ZeroDivisionError*
     Should Be Equal    ${result.stdout_path}    ${stdout_path}
     Should Be Equal    ${result.stderr_path}    ${stderr_path}
- [Teardown] Remove Directory and File %{TEMPDIR}/hc ${stdout_path}}
+    [Teardown]   Run Keywords
+    ...    Safe Remove Directory   %{TEMPDIR}/hc    AND
+    ...    Safe Remove File    ${stdout_path}

 *** Keywords ***
 Restart Suite Process If Needed
     ${alive}=    Is Process Running    suite_process
     Run Keyword Unless    ${alive}    Some process    suite_process
-
-Suite Setup
-    Check Preconditions
-    Some process    suite_process
-
-Suite Teardown
-    ${is_ok}=   Valid Platform
-    Run Keyword If  ${is_ok}   Stop some process    suite_process
-
-Check Preconditions
-    ${is_ok}=   Valid Platform
- Run Keyword Unless ${is_ok} Set Suite Metadata info precondition_fail
-    Run Keyword Unless   ${is_ok}    Fail
-
-Valid Platform
-    ${is_ok}=   Evaluate   sys.version_info >= (2,6)   sys
-    [Return]    ${is_ok}

 Create env dictionary
     [Arguments]  @{env_args}
@@ -187,8 +170,3 @@
     ${systemroot}=  Get Environment Variable  SYSTEMROOT  default=.
${setenv}= Create Dictionary PATH ${path} SYSTEMROOT ${SYSTEMROOT} @{env_args}
     [Return]  ${setenv}
-
-Remove Directory and File
-    [Arguments]  ${dir_to_remove}    ${file_to_remove}
- Run Keyword And Ignore Error Remove Directory ${dir_to_remove} recursive=True
-    Run Keyword And Ignore Error     Remove File         ${file_to_remove}
=======================================
--- /atest/testdata/standard_libraries/process/resource.txt Mon Jun 10 13:42:20 2013 +++ /atest/testdata/standard_libraries/process/resource.txt Thu Jun 13 16:28:50 2013
@@ -1,3 +1,7 @@
+*** Settings ***
+Library           Process
+Library           OperatingSystem
+
 *** Keywords ***
 Some process
     [Arguments]    ${alias}=${null}
@@ -32,3 +36,19 @@
     Log    ${result.rc}
     Log    ${result.stderr}
     [Return]    ${result}
+
+Safe Remove File
+    [Documentation]    Ignore errors caused by process being locked.
+    ...                That happens at least with IronPython.
+    [Arguments]    ${path}
+    Run Keyword And Ignore Error    Remove File    ${path}
+
+Safe Remove Directory
+    [Arguments]    ${path}
+ Run Keyword And Ignore Error Remove Directory ${path} recursive=yep
+
+Check Precondition
+    [Arguments]    ${precondition}
+    ${nok}=    Evaluate    not ${precondition}    modules=sys
+    Run Keyword If  ${nok}    Set Suite Metadata  info   precondition_fail
+    Run Keyword If  ${nok}    Fail    ${precondition} was not true
=======================================
--- /atest/testdata/standard_libraries/process/start_process_preferences.txt Tue Jun 11 04:28:34 2013 +++ /atest/testdata/standard_libraries/process/start_process_preferences.txt Thu Jun 13 16:28:50 2013
@@ -1,5 +1,4 @@
 *** Settings ***
-#Suite Setup       Check Preconditions
 Library           Process
 Library           OperatingSystem
 Library           CustomLib.py
@@ -36,9 +35,3 @@
     Switch Process  p2
     OperatingSystem.Switch Process  op1
     OperatingSystem.Switch Process  op2
-
-*** Keywords ***
-Check Preconditions
-    ${is_ok}=   Evaluate   sys.version_info >= (2,6)  sys
- Run Keyword If not ${is_ok} Set Suite Metadata info precondition_fail
-    Run Keyword If  not ${is_ok}    Fail
=======================================
--- /atest/testdata/standard_libraries/process/terminate_and_pid.txt Thu Jun 13 13:32:38 2013 +++ /atest/testdata/standard_libraries/process/terminate_and_pid.txt Thu Jun 13 16:28:50 2013
@@ -1,7 +1,5 @@
 *** Settings ***
-Suite Setup       Check Preconditions
-Library           Process.py
-Library           OperatingSystem
+Suite Setup       Check Precondition    sys.version_info >= (2,6)
 Resource          resource.txt
 Test Timeout      15s

@@ -78,7 +76,7 @@
     ${stdout}=    Normalize Path    %{TEMPDIR}/stdout.txt
${handle}= Run Process python -c "for i in range(350000): \tprint 'a'*400" shell=True stdout=${stdout} stderr=STDOUT
     File Should Not Be Empty    ${stdout}
-    [Teardown]    Run Keyword And Ignore Error    Remove File    ${stdout}
+    [Teardown]    Safe Remove File    ${stdout}

 Getting PIDs in different ways should give same result
${handle}= Start Process python -c "print 'hello'" shell=True alias=hello
@@ -87,11 +85,3 @@
     ${pid3}=      Get Process Id   ${handle}
     Should Be Equal As Integers   ${pid1}   ${pid2}
     Should Be Equal As Integers   ${pid1}   ${pid3}
-
-
-*** Keywords ***
-Check Preconditions
-    ${is_ok}=   Evaluate   sys.version_info >= (2,6)  sys
- Run Keyword If not ${is_ok} Set Suite Metadata info precondition_fail
-    Run Keyword If  not ${is_ok}    Fail
-

==============================================================================
Revision: 43ea0b0f453b
Branch:   default
Author:   Pekka Klärck
Date:     Thu Jun 13 17:11:30 2013
Log: Collections: Create Dictionary and Set To Dictionary take items as **itemns

Update issue 1473
Status: Done
Owner: pekka.klarck
Summary: Collections: `Create Dictionary` and `Set To Dictionary` should accept `**items`
http://code.google.com/p/robotframework/source/detail?r=43ea0b0f453b

Modified:
 /atest/robot/standard_libraries/collections/dictionary.txt
 /atest/testdata/standard_libraries/collections/dictionary.txt
 /src/robot/libraries/Collections.py

=======================================
--- /atest/robot/standard_libraries/collections/dictionary.txt Thu Apr 25 06:53:26 2013 +++ /atest/robot/standard_libraries/collections/dictionary.txt Thu Jun 13 17:11:30 2013
@@ -11,12 +11,18 @@

 Create Dictionary with wrong number of arguments
     Check Test Case  ${TEST NAME}
+
+Create Dictionary With **kwargs
+    Check Test Case  ${TEST NAME}

 Set To Dictionary
     Check Test Case  ${TEST NAME}

 Set To Dictionary With wrong number of arguments
     Check Test Case  ${TEST NAME}
+
+Set To Dictionary With **kwargs
+    Check Test Case  ${TEST NAME}

 Remove From Dictionary
     ${tc} =  Check Test Case  ${TEST NAME}
=======================================
--- /atest/testdata/standard_libraries/collections/dictionary.txt Thu Apr 25 06:53:26 2013 +++ /atest/testdata/standard_libraries/collections/dictionary.txt Thu Jun 13 17:11:30 2013
@@ -13,6 +13,10 @@
 Create Dictionary with wrong number of arguments
[Documentation] FAIL ValueError: Creating a dictionary failed. There should be an even number of key-value-pairs.
     Create Dictionary  a  1  b
+
+Create Dictionary With **kwargs
+ ${dict} = Create Dictionary k1 ${1} over write k2=${2} over=written + Compare To Expected String ${dict} {'k1': 1, 'k2': 2, 'over': 'written'}

 Set To Dictionary
     Set To Dictionary  ${D0}  a  ${1}
@@ -23,6 +27,10 @@
 Set To Dictionary With wrong number of arguments
[Documentation] FAIL ValueError: Adding data to a dictionary failed. There should be an even number of key-value-pairs.
     Set To Dictionary  ${D0}  a
+
+Set To Dictionary With **kwargs
+    Set To Dictionary  ${D0}  k1  ${1}  over  write  k2=${2}  over=written
+ Compare To Expected String ${D0} {'k1': 1, 'k2': 2, 'over': 'written'}

 Remove From Dictionary
     Remove From Dictionary  ${D3}  b  x  ${2}
=======================================
--- /src/robot/libraries/Collections.py Thu Jun  6 07:00:44 2013
+++ /src/robot/libraries/Collections.py Thu Jun 13 17:11:30 2013
@@ -425,25 +425,35 @@

 class _Dictionary:

-    def create_dictionary(self, *key_value_pairs):
- """Creates and returns a dictionary from the given `key_value_pairs`.
+    def create_dictionary(self, *key_value_pairs, **items):
+        """Creates and returns a dictionary based on given items.

-        Examples:
-        | ${x} = | Create Dictionary | name | value |   |   |
-        | ${y} = | Create Dictionary | a    | 1     | b | 2 |
-        | ${z} = | Create Dictionary | a    | ${1}  | b | ${2} |
+        Giving items as `key_value_pairs` means giving keys and values
+        as separate arguments:
+
+        | ${x} = | Create Dictionary | name | value |   |      |
+        | ${y} = | Create Dictionary | a    | 1     | b | ${2} |
         =>
         - ${x} = {'name': 'value'}
-        - ${y} = {'a': '1', 'b': '2'}
-        - ${z} = {'a': 1, 'b': 2}
+        - ${y} = {'a': '1', 'b': 2}
+
+ Starting from Robot Framework 2.8.1, items can also be given as kwargs:
+
+        | ${x} = | Create Dictionary | name=value |        |
+        | ${y} = | Create Dictionary | a=1        | b=${2} |
+
+        The latter syntax is typically more convenient to use, but it has
+        a limitation that keys must be strings.
         """
         if len(key_value_pairs) % 2 != 0:
raise ValueError("Creating a dictionary failed. There should be "
                              "an even number of key-value-pairs.")
-        return self.set_to_dictionary({}, *key_value_pairs)
+        return self.set_to_dictionary({}, *key_value_pairs, **items)
+
+    def set_to_dictionary(self, dictionary, *key_value_pairs, **items):
+        """Adds the given `key_value_pairs` and `items`to the `dictionary`.

-    def set_to_dictionary(self, dictionary, *key_value_pairs):
-        """Adds the given `key_value_pairs` to the `dictionary`.
+        See `Create Dictionary` for information about giving items.

         Example:
         | Set To Dictionary | ${D1} | key | value |
@@ -455,6 +465,7 @@
"should be an even number of key-value-pairs.")
         for i in range(0, len(key_value_pairs), 2):
             dictionary[key_value_pairs[i]] = key_value_pairs[i+1]
+        dictionary.update(items)
         return dictionary

     def remove_from_dictionary(self, dictionary, *keys):
@@ -585,7 +596,7 @@
         The given dictionary is never altered by this keyword.
         """
         self.dictionary_should_contain_key(dictionary, key, msg)
-        actual, expected =  unicode(dictionary[key]), unicode(value)
+        actual, expected = unicode(dictionary[key]), unicode(value)
default = "Value of dictionary key '%s' does not match. '%s'!='%s'" % (key, actual, expected)
         _verify_condition(actual == expected, default, msg)

--

--- You received this message because you are subscribed to the Google Groups "robotframework-commit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to robotframework-commit+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to