From c39326616c6d0c59a8f33bc7091b48d4e8e34caa Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Thu, 19 Mar 2020 01:04:48 +0100 Subject: [PATCH] A lot of improvements for the features & limitations docs --- README.rst | 4 +-- docs/docs/features.rst | 78 ++++++++++++++++++++++++++---------------- jedi/utils.py | 19 +++++----- 3 files changed, 61 insertions(+), 40 deletions(-) diff --git a/README.rst b/README.rst index 3d9592a4..f8f287d4 100644 --- a/README.rst +++ b/README.rst @@ -101,8 +101,8 @@ You don't want to use ``pip``? Please refer to the `manual `_. -Feature Support and Caveats -=========================== +Features and Limitations +======================== Jedi really understands your Python code. For a comprehensive list what Jedi understands, see: `Features diff --git a/docs/docs/features.rst b/docs/docs/features.rst index 8de4bdcd..443eac63 100644 --- a/docs/docs/features.rst +++ b/docs/docs/features.rst @@ -1,12 +1,12 @@ .. include:: ../global.rst -Features and Caveats -==================== +Features and Limitations +======================== -Jedi's main API calls and featuresare: +Jedi's main API calls and features are: - Autocompletion: :meth:`.Script.complete`; It's also possible to get it - working in (:ref:`your REPL (IPython, etc.) `) + working in :ref:`your REPL (IPython, etc.) ` - Goto/Type Inference: :meth:`.Script.goto` and :meth:`.Script.infer` - Static Analysis: :meth:`.Script.get_names` and :meth:`.Script.get_syntax_errors` - Refactorings: :meth:`.Script.rename`, :meth:`.Script.inline`, @@ -20,9 +20,11 @@ Basic Features - Ignores syntax errors and wrong indentation - Can deal with complex module / function / class structures - Great ``virtualenv``/``venv`` support -- Can infer function arguments from PEP0484-style :ref:`type hints `, - sphinx, epydoc and basic numpydoc docstrings +- Works great with Python's :ref:`type hinting `, - Understands stub files +- Can infer function arguments for sphinx, epydoc and basic numpydoc docstrings +- Is overall a very solid piece of software that has been refined for a long + time. Bug reports are very welcome and are usually fixed within a few weeks. Supported Python Features @@ -37,7 +39,7 @@ Supported Python Features - ``*args`` / ``**kwargs`` - decorators / lambdas / closures - generators / iterators -- some descriptors: property / staticmethod / classmethod +- descriptors: property / staticmethod / classmethod / custom descriptors - some magic methods: ``__call__``, ``__iter__``, ``__next__``, ``__get__``, ``__getitem__``, ``__init__`` - ``list.append()``, ``set.add()``, ``list.extend()``, etc. @@ -45,33 +47,33 @@ Supported Python Features - relative imports - ``getattr()`` / ``__getattr__`` / ``__getattribute__`` - function annotations -- class decorators (py3k feature, are being ignored too, until I find a use - case, that doesn't work with |jedi|) -- simple/usual ``sys.path`` modifications +- simple/typical ``sys.path`` modifications - ``isinstance`` checks for if/while/assert - namespace packages (includes ``pkgutil``, ``pkg_resources`` and PEP420 namespaces) - Django / Flask / Buildout support - Understands Pytest fixtures -Not Supported -------------- +Limitations +----------- -Things that will probably never be implemented: +In general Jedi's limit are quite high, but for very big projects or very +complex code, sometimes Jedi intentionally stops type inference, to avoid +hanging for a long time. -- Arbitrary metaclasses (how could an auto-completion ever support this), some - of them like enums and dataclasses are reimplemented in Jedi to make them - work. Most of the time stubs are good enough to get type inference working, - even when metaclasses are involved. +Additionally there are some Python patterns Jedi does not support. This is +intentional and below should be a complete list: + +- Arbitrary metaclasses: Some metaclasses like enums and dataclasses are + reimplemented in Jedi to make them work. Most of the time stubs are good + enough to get type inference working, even when metaclasses are involved. - ``setattr()``, ``__import__()`` - Writing to some dicts: ``globals()``, ``locals()``, ``object.__dict__`` - Manipulations of instances outside the instance variables without using - methods + methods -Caveats -------- - -**Slow Performance** +Performance Issues +~~~~~~~~~~~~~~~~~~ Importing ``numpy`` can be quite slow sometimes, as well as loading the builtins the first time. If you want to speed things up, you could preload @@ -79,15 +81,33 @@ libriaries in |jedi|, with :func:`.preload_module`. However, once loaded, this should not be a problem anymore. The same is true for huge modules like ``PySide``, ``wx``, ``tensorflow``, ``pandas``, etc. -**Security** +Jedi does not have a very good cache layer. This is probably the biggest and +only architectural `issue `_ in +Jedi. Unfortunately it is not easy to change that. Dave Halter is thinking +about rewriting Jedi in Rust, but it has taken Jedi more than 8 years to reach +version 1.0, a rewrite will probably also take years. -Security is an important issue for |jedi|. Therefore no Python code is -executed. As long as you write pure Python, everything is inferred -statically. Only if you enable ``load_unsafe_extensions=True`` for your +Security +-------- + +For :class:`.Script` +~~~~~~~~~~~~~~~~~~~~ + +Security is an important topic for |jedi|. By default, no code is executed +within Jedi. As long as you write pure Python, everything is inferred +statically. If you enable ``load_unsafe_extensions=True`` for your :class:`.Project` and you use builtin modules (``c_builtin``) Jedi will execute -those modules. -If you don't trust a code base, please do not enable that option. It might lead -to arbitrary code execution. +those modules. If you don't trust a code base, please do not enable that +option. It might lead to arbitrary code execution. + +For :class:`.Interpreter` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want security for :class:`.Interpreter`, ``do not`` use it. Jedi does +execute properties and in general is not very careful to avoid code execution. +This is intentional: Most people trust the code bases they have imported, +because at that point a malicious code base would have had code execution +already. Recipes ------- diff --git a/jedi/utils.py b/jedi/utils.py index 85fe4314..9d675174 100644 --- a/jedi/utils.py +++ b/jedi/utils.py @@ -19,15 +19,14 @@ READLINE_DEBUG = False def setup_readline(namespace_module=__main__, fuzzy=False): """ - Install Jedi completer to :mod:`readline`. + This function sets up :mod:`readline` to use Jedi in a Python interactive + shell. - This function setups :mod:`readline` to use Jedi in Python interactive - shell. If you want to use a custom ``PYTHONSTARTUP`` file (typically + If you want to use a custom ``PYTHONSTARTUP`` file (typically ``$HOME/.pythonrc.py``), you can add this piece of code:: try: from jedi.utils import setup_readline - setup_readline() except ImportError: # Fallback to the stdlib readline completer if it is installed. # Taken from http://docs.python.org/2/library/rlcompleter.html @@ -38,6 +37,8 @@ def setup_readline(namespace_module=__main__, fuzzy=False): readline.parse_and_bind("tab: complete") except ImportError: print("Readline is not installed either. No tab completion is enabled.") + else: + setup_readline() This will fallback to the readline completer if Jedi is not installed. The readline completer will only complete names in the global namespace, @@ -45,18 +46,18 @@ def setup_readline(namespace_module=__main__, fuzzy=False): ran - will complete to ``range`` + will complete to ``range``. - with both Jedi and readline, but:: + With Jedi the following code:: range(10).cou - will show complete to ``range(10).count`` only with Jedi. + will complete to ``range(10).count``, this does not work with the default + cPython :mod:`readline` completer. - You'll also need to add ``export PYTHONSTARTUP=$HOME/.pythonrc.py`` to + You will also need to add ``export PYTHONSTARTUP=$HOME/.pythonrc.py`` to your shell profile (usually ``.bash_profile`` or ``.profile`` if you use bash). - """ if READLINE_DEBUG: logging.basicConfig(