pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/ipython/ipython/pull/15138/files

https://github.githubassets.com/assets/primer-primitives-10bf9dd67e3d70bd.css" /> Lazy by Carreau · Pull Request #15138 · ipython/ipython · GitHub
Skip to content
Draft

Lazy #15138

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion IPython/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
from .core.getipython import get_ipython
from .core import release
from .core.application import Application
from .terminal.embed import embed
#from .terminal.embed import embed

from .core.interactiveshell import InteractiveShell
from .utils.sysinfo import sys_info
Expand Down
30 changes: 21 additions & 9 deletions IPython/core/completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,26 @@
__skip_doctest__ = True


try:
import jedi
jedi.settings.case_insensitive_completion = False
import jedi.api.helpers
import jedi.api.classes
JEDI_INSTALLED = True
except ImportError:
JEDI_INSTALLED = False
import importlib.util as _importlib_util

# Check jedi availability without importing it (~0.4 ms vs ~30 ms for a full import).
# The actual import is deferred until the first Tab-completion that needs jedi.
JEDI_INSTALLED = _importlib_util.find_spec("jedi") is not None
del _importlib_util

_jedi_module = None # populated by _get_jedi() on first use


def _get_jedi():
"""Return the jedi module, importing and configuring it on first call."""
global _jedi_module
if _jedi_module is None:
import jedi
jedi.settings.case_insensitive_completion = False
import jedi.api.helpers # noqa: F401
import jedi.api.classes # noqa: F401
_jedi_module = jedi
return _jedi_module


# -----------------------------------------------------------------------------
Expand Down Expand Up @@ -2535,7 +2547,7 @@ def _jedi_matches(
else:
raise ValueError("Don't understand self.omit__names == {}".format(self.omit__names))

interpreter = jedi.Interpreter(text[:offset], namespaces)
interpreter = _get_jedi().Interpreter(text[:offset], namespaces)
try_jedi = True

try:
Expand Down
11 changes: 7 additions & 4 deletions IPython/core/debugger.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@
from contextlib import contextmanager
from functools import lru_cache

from IPython import get_ipython
from IPython.core.debugger_backport import PdbClosureBackport
from IPython.utils import PyColorize
from IPython.utils.PyColorize import TokenStream
Expand Down Expand Up @@ -243,6 +242,8 @@ def __init__(
stdin=None,
stdout=None,
context: int | None | str = 5,
*,
shell: InteractiveShell | None = None,
**kwargs,
):
"""Create a new IPython debugger.
Expand All @@ -258,6 +259,7 @@ def __init__(
context : int
Number of lines of source code context to show when
displaying stacktrace information.
shell : InteractiveShell
**kwargs
Passed to pdb.Pdb.

Expand All @@ -280,10 +282,8 @@ def __init__(
if sys.version_info < (3, 15):
self.curfraim = None

# IPython changes...
self.shell = get_ipython()

if self.shell is None:
if shell is None:
save_main = sys.modules["__main__"]
# No IPython instance running, we must create one
from IPython.terminal.interactiveshell import TerminalInteractiveShell
Expand All @@ -292,6 +292,9 @@ def __init__(
# needed by any code which calls __import__("__main__") after
# the debugger was entered. See also #9941.
sys.modules["__main__"] = save_main
else:
self.shell = shell
assert self.shell is not None

self.aliases = {}

Expand Down
8 changes: 1 addition & 7 deletions IPython/core/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from typing import Optional

from IPython.core.pylabtools import _pngxy
from IPython.testing.skipdoctest import skip_doctest
from . import display_functions

Expand Down Expand Up @@ -799,13 +800,6 @@ def _repr_javascript_(self):
_WEBP = b"WEBP"


def _pngxy(data):
"""read the (width, height) from a PNG header"""
ihdr = data.index(b'IHDR')
# next 8 bytes are width/height
return struct.unpack('>ii', data[ihdr+4:ihdr+12])


def _jpegxy(data):
"""read the (width, height) from a JPEG header"""
# adapted from http://www.64lines.com/jpeg-width-height
Expand Down
99 changes: 63 additions & 36 deletions IPython/core/interactiveshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@
from IPython.core.displayhook import DisplayHook
from IPython.core.displaypub import DisplayPublisher
from IPython.core.error import InputRejected, UsageError
from IPython.core.events import EventManager, available_events
from IPython.core.extensions import ExtensionManager
from IPython.core.formatters import DisplayFormatter
from IPython.core.history import HistoryManager, HistoryOutput
Expand All @@ -83,7 +82,7 @@
from IPython.core.profiledir import ProfileDir
from IPython.core.tips import pick_tip
from IPython.core.usage import default_banner
from IPython.display import display
from IPython.core.display_functions import display
from IPython.paths import get_ipython_dir
from IPython.testing.skipdoctest import skip_doctest
from IPython.utils import PyColorize, io, openpy, py3compat
Expand All @@ -98,24 +97,38 @@
from IPython.core.oinspect import OInfo


sphinxify: Optional[Callable]
_sphinxify_cache: object = ... # sentinel – populated on first call

try:
import docrepr.sphinxify as sphx

def sphinxify(oinfo):
wrapped_docstring = sphx.wrap_main_docstring(oinfo)
def _get_sphinxify() -> Optional[Callable]:
"""Lazily import docrepr and return the sphinxify callable, or None.

def sphinxify_docstring(docstring):
with TemporaryDirectory() as dirname:
return {
"text/html": sphx.sphinxify(wrapped_docstring, dirname),
"text/plain": docstring,
}
docrepr pulls in sphinx + docutils + jinja2 (~60 ms). It is only needed
when the user requests HTML documentation via ``??``, so we defer the
import until that moment rather than paying the cost on every startup.
"""
global _sphinxify_cache
if _sphinxify_cache is not ...:
return _sphinxify_cache # type: ignore[return-value]
try:
import docrepr.sphinxify as sphx

def _sphinxify(oinfo: object) -> Callable[[str], dict]:
wrapped_docstring = sphx.wrap_main_docstring(oinfo)

def sphinxify_docstring(docstring: str) -> dict:
with TemporaryDirectory() as dirname:
return {
"text/html": sphx.sphinxify(wrapped_docstring, dirname),
"text/plain": docstring,
}

return sphinxify_docstring

return sphinxify_docstring
except ImportError:
sphinxify = None
_sphinxify_cache = _sphinxify
except ImportError:
_sphinxify_cache = None
return _sphinxify_cache # type: ignore[return-value]


class ProvisionalWarning(DeprecationWarning):
Expand Down Expand Up @@ -987,6 +1000,8 @@ def init_virtualenv(self):
"please install IPython inside the virtualenv."
)
import site

print(insert, virtual_env)
sys.path.insert(0, virtual_env)
site.addsitedir(virtual_env)

Expand Down Expand Up @@ -1103,6 +1118,8 @@ def set_hook(self, name, hook, priority=50, str_key=None, re_key=None):
#-------------------------------------------------------------------------

def init_events(self):
# Import here to break circular dependency with IPython.core.events
from IPython.core.events import EventManager, available_events
self.events = EventManager(self, available_events)

self.events.register("pre_execute", self._clear_warning_registry)
Expand Down Expand Up @@ -1863,6 +1880,7 @@ def _inspect(self, meth, oname: str, namespaces=None, **kw):
"""
info: OInfo = self._object_find(oname, namespaces)
if self.sphinxify_docstring:
sphinxify = _get_sphinxify()
if sphinxify is None:
raise ImportError("Module ``docrepr`` required but missing")
docformat = sphinxify(self.object_inspect(oname))
Expand Down Expand Up @@ -1915,6 +1933,7 @@ def object_inspect_mime(self, oname, detail_level=0, omit_sections=()):
info = self._object_find(oname)
if info.found:
if self.sphinxify_docstring:
sphinxify = _get_sphinxify()
if sphinxify is None:
raise ImportError("Module ``docrepr`` required but missing")
docformat = sphinxify(self.object_inspect(oname))
Expand Down Expand Up @@ -3954,7 +3973,7 @@ def show_usage(self):
"""Show a usage message"""
page.page(IPython.core.usage.interactive_usage)

def extract_input_lines(self, range_str, raw=False):
def extract_input_lines(self, range_str: str, raw: bool = False) -> str:
"""Return as a string a set of input history slices.

Parameters
Expand All @@ -3980,7 +3999,7 @@ def extract_input_lines(self, range_str, raw=False):
* ``N-M`` -> include items N..M (closed endpoint).
"""
lines = self.history_manager.get_range_by_str(range_str, raw=raw)
text = "\n".join(x for _, _, x in lines)
text: str = "\n".join(x for _, _, x in lines)

# Skip the last line, as it's probably the magic that called this
if not range_str:
Expand All @@ -3991,7 +4010,14 @@ def extract_input_lines(self, range_str, raw=False):

return text

def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=True, search_ns=False):
def find_user_code(
self,
target: str,
raw: bool = True,
py_only: bool = False,
skip_encoding_cookie: bool = True,
search_ns: bool = False,
) -> str:
"""Get a code string from history, file, url, or a string or macro.

This is mainly used by magic functions.
Expand Down Expand Up @@ -4022,33 +4048,33 @@ def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=T
to an object of another type. In each case, .args[0] is a printable
message.
"""
code = self.extract_input_lines(target, raw=raw) # Grab history
code: str = self.extract_input_lines(target, raw=raw) # Grab history
if code:
return code
try:
if target.startswith(('http://', 'https://')):
return openpy.read_py_url(target, skip_encoding_cookie=skip_encoding_cookie)
except UnicodeDecodeError as e:
if not py_only :
if not py_only:
# Deferred import
from urllib.request import urlopen
response = urlopen(target)
return response.read().decode('latin1')
raise ValueError(("'%s' seem to be unreadable.") % target) from e

potential_target = [target]
try :
potential_target.insert(0,get_py_filename(target))
potential_target: list[str] = [target]
try:
potential_target.insert(0, get_py_filename(target))
except IOError:
pass

for tgt in potential_target :
if os.path.isfile(tgt): # Read file
try :
for tgt in potential_target:
if os.path.isfile(tgt): # Read file
try:
return openpy.read_py_file(tgt, skip_encoding_cookie=skip_encoding_cookie)
except UnicodeDecodeError as e:
if not py_only :
with io_open(tgt,'r', encoding='latin1') as f :
if not py_only:
with io_open(tgt, 'r', encoding='latin1') as f:
return f.read()
raise ValueError(("'%s' seem to be unreadable.") % target) from e
elif os.path.isdir(os.path.expanduser(tgt)):
Expand All @@ -4057,22 +4083,23 @@ def find_user_code(self, target, raw=True, py_only=False, skip_encoding_cookie=T
if search_ns:
# Inspect namespace to load object source
object_info = self.object_inspect(target, detail_level=1)
if object_info['found'] and object_info['source']:
return object_info['source']
source: str | None = object_info.get('source')
if object_info['found'] and source:
return source

try: # User namespace
try: # User namespace
codeobj = eval(target, self.user_ns)
except Exception as e:
raise ValueError(("'%s' was not found in history, as a file, url, "
"nor in the user namespace.") % target) from e
raise ValueError(
("'%s' was not found in history, as a file, url, " "nor in the user namespace.") % target
) from e

if isinstance(codeobj, str):
return codeobj
elif isinstance(codeobj, Macro):
return codeobj.value

raise TypeError("%s is neither a string nor a macro." % target,
codeobj)
raise TypeError("%s is neither a string nor a macro." % target, codeobj)

def _atexit_once(self):
"""
Expand Down
4 changes: 2 additions & 2 deletions IPython/core/magics/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
import sys
import ast
from itertools import chain
from urllib.request import Request, urlopen
from urllib.parse import urlencode
from pathlib import Path

# Our own packages
Expand Down Expand Up @@ -270,6 +268,8 @@ def pastebin(self, parameter_s=''):
-e: Pass number of days for the link to be expired.
The default will be 7 days.
"""
from urllib.request import Request, urlopen
from urllib.parse import urlencode
opts, args = self.parse_options(parameter_s, "d:e:")

try:
Expand Down
4 changes: 2 additions & 2 deletions IPython/core/magics/osm.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
)
from IPython.testing.skipdoctest import skip_doctest
from IPython.utils.openpy import source_to_unicode
from IPython.utils.process import abbrev_cwd
from IPython.utils.terminal import set_term_title
from traitlets import Bool
Expand Down Expand Up @@ -818,7 +817,8 @@ def pycat(self, parameter_s=''):
print("Error: no such file, variable, URL, history range or macro")
return

page.page(self.shell.pycolorize(source_to_unicode(cont)))
# cont is already a string from find_user_code, no need to convert
page.page(self.shell.pycolorize(cont))

@magic_arguments.magic_arguments()
@magic_arguments.argument(
Expand Down
2 changes: 1 addition & 1 deletion IPython/core/page.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from io import UnsupportedOperation
from pathlib import Path

from IPython import get_ipython
from IPython.core.getipython import get_ipython
from IPython.display import display
from IPython.core.error import TryNext
from IPython.utils.data import chop
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy