Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bab26ab

Browse files
committed
Merge remote-tracking branch 'public-upstream/master' into links-rebase
Conflicts: examples/Interactive Widgets/Widget Events.ipynb
2 parents c7253b2 + 7d035da commit bab26ab

536 files changed

Lines changed: 100114 additions & 37355 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ _build
55
docs/man/*.gz
66
docs/source/api/generated
77
docs/source/config/options
8+
docs/source/interactive/magics-generated.txt
89
docs/gh-pages
910
IPython/html/notebook/static/mathjax
1011
IPython/html/static/style/*.map
@@ -16,3 +17,6 @@ __pycache__
1617
.ipynb_checkpoints
1718
.tox
1819
.DS_Store
20+
\#*#
21+
.#*
22+
.coverage

.travis.yml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ before_install:
1111
# workaround for https://github.com/travis-ci/travis-cookbooks/issues/155
1212
- sudo rm -rf /dev/shm && sudo ln -s /run/shm /dev/shm
1313
# Pierre Carrier's PPA for PhantomJS and CasperJS
14-
- time sudo add-apt-repository -y ppa:pcarrier/ppa
15-
- time sudo apt-get update
16-
- time sudo apt-get install pandoc casperjs libzmq3-dev
17-
# pin tornado < 4 for js tests while phantom is on super old webkit
18-
- if [[ $GROUP == 'js' ]]; then pip install 'tornado<4'; fi
19-
- time pip install -f https://nipy.bic.berkeley.edu/wheelhouse/travis jinja2 sphinx pygments tornado requests mock pyzmq jsonschema jsonpointer mistune
14+
- sudo add-apt-repository -y ppa:pcarrier/ppa
15+
# Needed to get recent version of pandoc in ubntu 12.04
16+
- sudo add-apt-repository -y ppa:marutter/c2d4u
17+
- sudo apt-get update
18+
- sudo apt-get install pandoc casperjs libzmq3-dev
19+
- git clone --quiet --depth 1 https://github.com/minrk/travis-wheels travis-wheels
20+
- 'if [[ $GROUP == js* ]]; then python -m IPython.external.mathjax; fi'
2021
install:
21-
- time python setup.py install -q
22+
- pip install -f travis-wheels/wheelhouse file://$PWD#egg=ipython[all]
2223
script:
2324
- cd /tmp && iptest $GROUP
2425

Dockerfile

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ FROM ubuntu:14.04
55

66
MAINTAINER IPython Project <[email protected]>
77

8-
# Make sure apt is up to date
9-
RUN apt-get update
10-
RUN apt-get upgrade -y
8+
ENV DEBIAN_FRONTEND noninteractive
119

1210
# Not essential, but wise to set the lang
1311
# Note: Users with other languages should set this in their derivative image
14-
RUN apt-get install -y language-pack-en
12+
RUN apt-get update && apt-get install -y language-pack-en
1513
ENV LANGUAGE en_US.UTF-8
1614
ENV LANG en_US.UTF-8
1715
ENV LC_ALL en_US.UTF-8
@@ -20,14 +18,32 @@ RUN locale-gen en_US.UTF-8
2018
RUN dpkg-reconfigure locales
2119

2220
# Python binary dependencies, developer tools
23-
RUN apt-get install -y -q build-essential make gcc zlib1g-dev git && \
24-
apt-get install -y -q python python-dev python-pip python3-dev python3-pip && \
25-
apt-get install -y -q libzmq3-dev sqlite3 libsqlite3-dev pandoc libcurl4-openssl-dev nodejs nodejs-legacy npm
21+
RUN apt-get update && apt-get install -y -q \
22+
build-essential \
23+
make \
24+
gcc \
25+
zlib1g-dev \
26+
git \
27+
python \
28+
python-dev \
29+
python-pip \
30+
python3-dev \
31+
python3-pip \
32+
python-sphinx \
33+
python3-sphinx \
34+
libzmq3-dev \
35+
sqlite3 \
36+
libsqlite3-dev \
37+
pandoc \
38+
libcurl4-openssl-dev \
39+
nodejs \
40+
nodejs-legacy \
41+
npm
2642

2743
# In order to build from source, need less
28-
RUN npm install -g less
44+
RUN npm install -g less@1.7.5
2945

30-
RUN apt-get -y install fabric
46+
RUN pip install invoke
3147

3248
RUN mkdir -p /srv/
3349
WORKDIR /srv/
@@ -37,10 +53,14 @@ RUN chmod -R +rX /srv/ipython
3753

3854
# .[all] only works with -e, so use file://path#egg
3955
# Can't use -e because ipython2 and ipython3 will clobber each other
40-
RUN pip2 install --upgrade file:///srv/ipython#egg=ipython[all]
41-
RUN pip3 install --upgrade file:///srv/ipython#egg=ipython[all]
56+
RUN pip2 install file:///srv/ipython#egg=ipython[all]
57+
RUN pip3 install file:///srv/ipython#egg=ipython[all]
4258

4359
# install kernels
4460
RUN python2 -m IPython kernelspec install-self --system
4561
RUN python3 -m IPython kernelspec install-self --system
4662

63+
WORKDIR /tmp/
64+
65+
RUN iptest2
66+
RUN iptest3

IPython/config/application.py

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
from __future__ import print_function
88

9+
import json
910
import logging
1011
import os
1112
import re
@@ -123,7 +124,16 @@ class Application(SingletonConfigurable):
123124

124125
# A sequence of Configurable subclasses whose config=True attributes will
125126
# be exposed at the command line.
126-
classes = List([])
127+
classes = []
128+
@property
129+
def _help_classes(self):
130+
"""Define `App.help_classes` if CLI classes should differ from config file classes"""
131+
return getattr(self, 'help_classes', self.classes)
132+
133+
@property
134+
def _config_classes(self):
135+
"""Define `App.config_classes` if config file classes should differ from CLI classes."""
136+
return getattr(self, 'config_classes', self.classes)
127137

128138
# The version string of this application.
129139
version = Unicode(u'0.0')
@@ -256,7 +266,7 @@ def print_alias_help(self):
256266

257267
lines = []
258268
classdict = {}
259-
for cls in self.classes:
269+
for cls in self._help_classes:
260270
# include all parents (up to, but excluding Configurable) in available names
261271
for c in cls.mro()[:-3]:
262272
classdict[c.__name__] = c
@@ -331,15 +341,16 @@ def print_help(self, classes=False):
331341
self.print_options()
332342

333343
if classes:
334-
if self.classes:
344+
help_classes = self._help_classes
345+
if help_classes:
335346
print("Class parameters")
336347
print("----------------")
337348
print()
338349
for p in wrap_paragraphs(self.keyvalue_description):
339350
print(p)
340351
print()
341352

342-
for cls in self.classes:
353+
for cls in help_classes:
343354
cls.class_print_help()
344355
print()
345356
else:
@@ -412,7 +423,7 @@ def flatten_flags(self):
412423
# it will be a dict by parent classname of classes in our list
413424
# that are descendents
414425
mro_tree = defaultdict(list)
415-
for cls in self.classes:
426+
for cls in self._help_classes:
416427
clsname = cls.__name__
417428
for parent in cls.mro()[1:-3]:
418429
# exclude cls itself and Configurable,HasTraits,object
@@ -491,27 +502,32 @@ def _load_config_files(cls, basefilename, path=None, log=None):
491502
492503
yield each config object in turn.
493504
"""
494-
pyloader = PyFileConfigLoader(basefilename+'.py', path=path, log=log)
495-
jsonloader = JSONFileConfigLoader(basefilename+'.json', path=path, log=log)
496-
config = None
497-
for loader in [pyloader, jsonloader]:
498-
try:
499-
config = loader.load_config()
500-
except ConfigFileNotFound:
501-
pass
502-
except Exception:
503-
# try to get the full filename, but it will be empty in the
504-
# unlikely event that the error raised before filefind finished
505-
filename = loader.full_filename or basefilename
506-
# problem while running the file
507-
if log:
508-
log.error("Exception while loading config file %s",
509-
filename, exc_info=True)
510-
else:
511-
if log:
512-
log.debug("Loaded config file: %s", loader.full_filename)
513-
if config:
514-
yield config
505+
506+
if not isinstance(path, list):
507+
path = [path]
508+
for path in path[::-1]:
509+
# path list is in descending priority order, so load files backwards:
510+
pyloader = PyFileConfigLoader(basefilename+'.py', path=path, log=log)
511+
jsonloader = JSONFileConfigLoader(basefilename+'.json', path=path, log=log)
512+
config = None
513+
for loader in [pyloader, jsonloader]:
514+
try:
515+
config = loader.load_config()
516+
except ConfigFileNotFound:
517+
pass
518+
except Exception:
519+
# try to get the full filename, but it will be empty in the
520+
# unlikely event that the error raised before filefind finished
521+
filename = loader.full_filename or basefilename
522+
# problem while running the file
523+
if log:
524+
log.error("Exception while loading config file %s",
525+
filename, exc_info=True)
526+
else:
527+
if log:
528+
log.debug("Loaded config file: %s", loader.full_filename)
529+
if config:
530+
yield config
515531

516532
raise StopIteration
517533

@@ -520,8 +536,17 @@ def _load_config_files(cls, basefilename, path=None, log=None):
520536
def load_config_file(self, filename, path=None):
521537
"""Load config files by filename and path."""
522538
filename, ext = os.path.splitext(filename)
539+
loaded = []
523540
for config in self._load_config_files(filename, path=path, log=self.log):
541+
loaded.append(config)
524542
self.update_config(config)
543+
if len(loaded) > 1:
544+
collisions = loaded[0].collisions(loaded[1])
545+
if collisions:
546+
self.log.warn("Collisions detected in {0}.py and {0}.json config files."
547+
" {0}.json has higher priority: {1}".format(
548+
filename, json.dumps(collisions, indent=2),
549+
))
525550

526551

527552
def generate_config_file(self):
@@ -530,7 +555,7 @@ def generate_config_file(self):
530555
lines.append('')
531556
lines.append('c = get_config()')
532557
lines.append('')
533-
for cls in self.classes:
558+
for cls in self._config_classes:
534559
lines.append(cls.class_config_section())
535560
return '\n'.join(lines)
536561

IPython/config/loader.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,27 @@ def merge(self, other):
193193
to_update[k] = copy.deepcopy(v)
194194

195195
self.update(to_update)
196-
196+
197+
def collisions(self, other):
198+
"""Check for collisions between two config objects.
199+
200+
Returns a dict of the form {"Class": {"trait": "collision message"}}`,
201+
indicating which values have been ignored.
202+
203+
An empty dict indicates no collisions.
204+
"""
205+
collisions = {}
206+
for section in self:
207+
if section not in other:
208+
continue
209+
mine = self[section]
210+
theirs = other[section]
211+
for key in mine:
212+
if key in theirs and mine[key] != theirs[key]:
213+
collisions.setdefault(section, {})
214+
collisions[section][key] = "%r ignored, using %r" % (mine[key], theirs[key])
215+
return collisions
216+
197217
def __contains__(self, key):
198218
# allow nested contains of the form `"Section.key" in config`
199219
if '.' in key:
@@ -565,7 +585,7 @@ def clear(self):
565585

566586

567587
def _decode_argv(self, argv, enc=None):
568-
"""decode argv if bytes, using stin.encoding, falling back on default enc"""
588+
"""decode argv if bytes, using stdin.encoding, falling back on default enc"""
569589
uargv = []
570590
if enc is None:
571591
enc = DEFAULT_ENCODING

IPython/config/tests/test_application.py

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,18 @@
11
# coding: utf-8
22
"""
33
Tests for IPython.config.application.Application
4-
5-
Authors:
6-
7-
* Brian Granger
84
"""
95

10-
#-----------------------------------------------------------------------------
11-
# Copyright (C) 2008-2011 The IPython Development Team
12-
#
13-
# Distributed under the terms of the BSD License. The full license is in
14-
# the file COPYING, distributed as part of this software.
15-
#-----------------------------------------------------------------------------
16-
17-
#-----------------------------------------------------------------------------
18-
# Imports
19-
#-----------------------------------------------------------------------------
6+
# Copyright (c) IPython Development Team.
7+
# Distributed under the terms of the Modified BSD License.
208

219
import logging
10+
import os
2211
from io import StringIO
2312
from unittest import TestCase
2413

14+
pjoin = os.path.join
15+
2516
import nose.tools as nt
2617

2718
from IPython.config.configurable import Configurable
@@ -31,13 +22,11 @@
3122
Application
3223
)
3324

25+
from IPython.utils.tempdir import TemporaryDirectory
3426
from IPython.utils.traitlets import (
3527
Bool, Unicode, Integer, List, Dict
3628
)
3729

38-
#-----------------------------------------------------------------------------
39-
# Code
40-
#-----------------------------------------------------------------------------
4130

4231
class Foo(Configurable):
4332

@@ -189,5 +178,21 @@ def test_extra_args(self):
189178
def test_unicode_argv(self):
190179
app = MyApp()
191180
app.parse_command_line(['ünîcødé'])
192-
181+
182+
def test_multi_file(self):
183+
app = MyApp()
184+
app.log = logging.getLogger()
185+
name = 'config.py'
186+
with TemporaryDirectory('_1') as td1:
187+
with open(pjoin(td1, name), 'w') as f1:
188+
f1.write("get_config().MyApp.Bar.b = 1")
189+
with TemporaryDirectory('_2') as td2:
190+
with open(pjoin(td2, name), 'w') as f2:
191+
f2.write("get_config().MyApp.Bar.b = 2")
192+
app.load_config_file(name, path=[td2, td1])
193+
app.init_bar()
194+
self.assertEqual(app.bar.b, 2)
195+
app.load_config_file(name, path=[td1, td2])
196+
app.init_bar()
197+
self.assertEqual(app.bar.b, 1)
193198

0 commit comments

Comments
 (0)