Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-88427: Deprecate socket.SocketType #126272

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open

Conversation

rruuaanng
Copy link
Contributor

@rruuaanng rruuaanng commented Nov 1, 2024

I propose to deprecate socket.SocketType. There's no reason to publicly expose _socket.socket separately from socket.socket, the only type that moat users should care about.
SocketType isn't needed for type checking; socket.socket is itself a class and can be used in type annotations.

cc @JelleZijlstra

@rruuaanng rruuaanng changed the title gh88427: Deprecated socket.SocketType gh-88427: Deprecated socket.SocketType Nov 1, 2024
Copy link
Member

@ZeroIntensity ZeroIntensity left a comment

Choose a reason for hiding this comment

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

SocketType isn't deprecated right now, so we can't remove it yet.

Please update the PR to raise a DeprecationWarning when accessing a SocketType (you can do this via a PEP-562 __getattr__), and then add the documentation notes.

@rruuaanng
Copy link
Contributor Author

Maybe we can wait for the promoter to answer. I won't open this PR before I decide whether to abandon or remove it.

@JelleZijlstra
Copy link
Member

I looked at the code again and agree with my opinion from 2021: it should be deprecated and eventually removed.

It could be useful to do a code search (e.g., GitHub code search, Hugo's top 5k pypi packages tool) to see how the name is being used.

A possible approach to deprecation could be to remove the current line adding it to _socket, and add a module __getattr__ to both the _socket and socket modules that raises a DeprecationWarning and then returns _socket.socket.

@rruuaanng
Copy link
Contributor Author

Okay, I'll re-revise this PR so that it throws a warning when calling this type. Call me back in this PR when we consider removing it in the future :)

Doc/library/socket.rst Outdated Show resolved Hide resolved
Lib/socket.py Outdated Show resolved Hide resolved
Lib/socket.py Outdated Show resolved Hide resolved
Doc/library/socket.rst Outdated Show resolved Hide resolved
Lib/socket.py Show resolved Hide resolved
@rruuaanng
Copy link
Contributor Author

It seems that the module __getattr__ only works for attributes that do not exist, which makes it necessary to remove the export in socketmodule. But it triggers a deprecation warning. Emmm...

@picnixz
Copy link
Contributor

picnixz commented Nov 2, 2024

It seems that the module getattr only works for attributes that do not exist, which makes it necessary to remove the export in socketmodule. But it triggers a deprecation warning. Emmm...

It works for any kind of attributes. Please, read PEP-562 for examples on how to use it.

@rruuaanng
Copy link
Contributor Author

rruuaanng commented Nov 2, 2024

It seems that the module getattr only works for attributes that do not exist, which makes it necessary to remove the export in socketmodule. But it triggers a deprecation warning. Emmm...

It works for any kind of attributes. Please, read PEP-562 for examples on how to use it.

I read the document and modified it. But why does it trigger this

Traceback (most recent call last):
  File "D:\a\cpython\cpython\Lib\test\pythoninfo.py", line 1062, in collect_info
    collect_func(info_add)
    ~~~~~~~~~~~~^^^^^^^^^^
  File "D:\a\cpython\cpython\Lib\test\pythoninfo.py", line 727, in collect_test_socket
    from test import test_socket
  File "D:\a\cpython\cpython\Lib\test\test_socket.py", line 201, in <module>
    HAVE_SOCKET_CAN = _have_socket_can()
  File "D:\a\cpython\cpython\Lib\test\test_socket.py", line 104, in _have_socket_can
    s = socket.socket(socket.PF_CAN, socket.SOCK_RAW, socket.CAN_RAW)
  File "D:\a\cpython\cpython\Lib\socket.py", line 242, in __init__
    _socket.socket.__init__(self, family, type, proto, fileno)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'NoneType' object cannot be interpreted as an integer

Edit
It seems to be a consistent bug since I opened the PR.

@ZeroIntensity
Copy link
Member

I think you need to raise an AttributeError from the __getattr__ if it isn't SocketType.

@rruuaanng rruuaanng marked this pull request as ready for review November 2, 2024 01:50
Doc/library/socket.rst Outdated Show resolved Hide resolved
@vstinner vstinner changed the title gh-88427: Deprecated socket.SocketType gh-88427: Deprecate socket.SocketType Nov 7, 2024
Doc/library/socket.rst Outdated Show resolved Hide resolved
Lib/socket.py Show resolved Hide resolved
Doc/deprecations/pending-removal-in-3.16.rst Outdated Show resolved Hide resolved
@JelleZijlstra JelleZijlstra self-requested a review November 7, 2024 17:05
Comment on lines -7434 to -7436
if (PyModule_AddObjectRef(m, "SocketType", sock_type) < 0) {
goto error;
}
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, could users have been relying on _socket.SocketType instead of socket.SocketType?

@rruuaanng
Copy link
Contributor Author

I have changed them as required. Please review them again :)

@vstinner

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

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

Doc/deprecations/pending-removal-in-3.16.rst Outdated Show resolved Hide resolved
Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@ZeroIntensity ZeroIntensity left a comment

Choose a reason for hiding this comment

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

@rruuaanng, please don't mark conversations as resolved without addressing it them first.

Sorry, the removal of _socket.SocketType without a deprecation is problematic. Normally I wouldn't care about private APIs, but other Python implementations are exposing it for consistency, and it doesn't seem right for us to remove that without a deprecation period.

@vstinner, could you take a second look? (I'm not 100% certain what our policy for other Python implementations is, it's possibly fine to merge as is, but I'd like a second set of eyes.)

Comment on lines -7434 to -7436
if (PyModule_AddObjectRef(m, "SocketType", sock_type) < 0) {
goto error;
}
Copy link
Member

Choose a reason for hiding this comment

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

OK, this part is a breaking change. Please add it back temporarily. (We possibly need to add a __getattr__ to the C code as well to emit a deprecation.)

There are a few large things downstream relying on this:

Nonetheless, I don't want to give users of other implementations an unpleasant surprise.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, can we add a module-level __getattr__ to _socket too that raises a DeprecationWarning?

@rruuaanng
Copy link
Contributor Author

@ZeroIntensity

It has no issues. Since I wrote it in the socket, if this property is used, it returns _socket.socket instead of SocketType. In reality, this alias is completely useless and doesn't need to be used. In practical applications, using it only triggers a deprecation warning and causes no other runtime issues.

I don't think it hasn't been solved.

@ZeroIntensity
Copy link
Member

ZeroIntensity commented Nov 8, 2024

I'll double check, but you wrote it for the socket module, not _socket. Now accessing _socket.SocketType raises an attribute error, yes?

Edit: Yup

Python 3.14.0a0 (heads/pr_126272:261d87f082, Nov  8 2024, 13:59:09) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import _socket
>>> _socket.SocketType
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    _socket.SocketType
AttributeError: module '_socket' has no attribute 'SocketType'

@rruuaanng
Copy link
Contributor Author

Yes. But private modules have always been unstable (in my view, it's not surprising if some features are missing, since we don't encourage their use and remain vigilant about the behavior they exhibit).

From jelle

socket.socket the only type that moat users should care about.

@ZeroIntensity
Copy link
Member

_socket is supposed to be private, yes, but Python is big. If we know something will break downstream, we shouldn't try and brush it off as their fault. I gave examples of some very large downstream users, so we need to add a deprecation for it.

@rruuaanng
Copy link
Contributor Author

I think we could add a getter in the C code, but I’m not sure how Victor feels about it. He didn’t raise any concerns about this during the audit, so maybe he had other considerations in mind.

@ZeroIntensity
Copy link
Member

Victor likely didn't notice because you marked my comment as resolved :(

@rruuaanng
Copy link
Contributor Author

Emmm, maybe he saw it but didn’t think there was any issue. We can wait for his reply.
(for adding it at c level, I agree.)

@vstinner
Copy link
Member

vstinner commented Nov 8, 2024

Alright, if possible, it would be better to implement __getattr__ in the _socket module.

I didn't know that _socket.SocketType is used currently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants