Skip to content
This repository was archived by the owner on Nov 23, 2017. It is now read-only.

Conversation

@sethmlarson
Copy link

@sethmlarson sethmlarson commented Sep 12, 2016

Some platforms define SO_REUSEPORT but do not implement it, resulting in cryptic OSErrors when trying to use socket.SO_REUSEPORT. This PR would solve that issue for all platforms that implement but don't define a usable SO_REUSEPORT. More info in Python issue 26858. See issue #352 .

Edit: I have signed the PSF Contributor Agreement

socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if reuse_port:
if not hasattr(socket, 'SO_REUSEPORT'):
if not hasattr(socket, "SO_REUSEPORT") or \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't you use just if not _HAS_USABLE_SO_REUSEPORT:?

(Also, please don't use \ for continuations, use an extra pair of (). PEP 8 please!

Copy link
Author

@sethmlarson sethmlarson Sep 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of all the mock patching in the test cases. Patching the socket module in the *_test_nosoreuseport prevents that atm. And I will change the bracing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched the order of the check, should still pass tests but also will not have to check hasattr() each call in real use.

@gvanrossum
Copy link
Member

I think those tests need to be fixed then. There should be only one way to test for SO_REUSEPORT.

@sethmlarson
Copy link
Author

@gvanrossum Alternative is to do the check inline when the reuse_port option is specified? Wouldn't be a performance hit as create_server and create_unix_server probably get used once and forgotten.

@gvanrossum
Copy link
Member

Hm, maybe just catch the exception and translate it into the same ValueError (actually a slightly similar message so we can tell the difference).

@sethmlarson
Copy link
Author

@gvanrossum I switched to catching the exception inline, I also added a test to test an ill-defined SO_REUSEPORT as with the issue this PR fixes.

@gvanrossum
Copy link
Member

LGTM now. @1st1 what do you think?

@1st1
Copy link
Member

1st1 commented Sep 12, 2016

LGTM. Can we merge this after b1?

@sethmlarson
Copy link
Author

This also closes issue #352 as mentioned above. Can be closed if accepted but awaiting merge?

@gvanrossum
Copy link
Member

gvanrossum commented Sep 12, 2016 via email

@1st1
Copy link
Member

1st1 commented Sep 15, 2016

Pushed in 610c03f. Thanks!

@1st1 1st1 closed this Sep 15, 2016
@1st1
Copy link
Member

1st1 commented Sep 15, 2016

See also https://hg.python.org/cpython/rev/c1c247cf3488/. Looks like this is your first commit to CPython, congrats if so!

BTW, did you sign Python Contributor Agreement?

@sethmlarson
Copy link
Author

sethmlarson commented Sep 15, 2016

@1st1 Thank you! This is my first commit and I signed it the day I submitted this PR. See my comment above in the PR.

@Dakkaron
Copy link

I am sorry, but to me this fix actually causes more problems than it fixes.

Yes, the old error message is rather cryptic and the new exception message is way better, but changing the exception type seems wrong to me. Yes, ValueError might fit better, but changing the type will cause a lot of problems.

  • Since an exception is raised as before, code that does not catch anything here will still fail.
  • Old code that caught the old OSError is now broken, since it does not catch ValueError.
  • New code that catches only ValueError will fail on older versions of Python, since it does not catch OSError
  • From what I can see, the documentation mentions neither OSError nor ValueError, so if a programmer wants to make sure they have proper exception handling for that function, they must check the source, which, depending on their Python version, will say either OSError or ValueError, which will break if used on a different version of Python.

My recommendation would be to catch the old OSError and then raise a new OSError with the improved error message.

@sethmlarson
Copy link
Author

@Dakkaron I made this change for consistency reasons so that trying to use reuse_port on a unsupporting platform and a platform that advertises support but is actually horribly broken raise the same error type. I didn't see the value in having to catch two different error types for a very similar situation (ie you can't use SO_REUSEPORT).

If you think this should be changed you can raise an issue on the Python tracker.

@Dakkaron
Copy link

Sorry, my bad, I didn't notice that the old version already raised a ValueError, so your version just removes one exception type. So your change does actually help.

@sethmlarson
Copy link
Author

Glad I could clarify. :)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants