Skip to content

create_server returns a Server, not AbstractServer#3131

Merged
srittau merged 3 commits intopython:masterfrom
scottbelden:asyncio_server
Aug 23, 2019
Merged

create_server returns a Server, not AbstractServer#3131
srittau merged 3 commits intopython:masterfrom
scottbelden:asyncio_server

Conversation

@scottbelden
Copy link
Copy Markdown
Contributor

I believe this should resolve my current error:

error: Module 'asyncio.base_events' has no attribute 'Server'

Also, looking at the implementation of create_server and a few other functions, it seems like they should return a Server, not an AbstractServer: https://github.com/python/cpython/blob/9cd39b16e2655f748f7aa8d20bca4812da00ba70/Lib/asyncio/base_events.py#L1466-L1476

@JelleZijlstra
Copy link
Copy Markdown
Member

mypy is unhappy with this for reasons I don't fully understand. Maybe if you make these functions use async def these errors will go away.

@scottbelden
Copy link
Copy Markdown
Contributor Author

Oh, I wonder if it's because there is another create_server here

def create_server(self, protocol_factory: _ProtocolFactory, host: Optional[Union[str, Sequence[str]]] = ..., port: int = ..., *,
family: int = ..., flags: int = ...,
sock: None = ..., backlog: int = ..., ssl: _SSLContext = ...,
reuse_address: Optional[bool] = ...,
reuse_port: Optional[bool] = ...) -> Generator[Any, None, AbstractServer]: ...
that I didn't change. Is it a problem that the abstract event loop returns an AbstractServer and this base loop returns a Server?

Comment thread stdlib/3/asyncio/base_events.pyi Outdated
@coroutine
def create_unix_server(self, protocol_factory: _ProtocolFactory, path: str, *,
sock: Optional[socket] = ..., backlog: int = ..., ssl: _SSLContext = ...) -> Generator[Any, None, AbstractServer]: ...
sock: Optional[socket] = ..., backlog: int = ..., ssl: _SSLContext = ...) -> Generator[Any, None, Server]: ...
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

create_unix_server() is actually not implemented by BaseEventLoop. Just tested this and it throws a NotImplementedError when called. So they should just be removed from here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed. I believe the same is true of create_unix_connection and it should probably be removed as well. I haven't done that yet (as it's a bit of a separate issue than what this PR is intending) but can easily do so if you'd like.

Copy link
Copy Markdown
Collaborator

@srittau srittau Jul 25, 2019

Choose a reason for hiding this comment

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

@scottbelden I think removing create_unix_connection as well would be a good idea. But that leaves us with the problem that mypy complains that create_unix_* is missing, because it's abstract in the base class and BaseEventLoop, which is concrete, does not implement it. I see several possible solutions:

  1. Restore create_unix_server as a copy of AbstractEventLoops signature and leave create_unix_connection alone. I don't like this, because it doesn't reflect reality.
  2. Add ABCMeta as metaclass to BaseEventLoop. That even worse, since BaseEventLoop is clearly not meant to be abstract and this can cause problems down the line.
  3. Just add # type: ignore to line 22 to force this error to go away. Works, but it's a bit rough, and means that classes deriving from BaseEventLoop need to do the same.
  4. Remove @abstractmethod from AbstractEventLoop.create_unix_server and create_unix_connection (and instead add a comment with an explanation). I prefer this solution as these methods are clearly not abstract in the sense that they need to be implemented by any concrete sub-class (which is what @abstractmethod implies).

I'd like to hear @JelleZijlstra's thoughts about this, though.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So if I understand correctly, the problem is:

  • The base abstract class, AbstractEventLoop, has an abstract method create_unix_server
  • BaseEventLoop is meant to be concrete but does not actually implement create_unix_server.

But the second part isn't true: BaseEventLoop has a number of unimplemented methods, and the actual runtime type of an event loop is asyncio.unix_events._UnixSelectorEventLoop for me (and presumably some other class on Windows). So it should be fine to add ABCMeta to BaseEventLoop.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Ah, if BaseEventLoop is not actually meant to be instantiated, I agree.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If I understand correctly, class BaseEventLoop(AbstractEventLoop) should be changed to class BaseEventLoop(AbstractEventLoop, metaclass=ABCMeta). Is this correct? Should the create_unix_* methods still be removed from BaseEventLoop?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@scottbelden Yes to both questions. Hopefully that will resolve the build failure.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

(Also, it's easier for us if you don't force-push. We will squash merge anyway.)

@JelleZijlstra
Copy link
Copy Markdown
Member

Could you fix the merge conflict and the Travis failure?

@scottbelden
Copy link
Copy Markdown
Contributor Author

Sorry, was away for a bit. I believe I addressed the comments and merged with master. It's running through CI right now.

@srittau srittau merged commit 04bcb89 into python:master Aug 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants