##// END OF EJS Templates
Reset the interactive namespace __warningregistry__ before executing code...
Reset the interactive namespace __warningregistry__ before executing code Fixes #6611. Idea: Right now, people often don't see important warnings when running code in IPython, because (to a first approximation) any given warning will only issue once per session. Blink and you'll miss it! This is a very common contributor to confused emails to numpy-discussion. E.g.: In [5]: 1 / my_array_with_random_contents /home/njs/.user-python2.7-64bit-3/bin/ipython:1: RuntimeWarning: divide by zero encountered in divide #!/home/njs/.user-python2.7-64bit-3/bin/python Out[5]: array([ 1.77073316, -2.29765021, -2.01800811, ..., 1.13871243, -1.08302964, -8.6185091 ]) Oo, right, guess I gotta be careful of those zeros -- thanks, numpy, for giving me that warning! A few days later: In [592]: 1 / some_other_array Out[592]: array([ 3.07735763, 0.50769289, 0.83984078, ..., -0.67563917, -0.85736257, -1.36511271]) Oops, it turns out that this array had a zero in it too, and that's going to bite me later. But no warning this time! The effect of this commit is to make it so that warnings triggered by the code in cell 5 do *not* suppress warnings triggered by the code in cell 592. Note that this only applies to warnings triggered *directly* by code entered interactively -- if somepkg.foo() calls anotherpkg.bad_func() which issues a warning, then this warning will still only be displayed once, even if multiple cells call somepkg.foo(). But if cell 5 and cell 592 both call anotherpkg.bad_func() directly, then both will get warnings. (Important exception: if foo() is defined *interactively*, and calls anotherpkg.bad_func(), then every cell that calls foo() will display the warning again. This is unavoidable without fixes to CPython upstream.) Explanation: Python's warning system has some weird quirks. By default, it tries to suppress duplicate warnings, where "duplicate" means the same warning message triggered twice by the same line of code. This requires determining which line of code is responsible for triggering a warning, and this is controlled by the stacklevel= argument to warnings.warn. Basically, though, the idea is that if foo() calls bar() which calls baz() which calls some_deprecated_api(), then baz() will get counted as being "responsible", and the warning system will make a note that the usage of some_deprecated_api() inside baz() has already been warned about and doesn't need to be warned about again. So far so good. To accomplish this, obviously, there has to be a record of somewhere which line this was. You might think that this would be done by recording the filename:linenumber pair in a dict inside the warnings module, or something like that. You would be wrong. What actually happens is that the warnings module will use stack introspection to reach into baz()'s execution environment, create a global (module-level) variable there named __warningregistry__, and then, inside this dictionary, record just the line number. Basically, it assumes that any given module contains only one line 1, only one line 2, etc., so storing the filename is irrelevant. Obviously for interactive code this is totally wrong -- all cells share the same execution environment and global namespace, and they all contain a new line 1. Currently the warnings module treats these as if they were all the same line. In fact they are not the same line; once we have executed a given chunk of code, we will never see those particular lines again. As soon as a given chunk of code finishes executing, its line number labels become meaningless, and the corresponding warning registry entries become meaningless as well. Therefore, with this patch we delete the __warningregistry__ each time we execute a new block of code.

File last commit:

r16181:c02e83e2
r18548:61431d7d
Show More
localinterfaces.py
278 lines | 8.2 KiB | text/x-python | PythonLexer
MinRK
added localinterfaces to utils
r3143 """Simple utility for building a list of local IPs using the socket module.
This module defines two constants:
Bernardo B. Marques
remove all trailling spaces
r4872 LOCALHOST : The loopback interface, or the first interface that points to this
MinRK
added localinterfaces to utils
r3143 machine. It will *almost* always be '127.0.0.1'
LOCAL_IPS : A list of IP addresses, loopback first, that point to this machine.
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 This will include LOCALHOST, PUBLIC_IPS, and aliases for all hosts,
such as '0.0.0.0'.
W. Trevor King
utils.localinterfaces: Add PUBLIC_IPS to consolidate socket logic...
r9250
PUBLIC_IPS : A list of public IP addresses that point to this machine.
Use these to tell remote clients where to find you.
MinRK
added localinterfaces to utils
r3143 """
#-----------------------------------------------------------------------------
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 # Copyright (C) 2010 The IPython Development Team
MinRK
added localinterfaces to utils
r3143 #
# Distributed under the terms of the BSD License. The full license is in
# the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 import os
MinRK
relax ipconfig matching on Windows...
r13613 import re
MinRK
added localinterfaces to utils
r3143 import socket
W. Trevor King
utils.localinterfaces: Uniquify LOCAL_IPS...
r9248 from .data import uniq_stable
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 from .process import get_output_error_code
from .warn import warn
W. Trevor King
utils.localinterfaces: Uniquify LOCAL_IPS...
r9248
MinRK
added localinterfaces to utils
r3143 #-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------
LOCAL_IPS = []
W. Trevor King
utils.localinterfaces: Add PUBLIC_IPS to consolidate socket logic...
r9250 PUBLIC_IPS = []
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 LOCALHOST = ''
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591
def _only_once(f):
"""decorator to only run a function once"""
f.called = False
Thomas Kluyver
Add test for IPython.utils.localinterfaces
r12960 def wrapped(**kwargs):
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591 if f.called:
return
Thomas Kluyver
Add test for IPython.utils.localinterfaces
r12960 ret = f(**kwargs)
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591 f.called = True
return ret
return wrapped
def _requires_ips(f):
"""decorator to ensure load_ips has been run before f"""
def ips_loaded(*args, **kwargs):
_load_ips()
return f(*args, **kwargs)
return ips_loaded
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 # subprocess-parsing ip finders
class NoIPAddresses(Exception):
pass
def _populate_from_list(addrs):
"""populate local and public IPs from flat list of all IPs"""
if not addrs:
raise NoIPAddresses
global LOCALHOST
public_ips = []
local_ips = []
for ip in addrs:
local_ips.append(ip)
if not ip.startswith('127.'):
public_ips.append(ip)
elif not LOCALHOST:
LOCALHOST = ip
if not LOCALHOST:
LOCALHOST = '127.0.0.1'
local_ips.insert(0, LOCALHOST)
local_ips.extend(['0.0.0.0', ''])
LOCAL_IPS[:] = uniq_stable(local_ips)
PUBLIC_IPS[:] = uniq_stable(public_ips)
def _load_ips_ifconfig():
"""load ip addresses from `ifconfig` output (posix)"""
out, err, rc = get_output_error_code('ifconfig')
if rc:
# no ifconfig, it's usually in /sbin and /sbin is not on everyone's PATH
out, err, rc = get_output_error_code('/sbin/ifconfig')
if rc:
raise IOError("no ifconfig: %s" % err)
Thomas Kluyver
Fix loading IP addresses from subprocess output
r12961 lines = out.splitlines()
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 addrs = []
for line in lines:
blocks = line.lower().split()
Thomas Kluyver
Fix loading IP addresses from subprocess output
r12961 if (len(blocks) >= 2) and (blocks[0] == 'inet'):
James Porter
Use `startswith` instead of `in`
r13986 if blocks[1].startswith("addr:"):
James Porter
Fix bug in determination of public ips....
r13982 addrs.append(blocks[1].split(":")[1])
else:
addrs.append(blocks[1])
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 _populate_from_list(addrs)
def _load_ips_ip():
"""load ip addresses from `ip addr` output (Linux)"""
out, err, rc = get_output_error_code('ip addr')
if rc:
raise IOError("no ip: %s" % err)
Thomas Kluyver
Fix loading IP addresses from subprocess output
r12961 lines = out.splitlines()
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 addrs = []
for line in lines:
blocks = line.lower().split()
Thomas Kluyver
Fix loading IP addresses from subprocess output
r12961 if (len(blocks) >= 2) and (blocks[0] == 'inet'):
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 addrs.append(blocks[1].split('/')[0])
_populate_from_list(addrs)
Thomas Kluyver
Fix ipconfig regex pattern...
r16181 _ipconfig_ipv4_pat = re.compile(r'ipv4.*?(\d+\.\d+\.\d+\.\d+)$', re.IGNORECASE)
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832
def _load_ips_ipconfig():
"""load ip addresses from `ipconfig` output (Windows)"""
out, err, rc = get_output_error_code('ipconfig')
if rc:
raise IOError("no ipconfig: %s" % err)
Thomas Kluyver
Fix loading IP addresses from subprocess output
r12961 lines = out.splitlines()
MinRK
don't include 127.0.0.1 in load_ips_ipconfig
r13614 addrs = []
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 for line in lines:
MinRK
relax ipconfig matching on Windows...
r13613 m = _ipconfig_ipv4_pat.match(line.strip())
if m:
addrs.append(m.group(1))
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 _populate_from_list(addrs)
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 def _load_ips_netifaces():
"""load ip addresses with netifaces"""
import netifaces
global LOCALHOST
local_ips = []
public_ips = []
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 # list of iface names, 'lo0', 'eth0', etc.
for iface in netifaces.interfaces():
# list of ipv4 addrinfo dicts
ipv4s = netifaces.ifaddresses(iface).get(netifaces.AF_INET, [])
for entry in ipv4s:
addr = entry.get('addr')
if not addr:
continue
if not (iface.startswith('lo') or addr.startswith('127.')):
public_ips.append(addr)
elif not LOCALHOST:
LOCALHOST = addr
local_ips.append(addr)
if not LOCALHOST:
# we never found a loopback interface (can this ever happen?), assume common default
LOCALHOST = '127.0.0.1'
local_ips.insert(0, LOCALHOST)
local_ips.extend(['0.0.0.0', ''])
LOCAL_IPS[:] = uniq_stable(local_ips)
PUBLIC_IPS[:] = uniq_stable(public_ips)
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 def _load_ips_gethostbyname():
"""load ip addresses with socket.gethostbyname_ex
This can be slow.
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591 """
global LOCALHOST
try:
LOCAL_IPS[:] = socket.gethostbyname_ex('localhost')[2]
except socket.error:
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 # assume common default
LOCAL_IPS[:] = ['127.0.0.1']
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591
try:
hostname = socket.gethostname()
PUBLIC_IPS[:] = socket.gethostbyname_ex(hostname)[2]
# try hostname.local, in case hostname has been short-circuited to loopback
if not hostname.endswith('.local') and all(ip.startswith('127') for ip in PUBLIC_IPS):
PUBLIC_IPS[:] = socket.gethostbyname_ex(socket.gethostname() + '.local')[2]
except socket.error:
pass
finally:
PUBLIC_IPS[:] = uniq_stable(PUBLIC_IPS)
LOCAL_IPS.extend(PUBLIC_IPS)
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591 # include all-interface aliases: 0.0.0.0 and ''
LOCAL_IPS.extend(['0.0.0.0', ''])
LOCAL_IPS[:] = uniq_stable(LOCAL_IPS)
LOCALHOST = LOCAL_IPS[0]
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 def _load_ips_dumb():
"""Fallback in case of unexpected failure"""
global LOCALHOST
LOCALHOST = '127.0.0.1'
LOCAL_IPS[:] = [LOCALHOST, '0.0.0.0', '']
PUBLIC_IPS[:] = []
@_only_once
Thomas Kluyver
Add test for IPython.utils.localinterfaces
r12960 def _load_ips(suppress_exceptions=True):
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 """load the IPs that point to this machine
This function will only ever be called once.
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 It will use netifaces to do it quickly if available.
Then it will fallback on parsing the output of ifconfig / ip addr / ipconfig, as appropriate.
Finally, it will fallback on socket.gethostbyname_ex, which can be slow.
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 """
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 try:
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 # first priority, use netifaces
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 try:
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 return _load_ips_netifaces()
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 except ImportError:
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 pass
# second priority, parse subprocess output (how reliable is this?)
if os.name == 'nt':
try:
return _load_ips_ipconfig()
except (IOError, NoIPAddresses):
pass
else:
try:
return _load_ips_ifconfig()
except (IOError, NoIPAddresses):
pass
try:
return _load_ips_ip()
except (IOError, NoIPAddresses):
pass
# lowest priority, use gethostbyname
return _load_ips_gethostbyname()
except Exception as e:
Thomas Kluyver
Add test for IPython.utils.localinterfaces
r12960 if not suppress_exceptions:
raise
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830 # unexpected error shouldn't crash, load dumb default values instead.
MinRK
parse ifconfig / ip addr / ipconfig in localinterfaces...
r12832 warn("Unexpected error discovering local network interfaces: %s" % e)
_load_ips_dumb()
MinRK
use netifaces for faster IPython.utils.localinterfaces
r12830
MinRK
avoid executing code in utils.localinterfaces at import time...
r12591 @_requires_ips
def local_ips():
"""return the IP addresses that point to this machine"""
return LOCAL_IPS
@_requires_ips
def public_ips():
"""return the IP addresses for this machine that are visible to other machines"""
return PUBLIC_IPS
@_requires_ips
def localhost():
"""return ip for localhost (almost always 127.0.0.1)"""
return LOCALHOST
@_requires_ips
def is_local_ip(ip):
"""does `ip` point to this machine?"""
return ip in LOCAL_IPS
@_requires_ips
def is_public_ip(ip):
"""is `ip` a publicly visible address?"""
return ip in PUBLIC_IPS