3 new revisions:

Revision: 2a77a2b82640
Branch:   default
Author:   Pekka Klärck
Date:     Mon Jan 27 07:47:12 2014 UTC
Log:      OS: New 'Append To Environment Variable' keyword....
http://code.google.com/p/robotframework/source/detail?r=2a77a2b82640

Revision: e421419f2cdd
Branch:   default
Author:   Pekka Klärck
Date:     Mon Jan 27 07:56:47 2014 UTC
Log: Support 'Package.MyLib' import when MyLib is module with class MyLib....
http://code.google.com/p/robotframework/source/detail?r=e421419f2cdd

Revision: 6a07ecac5295
Branch:   default
Author:   Pekka Klärck
Date:     Mon Jan 27 08:26:09 2014 UTC
Log: UG: Documented that dropping class name when importing libs now works ...
http://code.google.com/p/robotframework/source/detail?r=6a07ecac5295

==============================================================================
Revision: 2a77a2b82640
Branch:   default
Author:   Pekka Klärck
Date:     Mon Jan 27 07:47:12 2014 UTC
Log:      OS: New 'Append To Environment Variable' keyword.

New issue
Summary: OperatingSystem: New `Append To Environment Variable` keyword
Owner: pekka.klarck
Status: Review
Labels: Priority-Low Target-2.8.4 Type-Enhancement
This keyword eases setting environment variables that contain different entries separated by ';' (Windows) or ':' (elsewhere). Such environment variables include PATH, PYTHONPATH and CLASSPATH.

The keyword accepts multiple values and joins them together with the correct path separator. If the environment variable was already set, the original value is preserved in the beginning of the new value.

This keyword ought to be done (implemented, tested, and documented), but there are two things still to be considered:

1) Should separator be configurable? Could easily add **kwargs and read optional separator from there, but I'm not sure are there any use cases for it.

2) Since this the main use case is setting PATH and PATH-like environment variables, should we also change the name to `Append To PATH Environment Variable`? I doubt this would make the keyword much easier to understand, though.
http://code.google.com/p/robotframework/source/detail?r=2a77a2b82640

Modified:
 /atest/robot/standard_libraries/operating_system/env_vars.txt
 /atest/testdata/standard_libraries/operating_system/env_vars.txt
 /src/robot/libraries/OperatingSystem.py

=======================================
--- /atest/robot/standard_libraries/operating_system/env_vars.txt Tue Feb 28 14:51:49 2012 UTC +++ /atest/robot/standard_libraries/operating_system/env_vars.txt Mon Jan 27 07:47:12 2014 UTC
@@ -9,6 +9,9 @@

 Set Environment Variable
     Check test case    ${TEST NAME}
+
+Append To Environment Variable
+    Check test case    ${TEST NAME}

 Remove Environment Variable
     Check test case    ${TEST NAME}
=======================================
--- /atest/testdata/standard_libraries/operating_system/env_vars.txt Wed Feb 29 13:30:39 2012 UTC +++ /atest/testdata/standard_libraries/operating_system/env_vars.txt Mon Jan 27 07:47:12 2014 UTC
@@ -24,6 +24,12 @@
     Set Environment Variable    ${NAME}    Moi
     Should Be Equal    %{${NAME}}    Moi

+Append To Environment Variable
+    Append To Environment Variable    ${NAME}    first
+    Should Be Equal    %{${NAME}}    first
+    Append To Environment Variable    ${NAME}    second    third
+    Should Be Equal    %{${NAME}}    first${:}second${:}third
+
 Remove Environment Variable
     Set Environment Variable    ${NAME}    Hello
     Remove Environment Variable    ${NAME}
=======================================
--- /src/robot/libraries/OperatingSystem.py     Fri Jan 24 12:27:32 2014 UTC
+++ /src/robot/libraries/OperatingSystem.py     Mon Jan 27 07:47:12 2014 UTC
@@ -926,6 +926,28 @@
         set_env_var(name, value)
self._info("Environment variable '%s' set to value '%s'" % (name, value))

+    def append_to_environment_variable(self, name, *values):
+        """Appends given `values` to environment variable `name`.
+
+ If the environment variable already exists, values are added after it,
+        otherwise a new environment variable is created. Values are joined
+        together using the operating system path separator (';' on Windows,
+        ':' elsewhere).
+
+        Examples (assuming `EXAMPLE` does not exist initially):
+        | Append To Environment Variable | EXAMPLE    | first  |       |
+        | Should Be Equal                | %{EXAMPLE} | first  |       |
+        | Append To Environment Variable | EXAMPLE    | second | third |
+ | Should Be Equal | %{EXAMPLE} | first${:}second${:}third |
+
+        New in Robot Framework 2.8.4.
+        """
+        sentinel = object()
+        initial = self.get_environment_variable(name, sentinel)
+        if initial is not sentinel:
+            values = (initial,) + values
+        self.set_environment_variable(name, os.pathsep.join(values))
+
     def remove_environment_variable(self, *names):
         """Deletes the specified environment variable.


==============================================================================
Revision: e421419f2cdd
Branch:   default
Author:   Pekka Klärck
Date:     Mon Jan 27 07:56:47 2014 UTC
Log: Support 'Package.MyLib' import when MyLib is module with class MyLib.

Update issue 1614
Owner: pekka.klarck
Status: Started
Fixing this problem turned out to be pretty trivial. Creating tests too much more time.

Still need to check what User Guide says about this subject and possibly update it. It might also be possible to remove import related code now that NonDottedImporter and DottedImporter work same way in this regard.
http://code.google.com/p/robotframework/source/detail?r=e421419f2cdd

Added:
 /atest/robot/test_libraries/package_library.txt
 /atest/testdata/test_libraries/MyLibDir/ClassLib.py
 /atest/testdata/test_libraries/MyLibDir/SubModuleLib.py
 /atest/testdata/test_libraries/MyLibDir/SubPackage/ClassLib.py
 /atest/testdata/test_libraries/MyLibDir/SubPackage/SubModuleLib.py
 /atest/testdata/test_libraries/MyLibDir/SubPackage/__init__.py
 /atest/testdata/test_libraries/MyLibDir/SubPackage2/__init__.py
 /atest/testdata/test_libraries/package_library.txt
Modified:
 /src/robot/utils/importer.py

=======================================
--- /dev/null
+++ /atest/robot/test_libraries/package_library.txt Mon Jan 27 07:56:47 2014 UTC
@@ -0,0 +1,47 @@
+*** Settings ***
+Suite Setup      Set PYTHONPATH and run tests
+Force Tags       regression    pybot    jybot
+Resource         atest_resource.txt
+
+*** Test Cases ***
+Class in package as library implicitly
+    Check Test Case    ${TESTNAME}
+
+Class in package as library explicitly
+    Check Test Case    ${TESTNAME}
+
+Package itself as library
+    Check Test Case    ${TESTNAME}
+
+Class in sub-module as library implicitly
+    Check Test Case    ${TESTNAME}
+
+Class in sub-module as library explicitly
+    Check Test Case    ${TESTNAME}
+
+Sub-module itself as library
+    Check Test Case    ${TESTNAME}
+
+Class in sub-package as library implicitly
+    Check Test Case    ${TESTNAME}
+
+Class in sub-package as library explicitly
+    Check Test Case    ${TESTNAME}
+
+Sub-package itself as library
+    Check Test Case    ${TESTNAME}
+
+Class in sub-sub-module as library implicitly
+    Check Test Case    ${TESTNAME}
+
+Class in sub-sub-module as library explicitly
+    Check Test Case    ${TESTNAME}
+
+Sub-sub-module itself as library
+    Check Test Case    ${TESTNAME}
+
+*** Keywords ***
+Set PYTHONPATH and run tests
+    ${dir} =    Normalize Path    ${DATADIR}/test_libraries
+ Append To Environment Variable PYTHONPATH ${dir} ${dir}${/}dir_for_libs
+    Run Tests    ${EMPTY}    test_libraries/package_library.txt
=======================================
--- /dev/null
+++ /atest/testdata/test_libraries/MyLibDir/ClassLib.py Mon Jan 27 07:56:47 2014 UTC
@@ -0,0 +1,4 @@
+class ClassLib(object):
+
+    def keyword_in_mylibdir_classlib(self):
+        pass
=======================================
--- /dev/null
+++ /atest/testdata/test_libraries/MyLibDir/SubModuleLib.py Mon Jan 27 07:56:47 2014 UTC
@@ -0,0 +1,2 @@
+def keyword_in_mylibdir_submodulelib():
+    pass
=======================================
--- /dev/null
+++ /atest/testdata/test_libraries/MyLibDir/SubPackage/ClassLib.py Mon Jan 27 07:56:47 2014 UTC
@@ -0,0 +1,4 @@
+class ClassLib(object):
+
+    def keyword_in_mylibdir_subpackage_classlib(self):
+        pass
=======================================
--- /dev/null
+++ /atest/testdata/test_libraries/MyLibDir/SubPackage/SubModuleLib.py Mon Jan 27 07:56:47 2014 UTC
@@ -0,0 +1,2 @@
+def keyword_in_mylibdir_subpackage_submodulelib():
+    pass
=======================================
--- /dev/null
+++ /atest/testdata/test_libraries/MyLibDir/SubPackage/__init__.py Mon Jan 27 07:56:47 2014 UTC
@@ -0,0 +1,4 @@
+class SubPackage(object):
+
+    def keyword_in_mylibdir_subpackage_class(self):
+        pass
=======================================
--- /dev/null
+++ /atest/testdata/test_libraries/MyLibDir/SubPackage2/__init__.py Mon Jan 27 07:56:47 2014 UTC
@@ -0,0 +1,2 @@
+def keyword_in_mylibdir_subpackage2_package():
+    pass
=======================================
--- /dev/null
+++ /atest/testdata/test_libraries/package_library.txt Mon Jan 27 07:56:47 2014 UTC
@@ -0,0 +1,50 @@
+*** Settings ***
+Library           MyLibDir
+Library           MyLibDir.MyLibDir
+Library           MyLibDir2
+Library           MyLibDir.ClassLib
+Library           MyLibDir.ClassLib.ClassLib
+Library           MyLibDir.SubModuleLib
+Library           MyLibDir.SubPackage
+Library           MyLibDir.SubPackage.SubPackage
+Library           MyLibDir.SubPackage2
+Library           MyLibDir.SubPackage.ClassLib
+Library           MyLibDir.SubPackage.ClassLib.ClassLib
+Library           MyLibDir.SubPackage.SubModuleLib
+
+*** Test Cases ***
+Class in package as library implicitly
+    MyLibDir.Keyword In My Lib Dir
+
+Class in package as library explicitly
+    MyLibDir.MyLibDir.Keyword In My Lib Dir
+
+Package itself as library
+    MyLibDir2.Keyword In My Lib Dir 2
+
+Class in sub-module as library implicitly
+    MyLibDir.ClassLib.Keyword In MyLibDir ClassLib
+
+Class in sub-module as library explicitly
+    MyLibDir.ClassLib.ClassLib.Keyword In MyLibDir ClassLib
+
+Sub-module itself as library
+    MyLibDir.SubModuleLib.Keyword In MyLibDir SubModuleLib
+
+Class in sub-package as library implicitly
+    MyLibDir.SubPackage.Keyword In MyLibDir SubPackage Class
+
+Class in sub-package as library explicitly
+    MyLibDir.SubPackage.SubPackage.Keyword In MyLibDir SubPackage Class
+
+Sub-package itself as library
+    MyLibDir.SubPackage2.Keyword In MyLibDir SubPackage2 Package
+
+Class in sub-sub-module as library implicitly
+    MyLibDir.SubPackage.ClassLib.Keyword In MyLibDir SubPackage ClassLib
+
+Class in sub-sub-module as library explicitly
+ MyLibDir.SubPackage.ClassLib.ClassLib.Keyword In MyLibDir SubPackage ClassLib
+
+Sub-sub-module itself as library
+ MyLibDir.SubPackage.SubModuleLib.Keyword In MyLibDir SubPackage SubModuleLib
=======================================
--- /src/robot/utils/importer.py        Thu Jan 23 14:00:53 2014 UTC
+++ /src/robot/utils/importer.py        Mon Jan 27 07:56:47 2014 UTC
@@ -155,8 +155,8 @@
             return imported
raise DataError('Expected class or module, got <%s>.' % type(imported).__name__)

-    def _get_class_from_module(self, module):
-        klass = getattr(module, module.__name__, None)
+    def _get_class_from_module(self, module, name=None):
+        klass = getattr(module, name or module.__name__, None)
         return klass if inspect.isclass(klass) else None

     def _get_source(self, module):
@@ -251,4 +251,5 @@
         except AttributeError:
             raise DataError("Module '%s' does not contain '%s'."
                             % (parent_name, lib_name))
+ imported = self._get_class_from_module(imported, lib_name) or imported
         return self._verify_type(imported), self._get_source(parent)

==============================================================================
Revision: 6a07ecac5295
Branch:   default
Author:   Pekka Klärck
Date:     Mon Jan 27 08:26:09 2014 UTC
Log: UG: Documented that dropping class name when importing libs now works also with submodules.

Update issue 1614
Updated documentation the User Guide.
http://code.google.com/p/robotframework/source/detail?r=6a07ecac5295

Modified:
 /doc/userguide/RobotFrameworkUserGuide.html
 /doc/userguide/src/ExtendingRobotFramework/CreatingTestLibraries.rst

=======================================
--- /doc/userguide/RobotFrameworkUserGuide.html Sun Jan 26 16:48:25 2014 UTC
+++ /doc/userguide/RobotFrameworkUserGuide.html Mon Jan 27 08:26:09 2014 UTC
@@ -12365,22 +12365,29 @@
 <h4><a class="toc-backref" href="#id666">Test library names</a></h4>
 <p>The name of a test library that is used when a library is imported is
 the same as the name of the module or class implementing it. For
-example, if you have a Python module <span class="code">MyLibrary</span> (that is, the -file <span class="path">MyLibrary.py</span>), it will create a library with a name +example, if you have a Python module <span class="code">MyLibrary</span> (that is, +file <span class="path">MyLibrary.py</span>), it will create a library with name <span class="name">MyLibrary</span>. Similarly, a Java class <span class="code">YourLibrary</span>, when
 it is not in any package, creates a library with exactly that name.</p>
 <p>Python classes are always inside a module. If the name of a class
 implementing a library is the same as the name of the module, Robot
-Framework allows dropping the module name when importing the
-library. For example, the class <span class="code">MyLib</span> in the <span class="path">MyLib.py</span> -file can be used as a library with the name <span class="name">MyLib</span>. If the
-module name and class name are different, libraries must be taken into
-use using both module and class names, such as
-<span class="name">mymodule.MyLibrary</span>.</p>
+Framework allows dropping the class name when importing the
+library. For example, class <span class="code">MyLib</span> in <span class="path">MyLib.py</span> +file can be used as a library with just name <span class="name">MyLib</span>. This also +works with submodules so that if, for example, <span class="code">parent.MyLib</span> module +has class <span class="code">MyLib</span>, importing it using just <span class="name">parent.MyLib</span>
+works. If the module name and class name are different, libraries must be
+taken into use using both module and class names, such as
+<span class="name">mymodule.MyLibrary</span> or <span class="name">parent.submodule.MyLib</span>.</p>
 <p>Java classes in a non-default package must be taken into use with the
-full name. For example, the class <span class="code">MyLib</span> in the
-<span class="code">com.mycompany.myproject</span> package must be imported with the name
-<span class="name">com.mycompany.myproject.MyLib</span>.</p>
+full name. For example, class <span class="code">MyLib</span> in <span class="code">com.mycompany.myproject</span> +package must be imported with name <span class="name">com.mycompany.myproject.MyLib</span>.</p>
+<div class="note">
+<p class="first admonition-title">Note</p>
+<p class="last">Dropping class names with submodules works only in Robot Framework
+2.8.4 and newer. With earlier versions you need to include also
+the class name like <span class="name">parent.MyLib.MyLib</span>.</p>
+</div>
 <div class="tip">
 <p class="first admonition-title">Tip</p>
<p class="last">If the library name is really long, for example when the Java
@@ -17810,7 +17817,7 @@
 <div class="footer">
 <hr class="footer" />
<p>Generated by <a class="reference external" href="http://docutils.sourceforge.net/rst.html";>reStructuredText</a>. Syntax highlighting by <a class="reference external" href="http://pygments.org/";>Pygments</a>.</p>
-<p>Generated on: 2014-01-26 16:48 UTC.
+<p>Generated on: 2014-01-27 08:24 UTC.
 </p>

 </div>
=======================================
--- /doc/userguide/src/ExtendingRobotFramework/CreatingTestLibraries.rst Fri Jan 17 21:18:14 2014 UTC +++ /doc/userguide/src/ExtendingRobotFramework/CreatingTestLibraries.rst Mon Jan 27 08:26:09 2014 UTC
@@ -101,24 +101,29 @@

 The name of a test library that is used when a library is imported is
 the same as the name of the module or class implementing it. For
-example, if you have a Python module :code:`MyLibrary` (that is, the
-file :path:`MyLibrary.py`), it will create a library with a name
+example, if you have a Python module :code:`MyLibrary` (that is,
+file :path:`MyLibrary.py`), it will create a library with name
 :name:`MyLibrary`. Similarly, a Java class :code:`YourLibrary`, when
 it is not in any package, creates a library with exactly that name.

 Python classes are always inside a module. If the name of a class
 implementing a library is the same as the name of the module, Robot
-Framework allows dropping the module name when importing the
-library. For example, the class :code:`MyLib` in the :path:`MyLib.py`
-file can be used as a library with the name :name:`MyLib`. If the
-module name and class name are different, libraries must be taken into
-use using both module and class names, such as
-:name:`mymodule.MyLibrary`.
+Framework allows dropping the class name when importing the
+library. For example, class :code:`MyLib` in :path:`MyLib.py`
+file can be used as a library with just name :name:`MyLib`. This also
+works with submodules so that if, for example, :code:`parent.MyLib` module
+has class :code:`MyLib`, importing it using just :name:`parent.MyLib`
+works. If the module name and class name are different, libraries must be
+taken into use using both module and class names, such as
+:name:`mymodule.MyLibrary` or :name:`parent.submodule.MyLib`.

 Java classes in a non-default package must be taken into use with the
-full name. For example, the class :code:`MyLib` in the
-:code:`com.mycompany.myproject` package must be imported with the name
-:name:`com.mycompany.myproject.MyLib`.
+full name. For example, class :code:`MyLib` in :code:`com.mycompany.myproject`
+package must be imported with name :name:`com.mycompany.myproject.MyLib`.
+
+.. note:: Dropping class names with submodules works only in Robot Framework
+          2.8.4 and newer. With earlier versions you need to include also
+          the class name like :name:`parent.MyLib.MyLib`.

 .. tip:: If the library name is really long, for example when the Java
          package name is long, it is recommended to give the library a

--

--- 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