diff --git a/IPython/config/application.py b/IPython/config/application.py index 264d379..3b848c3 100644 --- a/IPython/config/application.py +++ b/IPython/config/application.py @@ -14,7 +14,7 @@ import sys from copy import deepcopy from collections import defaultdict -from IPython.external.decorator import decorator +from decorator import decorator from IPython.config.configurable import SingletonConfigurable from IPython.config.loader import ( diff --git a/IPython/core/formatters.py b/IPython/core/formatters.py index f5126c9..3c622cf 100644 --- a/IPython/core/formatters.py +++ b/IPython/core/formatters.py @@ -17,7 +17,7 @@ import sys import traceback import warnings -from IPython.external.decorator import decorator +from decorator import decorator from IPython.config.configurable import Configurable from IPython.core.getipython import get_ipython diff --git a/IPython/core/history.py b/IPython/core/history.py index c615ad8..7c1076c 100644 --- a/IPython/core/history.py +++ b/IPython/core/history.py @@ -28,7 +28,7 @@ import threading # Our own packages from IPython.config.configurable import Configurable -from IPython.external.decorator import decorator +from decorator import decorator from IPython.utils.decorators import undoc from IPython.utils.path import locate_profile from IPython.utils import py3compat diff --git a/IPython/core/magic.py b/IPython/core/magic.py index f085717..7d8b981 100644 --- a/IPython/core/magic.py +++ b/IPython/core/magic.py @@ -27,7 +27,7 @@ from IPython.config.configurable import Configurable from IPython.core import oinspect from IPython.core.error import UsageError from IPython.core.inputsplitter import ESC_MAGIC, ESC_MAGIC2 -from IPython.external.decorator import decorator +from decorator import decorator from IPython.utils.ipstruct import Struct from IPython.utils.process import arg_split from IPython.utils.py3compat import string_types, iteritems diff --git a/IPython/core/tests/test_oinspect.py b/IPython/core/tests/test_oinspect.py index 1d7f7bc..a0d0f55 100644 --- a/IPython/core/tests/test_oinspect.py +++ b/IPython/core/tests/test_oinspect.py @@ -26,7 +26,7 @@ from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic, line_cell_magic, register_line_magic, register_cell_magic, register_line_cell_magic) -from IPython.external.decorator import decorator +from decorator import decorator from IPython.testing.decorators import skipif from IPython.testing.tools import AssertPrints from IPython.utils.path import compress_user diff --git a/IPython/external/decorator/__init__.py b/IPython/external/decorator/__init__.py deleted file mode 100644 index d0e95b4..0000000 --- a/IPython/external/decorator/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -try: - from decorator import * -except ImportError: - from ._decorator import * diff --git a/IPython/external/decorator/_decorator.py b/IPython/external/decorator/_decorator.py deleted file mode 100644 index ef56922..0000000 --- a/IPython/external/decorator/_decorator.py +++ /dev/null @@ -1,229 +0,0 @@ -########################## LICENCE ############################### - -# Copyright (c) 2005-2012, Michele Simionato -# All rights reserved. - -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: - -# Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# Redistributions in bytecode form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in -# the documentation and/or other materials provided with the -# distribution. - -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -# DAMAGE. - -""" -Decorator module, see http://pypi.python.org/pypi/decorator -for the documentation. - -NOTE: this is an IPython-patched version to work on IronPython. See - FIXED comment below. -""" -from __future__ import print_function - -__version__ = '3.3.3' - -__all__ = ["decorator", "FunctionMaker", "partial"] - -import sys, re, inspect - -try: - from functools import partial -except ImportError: # for Python version < 2.5 - class partial(object): - "A simple replacement of functools.partial" - def __init__(self, func, *args, **kw): - self.func = func - self.args = args - self.keywords = kw - def __call__(self, *otherargs, **otherkw): - kw = self.keywords.copy() - kw.update(otherkw) - return self.func(*(self.args + otherargs), **kw) - -if sys.version >= '3': - from inspect import getfullargspec -else: - class getfullargspec(object): - "A quick and dirty replacement for getfullargspec for Python 2.X" - def __init__(self, f): - self.args, self.varargs, self.varkw, self.defaults = \ - inspect.getargspec(f) - self.kwonlyargs = [] - self.kwonlydefaults = None - def __iter__(self): - yield self.args - yield self.varargs - yield self.varkw - yield self.defaults - -DEF = re.compile('\s*def\s*([_\w][_\w\d]*)\s*\(') - -# basic functionality -class FunctionMaker(object): - """ - An object with the ability to create functions with a given signature. - It has attributes name, doc, module, signature, defaults, dict and - methods update and make. - """ - def __init__(self, func=None, name=None, signature=None, - defaults=None, doc=None, module=None, funcdict=None): - self.shortsignature = signature - if func: - # func can be a class or a callable, but not an instance method - self.name = func.__name__ - if self.name == '': # small hack for lambda functions - self.name = '_lambda_' - self.doc = func.__doc__ - self.module = func.__module__ - if inspect.isfunction(func): - argspec = getfullargspec(func) - self.annotations = getattr(func, '__annotations__', {}) - for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs', - 'kwonlydefaults'): - setattr(self, a, getattr(argspec, a)) - for i, arg in enumerate(self.args): - setattr(self, 'arg%d' % i, arg) - if sys.version < '3': # easy way - self.shortsignature = self.signature = \ - inspect.formatargspec( - formatvalue=lambda val: "", *argspec)[1:-1] - else: # Python 3 way - self.signature = self.shortsignature = ', '.join(self.args) - if self.varargs: - self.signature += ', *' + self.varargs - self.shortsignature += ', *' + self.varargs - if self.kwonlyargs: - for a in self.kwonlyargs: - self.signature += ', %s=None' % a - self.shortsignature += ', %s=%s' % (a, a) - if self.varkw: - self.signature += ', **' + self.varkw - self.shortsignature += ', **' + self.varkw - self.dict = func.__dict__.copy() - # func=None happens when decorating a caller - if name: - self.name = name - if signature is not None: - self.signature = signature - if defaults: - self.defaults = defaults - if doc: - self.doc = doc - if module: - self.module = module - if funcdict: - self.dict = funcdict - # check existence required attributes - assert hasattr(self, 'name') - if not hasattr(self, 'signature'): - raise TypeError('You are decorating a non function: %s' % func) - - def update(self, func, **kw): - "Update the signature of func with the data in self" - func.__name__ = self.name - func.__doc__ = getattr(self, 'doc', None) - func.__dict__ = getattr(self, 'dict', {}) - func.__defaults__ = getattr(self, 'defaults', ()) - func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None) - func.__annotations__ = getattr(self, 'annotations', None) - # FIXED: The following is try/excepted in IPython to work - # with IronPython. - try: - callermodule = sys._getframe(3).f_globals.get('__name__', '?') - except AttributeError: # IronPython _getframe only exists with FullFrames - callermodule = '?' - func.__module__ = getattr(self, 'module', callermodule) - func.__dict__.update(kw) - - def make(self, src_templ, evaldict=None, addsource=False, **attrs): - "Make a new function from a given template and update the signature" - src = src_templ % vars(self) # expand name and signature - evaldict = evaldict or {} - mo = DEF.match(src) - if mo is None: - raise SyntaxError('not a valid function template\n%s' % src) - name = mo.group(1) # extract the function name - names = set([name] + [arg.strip(' *') for arg in - self.shortsignature.split(',')]) - for n in names: - if n in ('_func_', '_call_'): - raise NameError('%s is overridden in\n%s' % (n, src)) - if not src.endswith('\n'): # add a newline just for safety - src += '\n' # this is needed in old versions of Python - try: - code = compile(src, '', 'single') - # print >> sys.stderr, 'Compiling %s' % src - exec(code, evaldict) - except: - print('Error in generated code:', file=sys.stderr) - print(src, file=sys.stderr) - raise - func = evaldict[name] - if addsource: - attrs['__source__'] = src - self.update(func, **attrs) - return func - - @classmethod - def create(cls, obj, body, evaldict, defaults=None, - doc=None, module=None, addsource=True, **attrs): - """ - Create a function from the strings name, signature and body. - evaldict is the evaluation dictionary. If addsource is true an attribute - __source__ is added to the result. The attributes attrs are added, - if any. - """ - if isinstance(obj, str): # "name(signature)" - name, rest = obj.strip().split('(', 1) - signature = rest[:-1] #strip a right parens - func = None - else: # a function - name = None - signature = None - func = obj - self = cls(func, name, signature, defaults, doc, module) - ibody = '\n'.join(' ' + line for line in body.splitlines()) - return self.make('def %(name)s(%(signature)s):\n' + ibody, - evaldict, addsource, **attrs) - -def decorator(caller, func=None): - """ - decorator(caller) converts a caller function into a decorator; - decorator(caller, func) decorates a function using a caller. - """ - if func is not None: # returns a decorated function - evaldict = func.__globals__.copy() - evaldict['_call_'] = caller - evaldict['_func_'] = func - return FunctionMaker.create( - func, "return _call_(_func_, %(shortsignature)s)", - evaldict, undecorated=func, __wrapped__=func) - else: # returns a decorator - if isinstance(caller, partial): - return partial(decorator, caller) - # otherwise assume caller is a function - first = inspect.getargspec(caller)[0][0] # first arg - evaldict = caller.__globals__.copy() - evaldict['_call_'] = caller - evaldict['decorator'] = decorator - return FunctionMaker.create( - '%s(%s)' % (caller.__name__, first), - 'return decorator(_call_, %s)' % first, - evaldict, undecorated=caller, __wrapped__=caller, - doc=caller.__doc__, module=caller.__module__) diff --git a/IPython/parallel/client/asyncresult.py b/IPython/parallel/client/asyncresult.py index 7c45a70..340398b 100644 --- a/IPython/parallel/client/asyncresult.py +++ b/IPython/parallel/client/asyncresult.py @@ -12,7 +12,7 @@ from datetime import datetime from zmq import MessageTracker from IPython.core.display import clear_output, display, display_pretty -from IPython.external.decorator import decorator +from decorator import decorator from IPython.parallel import error from IPython.utils.py3compat import string_types diff --git a/IPython/parallel/client/client.py b/IPython/parallel/client/client.py index 44c6d1a..ea17490 100644 --- a/IPython/parallel/client/client.py +++ b/IPython/parallel/client/client.py @@ -31,7 +31,7 @@ from IPython.utils.path import get_ipython_dir, compress_user from IPython.utils.py3compat import cast_bytes, string_types, xrange, iteritems from IPython.utils.traitlets import (HasTraits, Integer, Instance, Unicode, Dict, List, Bool, Set, Any) -from IPython.external.decorator import decorator +from decorator import decorator from IPython.parallel import Reference from IPython.parallel import error diff --git a/IPython/parallel/client/remotefunction.py b/IPython/parallel/client/remotefunction.py index ebf5c3b..4453ff2 100644 --- a/IPython/parallel/client/remotefunction.py +++ b/IPython/parallel/client/remotefunction.py @@ -8,7 +8,7 @@ from __future__ import division import sys import warnings -from IPython.external.decorator import decorator +from decorator import decorator from IPython.testing.skipdoctest import skip_doctest from . import map as Map diff --git a/IPython/parallel/client/view.py b/IPython/parallel/client/view.py index 63f73aa..f6b17f6 100644 --- a/IPython/parallel/client/view.py +++ b/IPython/parallel/client/view.py @@ -18,7 +18,7 @@ from IPython.utils import pickleutil from IPython.utils.traitlets import ( HasTraits, Any, Bool, List, Dict, Set, Instance, CFloat, Integer ) -from IPython.external.decorator import decorator +from decorator import decorator from IPython.parallel import util from IPython.parallel.controller.dependency import Dependency, dependent diff --git a/IPython/parallel/controller/scheduler.py b/IPython/parallel/controller/scheduler.py index 55cc37f..26589b9 100644 --- a/IPython/parallel/controller/scheduler.py +++ b/IPython/parallel/controller/scheduler.py @@ -26,7 +26,7 @@ import zmq from zmq.eventloop import ioloop, zmqstream # local imports -from IPython.external.decorator import decorator +from decorator import decorator from IPython.config.application import Application from IPython.config.loader import Config from IPython.utils.traitlets import Instance, Dict, List, Set, Integer, Enum, CBytes diff --git a/IPython/parallel/tests/clienttest.py b/IPython/parallel/tests/clienttest.py index 28cd73d..1bf3403 100644 --- a/IPython/parallel/tests/clienttest.py +++ b/IPython/parallel/tests/clienttest.py @@ -22,7 +22,7 @@ from nose import SkipTest import zmq from zmq.tests import BaseZMQTestCase -from IPython.external.decorator import decorator +from decorator import decorator from IPython.parallel import error from IPython.parallel import Client diff --git a/IPython/parallel/util.py b/IPython/parallel/util.py index 870063e..3596edf 100644 --- a/IPython/parallel/util.py +++ b/IPython/parallel/util.py @@ -28,7 +28,7 @@ import zmq from zmq.log import handlers from IPython.utils.log import get_logger -from IPython.external.decorator import decorator +from decorator import decorator from IPython.config.application import Application from IPython.utils.localinterfaces import localhost, is_public_ip, public_ips diff --git a/IPython/testing/decorators.py b/IPython/testing/decorators.py index 9537f11..2014c07 100644 --- a/IPython/testing/decorators.py +++ b/IPython/testing/decorators.py @@ -52,7 +52,7 @@ import unittest # Third-party imports # This is Michele Simionato's decorator module, kept verbatim. -from IPython.external.decorator import decorator +from decorator import decorator # Expose the unittest-driven decorators from .ipunittest import ipdoctest, ipdocstring diff --git a/setup.py b/setup.py index 202d7e0..54638ed 100755 --- a/setup.py +++ b/setup.py @@ -269,6 +269,7 @@ extras_require['notebook'].extend(extras_require['nbformat']) extras_require['nbconvert'].extend(extras_require['nbformat']) install_requires = [ + 'decorator', 'path.py', # required by pickleshare, remove when pickleshare is added here ]