Skip to content

Commit

Permalink
general: public API refactored
Browse files Browse the repository at this point in the history
use static re-exports instead of dynamic loading — support
IDEs like PyDev
  • Loading branch information
svinota committed Jul 4, 2017
1 parent c69694c commit 85cbd4a
Show file tree
Hide file tree
Showing 14 changed files with 348 additions and 393 deletions.
161 changes: 54 additions & 107 deletions pyroute2/__init__.py
Expand Up @@ -8,15 +8,35 @@
import sys
import struct
import logging
from abc import ABCMeta
from pyroute2.ipdb.exceptions import \
DeprecationException, \
CommitException, \
CreateException, \
PartialCommitException
from pyroute2.netlink.exceptions import \
NetlinkError, \
NetlinkDecodeError
from pyroute2.ipdb.exceptions import (DeprecationException,
CommitException,
CreateException,
PartialCommitException)
from pyroute2.netlink.exceptions import (NetlinkError,
NetlinkDecodeError)
from pyroute2.netlink.rtnl.req import (IPRouteRequest,
IPLinkRequest)
from pyroute2.iproute import (IPRoute,
IPBatch,
RawIPRoute)
from pyroute2.ipset import IPSet
from pyroute2.ipdb.main import IPDB
from pyroute2.iwutil import IW
from pyroute2.devlink import DL
from pyroute2.netns.nslink import NetNS
from pyroute2.netns.process.proxy import NSPopen
from pyroute2.netlink.rtnl.iprsocket import IPRSocket
from pyroute2.netlink.taskstats import TaskStats
from pyroute2.netlink.nl80211 import NL80211
from pyroute2.netlink.devlink import DevlinkSocket
from pyroute2.netlink.event.acpi_event import AcpiEventSocket
from pyroute2.netlink.event.dquot import DQuotSocket
from pyroute2.netlink.ipq import IPQSocket
from pyroute2.netlink.diag import DiagSocket
from pyroute2.netlink.generic import GenericNetlinkSocket
from pyroute2.netlink.nfnetlink.nftables import NFTSocket
from pyroute2.cli import Console


log = logging.getLogger(__name__)
# Add a NullHandler to the library's top-level logger to avoid complaints
Expand Down Expand Up @@ -48,105 +68,31 @@ def wrapped(fmt, buf, offset=0):
CreateException,
PartialCommitException]

__all__ = []
_modules = {'IPRoute': 'pyroute2.iproute',
'IPBatch': 'pyroute2.iproute',
'RawIPRoute': 'pyroute2.iproute',
'IPSet': 'pyroute2.ipset',
'IPDB': 'pyroute2.ipdb.main',
'IW': 'pyroute2.iwutil',
'DL': 'pyroute2.devlink',
'NetNS': 'pyroute2.netns.nslink',
'NSPopen': 'pyroute2.netns.process.proxy',
'IPRSocket': 'pyroute2.netlink.rtnl.iprsocket',
'IPRouteRequest': 'pyroute2.netlink.rtnl.req',
'IPLinkRequest': 'pyroute2.netlink.rtnl.req',
'TaskStats': 'pyroute2.netlink.taskstats',
'NL80211': 'pyroute2.netlink.nl80211',
'DevlinkSocket': 'pyroute2.netlink.devlink',
'AcpiEventSocket': 'pyroute2.netlink.event.acpi_event',
'DQuotSocket': 'pyroute2.netlink.event.dquot',
'IPQSocket': 'pyroute2.netlink.ipq',
'DiagSocket': 'pyroute2.netlink.diag',
'GenericNetlinkSocket': 'pyroute2.netlink.generic',
'NFTSocket': 'pyroute2.netlink.nfnetlink.nftables',
'Console': 'pyroute2.cli'}


_DISCLAIMER = '''\n\nNotice:\n
This is a proxy class. To read full docs, please run
the `help()` method on the instance instead.
Usage of the proxy allows to postpone the module load,
thus providing a safe way to substitute base classes,
if it is required. More details see in the `pyroute2.config`
module.
\n'''


def _bake(name):

class Doc(str):

def __init__(self, registry, *argv, **kwarg):
self.registry = registry
super(Doc, self).__init__(*argv, **kwarg)

def __repr__(self):
return repr(self.registry['doc'])
# reexport classes
classes = [IPRouteRequest,
IPLinkRequest,
IPRoute,
IPBatch,
RawIPRoute,
IPSet,
IPDB,
IW,
DL,
NetNS,
NSPopen,
IPRSocket,
TaskStats,
NL80211,
DevlinkSocket,
AcpiEventSocket,
DQuotSocket,
IPQSocket,
DiagSocket,
GenericNetlinkSocket,
NFTSocket,
Console]

def __str__(self):
return str(self.registry['doc'])

def expandtabs(self, ts=4):
return self.registry['doc'].expandtabs(ts)

class Registry(object):
def __init__(self):
self.target = {}

def __getitem__(self, key):
if not self.target:
module = __import__(_modules[name],
globals(),
locals(),
[name], 0)
self.target['class'] = getattr(module, name)
self.target['doc'] = self.target['class'].__doc__
try:
self.target['doc'] += _DISCLAIMER
except TypeError:
# ignore cases, when __doc__ is not a string, e.g. None
pass
return self.target[key]

@classmethod
def __hook__(cls, C):
if hasattr(C, 'registry'):
try:
return issubclass(C.registry['class'], cls.registry['class'])
except Exception:
pass
return issubclass(C, cls.registry['class'])

def __new__(cls, *argv, **kwarg):
cls.register(cls.registry['class'])
return cls.registry['class'](*argv, **kwarg)

registry = Registry()
doc = Doc(registry)

proxy = ABCMeta('proxy', (object, ), {'__new__': __new__,
'__doc__': doc,
'__subclasshook__': __hook__,
'registry': registry})
return proxy


for name in _modules:
f = _bake(name)
globals()[name] = f
__all__.append(name)
__all__ = []


class __common(object):
Expand All @@ -159,3 +105,4 @@ def __getattribute__(self, key):
globals()['ipdb'].common = __common()

__all__.extend([x.__name__ for x in exceptions])
__all__.extend([x.__name__ for x in classes])
2 changes: 0 additions & 2 deletions pyroute2/config/__init__.py
@@ -1,10 +1,8 @@
import socket
import platform
import multiprocessing
from pyroute2 import common
from distutils.version import LooseVersion

TransactionalBase = common.Dotkeys
SocketBase = socket.socket
MpPipe = multiprocessing.Pipe
MpQueue = multiprocessing.Queue
Expand Down
4 changes: 2 additions & 2 deletions pyroute2/ipdb/interfaces.py
Expand Up @@ -6,7 +6,7 @@
from pyroute2.common import basestring
from pyroute2.common import dqn2int
from pyroute2.common import View
from pyroute2.config import TransactionalBase
from pyroute2.common import Dotkeys
from pyroute2.netlink import rtnl
from pyroute2.netlink import NLM_F_ACK
from pyroute2.netlink import NLM_F_REQUEST
Expand Down Expand Up @@ -1100,7 +1100,7 @@ def shadow(self):
return self


class InterfacesDict(TransactionalBase):
class InterfacesDict(Dotkeys):

def __init__(self, ipdb):
self.ipdb = ipdb
Expand Down
10 changes: 5 additions & 5 deletions pyroute2/ipdb/transactional.py
Expand Up @@ -2,8 +2,8 @@
'''
import logging
import threading
from pyroute2.config import TransactionalBase
from pyroute2.common import uuid32
from pyroute2.common import Dotkeys
from pyroute2.ipdb.linkedset import LinkedSet
from pyroute2.ipdb.exceptions import CommitException

Expand Down Expand Up @@ -81,7 +81,7 @@ def decorated(self, direct, *argv, **kwarg):
return update(decorated)


class Transactional(TransactionalBase):
class Transactional(Dotkeys):
'''
Utility class that implements common transactional logic.
'''
Expand Down Expand Up @@ -124,7 +124,7 @@ def __init__(self, ipdb=None, mode=None, parent=None, uid=None):
self._linked_sets = self._linked_sets or set()
#
for i in self._fields:
TransactionalBase.__setitem__(self, i, None)
Dotkeys.__setitem__(self, i, None)

@property
def ro(self):
Expand Down Expand Up @@ -444,7 +444,7 @@ def __setitem__(self, direct, key, value):
transaction._targets[key] = threading.Event()
else:
# set the item
TransactionalBase.__setitem__(self, key, value)
Dotkeys.__setitem__(self, key, value)

# update on local targets
with self._write_lock:
Expand All @@ -471,7 +471,7 @@ def __delitem__(self, direct, key):
if key in transaction:
del transaction[key]
else:
TransactionalBase.__delitem__(self, key)
Dotkeys.__delitem__(self, key)

def option(self, key, value):
self[key] = value
Expand Down
2 changes: 1 addition & 1 deletion pyroute2/iproute.py
Expand Up @@ -229,7 +229,7 @@
from pyroute2.netlink.rtnl.ifaddrmsg import ifaddrmsg
from pyroute2.netlink.rtnl.iprsocket import IPRSocket
from pyroute2.netlink.rtnl.iprsocket import IPBatchSocket
from pyroute2.netlink.rtnl.iprsocket import RawIPRSocket
from pyroute2.netlink.rtnl.riprsocket import RawIPRSocket

from pyroute2.common import AF_MPLS
from pyroute2.common import basestring
Expand Down
9 changes: 4 additions & 5 deletions pyroute2/netlink/nlsocket.py
Expand Up @@ -97,7 +97,6 @@
from socket import SO_SNDBUF

from pyroute2 import config
from pyroute2.config import SocketBase
from pyroute2.common import AddrPool
from pyroute2.common import DEFAULT_RCVBUF
from pyroute2.netlink import nlmsg
Expand Down Expand Up @@ -869,10 +868,10 @@ def post_init(self):
with self.lock:
if self._sock is not None:
self._sock.close()
self._sock = SocketBase(AF_NETLINK,
SOCK_DGRAM,
self.family,
self._fileno)
self._sock = config.SocketBase(AF_NETLINK,
SOCK_DGRAM,
self.family,
self._fileno)
for name in ('getsockname', 'getsockopt', 'makefile',
'setsockopt', 'setblocking', 'settimeout',
'gettimeout', 'shutdown', 'recvfrom',
Expand Down

0 comments on commit 85cbd4a

Please sign in to comment.