internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: cognitedata/cognite-sdk-python

Issue:
client.time_series.get_time_series does not return metadata
**Describe the bug**
When executing `client.time_series.get_time_series()` with `include_metadata = True` no metadata is returned.

**To Reproduce**
Runnable code reproducing the error.
```
import cognite
import requests
import os
import numpy as np
import pandas as pd
from datetime import datetime, timedelta

from cognite.client.stable.time_series import TimeSeries
sm_api = os.environ['SM_API_KEY']
client = cognite.CogniteClient(api_key = sm_api)
ts_name = 'Test_tssssss'
my_time_series = [TimeSeries(name=ts_name, 
                             description = 'test_description',
                             metadata = { 'ASSETSCOPENAME' : 'meta_test_1' })]
client.time_series.post_time_series(my_time_series)

# create dummy data
np.random.seed(1338)
start_time = int((datetime.now()-timedelta(1)).strftime("%s"))
timestamps = [(start_time + i * 10)*1000 for i in np.arange(11)]
df = pd.DataFrame({'timestamp' : timestamps})
df[ts_name] = np.random.random(df.shape[0])
client.datapoints.post_datapoints_frame(df)
# get time_series
ts1 = client.time_series.get_time_series(name = ts_name,
                                         include_metadata = True).to_pandas()
ts1_id = ts1['id'].loc[0] 
print(ts1.loc[0])
# no meta data
# requests:
# first with no metadata
r1 = requests.get(url = 'https://api.cognitedata.com/api/0.5/projects/smart-maintenance-sandbox/timeseries/' + str(ts1_id) ,
                  headers= { 'Api-Key' : sm_api} , params = {"includeMetadata" : False})
print(r1.text.split('\n'))
# then with metadata
r1 = requests.get(url = 'https://api.cognitedata.com/api/0.5/projects/smart-maintenance-sandbox/timeseries/' + str(ts1_id) ,
                  headers= { 'Api-Key' : sm_api} , params = {"includeMetadata" : True})
print(r1.text.split('\n'))
```
**Expected behavior**
The `client.time_series.get_time_series(name = ts_name,include_metadata = True)` should return the metadata.




Discussion:
This one's affecting me too.

I think the cause is that `to_pandas` has an independent `include_metadata` parameter which is false by default:
```python
class TimeSeriesListResponse(CogniteCollectionResponse):
    """Time series Response Object"""

    _RESPONSE_CLASS = TimeSeriesResponse

    def to_pandas(self, include_metadata: bool = False):
```

Resolving patch:
diff --git a/cognite/client/stable/time_series.py b/cognite/client/stable/time_series.py
--- a/cognite/client/stable/time_series.py
+++ b/cognite/client/stable/time_series.py
@@ -45,7 +45,7 @@ class TimeSeriesListResponse(CogniteCollectionResponse):
 
     _RESPONSE_CLASS = TimeSeriesResponse
 
-    def to_pandas(self, include_metadata: bool = False):
+    def to_pandas(self, include_metadata: bool = True):
         """Returns data as a pandas dataframe
 
         Args:


Test patch:
Repository: cognitedata/cognite-sdk-python

Issue:
Retrieving datapoints will fail if aggregation jobs are queued up.
The current method for retrieving datapoints uses count aggregates to get the distribution of the data. If aggregates have not been created for some newly posted datapoints yet, the current implementation of the DatapointsFetcher will fail.


Discussion:
only of 10k datapoints are retrieved and no aggregates at all exists for the same time period, which should be super rare. anyway, I think this fixes it:

if not res:
  return [_DPWindow(start, end)]

Resolving patch:
diff --git a/cognite/client/_api/datapoints.py b/cognite/client/_api/datapoints.py
--- a/cognite/client/_api/datapoints.py
+++ b/cognite/client/_api/datapoints.py
@@ -8,6 +8,7 @@
 from cognite.client import utils
 from cognite.client._api_client import APIClient
 from cognite.client.data_classes import Datapoints, DatapointsList, DatapointsQuery
+from cognite.client.exceptions import CogniteAPIError
 
 
 class DatapointsAPI(APIClient):
@@ -786,15 +787,20 @@ def _get_windows(self, id, start, end, granularity, request_limit, user_limit):
             "1d"
         ) < cognite.client.utils._time.granularity_to_ms(granularity):
             count_granularity = granularity
-        res = self._get_datapoints_with_paging(
-            start=start,
-            end=end,
-            ts_item={"id": id},
-            aggregates=["count"],
-            granularity=count_granularity,
-            include_outside_points=False,
-            limit=None,
-        )
+        try:
+            res = self._get_datapoints_with_paging(
+                start=start,
+                end=end,
+                ts_item={"id": id},
+                aggregates=["count"],
+                granularity=count_granularity,
+                include_outside_points=False,
+                limit=None,
+            )
+        except CogniteAPIError:
+            res = []
+        if not res:  # string based series or aggregates not yet calculated
+            return [_DPWindow(start, end)]
         counts = list(zip(res.timestamp, res.count))
         windows = []
         total_count = 0


Test patch:
diff --git a/tests/tests_integration/test_api/test_datapoints.py b/tests/tests_integration/test_api/test_datapoints.py
--- a/tests/tests_integration/test_api/test_datapoints.py
+++ b/tests/tests_integration/test_api/test_datapoints.py
@@ -88,6 +88,10 @@ def test_retrieve_dataframe(self, test_time_series):
         assert df.shape[1] == 1
         assert has_correct_timestamp_spacing(df, "1s")
 
+    def test_retrieve_string(self):
+        dps = COGNITE_CLIENT.datapoints.retrieve(external_id="test__string_b", start=1563000000000, end=1564100000000)
+        assert len(dps) > 100000
+
     def test_query(self, test_time_series):
         dps_query1 = DatapointsQuery(id=test_time_series[0].id, start="6h-ago", end="now")
         dps_query2 = DatapointsQuery(id=test_time_series[1].id, start="3h-ago", end="now")
Repository: cognitedata/cognite-sdk-python

Issue:
Full update on multiple items fails if a CogniteResourceList is passed.
Right now I'm doing it like this:
```tsList = c.time_series.retrieve_multiple(external_ids=ex_ids)
for ts in tsList:
    ts.description = "new description"    
    c.time_series.update(ts)
```
For big lists this is ofc super slow. So preferably I'd like to do sth like
```tsList = c.time_series.retrieve_multiple(external_ids=ex_ids)
for ts in tsList:
    ts.description = "new description
    
c.time_series.update(tsList)
```
instead. However this throws
```
ValueError: update item must be of type CogniteResource or CogniteUpdate
```


Discussion:

Resolving patch:
diff --git a/cognite/client/_api_client.py b/cognite/client/_api_client.py
--- a/cognite/client/_api_client.py
+++ b/cognite/client/_api_client.py
@@ -3,6 +3,7 @@
 import logging
 import os
 import re
+from collections import UserList
 from typing import Any, Dict, List, Union
 
 import requests.utils
@@ -415,7 +416,7 @@ def _update_multiple(
         cls = cls or self._LIST_CLASS
         resource_path = resource_path or self._RESOURCE_PATH
         patch_objects = []
-        single_item = not isinstance(items, list)
+        single_item = not isinstance(items, (list, UserList))
         if single_item:
             items = [items]
 


Test patch:
diff --git a/tests/tests_unit/test_api/test_time_series.py b/tests/tests_unit/test_api/test_time_series.py
--- a/tests/tests_unit/test_api/test_time_series.py
+++ b/tests/tests_unit/test_api/test_time_series.py
@@ -108,6 +108,12 @@ def test_update_multiple(self, mock_ts_response):
         assert isinstance(res, TimeSeriesList)
         assert mock_ts_response.calls[0].response.json()["items"] == res.dump(camel_case=True)
 
+    def test_update_multiple_list(self, mock_ts_response):
+        tsl = TS_API.retrieve_multiple(ids=[0])
+        res = TS_API.update(tsl)
+        assert isinstance(res, TimeSeriesList)
+        assert 1 == len(res)
+
     def test_search(self, mock_ts_response):
         res = TS_API.search(filter=TimeSeriesFilter(is_string=True))
         assert mock_ts_response.calls[0].response.json()["items"] == res.dump(camel_case=True)
Repository: chainer/chainer

Issue:
Hide `cuda.cutools` from `batch_normalization`
When CUDA is not enabled, it fails.
related to #7 



Discussion:

Resolving patch:
diff --git a/chainer/functions/batch_normalization.py b/chainer/functions/batch_normalization.py
--- a/chainer/functions/batch_normalization.py
+++ b/chainer/functions/batch_normalization.py
@@ -24,23 +24,24 @@ def _partial_reduce(x):
                             1, numpy.float32(0.0), ret.gpudata, 1)
     return ret
 
-@cuda.cutools.context_dependent_memoize
-def _create_reduction_kernel(shape0, expr1, expr2):
-    return cuda.elementwise(
-        '''
-            float* ret1, float* ret2,
-            const float* x, const float* y,
-            float alpha, int shape12
-        ''', '''
-            float sum1 = 0, sum2 = 0;
-            for (int j = 0; j < {0}; j++) {{
-                int I = j * shape12 + i;
-                sum1 += {1};
-                sum2 += {2};
-            }}
-            ret1[i] = sum1 * alpha;
-            ret2[i] = sum2 * alpha;
-        '''.format(shape0, expr1, expr2), 'bn_asix02')
+if cuda.available:
+    @cuda.cutools.context_dependent_memoize
+    def _create_reduction_kernel(shape0, expr1, expr2):
+        return cuda.elementwise(
+            '''
+                float* ret1, float* ret2,
+                const float* x, const float* y,
+                float alpha, int shape12
+            ''', '''
+                float sum1 = 0, sum2 = 0;
+                for (int j = 0; j < {0}; j++) {{
+                    int I = j * shape12 + i;
+                    sum1 += {1};
+                    sum2 += {2};
+                }}
+                ret1[i] = sum1 * alpha;
+                ret2[i] = sum2 * alpha;
+            '''.format(shape0, expr1, expr2), 'bn_asix02')
 
 def _cusum_axis02(x, y=None, expr1='x[I]', expr2='x[I] * x[I]', mean=False):
     with cuda.using_cumisc():


Test patch:
Repository: chainer/chainer

Issue:
`chainer-cuda-requirements` fails on an invalid environment
`chainer-cuda-requirements` command imports `cuda.requirements`. So, when `import chainer` fails on invalid environment, the command also fails.
This command needs to work on such a case because a user want to fix his invalid environment.

My idea is to write the requirements text in the script directly.



Discussion:

Resolving patch:
diff --git a/setup_cuda_deps.py b/setup_cuda_deps.py
new file mode 100644
--- /dev/null
+++ b/setup_cuda_deps.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+from setuptools import setup
+
+setup(
+    name='chainer-cuda-deps',
+    version='1.0.0',
+    description='Install dependent packages to use Chainer on CUDA',
+    author='Seiya Tokui',
+    author_email='tokui@preferred.jp',
+    url='http://chainer.org/',
+    packages=[],
+    install_requires=[
+        'chainer',
+        'pycuda>=2014.1',
+        'scikits.cuda>=0.5.0b1,!=0.042',
+        'Mako',
+        'six>=1.9.0',
+    ],
+)


Test patch:
Repository: chainer/chainer

Issue:
Don't use `wget` in example of sentiment analysis
Use Python as `ptb` example.



Discussion:
We also need to remove dependency to `uzip` command.


Resolving patch:
diff --git a/examples/sentiment/download.py b/examples/sentiment/download.py
new file mode 100755
--- /dev/null
+++ b/examples/sentiment/download.py
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+import urllib, zipfile, os, os.path
+
+urllib.urlretrieve('http://nlp.stanford.edu/sentiment/trainDevTestTrees_PTB.zip', 'trainDevTestTrees_PTB.zip')
+zf = zipfile.ZipFile('trainDevTestTrees_PTB.zip')
+for name in zf.namelist():
+    (dirname, filename) = os.path.split(name)
+    if not filename == '':
+        zf.extract(name, '.')


Test patch:
Repository: chainer/chainer

Issue:
NameError: global name 'drv' is not defined
When `Variable#__init__` get an integer as the parameter `data`, the exception `NameError: global name 'drv' is not defined` occurs.

To reproduce:

```
Variable(1) + 1
```

It causes:

```
.../chainer/chainer/cuda.pyc in get_device(arg)
    222             arg = arg.base
    223         return arg.gpudata.device
--> 224     return drv.Device(arg)
    225
    226

NameError: global name 'drv' is not defined
```

Possible solution: to raise AssertionError in `Variable#__init__` if `data` is not an expected type.



Discussion:
Here is a blog entry in Japanese: http://d.hatena.ne.jp/nishiohirokazu/20150628/1435471207

Thank you very much! We need to check types of arguments in `Variable.__init__` and other APIs.

And, maybe it is because infix operators of `Variable` are overrided.


Resolving patch:
diff --git a/chainer/variable.py b/chainer/variable.py
--- a/chainer/variable.py
+++ b/chainer/variable.py
@@ -59,6 +59,9 @@ def __init__(self, data, volatile=False):
            :mod:`cuda` automatically uses this allocator.
 
         """
+        assert isinstance(data, (numpy.ndarray, cuda.GPUArray))
+        assert isinstance(volatile, bool)
+
         self.data = data
         self.rank = 0
         self.volatile = volatile


Test patch:
diff --git a/tests/test_variable.py b/tests/test_variable.py
--- a/tests/test_variable.py
+++ b/tests/test_variable.py
@@ -116,3 +116,7 @@ def test_unchain_backward_gpu_retain_grad(self):
         ret = self.create_linear_chain(3, False)
         ret[1].unchain_backward()
         self.check_backward((ret[1], ), (ret[2], ), (ret[3], ), False)
+
+    def test_invalid_value_type(self):
+        with self.assertRaises(AssertionError):
+            chainer.Variable(1)
Repository: chainer/chainer

Issue:
Remove `chainer-cuda-requirements` that is deprecated
`pip install chainer-cuda-deps` is recommended, and `chainer-cuda-requirements` is deprecated now. It will be removed in the future minor release.



Discussion:

Resolving patch:
diff --git a/chainer/requirements/__init__.py b/chainer/requirements/__init__.py
deleted file mode 100644
--- a/chainer/requirements/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import os
-
-
-def get_cuda_requirements_path():
-    return os.path.join(os.path.dirname(__file__), 'cuda-requirements.txt')
-
-
-def get_cuda_requirements():
-    with open(get_cuda_requirements_path()) as f:
-        return f.read()
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -12,11 +12,8 @@
               'chainer.cudnn',
               'chainer.functions',
               'chainer.optimizers',
-              'chainer.requirements',
               'chainer.utils'],
-    package_data={'chainer.requirements': ['cuda-requirements.txt']},
     install_requires=['numpy',
                       'six>=1.9.0'],
-    scripts=['scripts/chainer-cuda-requirements'],
     tests_require=['nose'],
 )


Test patch:
Repository: chainer/chainer

Issue:
MSE returns float64 value
MSE returns float64. It propagates backward, and cause a type error.

Thanks @ktnyt
https://gist.github.com/ktnyt/379cc31c29cfb5bdc9a0



Discussion:

Resolving patch:
diff --git a/chainer/functions/mean_squared_error.py b/chainer/functions/mean_squared_error.py
--- a/chainer/functions/mean_squared_error.py
+++ b/chainer/functions/mean_squared_error.py
@@ -12,7 +12,7 @@ def forward_cpu(self, inputs):
         x0, x1 = inputs
         self.diff = x0 - x1
         diff = self.diff.ravel()
-        return numpy.array([diff.dot(diff) / diff.size]),
+        return numpy.array(diff.dot(diff) / diff.size, numpy.float32),
 
     def forward_gpu(self, inputs):
         x0, x1 = inputs


Test patch:
diff --git a/tests/functions_tests/test_mean_squared_error.py b/tests/functions_tests/test_mean_squared_error.py
--- a/tests/functions_tests/test_mean_squared_error.py
+++ b/tests/functions_tests/test_mean_squared_error.py
@@ -23,7 +23,9 @@ def check_forward(self, x0_data, x1_data):
         x0 = chainer.Variable(x0_data)
         x1 = chainer.Variable(x1_data)
         loss = functions.mean_squared_error(x0, x1)
-        loss_value = float(cuda.to_cpu(loss.data))
+        loss_value = cuda.to_cpu(loss.data)
+        self.assertEqual(loss_value.dtype, numpy.float32)
+        self.assertEqual(loss_value.shape, ())
 
         # Compute expected value
         loss_expect = 0.
@@ -53,6 +55,8 @@ def check_backward(self, x0_data, x1_data):
 
         gradient_check.assert_allclose(gx0, x0.grad)
         gradient_check.assert_allclose(gx1, x1.grad)
+        self.assertEqual(x0.grad.dtype, numpy.float32)
+        self.assertEqual(x1.grad.dtype, numpy.float32)
 
     def test_backward_cpu(self):
         self.check_backward(self.x0, self.x1)
Repository: chainer/chainer

Issue:
Stop using OpenCV to just reading a JPEG file in the ImageNet example
Current ImageNet example uses the cv2 package to just load JPEG image files. This is overkill.



Discussion:

Resolving patch:
diff --git a/examples/imagenet/compute_mean.py b/examples/imagenet/compute_mean.py
--- a/examples/imagenet/compute_mean.py
+++ b/examples/imagenet/compute_mean.py
@@ -2,8 +2,8 @@
 import argparse
 import sys
 
-import cv2
 import numpy
+from PIL import Image
 import six.moves.cPickle as pickle
 
 
@@ -17,8 +17,7 @@
 count = 0
 for line in open(args.dataset):
     filepath = line.strip().split()[0]
-    image = cv2.imread(filepath)
-    image = image[:, :, [2, 1, 0]].transpose(2, 0, 1)
+    image = numpy.asarray(Image.open(filepath)).transpose(2, 0, 1)
     if sum_image is None:
         sum_image = numpy.ndarray(image.shape, dtype=numpy.float32)
         sum_image[:] = image
diff --git a/examples/imagenet/train_imagenet.py b/examples/imagenet/train_imagenet.py
--- a/examples/imagenet/train_imagenet.py
+++ b/examples/imagenet/train_imagenet.py
@@ -17,8 +17,8 @@
 import threading
 import time
 
-import cv2
 import numpy as np
+from PIL import Image
 import six
 import six.moves.cPickle as pickle
 from six.moves import queue
@@ -101,7 +101,7 @@ def load_image_list(path):
 
 
 def read_image(path, center=False, flip=False):
-    image = cv2.imread(path).transpose(2, 0, 1)
+    image = np.asarray(Image.open(path)).transpose(2, 0, 1)
     if center:
         top = left = cropwidth / 2
     else:
@@ -110,7 +110,7 @@ def read_image(path, center=False, flip=False):
     bottom = model.insize + top
     right = model.insize + left
 
-    image = image[[2, 1, 0], top:bottom, left:right].astype(np.float32)
+    image = image[:, top:bottom, left:right].astype(np.float32)
     image -= mean_image[:, top:bottom, left:right]
     image /= 255
     if flip and random.randint(0, 1) == 0:
diff --git a/examples/modelzoo/evaluate_caffe_net.py b/examples/modelzoo/evaluate_caffe_net.py
--- a/examples/modelzoo/evaluate_caffe_net.py
+++ b/examples/modelzoo/evaluate_caffe_net.py
@@ -13,8 +13,8 @@
 import os
 import sys
 
-import cv2
 import numpy as np
+from PIL import Image
 
 import chainer
 from chainer import cuda
@@ -92,8 +92,7 @@ def forward(x, t):
 accum_loss = 0
 accum_accuracy = 0
 for path, label in dataset:
-    # TODO(beam2d): Remove dependency on OpenCV
-    image = cv2.imread(path).transpose(2, 0, 1)
+    image = np.asarray(Image.open(path)).transpose(2, 0, 1)[::-1]
     image = image[:, start:stop, start:stop].astype(np.float32)
     image -= mean_image
 


Test patch:
Repository: chainer/chainer

Issue:
scikits.cuda renamed to scikit-cuda, 0.5.0 released (and 0.042 removed from pypi)
You may wish to update chainer's installation instructions.



Discussion:
Thank you for reporting us. We will change the installation process as soon as possible.


Resolving patch:
diff --git a/chainer/cuda.py b/chainer/cuda.py
--- a/chainer/cuda.py
+++ b/chainer/cuda.py
@@ -42,7 +42,7 @@
 try:
     _requires = [
         'pycuda>=2014.1',
-        'scikits.cuda>=0.5.0b2,!=0.042',
+        'scikit-cuda>=0.5.0',
         'Mako',
         'six>=1.9.0',
     ]
diff --git a/cuda_deps/setup.py b/cuda_deps/setup.py
--- a/cuda_deps/setup.py
+++ b/cuda_deps/setup.py
@@ -12,7 +12,7 @@
     install_requires=[
         'chainer',
         'pycuda>=2014.1',
-        'scikits.cuda>=0.5.0b2,!=0.042',
+        'scikit-cuda>=0.5.0',
         'Mako',
         'six>=1.9.0',
     ],


Test patch:
Repository: chainer/chainer

Issue:
Use `skcuda` module instead of `scikits.cuda`
`scikits.cuda` module is deprecated. Replace it with `skcuda`.



Discussion:

Resolving patch:
diff --git a/chainer/cuda.py b/chainer/cuda.py
--- a/chainer/cuda.py
+++ b/chainer/cuda.py
@@ -1,4 +1,4 @@
-"""Device, context and memory management on PyCUDA and scikits.cuda.
+"""Device, context and memory management on PyCUDA and scikit-cuda.
 
 Chainer uses PyCUDA facilities (with very thin wrapper) to exploit the speed of
 GPU computation. Following modules and classes are imported to :mod:`cuda`
@@ -8,11 +8,11 @@
 ============================ =================================
  imported name                original name
 ============================ =================================
- ``chainer.cuda.cublas``      :mod:`scikits.cuda.cublas`
+ ``chainer.cuda.cublas``      :mod:`skcuda.cublas`
  ``chainer.cuda.cumath``      :mod:`pycuda.cumath`
  ``chainer.cuda.curandom``    :mod:`pycuda.curandom`
- ``chainer.cuda.culinalg``    :mod:`scikits.cuda.linalg`
- ``chainer.cuda.cumisc``      :mod:`scikits.cuda.misc`
+ ``chainer.cuda.culinalg``    :mod:`skcuda.linalg`
+ ``chainer.cuda.cumisc``      :mod:`skcuda.misc`
  ``chainer.cuda.gpuarray``    :mod:`pycuda.gpuarray`
 
  ``chainer.cuda.Context``     :mod:`pycuda.driver.Context`
@@ -55,16 +55,16 @@
     import pycuda.gpuarray
     import pycuda.reduction
     import pycuda.tools
-    import scikits.cuda.cublas
-    import scikits.cuda.linalg
-    import scikits.cuda.misc
+    import skcuda.cublas
+    import skcuda.linalg
+    import skcuda.misc
     available = True
 
-    cublas = scikits.cuda.cublas
+    cublas = skcuda.cublas
     cumath = pycuda.cumath
     curandom = pycuda.curandom
-    culinalg = scikits.cuda.linalg
-    cumisc = scikits.cuda.misc
+    culinalg = skcuda.linalg
+    cumisc = skcuda.misc
     cutools = pycuda.tools
     gpuarray = pycuda.gpuarray
 except pkg_resources.ResolutionError as e:
@@ -123,7 +123,7 @@ def init(device=None):
 
     .. warning::
 
-       This function also initializes PyCUDA and scikits.cuda. Since these
+       This function also initializes PyCUDA and scikit-cuda. Since these
        packages do not support forking after initialization, do not call this
        function before forking the process.
 
@@ -913,7 +913,7 @@ def __exit__(self, typ, value, traceback):
 
 
 def using_cumisc(handle=None):
-    """Temporarily set chainer's CUBLAS handle to scikits.cuda.
+    """Temporarily set chainer's CUBLAS handle to scikit-cuda.
 
     The usage is similar to :func:`using_device`.
 
diff --git a/docs/source/conf.py b/docs/source/conf.py
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -313,6 +313,6 @@
     'python': ('https://docs.python.org/2/', None),
     'numpy': ('http://docs.scipy.org/doc/numpy/', None),
     'pycuda': ('http://documen.tician.de/pycuda/', None),
-    'scikits.cuda': ('http://scikit-cuda.readthedocs.org/en/latest/', None),
+    'skcuda': ('http://scikit-cuda.readthedocs.org/en/latest/', None),
     'sklearn': ('http://scikit-learn.org/stable/', None),
 }


Test patch: