('Connection aborted.', OSError(89, 'Function not implemented')) in version 2.13.0

Version 2.13.0 request.get() function thrown an exception with the message,
`('Connection aborted.', OSError(89, 'Function not implemented'))`

Reverting to version 2.12.5/4 resolved the issue.

Python Version: 3.5.2
OS: entware ng on asuswrt

Could you provide a full traceback? Or some kind of reproduction code? Are you running with gevent/eventlet? Do you have PyOpenSSL installed?

I have a theory, and my theory is that the Python you have on entware-ng is exposing one of the more complex selector syscalls (hard to know which because I can't see what OS entware considers to be its base, but it could *easily* be poll, if not epoll or kqueue), but does not actually support it.

It'd be really nice to get a whole traceback, but if you can't do it can you show me what selectors are present? That is, in a Python shell, run:

```python
import select
print(select.select)
print(select.poll)
print(select.epoll)
print(select.kqueue)
```

To be frank, I'm not a Python dev and is currently facing this issue while using Flexget. The code in Flexget that triggers the exception is,
```
response = requests.get(self.base_url, params=params)
```

I've run the command you mentioned above and the result is as follow,
```
Python 3.6.0 (default, Feb 17 2017, 13:43:51)
[GCC 5.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import select
>>> print(select.select)
<built-in function select>
>>> print(select.poll)
<built-in function poll>
>>> print(select.epoll)
<class 'select.epoll'>
>>> print(select.kqueue)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'select' has no attribute 'kqueue'
```

I'll be happy to perform whatever tasks you ask of me to resolve this issue.

Ok, so `poll` and `epoll` seem to be the problems there. Do you mind running this Python code quickly?

```python
import socket
from requests.packages.urllib3.util import wait

s = socket.create_connection(('httpbin.org', 80))
print(wait.wait_for_write([s])
```

Here's the result. Seems like we're on the right track,
```
Python 3.6.0 (default, Feb 17 2017, 13:43:51)
[GCC 5.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> from requests.packages.urllib3.util import wait
>>> s = socket.create_connection(('httpbin.org', 80))
>>> print(wait.wait_for_write([s])
... )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/lib/python3.6/site-packages/requests/packages/urllib3/util/wait.py", line 40, in wait_for_write
    return _wait_for_io_events(socks, EVENT_WRITE, timeout)
  File "/opt/lib/python3.6/site-packages/requests/packages/urllib3/util/wait.py", line 22, in _wait_for_io_events
    with DefaultSelector() as selector:
  File "/opt/lib/python3.6/site-packages/requests/packages/urllib3/util/selectors.py", line 364, in __init__
    self._epoll = select.epoll()
OSError: [Errno 89] Function not implemented
```


Aha, ok, so we're getting there. An explanation:

Requests, when using PyOpenSSL, needs to implement some logic to do non-blocking I/O. We do this by looking for the best available selector on the platform and using that. We check for the available selectors by looking at which names are defined in the `select` namespace.

It seems that this Python distribution is defining the `epoll` selector, but cannot actually *use* it. This is probably because the underlying OS defines the `epoll` syscall but cannot actually use it, and returns `ENOSYS`.

Now, we can work on this by extending our `selectors` module to actually attempt to create a selector on startup and looking to see if that works (/cc @SethMichaelLarson), but in the short term you can resolve this by running a small monkeypatch just after you import requests.

In your code, if you add:

```python
import requests.packages.urllib3.util.selectors
requests.packages.urllib3.util.selectors.DefaultSelector = requests.packages.urllib3.util.selectors.SelectSelector
```

Before you start running your main code, that should re-introduce the older behaviour. If `poll` works on your OS, you may want to use `PollSelector` instead of `SelectSelector`.

Longer term, you should consider reporting a bug upstream to suggest that they remove the definitions for syscalls that don't actually work on their platform: I imagine they'll run into trouble elsewhere.

Ok, thanks.

I'm not so familiar with Linux so who should I be reporting this issue to?
- Firmware dev (http://asuswrt.lostrealm.ca/), or
- Entware NG dev (https://github.com/Entware-ng/Entware-ng)

Entware is installed onto the firmware (I don't even know my sentence is correct or not). Then via Entware's opkg exec, I installed Python3.

I would *guess* that the firmware developer is the place to go. One thing that might be useful information to provide the firmware developer, if you can, is a copy of the Python script I wrote you above (the one that calls `wait_for_write`) along with the `strace` output that produces. It should show the epoll syscall failing.

Ok, thanks for the help.

@Lukasa, while I think this should be closed (since it's not a Requests bug), I also wonder if the selectors code in urllib3 should attempt to fallback to less efficient methods in cases like this and only then let the OS error bubble up. Thoughts?

@sigmavirus24 Yeah, so I said a few comments ago that the selectors module can detect this case by actually trying to *instantiate* the selectors, at least for some of them where the selector itself is an FD (we can't do it so easily for poll/select). That's why I tagged @SethMichaelLarson: this is a bit his baby.

I clearly need to finish my coffee before commenting. =)

Fix for this is coming within shazow/urllib3#1128. Basically when determining what `DefaultSelector` should be we'll attempt to allocate a single object in addition to checking whether `select` advertises the service if using non-`select.select` selectors. I would hope most firmware developers would not advertise `select.select` if it's not available because it's much more of a drastic difference from a usual platform.