Unbundle external libraries #191

Merged
merged 6 commits into from Mar 24, 2011
Jump to file
+135 −79
Split
@@ -27,7 +27,7 @@
# Our own imports
from IPython.config.configurable import Configurable
-from IPython.external import pretty
+from IPython.lib import pretty
from IPython.utils.traitlets import Bool, Dict, Int, Str, CStr
File renamed without changes.
@@ -0,0 +1,4 @@
+try:
+ from Itpl import *
+except ImportError:
+ from _Itpl import *
@@ -0,0 +1,12 @@
+try:
+ import argparse
+ # Workaround an argparse bug, FIXED in argparse 1.1.0
+ if 'RawTextHelpFormatterArgumentDefaultsHelpFormatter' in argparse.__all__:
+ import itertools
+ argparse.__all__ = list(itertools.chain( [i for i in argparse.__all__
+ if i != 'RawTextHelpFormatterArgumentDefaultsHelpFormatter'],
+ ['RawTextHelpFormatter', 'ArgumentDefaultsHelpFormatter']))
@takluyver
takluyver Mar 2, 2011 Member

Is it necessary to use itertools.chain here, rather than just [i for i in ...] + [a, b]?

@abadger
abadger Mar 2, 2011

I wrote the patch originally so tomspur asked me to comment.

AFAICT, there's no reason that the simpler method shouldn't work:

argparse.__all__ = ([i for i in argparse.__all__ 
        if i != 'RawTextHelpFormatterArgumentDefaultsHelpFormatter']
        +  ['RawTextHelpFormatter', 'ArgumentDefaultsHelpFormatter'])

itertools.chain seems like something I'd do while thinking things through and then fail to see that it was unnecessary when submitting the final patch.

@takluyver
takluyver Mar 2, 2011 Member

OK, smashing. It just stood out when I was scanning through. Thomas, since it's in your branch, do you want to tweak that? We'll run the tests again, and hopefully it's good to go (unless anyone else sees a reason why not - speak now or forever hold your peace, and all that).

@tomspur
tomspur Mar 3, 2011 Contributor

I'd leave it like it is.
itertools is a std python lib, so it doesn't add any dependency, so it's ok to use it.
When argparse 1.1.0 is common in all main linux distros, we can simply delete the workaround again.
(And I guess it might be the time right now... Debian, Ubuntu and Fedora has the 1.1. in the repositories, if I see that right (can only be sure for Fedora))

@takluyver
takluyver Mar 3, 2011 Member

Ubuntu seems to have 1.1.1 as of Lucid (the release before the current one), which is the first time it packaged it at all. The same version is in Debian stable (they had a new release recently). It looks like macports has 1.1 as well. Assuming the version that's in the stdlib for Python 2.7 and Python 3.2 doesn't have the bug, I think it's safe to remove the workaround.

@abadger
abadger Mar 3, 2011

The EPEL repositories for RHEL 6 have argparse-1.0.1 so I wouldn't characterize it as "safe" to remove. OTOH, argparse-1.1.x looks API compatible so we might be able to upgrade the EPEL packages to a newer version where necessary to get a newer ipython. Definitely a judgement call.

@takluyver
takluyver Mar 3, 2011 Member

But is IPython 0.11 (not even released yet) likely to be put onto that platform? I wouldn't make the assumption in the 0.10 series, but I don't think it's unreasonable for the next version of IPython to depend on a version of a package that's been out for at least a year.

@abadger
abadger Mar 3, 2011

tomspur might have a more definite answer since he's involved with maintaining ipython in fedora (on which the EPEL packages are based) -- all I can say for sure is that there's not yet an ipython package for EPEL6 and because users like to get the most recent versions, we generally give them the most recent version at the time that someone steps up to branch and maintain the initial package for that release. Oh, and of course, if users are running RHEL as their workstation (as opposed to a server) they may want to install the latest versions of ipython themselves rather than using what the distro and EPEL provide so they might want to install ipython-0.11 on RHEL5 even.... like I say, though, that could be a case where the EPEL maintainers could be convinced to update argparse to a later version if necessary.

+ argparse.__all__.append('SUPPRESS')
+ from argparse import *
+except ImportError:
+ from _argparse import *
@@ -1,18 +1,4 @@
-# -*- coding: utf-8 -*-
-
-# Copyright © 2006-2009 Steven J. Bethard <steven.bethard@gmail.com>.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may not
-# use this file except in compliance with the License. You may obtain a copy
-# of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
+# Author: Steven J. Bethard <steven.bethard@gmail.com>.
"""Command-line parsing library
@@ -75,7 +61,7 @@
still considered an implementation detail.)
"""
-__version__ = '1.1a1'
+__version__ = '1.1'
__all__ = [
'ArgumentParser',
'ArgumentError',
@@ -97,40 +83,10 @@
from gettext import gettext as _
-try:
- _set = set
-except NameError:
- from sets import Set as _set
-
-try:
- _basestring = basestring
-except NameError:
- _basestring = str
-
-try:
- _sorted = sorted
-except NameError:
-
- def _sorted(iterable, reverse=False):
- result = list(iterable)
- result.sort()
- if reverse:
- result.reverse()
- return result
-
def _callable(obj):
return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
-# silence Python 2.6 buggy warnings about Exception.message
-if _sys.version_info[:2] == (2, 6):
- import warnings
- warnings.filterwarnings(
- action='ignore',
- message='BaseException.message has been deprecated as of Python 2.6',
- category=DeprecationWarning,
- module='argparse')
-
SUPPRESS = '==SUPPRESS=='
@@ -163,7 +119,7 @@ def __repr__(self):
return '%s(%s)' % (type_name, ', '.join(arg_strings))
def _get_kwargs(self):
- return _sorted(self.__dict__.items())
+ return sorted(self.__dict__.items())
def _get_args(self):
return []
@@ -416,7 +372,7 @@ def get_lines(parts, indent, prefix=None):
def _format_actions_usage(self, actions, groups):
# find group indices and identify actions in groups
- group_actions = _set()
+ group_actions = set()
inserts = {}
for group in groups:
try:
@@ -486,7 +442,7 @@ def _format_actions_usage(self, actions, groups):
parts.append(part)
# insert things at the necessary indices
- for i in _sorted(inserts, reverse=True):
+ for i in sorted(inserts, reverse=True):
parts[i:i] = [inserts[i]]
# join all the action items with spaces
@@ -621,6 +577,9 @@ def _expand_help(self, action):
for name in list(params):
if params[name] is SUPPRESS:
del params[name]
+ for name in list(params):
+ if hasattr(params[name], '__name__'):
+ params[name] = params[name].__name__
if params.get('choices') is not None:
choices_str = ', '.join([str(c) for c in params['choices']])
params['choices'] = choices_str
@@ -1028,7 +987,7 @@ def __init__(self,
version=None,
dest=SUPPRESS,
default=SUPPRESS,
- help=None):
+ help="show program's version number and exit"):
super(_VersionAction, self).__init__(
option_strings=option_strings,
dest=dest,
@@ -1169,7 +1128,10 @@ class Namespace(_AttributeHolder):
"""
def __init__(self, **kwargs):
- self.__dict__.update(**kwargs)
+ for name in kwargs:
+ setattr(self, name, kwargs[name])
+
+ __hash__ = None
def __eq__(self, other):
return vars(self) == vars(other)
@@ -1296,6 +1258,12 @@ def add_argument(self, *args, **kwargs):
if not _callable(action_class):
raise ValueError('unknown action "%s"' % action_class)
action = action_class(**kwargs)
+
+ # raise an error if the action type is not callable
+ type_func = self._registry_get('type', action.type, action.type)
+ if not _callable(type_func):
+ raise ValueError('%r is not callable' % type_func)
+
return self._add_action(action)
def add_argument_group(self, *args, **kwargs):
@@ -1393,31 +1361,19 @@ def _get_optional_kwargs(self, *args, **kwargs):
option_strings = []
long_option_strings = []
for option_string in args:
- # error on one-or-fewer-character option strings
- if len(option_string) < 2:
- msg = _('invalid option string %r: '
- 'must be at least two characters long')
- raise ValueError(msg % option_string)
-
# error on strings that don't start with an appropriate prefix
if not option_string[0] in self.prefix_chars:
msg = _('invalid option string %r: '
'must start with a character %r')
tup = option_string, self.prefix_chars
raise ValueError(msg % tup)
- # error on strings that are all prefix characters
- if not (_set(option_string) - _set(self.prefix_chars)):
- msg = _('invalid option string %r: '
- 'must contain characters other than %r')
- tup = option_string, self.prefix_chars
- raise ValueError(msg % tup)
-
# strings starting with two prefix characters are long options
option_strings.append(option_string)
if option_string[0] in self.prefix_chars:
- if option_string[1] in self.prefix_chars:
- long_option_strings.append(option_string)
+ if len(option_string) > 1:
+ if option_string[1] in self.prefix_chars:
+ long_option_strings.append(option_string)
# infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
dest = kwargs.pop('dest', None)
@@ -1427,6 +1383,9 @@ def _get_optional_kwargs(self, *args, **kwargs):
else:
dest_option_string = option_strings[0]
dest = dest_option_string.lstrip(self.prefix_chars)
+ if not dest:
+ msg = _('dest= is required for options like %r')
+ raise ValueError(msg % option_string)
dest = dest.replace('-', '_')
# return the updated keyword arguments
@@ -1542,7 +1501,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
- usage -- A usage message (default: auto-generated from arguments)
- description -- A description of what the program does
- epilog -- Text following the argument descriptions
- - version -- Add a -v/--version option with the given version string
- parents -- Parsers whose arguments should be copied into this one
- formatter_class -- HelpFormatter class for printing help messages
- prefix_chars -- Characters that prefix optional arguments
@@ -1567,6 +1525,14 @@ def __init__(self,
conflict_handler='error',
add_help=True):
+ if version is not None:
+ import warnings
+ warnings.warn(
+ """The "version" argument to ArgumentParser is deprecated. """
+ """Please use """
+ """"add_argument(..., action='version', version="N", ...)" """
+ """instead""", DeprecationWarning)
+
superinit = super(ArgumentParser, self).__init__
superinit(description=description,
prefix_chars=prefix_chars,
@@ -1708,7 +1674,7 @@ def parse_known_args(self, args=None, namespace=None):
if not hasattr(namespace, action.dest):
if action.default is not SUPPRESS:
default = action.default
- if isinstance(action.default, _basestring):
+ if isinstance(action.default, basestring):
default = self._get_value(action, default)
setattr(namespace, action.dest, default)
@@ -1768,8 +1734,8 @@ def _parse_known_args(self, arg_strings, namespace):
arg_strings_pattern = ''.join(arg_string_pattern_parts)
# converts arg strings to the appropriate and then takes the action
- seen_actions = _set()
- seen_non_default_actions = _set()
+ seen_actions = set()
+ seen_non_default_actions = set()
def take_action(action, argument_strings, option_string=None):
seen_actions.add(action)
@@ -1973,7 +1939,10 @@ def _read_args_from_files(self, arg_strings):
try:
args_file = open(arg_string[1:])
try:
- arg_strings = args_file.read().splitlines()
+ arg_strings = []
+ for arg_line in args_file.read().splitlines():
+ for arg in self.convert_arg_line_to_args(arg_line):
+ arg_strings.append(arg)
arg_strings = self._read_args_from_files(arg_strings)
new_arg_strings.extend(arg_strings)
finally:
@@ -1985,6 +1954,9 @@ def _read_args_from_files(self, arg_strings):
# return the modified argument list
return new_arg_strings
+ def convert_arg_line_to_args(self, arg_line):
+ return [arg_line]
+
def _match_argument(self, action, arg_strings_pattern):
# match the pattern for this action to the arg strings
nargs_pattern = self._get_nargs_pattern(action)
@@ -2029,15 +2001,15 @@ def _parse_optional(self, arg_string):
if not arg_string[0] in self.prefix_chars:
return None
- # if it's just dashes, it was meant to be positional
- if not arg_string.strip('-'):
- return None
-
# if the option string is present in the parser, return the action
if arg_string in self._option_string_actions:
action = self._option_string_actions[arg_string]
return action, arg_string, None
+ # if it's just a single character, it was meant to be positional
+ if len(arg_string) == 1:
+ return None
+
# if the option string before the "=" is present, return the action
if '=' in arg_string:
option_string, explicit_arg = arg_string.split('=', 1)
@@ -2176,7 +2148,7 @@ def _get_values(self, action, arg_strings):
value = action.const
else:
value = action.default
- if isinstance(value, _basestring):
+ if isinstance(value, basestring):
value = self._get_value(action, value)
self._check_value(action, value)
@@ -2279,6 +2251,11 @@ def format_help(self):
return formatter.format_help()
def format_version(self):
+ import warnings
+ warnings.warn(
+ 'The format_version method is deprecated -- the "version" '
+ 'argument to ArgumentParser is no longer supported.',
+ DeprecationWarning)
formatter = self._get_formatter()
formatter.add_text(self.version)
return formatter.format_help()
@@ -2300,6 +2277,11 @@ def print_help(self, file=None):
self._print_message(self.format_help(), file)
def print_version(self, file=None):
+ import warnings
+ warnings.warn(
+ 'The print_version method is deprecated -- the "version" '
+ 'argument to ArgumentParser is no longer supported.',
+ DeprecationWarning)
self._print_message(self.format_version(), file)
def _print_message(self, message, file=None):
@@ -0,0 +1,4 @@
+try:
+ from configobj import *
+except ImportError:
+ from _configobj import *
@@ -0,0 +1,8 @@
+try:
+ from decorator import *
+ from decorator import getinfo, new_wrapper
+ # the following funcion is deprecated so using the python own one
+ from functools import update_wrapper
+except ImportError:
+ from _decorator import *
+ from _decorator import getinfo, update_wrapper, new_wrapper
@@ -0,0 +1,4 @@
+try:
+ from numpy.testing.decorators import *
+except ImportError:
+ from _decorators import *
@@ -0,0 +1,4 @@
+try:
+ from guid import *
+except ImportError:
+ from _guid import *
File renamed without changes.
@@ -0,0 +1,4 @@
+try:
+ from mglob import *
+except ImportError:
+ from _mglob import *
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
r""" mglob - enhanced file list expansion module
Use as stand-alone utility (for xargs, `backticks` etc.),
@@ -0,0 +1,4 @@
+try:
+ from path import *
+except ImportError:
+ from _path import *
File renamed without changes.
@@ -0,0 +1,5 @@
+try:
+ import pexpect
+ from pexpect import *
+except ImportError:
+ from _pexpect import *
@@ -0,0 +1,4 @@
+try:
+ from pyparsing import *
+except ImportError:
+ from _pyparsing import *
@@ -0,0 +1,4 @@
+try:
+ from simplegeneric import *
+except ImportError:
+ from _simplegeneric import *
@@ -0,0 +1,8 @@
+try:
+ import validate
+ if '__docformat__' in validate.__all__ and validate.__version__.split('.') >= ['1', '0', '1']:
+ # __docformat__ was removed in 1.0.1 but
+ validate.__all__ = [i for i in validate.__all__ if i != '__docformat__']
+ from validate import *
+except ImportError:
+ from _validate import *
File renamed without changes.
Oops, something went wrong.