Repository: pallets/werkzeug

Issue:
master (0.15.dev) is broken on Windows
To reproduce, run the example from the readme:

```python
from werkzeug.wrappers import Request, Response

@Request.application
def application(request):
    return Response('Hello, World!')

if __name__ == '__main__':
    from werkzeug.serving import run_simple
    run_simple('localhost', 4000, application)
```

On Windows, I get the following error:
```
Traceback (most recent call last):
  File "zzz.py", line 11, in <module>
    run_simple('localhost', 4000, application)
  File "...\werkzeug\serving.py", line 880, in run_simple
    inner()
  File "...\werkzeug\serving.py", line 836, in inner
    fd=fd)
  File "...\werkzeug\serving.py", line 723, in make_server
    passthrough_errors, ssl_context, fd=fd)
  File "...\werkzeug\serving.py", line 624, in __init__
    server_address = get_sockaddr(host, int(port), self.address_family)
  File "...\werkzeug\serving.py", line 593, in get_sockaddr
    if family == socket.AF_UNIX:
AttributeError: module 'socket' has no attribute 'AF_UNIX'
```

It seems it was broken in https://github.com/pallets/werkzeug/commit/d2140a4b9a4f0b9c9afc0a2fbff55acb5399eec6#diff-5561c422f09af0c38ec8260f0d17a52dR593
(merged in #1019)

------

Version info:
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Werkzeug 0.15.dev (d2140a4 and later)



Discussion:
I hit this today, I kludged in a hack to get going, sharing here.

    diff --git a/werkzeug/serving.py b/werkzeug/serving.py
    index 6fb43fb7..0561b42e 100644
    --- a/werkzeug/serving.py
    +++ b/werkzeug/serving.py
    @@ -86,6 +86,9 @@ else:
         class ForkingMixIn(object):
             pass

    +if not hasattr(socket, 'AF_UNIX'):
    +    socket.AF_UNIX = -99  # FIXME kludge
    +
     # important: do not use relative imports here or python -m will break
     import werkzeug
     from werkzeug._internal import _log
    @@ -591,7 +594,7 @@ def select_address_family(host, port):
     def get_sockaddr(host, port, family):
         """Return a fully qualified socket address that can be passed to
         :func:`socket.bind`."""
    -    if family == socket.AF_UNIX:
    +    if hasattr(socket, 'AF_UNIX') and family == socket.AF_UNIX:
             return host.split('://', 1)[1]
         try:
             res = socket.getaddrinfo(

the 2nd patch was my first attempt but there where a bunch of other places where socket.AF_UNIX was used so went with a quick-and-dirty to get my experiment up and running. DO NOT USE the monkey patch! ;)

Works for me with Python 2.7.13 and Python 3.6.1.


Resolving patch:
diff --git a/werkzeug/serving.py b/werkzeug/serving.py
--- a/werkzeug/serving.py
+++ b/werkzeug/serving.py
@@ -86,6 +86,12 @@ def _get_openssl_crypto_module():
     class ForkingMixIn(object):
         pass
 
+try:
+    af_unix = socket.AF_UNIX
+except AttributeError:
+    af_unix = None
+
+
 # important: do not use relative imports here or python -m will break
 import werkzeug
 from werkzeug._internal import _log
@@ -591,7 +597,7 @@ def select_address_family(host, port):
 def get_sockaddr(host, port, family):
     """Return a fully qualified socket address that can be passed to
     :func:`socket.bind`."""
-    if family == socket.AF_UNIX:
+    if family == af_unix:
         return host.split('://', 1)[1]
     try:
         res = socket.getaddrinfo(
@@ -626,11 +632,10 @@ def __init__(
 
         # remove socket file if it already exists
         if (
-            self.address_family == socket.AF_UNIX
+            self.address_family == af_unix
             and os.path.exists(server_address)
         ):
             os.unlink(server_address)
-
         HTTPServer.__init__(self, server_address, handler)
 
         self.app = app
@@ -820,7 +825,7 @@ def run_simple(hostname, port, application, use_reloader=False,
     def log_startup(sock):
         display_hostname = hostname not in ('', '*') and hostname or 'localhost'
         quit_msg = '(Press CTRL+C to quit)'
-        if sock.family is socket.AF_UNIX:
+        if sock.family == af_unix:
             _log('info', ' * Running on %s %s', display_hostname, quit_msg)
         else:
             if ':' in display_hostname:
@@ -872,7 +877,7 @@ def inner():
                 log_startup(s)
             else:
                 s.close()
-                if address_family is socket.AF_UNIX:
+                if address_family == af_unix:
                     _log('info', "Unlinking %s" % server_address)
                     os.unlink(server_address)
 


Test patch: