From 9a9bd2d77aa3a83f9492ead2db8d0d696ee62624 Mon Sep 17 00:00:00 2001 From: Mohamed ElKalioby Date: Tue, 5 Oct 2021 11:26:57 +0300 Subject: [PATCH 1/6] Handling Django Models in a better way --- bpython/inspection.py | 17 +++++++++++------ bpython/repl.py | 13 +++++++++---- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/bpython/inspection.py b/bpython/inspection.py index 4c0dbada..f5a55d3b 100644 --- a/bpython/inspection.py +++ b/bpython/inspection.py @@ -34,6 +34,8 @@ from .lazyre import LazyReCompile +DJANGO_CONSTANTS=["check","DoesNotExist","MultipleObjectsReturned"," check","clean","clean_fields","date_error_message","delete","from_db","full_clean","get_deferred_fields","get_next_by_birth_date","get_previous_by_birth_date","objects","prepare_database_save","refresh_from_db","save","save_base","serializable_value","unique_error_message","validate_unique"] + ArgSpec = namedtuple( "ArgSpec", [ @@ -55,8 +57,10 @@ class AttrCleaner: on attribute lookup.""" def __init__(self, obj: Any) -> None: - self.obj = obj - + if "ManagerDescriptor" in str(type(obj)): + self.obj = obj.manager + else: + self.obj = obj def __enter__(self): """Try to make an object not exhibit side-effects on attribute lookup.""" @@ -223,7 +227,7 @@ def getpydocspec(f, func): ) -def getfuncprops(func, f): +def getfuncprops(func, f,cls=None): # Check if it's a real bound method or if it's implicitly calling __init__ # (i.e. FooClass(...) and not FooClass.__init__(...) -- the former would # not take 'self', the latter would: @@ -244,7 +248,7 @@ def getfuncprops(func, f): # '__init__' throws xmlrpclib.Fault (see #202) return None try: - argspec = get_argspec_from_signature(f) + argspec = get_argspec_from_signature(f,cls) fixlongargs(f, argspec) if len(argspec) == 4: argspec = argspec + [list(), dict(), None] @@ -267,7 +271,7 @@ def is_eval_safe_name(string): ) -def get_argspec_from_signature(f): +def get_argspec_from_signature(f,cls=None): """Get callable signature from inspect.signature in argspec format. inspect.signature is a Python 3 only function that returns the signature of @@ -301,7 +305,8 @@ def get_argspec_from_signature(f): kwonly_defaults[parameter.name] = parameter.default elif parameter.kind == inspect.Parameter.VAR_KEYWORD: varkwargs = parameter.name - + if cls: + kwonly.extend([x[0] for x in inspect.getmembers(cls) if not x[0].startswith("_") and x[0] not in DJANGO_CONSTANTS]) # inspect.getfullargspec returns None for 'defaults', 'kwonly_defaults' and # 'annotations' if there are no values for them. if not defaults: diff --git a/bpython/repl.py b/bpython/repl.py index ba9acf4d..8021cee3 100644 --- a/bpython/repl.py +++ b/bpython/repl.py @@ -505,6 +505,8 @@ def get_object(self, name): obj = eval(attributes.pop(0), self.interp.locals) while attributes: with inspection.AttrCleaner(obj): + if "ManagerDescriptor" in str(type(obj)): + obj = obj.manager obj = getattr(obj, attributes.pop(0)) return obj @@ -576,7 +578,6 @@ def get_args(self): return True, otherwise set self.funcprops to None and return False""" self.current_func = None - if not self.config.arg_spec: return False @@ -602,17 +603,17 @@ def get_args(self): if hasattr(f, "__init__") and f.__init__ is not object.__init__: class_f = f.__init__ if ( - (not class_f or not inspection.getfuncprops(func, class_f)) + (not class_f or not inspection.getfuncprops(func, class_f, f)) and hasattr(f, "__new__") and f.__new__ is not object.__new__ and # py3 f.__new__.__class__ is not object.__new__.__class__ ): - class_f = f.__new__ if class_f: + self.funcprops = inspection.getfuncprops(func, class_f, f) f = class_f except Exception: # another case of needing to catch every kind of error @@ -622,7 +623,11 @@ def get_args(self): return False self.current_func = f - self.funcprops = inspection.getfuncprops(func, f) + if "BaseManager._get_queryset_methods" in str(f): + cls = eval(func.split(".")[0],self.interp.locals) + self.funcprops = inspection.getfuncprops(func, f,cls) + if not self.funcprops: + self.funcprops = inspection.getfuncprops(func, f) if self.funcprops: self.arg_pos = arg_number return True From 7038233313868e551bfa9db4dcbd5f4aed6e9f9a Mon Sep 17 00:00:00 2001 From: Mohamed ElKalioby Date: Tue, 5 Oct 2021 11:47:55 +0300 Subject: [PATCH 2/6] Better management for Django Members --- bpython/inspection.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bpython/inspection.py b/bpython/inspection.py index f5a55d3b..2ba7553c 100644 --- a/bpython/inspection.py +++ b/bpython/inspection.py @@ -34,7 +34,9 @@ from .lazyre import LazyReCompile -DJANGO_CONSTANTS=["check","DoesNotExist","MultipleObjectsReturned"," check","clean","clean_fields","date_error_message","delete","from_db","full_clean","get_deferred_fields","get_next_by_birth_date","get_previous_by_birth_date","objects","prepare_database_save","refresh_from_db","save","save_base","serializable_value","unique_error_message","validate_unique"] +DJANGO_CONSTANTS=["check","DoesNotExist","MultipleObjectsReturned"," check","clean","clean_fields","date_error_message", + "delete","from_db","full_clean","get_deferred_fields","objects","prepare_database_save","refresh_from_db", + "save","save_base","serializable_value","unique_error_message","validate_unique"] ArgSpec = namedtuple( "ArgSpec", @@ -306,7 +308,9 @@ def get_argspec_from_signature(f,cls=None): elif parameter.kind == inspect.Parameter.VAR_KEYWORD: varkwargs = parameter.name if cls: - kwonly.extend([x[0] for x in inspect.getmembers(cls) if not x[0].startswith("_") and x[0] not in DJANGO_CONSTANTS]) + members = inspect.getmembers(cls) + kwonly.extend([x[0] for x in members if not (x[0].startswith("_") or "get_pre" in x[0] + or "get_next" in x[0]) and x[0] not in DJANGO_CONSTANTS]) # inspect.getfullargspec returns None for 'defaults', 'kwonly_defaults' and # 'annotations' if there are no values for them. if not defaults: From 961800260a36b4c75e411cdccb3d4fc2dcd2a397 Mon Sep 17 00:00:00 2001 From: Mohamed ElKalioby Date: Mon, 11 Oct 2021 15:29:41 +0300 Subject: [PATCH 3/6] Initial Release --- README.md | 20 ++++ README.rst | 253 --------------------------------------------------- example1.png | Bin 0 -> 23103 bytes example2.png | Bin 0 -> 18974 bytes setup.cfg | 67 -------------- setup.py | 33 ++++++- 6 files changed, 50 insertions(+), 323 deletions(-) create mode 100644 README.md delete mode 100644 README.rst create mode 100644 example1.png create mode 100644 example2.png diff --git a/README.md b/README.md new file mode 100644 index 00000000..bfa832ae --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# bpython-django + +This project is based on [bpython](https://github.com/bpython/bpython) REPL, I liked it very much but it missed some features for Django, like +* Autocomplete the constructor for the model, +* Autocomplete the attribute name on ModelManager functions like 'filter()' and 'get()' + +## Examples + +![example1](./example1.png) +![example2](./example2.png) + +## Install + +`pip install bpython-django` + +## Usage + +`python manage shell` +or +`python manage shell -i bpython` \ No newline at end of file diff --git a/README.rst b/README.rst deleted file mode 100644 index 539d036b..00000000 --- a/README.rst +++ /dev/null @@ -1,253 +0,0 @@ -.. image:: https://img.shields.io/pypi/v/bpython - :target: https://pypi.org/project/bpython - -.. image:: https://readthedocs.org/projects/bpython/badge/?version=latest - :target: https://docs.bpython-interpreter.org/en/latest/ - -.. image:: https://img.shields.io/badge/code%20style-black-000000.svg - :target: https://github.com/ambv/black - - -*********************************************************************** -bpython: A fancy curses interface to the Python interactive interpreter -*********************************************************************** - -`bpython`_ is a lightweight Python interpreter that adds several features common -to IDEs. These features include **syntax highlighting**, **expected parameter -list**, **auto-indentation**, and **autocompletion**. (See below for example -usage). - -.. image:: https://bpython-interpreter.org/images/math.gif - :alt: bpython - :width: 566 - :height: 348 - :align: center - -bpython does **not** aim to be a complete IDE - the focus is on implementing a -few ideas in a practical, useful, and lightweight manner. - -bpython is a great replacement to any occasion where you would normally use the -vanilla Python interpreter - testing out solutions to people's problems on IRC, -quickly testing a method of doing something without creating a temporary file, -etc. - -You can find more about bpython - including `full documentation`_ - at our -`homepage`_. - -.. contents:: - :local: - :depth: 1 - :backlinks: none - -========================== -Installation & Basic Usage -========================== - -Installation using Pip ----------------------- - -If you have `pip`_ installed, you can simply run: - -.. code-block:: bash - - $ pip install bpython - -Start bpython by typing ``bpython`` in your terminal. You can exit bpython by -using the ``exit()`` command or by pressing control-D like regular interactive -Python. - -Installation via OS Package Manager ------------------------------------ - -The majority of desktop computer operating systems come with package management -systems. If you use one of these OSes, you can install ``bpython`` using the -package manager. - -Ubuntu/Debian -~~~~~~~~~~~~~ -Ubuntu/Debian family Linux users can install ``bpython`` using the ``apt`` -package manager, using the command with ``sudo`` privileges: - -.. code-block:: bash - - $ apt install bpython - -In case you are using an older version, run - -.. code-block:: bash - - $ apt-get install bpython - -Arch Linux -~~~~~~~~~~ -Arch Linux uses ``pacman`` as the default package manager; you can use it to install ``bpython``: - -.. code-block:: bash - - $ pacman -S bpython - -Fedora -~~~~~~~~~~ -Fedora users can install ``bpython`` directly from the command line using ``dnf``. - -.. code-block:: bash - - $ dnf install bpython - -Windows -~~~~~~~ -**Caveats:** As ``bpython`` makes use of the ncurses library of \*nix-family operating systems, -bpython on Windows is not officially supported and tested. - -However, you may still use bpython on Windows using a workaround. In brief, you should install -these two packages using ``pip``: - -.. code-block:: bash - - $ pip install bpython windows-curses - -Then you should invoke a program called ``bpython-curses.exe`` instead of ``bpython.exe`` to use bpython: - -.. code-block:: bash - - $ bpython-curses - -Mac OS -~~~~~~ -Like Windows, Mac OS does not include a package manager by default. If you have installed any -third-party package manager like MacPorts, you can install it via - -.. code-block:: bash - - $ sudo port install py-bpython - -=================== -Features & Examples -=================== -* Readline-like autocomplete, with suggestions displayed as you type. - -* In-line syntax highlighting. This uses Pygments for lexing the code as you - type, and colours appropriately. - -* Expected parameter list. As in a lot of modern IDEs, bpython will attempt to - display a list of parameters for any function you call. The inspect module (which - works with any Python function) is tried first, and then pydoc if that fails. - -* Rewind. This isn't called "Undo" because it would be misleading, but "Rewind" - is probably as bad. The idea is that the code entered is kept in memory and - when the Rewind function is called, the last line is popped and the entire - session is re-evaluated. Use to rewind. - -* Edit the current line or your entire session in an editor. F7 opens the current - session in a text editor, and if modifications are made, the session is rerun - with these changes. - -* Pastebin code/write to file. Use the key to upload the screen's contents - to pastebin, with a URL returned. - -* Reload imported Python modules. Use to clear sys.modules and rerun your - session to test changes to code in a module you're working on. - -============= -Configuration -============= -See the sample-config file for a list of available options. You should save -your config file as **~/.config/bpython/config** (i.e. -``$XDG_CONFIG_HOME/bpython/config``) or specify at the command line:: - - bpython --config /path/to/bpython/config - -============ -Dependencies -============ -* Pygments -* curtsies >= 0.3.5 -* greenlet -* pyxdg -* requests -* Sphinx >= 1.5 (optional, for the documentation) -* babel (optional, for internationalization) -* jedi (optional, for experimental multiline completion) -* watchdog (optional, for monitoring imported modules for changes) -* pyperclip (optional, for copying to the clipboard) - -bpython-urwid -------------- -``bpython-urwid`` requires the following additional packages: - -* urwid - -========== -Known Bugs -========== -For known bugs please see bpython's `known issues and FAQ`_ page. - -====================== -Contact & Contributing -====================== -I hope you find it useful and please feel free to submit any bugs/patches -suggestions to `Robert`_ or place them on the GitHub -`issues tracker`_. - -For any other ways of communicating with bpython users and devs you can find us -at the community page on the `project homepage`_, or in the `community`_. - -Hope to see you there! - -=================== -CLI Windows Support -=================== - -Dependencies ------------- -`Curses`_ Use the appropriate version compiled by Christoph Gohlke. - -`pyreadline`_ Use the version in the cheeseshop. - -Recommended ------------ -Obtain the less program from GnuUtils. This makes the pager work as intended. -It can be obtained from cygwin or GnuWin32 or msys - -Current version is tested with ------------------------------- -* Curses 2.2 -* pyreadline 1.7 - -Curses Notes ------------- -The curses used has a bug where the colours are displayed incorrectly: - -* red is swapped with blue -* cyan is swapped with yellow - -To correct this I have provided a windows.theme file. - -This curses implementation has 16 colors (dark and light versions of the -colours) - - -============ -Alternatives -============ - -`ptpython`_ - -`IPython`_ - -Feel free to get in touch if you know of any other alternatives that people -may be interested to try. - -.. _ptpython: https://github.com/jonathanslenders/ptpython -.. _ipython: https://ipython.org/ -.. _homepage: http://www.bpython-interpreter.org -.. _full documentation: http://docs.bpython-interpreter.org/ -.. _issues tracker: http://github.com/bpython/bpython/issues/ -.. _pip: https://pip.pypa.io/en/latest/index.html -.. _project homepage: http://bpython-interpreter.org -.. _community: http://docs.bpython-interpreter.org/community.html -.. _Robert: robertanthonyfarrell@gmail.com -.. _bpython: http://www.bpython-interpreter.org/ -.. _Curses: http://www.lfd.uci.edu/~gohlke/pythonlibs/ -.. _pyreadline: http://pypi.python.org/pypi/pyreadline/ -.. _known issues and FAQ: http://bpython-interpreter.org/known-issues-and-faq.html diff --git a/example1.png b/example1.png new file mode 100644 index 0000000000000000000000000000000000000000..6adc499df93d7f627e545fbc6821e281494eff1e GIT binary patch literal 23103 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 j!U}CS?Tfp$&@S&&$o*>*Z`b*Lc#-K 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 literal 0 HcmV?d00001 diff --git a/setup.cfg b/setup.cfg index 89b6cde6..e69de29b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,67 +0,0 @@ -[metadata] -name = bpython -long_description = file: README.rst -license = MIT -license_file = LICENSE -url = https://www.bpython-interpreter.org/ -project_urls = - GitHub = https://github.com/bpython/bpython - Documentation = https://doc.bpython-interpreter.org -classifiers = - Programming Language :: Python :: 3 - -[options] -python_requires = >=3.6 -packages = - bpython - bpython.curtsiesfrontend - bpython.test - bpython.test.fodder - bpython.translations - bpdb -install_requires = - backports.cached-property; python_version < "3.8" - curtsies >=0.3.5 - dataclasses; python_version < "3.7" - cwcwidth - greenlet - pygments - pyxdg - requests - -[options.extras_require] -clipboard = pyperclip -jedi = jedi >= 0.16 -urwid = urwid -watch = watchdog - -[options.entry_points] -console_scripts = - bpython = bpython.curtsies:main - bpython-curses = bpython.cli:main - bpython-urwid = bpython.urwid:main [urwid] - bpdb = bpdb:main - -[init_catalog] -domain = bpython -input_file = bpython/translations/bpython.pot -output_dir = bpython/translations - -[compile_catalog] -domain = bpython -directory = bpython/translations -use_fuzzy = true - -[update_catalog] -domain = bpython -input_file = bpython/translations/bpython.pot -output_dir = bpython/translations - -[extract_messages] -output_file = bpython/translations/bpython.pot -msgid_bugs_address = https://github.com/bpython/bpython/issues - -[build_sphinx_man] -builder = man -source_dir = doc/sphinx/source -build_dir = build diff --git a/setup.py b/setup.py index 42dd2a30..1ca7b450 100755 --- a/setup.py +++ b/setup.py @@ -178,10 +178,17 @@ def git_describe_to_python_version(version): mo_files.append(mo_subpath) setup( - version=version, - author=__author__, - author_email="robertanthonyfarrell@gmail.com", + name='bpython-django', + version="0.22.1", + author='Mohamed ElKalioby', + author_email="mkalioby@mkalioby.com", + description='Customized bpython for Django Projects', + long_description=open("README.md").read(), + long_description_content_type="text/markdown", data_files=data_files, + url = 'https://github.com/mkalioby/bpython-django/', + download_url='https://github.com/mkalioby/bpython-django/', + python_requires=">=3.6", package_data={ "bpython": ["sample-config"], "bpython.translations": mo_files, @@ -189,6 +196,26 @@ def git_describe_to_python_version(version): }, cmdclass=cmdclass, test_suite="bpython.test", +classifiers=[ + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "Framework :: Django", + "Framework :: Django :: 2.0", + "Framework :: Django :: 2.1", + "Framework :: Django :: 2.2", + "Framework :: Django :: 3.0", + "Framework :: Django :: 3.1", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.5", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Topic :: Software Development :: Libraries :: Python Modules" + ] ) # vim: fileencoding=utf-8 sw=4 ts=4 sts=4 ai et sta From 49546b41c87bc8e9dd9a945d489b69ff3691249c Mon Sep 17 00:00:00 2001 From: Mohamed ElKalioby Date: Mon, 11 Oct 2021 15:34:52 +0300 Subject: [PATCH 4/6] Better Setup --- setup.cfg | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 4 +-- 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index e69de29b..49cded0c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -0,0 +1,73 @@ +[metadata] +license = MIT +license_file = LICENSE +classifiers = + Programming Language :: Python :: 3 + +[options] +python_requires = >=3.6 +packages = + bpython + bpython.curtsiesfrontend + bpython.test + bpython.test.fodder + bpython.translations + bpdb +install_requires = + backports.cached-property; python_version < "3.8" + curtsies >=0.3.5 + dataclasses; python_version < "3.7" + cwcwidth + greenlet + pygments + pyxdg + requests + +[options.extras_require] +clipboard = pyperclip +jedi = jedi >= 0.16 +urwid = urwid +watch = watchdog + +[options.entry_points] +console_scripts = + bpython = bpython.curtsies:main + bpython-curses = bpython.cli:main + bpython-urwid = bpython.urwid:main [urwid] + bpdb = bpdb:main + +[init_catalog] +domain = bpython +input_file = bpython/translations/bpython.pot +output_dir = bpython/translations + +[compile_catalog] +domain = bpython +directory = bpython/translations +use_fuzzy = true + +[update_catalog] +domain = bpython +input_file = bpython/translations/bpython.pot +output_dir = bpython/translations + +[extract_messages] +output_file = bpython/translations/bpython.pot +msgid_bugs_address = https://github.com/bpython/bpython/issues + +[build_sphinx_man] +builder = man +source_dir = doc/sphinx/source +build_dir = build + +[mypy] +warn_return_any = True +warn_unused_configs = True +mypy_path=stubs +files=bpython + +[mypy-jedi] +ignore_missing_imports = True + +[mypy-urwid] +ignore_missing_imports = True diff --git a/setup.py b/setup.py index 1ca7b450..3ae414ce 100755 --- a/setup.py +++ b/setup.py @@ -179,7 +179,7 @@ def git_describe_to_python_version(version): setup( name='bpython-django', - version="0.22.1", + version="0.22.2", author='Mohamed ElKalioby', author_email="mkalioby@mkalioby.com", description='Customized bpython for Django Projects', @@ -196,7 +196,7 @@ def git_describe_to_python_version(version): }, cmdclass=cmdclass, test_suite="bpython.test", -classifiers=[ + classifiers=[ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", From ca362fbd62c4d9321f2aba974cb819c5b83e4a84 Mon Sep 17 00:00:00 2001 From: Mohamed El-Kalioby Date: Thu, 21 Oct 2021 14:59:53 +0300 Subject: [PATCH 5/6] Move to asciienma --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bfa832ae..40eaa5b3 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,7 @@ This project is based on [bpython](https://github.com/bpython/bpython) REPL, I l ## Examples -![example1](./example1.png) -![example2](./example2.png) +[![asciicast](https://asciinema.org/a/443735.png)](https://asciinema.org/a/443735?speed=3&t=10) ## Install @@ -17,4 +16,4 @@ This project is based on [bpython](https://github.com/bpython/bpython) REPL, I l `python manage shell` or -`python manage shell -i bpython` \ No newline at end of file +`python manage shell -i bpython` From 506300c44ce38f9e7a4f153e064c19ebd268f26e Mon Sep 17 00:00:00 2001 From: Mohamed El-Kalioby Date: Thu, 21 Oct 2021 15:00:47 +0300 Subject: [PATCH 6/6] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 40eaa5b3..131771af 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ This project is based on [bpython](https://github.com/bpython/bpython) REPL, I l * Autocomplete the constructor for the model, * Autocomplete the attribute name on ModelManager functions like 'filter()' and 'get()' -## Examples +## Example -[![asciicast](https://asciinema.org/a/443735.png)](https://asciinema.org/a/443735?speed=3&t=10) +[![asciicast](https://asciinema.org/a/443735.png)](https://asciinema.org/a/443735?speed=3&t=2) ## Install