internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: pallets/werkzeug

Issue:
dev server sets wrong HTTP_HOST when path starts with a double slash
See https://github.com/mitsuhiko/flask/issues/1639#issuecomment-162305541

```
if request_url.netloc:
    environ['HTTP_HOST'] = request_url.netloc
```

This code was added in 7486573d / #248. Do absolute http requests even make sense except for HTTP proxies?



Discussion:
As reported in the linked issue, this can lead to weird behavior.  http://127.0.0.1:5000//google.com will redirect to Google.

That should definitely be fixed.

Perhaps just change `if request_url.netloc` to `if request_url.scheme and request_url.netloc`.

Triaging: blocker bug


Resolving patch:
diff --git a/werkzeug/serving.py b/werkzeug/serving.py
--- a/werkzeug/serving.py
+++ b/werkzeug/serving.py
@@ -125,7 +125,7 @@ def shutdown_server():
             if key not in ('HTTP_CONTENT_TYPE', 'HTTP_CONTENT_LENGTH'):
                 environ[key] = value
 
-        if request_url.netloc:
+        if request_url.scheme and request_url.netloc:
             environ['HTTP_HOST'] = request_url.netloc
 
         return environ


Test patch:
diff --git a/tests/test_serving.py b/tests/test_serving.py
--- a/tests/test_serving.py
+++ b/tests/test_serving.py
@@ -24,6 +24,11 @@
 except ImportError:
     watchdog = None
 
+try:
+    import httplib
+except ImportError:
+    from http import client as httplib
+
 import requests
 import requests.exceptions
 import pytest
@@ -39,6 +44,36 @@ def test_serving(dev_server):
     assert b'Werkzeug/' + version.encode('ascii') in rv
 
 
+def test_absolute_requests(dev_server):
+    server = dev_server('''
+    def app(environ, start_response):
+        assert environ['HTTP_HOST'] == 'surelynotexisting.example.com:1337'
+        assert environ['PATH_INFO'] == '/index.htm'
+        addr = environ['HTTP_X_WERKZEUG_ADDR']
+        assert environ['SERVER_PORT'] == addr.split(':')[1]
+        start_response('200 OK', [('Content-Type', 'text/html')])
+        return [b'YES']
+    ''')
+
+    conn = httplib.HTTPConnection(server.addr)
+    conn.request('GET', 'http://surelynotexisting.example.com:1337/index.htm#ignorethis',
+                 headers={'X-Werkzeug-Addr': server.addr})
+    res = conn.getresponse()
+    assert res.read() == b'YES'
+
+
+def test_double_slash_path(dev_server):
+    server = dev_server('''
+    def app(environ, start_response):
+        assert 'fail' not in environ['HTTP_HOST']
+        start_response('200 OK', [('Content-Type', 'text/plain')])
+        return [b'YES']
+    ''')
+
+    r = requests.get(server.url + '//fail')
+    assert r.content == b'YES'
+
+
 def test_broken_app(dev_server):
     server = dev_server('''
     def app(environ, start_response):
Repository: pallets/werkzeug

Issue:
Add an 'extras_require' entry to setup.py for watchdog
The reloader feature has an optional dependency on the watchdog package:
http://werkzeug.pocoo.org/docs/0.11/serving/#reloader

Whilst people can just add 'watchdog' to their requirements files, it's clearer to specifically add an `extras_require` entry for it to setup.py, which allows people to instead add eg `Werkzeug[watchdog]` to their requirements file, which more clearly shows why the dependency is required.

In addition, should Werkzeug ever need a specific version of watchdog in the future (eg due to backwards incompatibilities), then the `extras_require` entry could be updated with a version range, causing zero breakage for people who'd used the `Werkzeug[watchdog]` form in their requirements file.

I'll open a PR for this shortly :-)



Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -109,6 +109,9 @@ def run(self):
         'Topic :: Software Development :: Libraries :: Python Modules'
     ],
     packages=['werkzeug', 'werkzeug.debug', 'werkzeug.contrib'],
+    extras_require={
+        'watchdog': ['watchdog'],
+    },
     cmdclass=dict(test=TestCommand),
     include_package_data=True,
     zip_safe=False,


Test patch:
Repository: pallets/werkzeug

Issue:
HTML text can vanish in the Werkzeug interactive debugger
(I feel like I might have raised this bug before, but I can’t find it if I have.)

If you’re using the interactive debugger and you type a command includes something that looks like an HTML tag, it gets treated as literal HTML text. This causes it to disappear once you’ve finished the command, which makes for an inconsistent history.

Here’s a simple repro:

![screen shot 2016-11-07 at 07 25 38](https://cloud.githubusercontent.com/assets/301220/20049525/6b86fc32-a4bb-11e6-984b-c713b4796d08.png)

The HTML tag should continue to be visible after executing your command.

Python/Werkzeug versions, although I know I’ve seen this on older versions too:

```console
$ python --version
Python 3.5.0

$ pip freeze | grep Werkzeug
Werkzeug==0.11.10
```


Discussion:
If anybody fancies having a crack at this, I suspect the fix needs to go into https://github.com/pallets/werkzeug/blob/master/werkzeug/debug/shared/debugger.js

I made a similar change in #994, but my JavaScript-fu is insufficient to fix this bug. Although it’s possible to swap out the `&lt;` and `&gt;` entities in the printed text fairly easily, doing so will also corrupt the history, so pressing up arrow shows you the last command was `print('&lt;foo&gt;')`.

I suspect the answer is to go after the `appendTo(consoleNode);` and intercept whatever gets inserted there, but I haven’t been able to do so successfully.

Confirmed.

No I think this needs to be fixed serverside. The entire HTML output for the console is generated serverside, JS needs to trust serverside HTML.

Ah, I saw the `<div class="output">[console ready]</div>` and assumed the display of the console was being handled client-side.


Resolving patch:
diff --git a/werkzeug/debug/console.py b/werkzeug/debug/console.py
--- a/werkzeug/debug/console.py
+++ b/werkzeug/debug/console.py
@@ -173,7 +173,7 @@ def runsource(self, source):
                 del self.buffer[:]
         finally:
             output = ThreadedStream.fetch()
-        return prompt + source + output
+        return prompt + escape(source) + output
 
     def runcode(self, code):
         try:


Test patch:
Repository: pallets/werkzeug

Issue:
IPython 5.0: DeprecationWarning for 'global_ns' keyword argument
Says it's a Warning but it's actually fatal, with the shell not starting at all.

DeprecationWarning: 'global_ns' keyword argument is deprecated, and has been removed in IPython 5.0 use `module` keyword argument instead.

```
venv/local/lib/python2.7/site-packages/werkzeug/script.pyc in action(ipython)
    275                 pass
    276             else:
--> 277                 sh(global_ns={}, local_ns=namespace)
    278                 return
    279         from code import interact

venv/local/lib/python2.7/site-packages/IPython/terminal/embed.pyc in __call__(self, header, local_ns, module, dummy, stack_depth, global_ns, compile_flags)
    159         # our call and get the original caller's namespaces.
    160         self.mainloop(local_ns, module, stack_depth=stack_depth,
--> 161                       global_ns=global_ns, compile_flags=compile_flags)
    162 
    163         self.banner2 = self.old_banner2

```

```
$ ipython --version
5.1.0
```

```
$ pip show werkzeug  # irrelevant output reducted

---
...
Version: 0.11.11
...
```

IPython 5.0: DeprecationWarning for 'global_ns' keyword argument
Says it's a Warning but it's actually fatal, with the shell not starting at all.

DeprecationWarning: 'global_ns' keyword argument is deprecated, and has been removed in IPython 5.0 use `module` keyword argument instead.

```
venv/local/lib/python2.7/site-packages/werkzeug/script.pyc in action(ipython)
    275                 pass
    276             else:
--> 277                 sh(global_ns={}, local_ns=namespace)
    278                 return
    279         from code import interact

venv/local/lib/python2.7/site-packages/IPython/terminal/embed.pyc in __call__(self, header, local_ns, module, dummy, stack_depth, global_ns, compile_flags)
    159         # our call and get the original caller's namespaces.
    160         self.mainloop(local_ns, module, stack_depth=stack_depth,
--> 161                       global_ns=global_ns, compile_flags=compile_flags)
    162 
    163         self.banner2 = self.old_banner2

```

```
$ ipython --version
5.1.0
```

```
$ pip show werkzeug  # irrelevant output reducted

---
...
Version: 0.11.11
...
```



Discussion:

Resolving patch:
diff --git a/werkzeug/script.py b/werkzeug/script.py
--- a/werkzeug/script.py
+++ b/werkzeug/script.py
@@ -279,14 +279,14 @@ def action(ipython=use_ipython):
             try:
                 try:
                     from IPython.frontend.terminal.embed import InteractiveShellEmbed
-                    sh = InteractiveShellEmbed(banner1=banner)
+                    sh = InteractiveShellEmbed.instance(banner1=banner)
                 except ImportError:
                     from IPython.Shell import IPShellEmbed
                     sh = IPShellEmbed(banner=banner)
             except ImportError:
                 pass
             else:
-                sh(global_ns={}, local_ns=namespace)
+                sh(local_ns=namespace)
                 return
         from code import interact
         interact(banner, local=namespace)


Test patch:
Repository: pallets/werkzeug

Issue:
TypeConversionDict should not return default for KeyError during conversion
From #1078. If the conversion function raises a `KeyError`, that should be propagated instead of returning the default.

~~~python
switch = {'a': 1}
data = TypeConversionDict(good='a', bad='b')
out = data.get('good', 'default', lambda v: switch[v])
assert out == 1
out = data.get('bad', 'default', lambda v: switch[v])
assert out != 'default' # shouldn't get here, should propagate KeyError from converter
~~~


Discussion:
Let's keep this out of the maintenance branch since the bugfix isn't critical but potentially breaks code.

Resolving patch:
diff --git a/werkzeug/datastructures.py b/werkzeug/datastructures.py
--- a/werkzeug/datastructures.py
+++ b/werkzeug/datastructures.py
@@ -299,10 +299,13 @@ def get(self, key, default=None, type=None):
         """
         try:
             rv = self[key]
-            if type is not None:
+        except KeyError:
+            return default
+        if type is not None:
+            try:
                 rv = type(rv)
-        except (KeyError, ValueError):
-            rv = default
+            except ValueError:
+                rv = default
         return rv
 
 


Test patch:
diff --git a/tests/test_datastructures.py b/tests/test_datastructures.py
--- a/tests/test_datastructures.py
+++ b/tests/test_datastructures.py
@@ -545,6 +545,24 @@ def test_iterables(self):
         assert sorted(iterkeys(ab)) == ["key_a", "key_b"]
 
 
+class TestTypeConversionDict(object):
+    storage_class = datastructures.TypeConversionDict
+
+    def test_value_conversion(self):
+        d = self.storage_class(foo='1')
+        assert d.get('foo', type=int) == 1
+
+    def test_return_default_when_conversion_is_not_possible(self):
+        d = self.storage_class(foo='bar')
+        assert d.get('foo', default=-1, type=int) == -1
+
+    def test_propagate_exceptions_in_conversion(self):
+        d = self.storage_class(foo='bar')
+        switch = {'a': 1}
+        with pytest.raises(KeyError):
+            d.get('foo', type=lambda x: switch[x])
+
+
 class TestCombinedMultiDict(object):
     storage_class = datastructures.CombinedMultiDict
Repository: pallets/werkzeug

Issue:
Confusing exception when creating RedisCache with null params

```
#!/usr/bin/env python                                                            

from werkzeug.contrib.cache import RedisCache

cache = RedisCache(host=None, password=None)                                     
                                                               
cache.get("foo")
```

Expected: some sort of redis.exceptions.RedisError, like redis.exceptions.ConnectionError

What happens: `AttributeError: 'NoneType' object has no attribute 'get'`

I think the error should be at least a little more relevant, not sure how the code even gets to the `cache.get` line.


Discussion:
What behaviour would you expect? Raise an exception if `host` is `None` when creating the `RedisCache` instance? I don't think we can do anything if the password is incorrectly set to `None`...

Resolving patch:
diff --git a/werkzeug/contrib/cache.py b/werkzeug/contrib/cache.py
--- a/werkzeug/contrib/cache.py
+++ b/werkzeug/contrib/cache.py
@@ -560,6 +560,8 @@ class RedisCache(BaseCache):
     def __init__(self, host='localhost', port=6379, password=None,
                  db=0, default_timeout=300, key_prefix=None, **kwargs):
         BaseCache.__init__(self, default_timeout)
+        if host is None:
+            raise ValueError('RedisCache host parameter may not be None')
         if isinstance(host, string_types):
             try:
                 import redis


Test patch:
diff --git a/tests/contrib/cache/test_cache.py b/tests/contrib/cache/test_cache.py
--- a/tests/contrib/cache/test_cache.py
+++ b/tests/contrib/cache/test_cache.py
@@ -12,6 +12,7 @@
 
 import pytest
 
+from werkzeug._compat import text_type
 from werkzeug.contrib import cache
 
 try:
@@ -219,6 +220,11 @@ def test_compat(self, c):
         assert c._client.set(c.key_prefix + 'foo', '42')
         assert c.get('foo') == 42
 
+    def test_empty_host(self):
+        with pytest.raises(ValueError) as exc_info:
+            cache.RedisCache(host=None)
+        assert text_type(exc_info.value) == 'RedisCache host parameter may not be None'
+
 
 class TestMemcachedCache(CacheTests):
     _can_use_fast_sleep = False
Repository: pallets/werkzeug

Issue:
Body of 412 responses not sent since ETag handling was added
On HTTP error, the response includes a message such as:

```
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>413 Request Entity Too Large</title>
<h1>Request Entity Too Large</h1>
<p>The data value transmitted exceeds the capacity limit.</p>
```

Since Etag handling was added, 412 error response does not include this message anymore.

Below is the test script I used.

```python
#!/usr/bin/env python3

from werkzeug.exceptions import default_exceptions
from flask import Flask, abort


for http_exc in default_exceptions:

    app = Flask('test')
    client = app.test_client()

    @app.route('/')
    def test():
        abort(http_exc)

    response = client.get('/')
    assert response.status_code == http_exc

    if not response.get_data(as_text=True):
        raise ValueError('Missing data for HTTP error {}'.format(http_exc))
```

Feeding it to `git bisect` pointed me to https://github.com/pallets/werkzeug/commit/092e59a127de324517faa820e33b160372db8a85.
  


Discussion:
This is currently intentional because this is a side effect of how conditional requests are implemented.

Resolving patch:
diff --git a/werkzeug/wrappers.py b/werkzeug/wrappers.py
--- a/werkzeug/wrappers.py
+++ b/werkzeug/wrappers.py
@@ -1251,7 +1251,7 @@ def get_wsgi_headers(self, environ):
             # Per section 3.3.2 of RFC 7230, "a server MUST NOT send a Content-Length header field
             # in any response with a status code of 1xx (Informational) or 204 (No Content)."
             headers.remove('Content-Length')
-        elif status in (304, 412):
+        elif status == 304:
             remove_entity_headers(headers)
 
         # if we can determine the content length automatically, we
@@ -1291,7 +1291,7 @@ def get_app_iter(self, environ):
         """
         status = self.status_code
         if environ['REQUEST_METHOD'] == 'HEAD' or \
-           100 <= status < 200 or status in (204, 304, 412):
+           100 <= status < 200 or status in (204, 304):
             iterable = ()
         elif self.direct_passthrough:
             if __debug__:


Test patch:
diff --git a/tests/test_wrappers.py b/tests/test_wrappers.py
--- a/tests/test_wrappers.py
+++ b/tests/test_wrappers.py
@@ -597,7 +597,8 @@ def test_etag_response_412():
     # headers left and the status code would have to be 412
     resp = wrappers.Response.from_app(response, env)
     assert resp.status_code == 412
-    assert 'content-length' not in resp.headers
+    # Make sure there is a body still
+    assert resp.data != b''
 
     # make sure date is not overriden
     response = wrappers.Response('Hello World')
Repository: pallets/werkzeug

Issue:
parse_cookie(): Does not ignore empty cookies
```python
parse_cookie("foo=bar; ; abc=def")
{'foo': 'bar', '; abc': 'def'}
```

As you can see, instead of a cookie named `abc`, there is one named `; abc`. I came across this problem when I accidentally added an empty cookie in Chrome by calling `document.cookie = ""` from Javascript. Chrome then sent a `Cookie` header similar to the one above, which caused another cookie not to be found anymore.


Discussion:
Are you using the latest version of Werkzeug? Similar to #1118, although I'm not sure if completely empty keys were addressed. If they weren't a similar fix should be pretty straightforward, if you can submit one.

Resolving patch:
diff --git a/werkzeug/http.py b/werkzeug/http.py
--- a/werkzeug/http.py
+++ b/werkzeug/http.py
@@ -999,6 +999,8 @@ def parse_cookie(header, charset='utf-8', errors='replace', cls=None):
     def _parse_pairs():
         for key, val in _cookie_parse_impl(header):
             key = to_unicode(key, charset, errors, allow_none_charset=True)
+            if not key:
+                continue
             val = to_unicode(val, charset, errors, allow_none_charset=True)
             yield try_coerce_native(key), val
 


Test patch:
diff --git a/tests/test_http.py b/tests/test_http.py
--- a/tests/test_http.py
+++ b/tests/test_http.py
@@ -396,6 +396,18 @@ def test_bad_cookies(self):
             }
         )
 
+    def test_empty_keys_are_ignored(self):
+        strict_eq(
+            dict(http.parse_cookie(
+                'first=IamTheFirst ; a=1; a=2 ;second=andMeTwo; ; '
+            )),
+            {
+                'first': u'IamTheFirst',
+                'a': u'2',
+                'second': u'andMeTwo'
+            }
+        )
+
     def test_cookie_quoting(self):
         val = http.dump_cookie("foo", "?foo")
         strict_eq(val, 'foo="?foo"; Path=/')
Repository: pallets/werkzeug

Issue:
Why set the default value of path_info=None while it cannot be?
As stated in issue  #440, #857

``` python
def test_mapadapterpath_info_is_none(self):
        m = r.Map([])
        ma = m.bind('example.org', path_info=None)
        m.match(return_rule=True)   #==========> it will crash
```

I just inspect the code and have a question why set the default value of path_info as None when it cannot be?

``` python
def match(self, path_info=None, method=None, return_rule=False,
                query_args=None):
        ...
def bind(self, server_name, script_name=None, subdomain=None,
             url_scheme='http', default_method='GET', path_info=None,
             query_args=None):
        ...
```



Discussion:
it can be given either in bind or match,

it has to be given in at least one, the one in match overriding the one given in bind

As I think, it would be better to give a friendly raise when both None happened instead of a rough AttributeError confusing the user. Do you think so?

i tested based on your example in a python shell an got a 404,
maybe i needs a rule to trigger the behavior

are you up for creating a small pull request including a test and fix?


Resolving patch:
diff --git a/werkzeug/routing.py b/werkzeug/routing.py
--- a/werkzeug/routing.py
+++ b/werkzeug/routing.py
@@ -1534,6 +1534,9 @@ def bind(self, server_name, script_name=None, subdomain=None,
 
         .. versionadded:: 0.8
            `query_args` can now also be a string.
+
+        .. versionchanged:: 0.15
+            ``path_info`` defaults to ``'/'`` if ``None``.
         """
         server_name = server_name.lower()
         if self.host_matching:
@@ -1544,6 +1547,8 @@ def bind(self, server_name, script_name=None, subdomain=None,
             subdomain = self.default_subdomain
         if script_name is None:
             script_name = '/'
+        if path_info is None:
+            path_info = '/'
         try:
             server_name = _encode_idna(server_name)
         except UnicodeError:


Test patch:
diff --git a/tests/test_routing.py b/tests/test_routing.py
--- a/tests/test_routing.py
+++ b/tests/test_routing.py
@@ -879,6 +879,12 @@ def test_empty_path_info():
     assert excinfo.value.new_url == "http://example.com/"
 
 
+def test_both_bind_and_match_path_info_are_none():
+    m = r.Map([r.Rule(u'/', endpoint='index')])
+    ma = m.bind('example.org')
+    strict_eq(ma.match(), ('index', {}))
+
+
 def test_map_repr():
     m = r.Map([
         r.Rule(u'/wat', endpoint='enter'),
Repository: pallets/werkzeug

Issue:
Triggering a code reload during a PDB session breaks terminal input
Pylons and Django hit the same issue: https://github.com/Pylons/pyramid/issues/689

PR incoming to do exactly what they did 🤷‍♂️


Discussion:

Resolving patch:
diff --git a/werkzeug/_reloader.py b/werkzeug/_reloader.py
--- a/werkzeug/_reloader.py
+++ b/werkzeug/_reloader.py
@@ -259,6 +259,22 @@ def run(self):
     reloader_loops['auto'] = reloader_loops['watchdog']
 
 
+def ensure_echo_on():
+    """Ensure that echo mode is enabled. Some tools such as PDB disable
+    it which causes usability issues after reload."""
+    # tcgetattr will fail if stdin isn't a tty
+    if not sys.stdin.isatty():
+        return
+    try:
+        import termios
+    except ImportError:
+        return
+    attributes = termios.tcgetattr(sys.stdin)
+    if not attributes[3] & termios.ECHO:
+        attributes[3] |= termios.ECHO
+        termios.tcsetattr(sys.stdin, termios.TCSANOW, attributes)
+
+
 def run_with_reloader(main_func, extra_files=None, interval=1,
                       reloader_type='auto'):
     """Run the given function in an independent python interpreter."""
@@ -267,6 +283,7 @@ def run_with_reloader(main_func, extra_files=None, interval=1,
     signal.signal(signal.SIGTERM, lambda *args: sys.exit(0))
     try:
         if os.environ.get('WERKZEUG_RUN_MAIN') == 'true':
+            ensure_echo_on()
             t = threading.Thread(target=main_func, args=())
             t.setDaemon(True)
             t.start()


Test patch: