Repository: rucio/rucio

Issue:
import of builtins not Python 2.6 compatible in downloadclient
Motivation
----------
https://github.com/rucio/rucio/blob/06e4f7e3ac03111f1ec94add1be3524d3d0fc4d9/lib/rucio/client/downloadclient.py#L35 is not compatible to Python 2.6 it seems, which is a problem for the deployment on the grid

Py2.6:
```
[desilva@atlas-sl6x64 ~]$ rucio --version
Traceback (most recent call last):
  File "/ALRB/atlasadmin/atlas-sl6x64.triumf.ca/ATLASLocalRootBase/x86_64/rucio-clients/1.18.6/bin/rucio", line 63, in <module>
    from rucio.client.downloadclient import DownloadClient
  File "/ALRB/atlasadmin/atlas-sl6x64.triumf.ca/ATLASLocalRootBase/x86_64/rucio-clients/1.18.6/lib/python2.7/site-packages/rucio/client/downloadclient.py", line 35, in <module>
    from builtins import round
ImportError: No module named builtins
```




Discussion:
Not sure why this was not caught by the Python 2.6 test though?
I will remove the imports and add a basic test to the python2.6 client test to check at least imports. Also the pylint check for python3 has to be changed to ignore round errors.

Resolving patch:
diff --git a/lib/rucio/client/downloadclient.py b/lib/rucio/client/downloadclient.py
--- a/lib/rucio/client/downloadclient.py
+++ b/lib/rucio/client/downloadclient.py
@@ -32,7 +32,6 @@
 import signal
 import time
 
-from builtins import round
 try:
     from Queue import Queue, Empty, deque
 except ImportError:
diff --git a/lib/rucio/core/rse.py b/lib/rucio/core/rse.py
--- a/lib/rucio/core/rse.py
+++ b/lib/rucio/core/rse.py
@@ -28,7 +28,6 @@
 # PY3K COMPATIBLE
 
 from __future__ import division
-from builtins import round
 from re import match
 try:
     from StringIO import StringIO


Test patch:
diff --git a/lib/rucio/tests/test_module_import.py b/lib/rucio/tests/test_module_import.py
new file mode 100644
--- /dev/null
+++ b/lib/rucio/tests/test_module_import.py
@@ -0,0 +1,68 @@
+# Copyright 2012-2018 CERN for the benefit of the ATLAS collaboration.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Authors:
+# - Vincent Garonne <vgaronne@gmail.com>, 2012-2018
+# - Mario Lassnig <mario.lassnig@cern.ch>, 2012-2018
+# - Angelos Molfetas <Angelos.Molfetas@cern.ch>, 2012
+# - Thomas Beermann <thomas.beermann@cern.ch>, 2012
+# - Joaquin Bogado <jbogado@linti.unlp.edu.ar>, 2014-2018
+# - Cheng-Hsi Chao <cheng-hsi.chao@cern.ch>, 2014
+# - Cedric Serfon <cedric.serfon@cern.ch>, 2015
+# - Martin Barisits <martin.barisits@cern.ch>, 2015-2016
+# - Frank Berghaus <frank.berghaus@cern.ch>, 2017-2018
+# - Tobias Wegner <twegner@cern.ch>, 2018
+# - Hannes Hansen <hannes.jakob.hansen@cern.ch>, 2018
+
+import nose.tools
+import re
+import subprocess
+
+
+def execute(cmd):
+    """
+    Executes a command in a subprocess. Returns a tuple
+    of (exitcode, out, err), where out is the string output
+    from stdout and err is the string output from stderr when
+    executing the command.
+    :param cmd: Command string to execute
+    """
+
+    process = subprocess.Popen(cmd,
+                               shell=True,
+                               stdin=subprocess.PIPE,
+                               stdout=subprocess.PIPE,
+                               stderr=subprocess.PIPE)
+    out = ''
+    err = ''
+    exitcode = 0
+
+    result = process.communicate()
+    (out, err) = result
+    exitcode = process.returncode
+
+    return exitcode, out, err
+
+
+class TestModuleImport():
+    def test_import(self):
+        """ """
+        cmd = 'rucio --version'
+        exitcode, out, err = execute(cmd)
+        out = out.decode()
+        err = err.decode()
+        nose.tools.assert_equal(re.search('ImportError', err), None)
+        nose.tools.assert_equal(re.search('ImportError', out), None)
+        nose.tools.assert_equal(re.search('Exception', err), None)
+        nose.tools.assert_equal(re.search('Exception', out), None)