Skip to content

Commit

Permalink
Merge pull request #53 from icgood/wip
Browse files Browse the repository at this point in the history
Fix docs and external APIs
  • Loading branch information
icgood committed Feb 16, 2019
2 parents d885432 + 7e083a8 commit 3546516
Show file tree
Hide file tree
Showing 24 changed files with 167 additions and 147 deletions.
5 changes: 3 additions & 2 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ Table of Contents
pymap.config
pymap.context
pymap.exceptions
pymap.fetch
pymap.filter
pymap.flags
pymap.listtree
pymap.mailbox
pymap.message
pymap.mime
pymap.search
pymap.selected
pymap.sockinfo
pymap.sockets
pymap.interfaces
pymap.parsing
pymap.mime
pymap.backend
pymap.imap
pymap.admin
Expand Down
9 changes: 9 additions & 0 deletions doc/source/pymap.admin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,12 @@

.. automodule:: pymap.admin.handlers
:members:

``pymap.admin.client``
----------------------

.. automodule:: pymap.admin.client
:members:

.. automodule:: pymap.admin.client.command
:members:
6 changes: 6 additions & 0 deletions doc/source/pymap.fetch.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

``pymap.fetch``
=================

.. automodule:: pymap.fetch
:members:
9 changes: 9 additions & 0 deletions doc/source/pymap.mime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,14 @@
.. automodule:: pymap.mime
:members:

``pymap.mime.cte``
------------------

.. automodule:: pymap.mime.cte
:members:

``pymap.mime.parsed``
---------------------

.. automodule:: pymap.mime.parsed
:members:
4 changes: 2 additions & 2 deletions doc/source/pymap.sieve.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
.. automodule:: pymap.sieve
:members:

``pymap.sieve.filter``
``pymap.sieve.manage``
----------------------

.. automodule:: pymap.sieve.filter
.. automodule:: pymap.sieve.manage
:members:
6 changes: 6 additions & 0 deletions doc/source/pymap.sockets.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

``pymap.sockets``
=================

.. automodule:: pymap.sockets
:members:
6 changes: 0 additions & 6 deletions doc/source/pymap.sockinfo.rst

This file was deleted.

20 changes: 17 additions & 3 deletions pymap/admin/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import asyncio
import sys
from argparse import ArgumentParser, Namespace, FileType
from typing import Type
from typing import Type, Mapping

from grpclib.client import Channel # type: ignore
from pkg_resources import iter_entry_points, DistributionNotFound
from pymap import __version__

from .append import AppendCommand
from .command import ClientCommand
from .. import AdminService
from ..grpc.admin_grpc import AdminStub
Expand All @@ -25,7 +25,9 @@ def main() -> int:

subparsers = parser.add_subparsers(dest='command',
help='which admin command to run')
commands = dict([AppendCommand.init(parser, subparsers)])
commands = _load_entry_points('pymap.admin.client')
for command_name, command_cls in commands.items():
command_cls.add_subparser(command_name, subparsers)
args = parser.parse_args()

if not args.command:
Expand All @@ -47,3 +49,15 @@ async def run(parser: ArgumentParser, args: Namespace,
finally:
channel.close()
return code


def _load_entry_points(group: str) -> Mapping[str, Type[ClientCommand]]:
ret = {}
for entry_point in iter_entry_points(group):
try:
cls = entry_point.load()
except DistributionNotFound:
pass # optional dependencies not installed
else:
ret[entry_point.name] = cls
return ret
10 changes: 4 additions & 6 deletions pymap/admin/client/append.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import sys
import time
import traceback
from argparse import ArgumentParser, FileType
from typing import Type, Tuple, TextIO
from argparse import FileType
from typing import Tuple, TextIO

from .command import ClientCommand
from ..grpc.admin_pb2 import AppendRequest, AppendResponse, \
Expand All @@ -22,10 +22,9 @@ class AppendCommand(ClientCommand):
'AppendFailure': '4.2.0 Message not deliverable'}

@classmethod
def init(cls, parser: ArgumentParser, subparsers) \
-> Tuple[str, Type['AppendCommand']]:
def add_subparser(cls, name: str, subparsers) -> None:
subparser = subparsers.add_parser(
'append', description=__doc__,
name, description=__doc__,
help='append a message to a mailbox')
subparser.add_argument('--from', metavar='ADDRESS', dest='sender',
default='', help='the message envelope sender')
Expand All @@ -52,7 +51,6 @@ def init(cls, parser: ArgumentParser, subparsers) \
const='\\Deleted', help='the message is deleted')
flags.add_argument('--answered', dest='flags', action='append_const',
const='\\Answered', help='the message is answered')
return 'append', cls

async def run(self, fileobj: TextIO) -> int:
args = self.args
Expand Down
12 changes: 5 additions & 7 deletions pymap/admin/client/command.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

from abc import abstractmethod, ABCMeta
from argparse import ArgumentParser, Namespace
from typing import Type, Tuple, TextIO
from argparse import Namespace
from typing import TextIO
from typing_extensions import Final

from ..grpc.admin_grpc import AdminStub
Expand All @@ -25,13 +25,11 @@ def __init__(self, stub: AdminStub, args: Namespace) -> None:

@classmethod
@abstractmethod
def init(cls, parser: ArgumentParser, subparsers) \
-> Tuple[str, Type['ClientCommand']]:
"""Initialize the client command, adding its subparser and returning
the command name and class.
def add_subparser(cls, name: str, subparsers) -> None:
"""Add the command-line argument subparser for the command.
Args:
parser: The argument parser object.
name: The name to use for the subparser.
subparsers: The special action object as returned by
:meth:`~argparse.ArgumentParser.add_subparsers`.
Expand Down
4 changes: 2 additions & 2 deletions pymap/backend/dict/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ def config(self) -> IMAPConfig:
return self._config

@classmethod
def add_subparser(cls, subparsers) -> None:
def add_subparser(cls, name: str, subparsers) -> None:
parser = subparsers.add_parser(
'dict', help='in-memory backend',
name, help='in-memory backend',
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('--demo-data', action='store_true',
help='load initial demo data')
Expand Down
4 changes: 2 additions & 2 deletions pymap/backend/maildir/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def config(self) -> IMAPConfig:
return self._config

@classmethod
def add_subparser(cls, subparsers) -> None:
def add_subparser(cls, name: str, subparsers) -> None:
parser = subparsers.add_parser(
'maildir', help='on-disk backend',
name, help='on-disk backend',
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('users_file', help='path the the users file')
parser.add_argument('--base-dir', metavar='DIR',
Expand Down
4 changes: 2 additions & 2 deletions pymap/backend/redis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def config(self) -> IMAPConfig:
return self._config

@classmethod
def add_subparser(cls, subparsers) -> None:
def add_subparser(cls, name: str, subparsers) -> None:
parser = subparsers.add_parser(
'redis', help='redis backend',
name, help='redis backend',
formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('address', nargs='?', default='redis://localhost',
help='the redis server address')
Expand Down
2 changes: 1 addition & 1 deletion pymap/bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def wrap(cls, data: MaybeBytes) -> 'Writeable':

@classmethod
def concat(cls, data: Iterable[MaybeBytes]) -> 'Writeable':
"""Wrap the iterable in a :class:`Writeable` that will write eachitem.
"""Wrap the iterable in a :class:`Writeable` that will write each item.
Args:
data: The iterable to wrap.
Expand Down
2 changes: 1 addition & 1 deletion pymap/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

from .concurrent import Subsystem
from .parsing.command import Command
from .sockinfo import SocketInfo
from .sockets import SocketInfo

__all__ = ['subsystem', 'current_command', 'socket_info', 'language_code']

Expand Down
5 changes: 3 additions & 2 deletions pymap/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@

__all__ = ['ResponseError', 'NotSupportedError', 'CloseConnection',
'CommandNotAllowed', 'SearchNotAllowed', 'InvalidAuth',
'MailboxError', 'MailboxNotFound', 'MailboxConflict',
'MailboxHasChildren', 'MailboxReadOnly', 'AppendFailure']
'MailboxError', 'MailboxAbort', 'MailboxNotFound',
'MailboxConflict', 'MailboxHasChildren', 'MailboxReadOnly',
'AppendFailure']


class ResponseError(Exception, metaclass=ABCMeta):
Expand Down
3 changes: 1 addition & 2 deletions pymap/imap/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
from pymap.parsing.exceptions import RequiresContinuation
from pymap.parsing.response import ResponseContinuation, Response, \
ResponseCode, ResponseBad, ResponseNo, ResponseBye, ResponseOk
from pymap.sockets import InheritedSockets
from pymap.sockinfo import SocketInfo
from pymap.sockets import InheritedSockets, SocketInfo
from pysasl import ServerChallenge, AuthenticationError, \
AuthenticationCredentials

Expand Down
7 changes: 2 additions & 5 deletions pymap/interfaces/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,15 @@ class BackendInterface(Protocol):

@classmethod
@abstractmethod
def add_subparser(cls, subparsers) -> None:
def add_subparser(cls, name: str, subparsers) -> None:
"""Add a command-line argument sub-parser that will be used to choose
this backend. For example::
parser = subparsers.add_parser('foo', help='foo backend')
parser.add_argument(...)
Note:
The name of the added sub-parser must be the same as the name of
the entry point registered by the backend.
Args:
name: The name to use for the subparser.
subparsers: The special action object as returned by
:meth:`~argparse.ArgumentParser.add_subparsers`.
Expand Down
7 changes: 3 additions & 4 deletions pymap/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ def main() -> None:
backends: _Backends = _load_entry_points('pymap.backend')
services: _Services = _load_entry_points('pymap.service')

for backend_cls in backends.values():
backend_cls.add_subparser(subparsers)
for backend_name, backend_cls in backends.items():
backend_cls.add_subparser(backend_name, subparsers)
for service_cls in services.values():
service_cls.add_arguments(parser)
parser.set_defaults(skip_services=[])
Expand Down Expand Up @@ -87,8 +87,7 @@ async def run(args: Namespace, backend_type: Type[BackendInterface],
await asyncio.gather(*[service.task for service in services])


def _load_entry_points(group: str) \
-> Mapping[str, Type[Any]]:
def _load_entry_points(group: str) -> Mapping[str, Type[Any]]:
ret = {}
for entry_point in iter_entry_points(group):
try:
Expand Down
2 changes: 1 addition & 1 deletion pymap/sieve/manage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from pymap.interfaces.session import LoginProtocol, SessionInterface
from pymap.parsing.exceptions import NotParseable
from pymap.parsing.primitives import String
from pymap.sockinfo import SocketInfo
from pymap.sockets import SocketInfo
from pysasl import ServerChallenge, AuthenticationError

from .command import Command, NoOpCommand, LogoutCommand, CapabilityCommand, \
Expand Down
Loading

0 comments on commit 3546516

Please sign in to comment.