spyder-kernels-0.5.2/0000775000175000017500000000000013537413361015265 5ustar carloscarlos00000000000000spyder-kernels-0.5.2/AUTHORS.txt0000664000175000017500000000157313332371305017153 0ustar carloscarlos00000000000000The Spyder Kernels Contributors are composed of: * Pierre Raybaut (Original Spyder author) * Carlos Cordoba (Current Spyder/-Kernels maintainer) * All other developers that have committed to the spyder-kernels repository: and contributors listed on the original files in the main spyder repository: spyder-kernels-0.5.2/LICENSE.txt0000664000175000017500000000211713332371305017103 0ustar carloscarlos00000000000000MIT License Copyright (c) 2009- Spyder Kernels Contributors (see AUTHORS.txt) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. spyder-kernels-0.5.2/MANIFEST.in0000664000175000017500000000011713511625132017013 0ustar carloscarlos00000000000000include AUTHORS.txt include CHANGELOG.md include LICENSE.txt include README.md spyder-kernels-0.5.2/spyder_kernels.egg-info/0000775000175000017500000000000013537413361022010 5ustar carloscarlos00000000000000spyder-kernels-0.5.2/spyder_kernels.egg-info/PKG-INFO0000664000175000017500000000630613537413360023111 0ustar carloscarlos00000000000000Metadata-Version: 2.1 Name: spyder-kernels Version: 0.5.2 Summary: Jupyter kernels for Spyder's console Home-page: https://github.com/spyder-ide/spyder-kernels Author: Spyder Development Team Author-email: spyderlib@googlegroups.com License: MIT Download-URL: https://www.spyder-ide.org/#fh5co-download Description: # Jupyter kernels for the Spyder console [![CircleCI](https://circleci.com/gh/spyder-ide/spyder-kernels.svg?style=shield)](https://circleci.com/gh/spyder-ide/spyder-kernels) [![AppVeyor](https://ci.appveyor.com/api/projects/status/pd0etf64xyiyd3qb/branch/master?svg=true)](https://ci.appveyor.com/project/spyder-ide/spyder-kernels/branch/master) [![codecov](https://codecov.io/gh/spyder-ide/spyder-kernels/branch/master/graph/badge.svg)](https://codecov.io/gh/spyder-ide/spyder-kernels) Package that provides Jupyter kernels for use with the consoles of Spyder, the Scientific Python Development Environment. These kernels can launched either through Spyder itself or in an independent Python session, and allow for interactive or file-based execution of Python code inside Spyder. To learn about creating, connecting to and using these kernels with the Spyder console, please read our [documentation](https://docs.spyder-ide.org/ipythonconsole.html). For advice on managing packages and environments with `spyder-kernels`, please visit our [wiki](https://github.com/spyder-ide/spyder/wiki/Working-with-packages-and-environments-in-Spyder). ## Installation To install this package, you can use either the ``pip`` or ``conda`` package managers, as follows: Using conda (the recommended way!): ``` conda install spyder-kernels ``` Using pip: ``` pip install spyder-kernels ``` ## Dependencies This project depends on: * [ipykernel](https://github.com/ipython/ipykernel/) * [cloudpickle](https://github.com/cloudpipe/cloudpickle) * [wurlitzer](https://github.com/minrk/wurlitzer) ## Changelog Visit our [CHANGELOG](CHANGELOG.md) file to know more about our new features and improvements. ## Development and contribution To start contributing to this project you can execute ``` pip install -e . ``` in your git clone and then test your changes in Spyder. We follow PEP8 and PEP257 style guidelines. Keywords: spyder jupyter kernel ipython console Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Framework :: Jupyter Classifier: Framework :: IPython Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Software Development :: Interpreters Description-Content-Type: text/markdown Provides-Extra: test spyder-kernels-0.5.2/spyder_kernels.egg-info/SOURCES.txt0000664000175000017500000000136713537413360023702 0ustar carloscarlos00000000000000AUTHORS.txt CHANGELOG.md LICENSE.txt MANIFEST.in README.md setup.cfg setup.py spyder_kernels/__init__.py spyder_kernels/_version.py spyder_kernels/py3compat.py spyder_kernels.egg-info/PKG-INFO spyder_kernels.egg-info/SOURCES.txt spyder_kernels.egg-info/dependency_links.txt spyder_kernels.egg-info/requires.txt spyder_kernels.egg-info/top_level.txt spyder_kernels/console/__init__.py spyder_kernels/console/__main__.py spyder_kernels/console/kernel.py spyder_kernels/console/start.py spyder_kernels/customize/__init__.py spyder_kernels/customize/spydercustomize.py spyder_kernels/utils/__init__.py spyder_kernels/utils/dochelpers.py spyder_kernels/utils/iofuncs.py spyder_kernels/utils/misc.py spyder_kernels/utils/nsview.py spyder_kernels/utils/test_utils.pyspyder-kernels-0.5.2/spyder_kernels.egg-info/requires.txt0000664000175000017500000000026313537413360024410 0ustar carloscarlos00000000000000ipykernel>=4.8.2 pyzmq>=17 jupyter-client>=5.2.3 cloudpickle [:platform_system != "Windows"] wurlitzer [test] numpy pandas scipy pytest pytest-cov mock cython matplotlib xarray spyder-kernels-0.5.2/spyder_kernels.egg-info/dependency_links.txt0000664000175000017500000000000113537413360026055 0ustar carloscarlos00000000000000 spyder-kernels-0.5.2/spyder_kernels.egg-info/top_level.txt0000664000175000017500000000001713537413360024537 0ustar carloscarlos00000000000000spyder_kernels spyder-kernels-0.5.2/README.md0000664000175000017500000000357613537412605016557 0ustar carloscarlos00000000000000# Jupyter kernels for the Spyder console [![CircleCI](https://circleci.com/gh/spyder-ide/spyder-kernels.svg?style=shield)](https://circleci.com/gh/spyder-ide/spyder-kernels) [![AppVeyor](https://ci.appveyor.com/api/projects/status/pd0etf64xyiyd3qb/branch/master?svg=true)](https://ci.appveyor.com/project/spyder-ide/spyder-kernels/branch/master) [![codecov](https://codecov.io/gh/spyder-ide/spyder-kernels/branch/master/graph/badge.svg)](https://codecov.io/gh/spyder-ide/spyder-kernels) Package that provides Jupyter kernels for use with the consoles of Spyder, the Scientific Python Development Environment. These kernels can launched either through Spyder itself or in an independent Python session, and allow for interactive or file-based execution of Python code inside Spyder. To learn about creating, connecting to and using these kernels with the Spyder console, please read our [documentation](https://docs.spyder-ide.org/ipythonconsole.html). For advice on managing packages and environments with `spyder-kernels`, please visit our [wiki](https://github.com/spyder-ide/spyder/wiki/Working-with-packages-and-environments-in-Spyder). ## Installation To install this package, you can use either the ``pip`` or ``conda`` package managers, as follows: Using conda (the recommended way!): ``` conda install spyder-kernels ``` Using pip: ``` pip install spyder-kernels ``` ## Dependencies This project depends on: * [ipykernel](https://github.com/ipython/ipykernel/) * [cloudpickle](https://github.com/cloudpipe/cloudpickle) * [wurlitzer](https://github.com/minrk/wurlitzer) ## Changelog Visit our [CHANGELOG](CHANGELOG.md) file to know more about our new features and improvements. ## Development and contribution To start contributing to this project you can execute ``` pip install -e . ``` in your git clone and then test your changes in Spyder. We follow PEP8 and PEP257 style guidelines. spyder-kernels-0.5.2/CHANGELOG.md0000664000175000017500000002654613537413014017106 0ustar carloscarlos00000000000000# History of changes ## Version 0.5.2 (2019-09-15) ### Issues Closed * [Issue 132](https://github.com/spyder-ide/spyder-kernels/issues/132) - tests use removed pandas.Panel ([PR 135](https://github.com/spyder-ide/spyder-kernels/pull/135)) In this release 1 issue was closed. ### Pull Requests Merged * [PR 149](https://github.com/spyder-ide/spyder-kernels/pull/149) - PR: Add xarray to our test deps in setup.py * [PR 135](https://github.com/spyder-ide/spyder-kernels/pull/135) - PR: Replace usage of Pandas Panel for Xarray Dataset in our tests ([132](https://github.com/spyder-ide/spyder-kernels/issues/132)) In this release 2 pull requests were closed. ---- ## Version 0.5.1 (2019-07-11) ### Issues Closed * [Issue 121](https://github.com/spyder-ide/spyder-kernels/issues/121) - Add test requirements to setup.py ([PR 122](https://github.com/spyder-ide/spyder-kernels/pull/122)) * [Issue 120](https://github.com/spyder-ide/spyder-kernels/issues/120) - Backport CI configuration from master to 0.x ([PR 123](https://github.com/spyder-ide/spyder-kernels/pull/123)) In this release 2 issues were closed. ### Pull Requests Merged * [PR 125](https://github.com/spyder-ide/spyder-kernels/pull/125) - PR: Fix not including tests in tarballs and wheels * [PR 123](https://github.com/spyder-ide/spyder-kernels/pull/123) - PR: Backport CI configuration from master to 0.x ([120](https://github.com/spyder-ide/spyder-kernels/issues/120)) * [PR 122](https://github.com/spyder-ide/spyder-kernels/pull/122) - PR: Add tests requirements to setup.py ([121](https://github.com/spyder-ide/spyder-kernels/issues/121)) In this release 3 pull requests were closed. ---- ## Version 0.5.0 (2019-06-23) ### New features * Set Matplotlib backend to inline for kernels started in a terminal. * Handle option sent from Spyder to show/hide cmd windows generated by the subprocess module. ### Issues Closed * [Issue 108](https://github.com/spyder-ide/spyder-kernels/issues/108) - Set matplotlib backend to inline by default on starting a new kernel ([PR 110](https://github.com/spyder-ide/spyder-kernels/pull/110)) In this release 1 issue was closed. ### Pull Requests Merged * [PR 110](https://github.com/spyder-ide/spyder-kernels/pull/110) - PR: Set Matplotlib backend to inline for kernels started outside Spyder ([108](https://github.com/spyder-ide/spyder-kernels/issues/108)) * [PR 107](https://github.com/spyder-ide/spyder-kernels/pull/107) - PR: Use Readme.md for long description in PyPi * [PR 104](https://github.com/spyder-ide/spyder-kernels/pull/104) - PR: Handle option to show/hide cmd windows generated by the subprocess module In this release 3 pull requests were closed. ---- ## Version 0.4.4 (2019-04-08) ### Issues Closed * [Issue 102](https://github.com/spyder-ide/spyder-kernels/issues/102) - Tkinter is now required for version 0.4.3 after patching the turtle code ([PR 103](https://github.com/spyder-ide/spyder-kernels/pull/103)) In this release 1 issue was closed. ### Pull Requests Merged * [PR 106](https://github.com/spyder-ide/spyder-kernels/pull/106) - PR: Skip test_turtle_launch if Tk is not installed * [PR 103](https://github.com/spyder-ide/spyder-kernels/pull/103) - PR: Enclose turtle customizations in a try/except to avoid a dependency on Tk ([102](https://github.com/spyder-ide/spyder-kernels/issues/102)) In this release 2 pull requests were closed. ---- ## Version 0.4.3 (2019-03-31) ### Issues Closed * [Issue 91](https://github.com/spyder-ide/spyder-kernels/issues/91) - KeyError when running "%reset -f" programmatically ([PR 96](https://github.com/spyder-ide/spyder-kernels/pull/96)) In this release 1 issue was closed. ### Pull Requests Merged * [PR 96](https://github.com/spyder-ide/spyder-kernels/pull/96) - PR: Avoid error when trying to pop __file__ out of the current namespace ([91](https://github.com/spyder-ide/spyder-kernels/issues/91)) * [PR 92](https://github.com/spyder-ide/spyder-kernels/pull/92) - PR: Include user site-packages directory in the list of excluded paths by the UMR ([8776](https://github.com/spyder-ide/spyder/issues/8776)) * [PR 90](https://github.com/spyder-ide/spyder-kernels/pull/90) - PR: Patch turtle.bye to make it work with multiple runnings of the same code ([6278](https://github.com/spyder-ide/spyder/issues/6278)) In this release 3 pull requests were closed. ---- ## Version 0.4.2 (2019-02-07) ### Issues Closed * [Issue 85](https://github.com/spyder-ide/spyder-kernels/issues/85) - NameError: name 'modpath' is not defined ([PR 86](https://github.com/spyder-ide/spyder-kernels/pull/86)) In this release 1 issue was closed. ### Pull Requests Merged * [PR 88](https://github.com/spyder-ide/spyder-kernels/pull/88) - PR: Improve Cython activation * [PR 87](https://github.com/spyder-ide/spyder-kernels/pull/87) - PR: Fix running Cython files * [PR 86](https://github.com/spyder-ide/spyder-kernels/pull/86) - PR: Fix problems with UMR's run method ([85](https://github.com/spyder-ide/spyder-kernels/issues/85)) In this release 3 pull requests were closed. ---- ## Version 0.4.1 (2019-02-03) ### Pull Requests Merged * [PR 84](https://github.com/spyder-ide/spyder-kernels/pull/84) - PR: Better way to skip standard library and site-packages modules from UMR * [PR 83](https://github.com/spyder-ide/spyder-kernels/pull/83) - PR: Blacklist tensorflow from the UMR ([8697](https://github.com/spyder-ide/spyder/issues/8697)) In this release 2 pull requests were closed. ---- ## Version 0.4 (2019-02-02) ### New features * This release fixes several important issues that prevented saving the current namespace to work as expected. ### Issues Closed * [Issue 75](https://github.com/spyder-ide/spyder-kernels/issues/75) - Namespace serialization silently fails if any object is unserializable, e.g. a Python module ([PR 81](https://github.com/spyder-ide/spyder-kernels/pull/81)) * [Issue 9](https://github.com/spyder-ide/spyder-kernels/issues/9) - Spydata files won't import if the original filename is changed ([PR 80](https://github.com/spyder-ide/spyder-kernels/pull/80)) In this release 2 issues were closed. ### Pull Requests Merged * [PR 82](https://github.com/spyder-ide/spyder-kernels/pull/82) - PR: Enclose calls to load wurlitzer and autoreload in try/except's ([8668](https://github.com/spyder-ide/spyder/issues/8668)) * [PR 81](https://github.com/spyder-ide/spyder-kernels/pull/81) - PR: Fix and improve saving of Spyder namespace with many types of objects ([75](https://github.com/spyder-ide/spyder-kernels/issues/75)) * [PR 80](https://github.com/spyder-ide/spyder-kernels/pull/80) - PR: Fix loading Spydata file with changed filename and other edge-cases in load_dict ([9](https://github.com/spyder-ide/spyder-kernels/issues/9)) In this release 3 pull requests were closed. ---- ## Version 0.3 (2018-11-23) ### New features * Add Wurlitzer as a new dependency on Posix systems. * Add tests for the console kernel. ### Issues Closed * [Issue 62](https://github.com/spyder-ide/spyder-kernels/issues/62) - Add support for AppVeyor ([PR 63](https://github.com/spyder-ide/spyder-kernels/pull/63)) * [Issue 60](https://github.com/spyder-ide/spyder-kernels/issues/60) - Only load Wurlitzer in Posix systems ([PR 64](https://github.com/spyder-ide/spyder-kernels/pull/64)) * [Issue 23](https://github.com/spyder-ide/spyder-kernels/issues/23) - Add tests for the console kernel ([PR 37](https://github.com/spyder-ide/spyder-kernels/pull/37)) In this release 3 issues were closed. ### Pull Requests Merged * [PR 64](https://github.com/spyder-ide/spyder-kernels/pull/64) - PR: Don't load Wurlitzer extension on Windows because it has no effect there ([60](https://github.com/spyder-ide/spyder-kernels/issues/60)) * [PR 63](https://github.com/spyder-ide/spyder-kernels/pull/63) - PR: Test on Windows with Appveyor ([62](https://github.com/spyder-ide/spyder-kernels/issues/62)) * [PR 61](https://github.com/spyder-ide/spyder-kernels/pull/61) - PR: Patch multiprocessing to make it work when all variables are removed ([8128](https://github.com/spyder-ide/spyder/issues/8128)) * [PR 59](https://github.com/spyder-ide/spyder-kernels/pull/59) - PR: Filter deprecation warnings in ipykernel ([8103](https://github.com/spyder-ide/spyder/issues/8103)) * [PR 56](https://github.com/spyder-ide/spyder-kernels/pull/56) - PR: Add Wurlitzer to Readme * [PR 55](https://github.com/spyder-ide/spyder-kernels/pull/55) - PR: Exclude all tests from our tarballs * [PR 54](https://github.com/spyder-ide/spyder-kernels/pull/54) - PR: Add the Wurlitzer package to capture stdout/stderr from C libraries ([3777](https://github.com/spyder-ide/spyder/issues/3777)) * [PR 53](https://github.com/spyder-ide/spyder-kernels/pull/53) - PR: Remove current working directory from sys.path before starting the console kernel ([8007](https://github.com/spyder-ide/spyder/issues/8007)) * [PR 37](https://github.com/spyder-ide/spyder-kernels/pull/37) - PR: Initial tests for the console kernel ([23](https://github.com/spyder-ide/spyder-kernels/issues/23)) * [PR 36](https://github.com/spyder-ide/spyder-kernels/pull/36) - PR: Make tests to really fail in CircleCI * [PR 21](https://github.com/spyder-ide/spyder-kernels/pull/21) - PR: Add AUTHORS.txt in MANIFEST.in to include in package In this release 11 pull requests were closed. ---- ## Version 0.2.6 (2018-08-09) ### Pull Requests Merged * [PR 20](https://github.com/spyder-ide/spyder-kernels/pull/20) - PR: Include license file again in tarball In this release 1 pull request was closed. ---- ## Version 0.2.5 (2018-08-09) ### Pull Requests Merged * [PR 19](https://github.com/spyder-ide/spyder-kernels/pull/19) - PR: Fix inconsistent EOLs * [PR 18](https://github.com/spyder-ide/spyder-kernels/pull/18) - PR: Fix legal texts and make them consistent across all files * [PR 17](https://github.com/spyder-ide/spyder-kernels/pull/17) - PR: Add/update descriptions, links and metadata in setup.py * [PR 16](https://github.com/spyder-ide/spyder-kernels/pull/16) - PR: Include test suite in manifest * [PR 11](https://github.com/spyder-ide/spyder-kernels/pull/11) - PR: Add codecov support to see coverage * [PR 10](https://github.com/spyder-ide/spyder-kernels/pull/10) - PR: Start testing with CircleCI * [PR 8](https://github.com/spyder-ide/spyder-kernels/pull/8) - PR: Demand specific dependency versions needed by Spyder In this release 7 pull requests were closed. ---- ## Version 0.2.4 (2018-06-25) ### Pull Requests Merged * [PR 6](https://github.com/spyder-ide/spyder-kernels/pull/6) - PR: Handle deprecated 'summary' method for Pandas In this release 1 pull request was closed. ---- ## Version 0.2.3 (2018-06-23) ### Pull Requests Merged * [PR 5](https://github.com/spyder-ide/spyder-kernels/pull/5) - PR: Add __version__ to package's init In this release 1 pull request was closed. ---- ## Version 0.2.2 (2018-06-22) ### Pull Requests Merged * [PR 4](https://github.com/spyder-ide/spyder-kernels/pull/4) - PR: Fix debugging in Python 2 In this release 1 pull request was closed. ---- ## Version 0.2.1 (2018-06-22) ### Pull Requests Merged * [PR 3](https://github.com/spyder-ide/spyder-kernels/pull/3) - PR: Fix debugging In this release 1 pull request was closed. ---- ## Version 0.2 (2018-06-20) ### Pull Requests Merged * [PR 2](https://github.com/spyder-ide/spyder-kernels/pull/2) - PR: Import our customizations directly here * [PR 1](https://github.com/spyder-ide/spyder-kernels/pull/1) - PR: Fix some errors in sitecustomize In this release 2 pull requests were closed. ---- ## Version 0.1 (2018-06-18) Initial release spyder-kernels-0.5.2/setup.cfg0000664000175000017500000000010313537413361017100 0ustar carloscarlos00000000000000[bdist_wheel] universal = 1 [egg_info] tag_build = tag_date = 0 spyder-kernels-0.5.2/PKG-INFO0000664000175000017500000000630613537413361016367 0ustar carloscarlos00000000000000Metadata-Version: 2.1 Name: spyder-kernels Version: 0.5.2 Summary: Jupyter kernels for Spyder's console Home-page: https://github.com/spyder-ide/spyder-kernels Author: Spyder Development Team Author-email: spyderlib@googlegroups.com License: MIT Download-URL: https://www.spyder-ide.org/#fh5co-download Description: # Jupyter kernels for the Spyder console [![CircleCI](https://circleci.com/gh/spyder-ide/spyder-kernels.svg?style=shield)](https://circleci.com/gh/spyder-ide/spyder-kernels) [![AppVeyor](https://ci.appveyor.com/api/projects/status/pd0etf64xyiyd3qb/branch/master?svg=true)](https://ci.appveyor.com/project/spyder-ide/spyder-kernels/branch/master) [![codecov](https://codecov.io/gh/spyder-ide/spyder-kernels/branch/master/graph/badge.svg)](https://codecov.io/gh/spyder-ide/spyder-kernels) Package that provides Jupyter kernels for use with the consoles of Spyder, the Scientific Python Development Environment. These kernels can launched either through Spyder itself or in an independent Python session, and allow for interactive or file-based execution of Python code inside Spyder. To learn about creating, connecting to and using these kernels with the Spyder console, please read our [documentation](https://docs.spyder-ide.org/ipythonconsole.html). For advice on managing packages and environments with `spyder-kernels`, please visit our [wiki](https://github.com/spyder-ide/spyder/wiki/Working-with-packages-and-environments-in-Spyder). ## Installation To install this package, you can use either the ``pip`` or ``conda`` package managers, as follows: Using conda (the recommended way!): ``` conda install spyder-kernels ``` Using pip: ``` pip install spyder-kernels ``` ## Dependencies This project depends on: * [ipykernel](https://github.com/ipython/ipykernel/) * [cloudpickle](https://github.com/cloudpipe/cloudpickle) * [wurlitzer](https://github.com/minrk/wurlitzer) ## Changelog Visit our [CHANGELOG](CHANGELOG.md) file to know more about our new features and improvements. ## Development and contribution To start contributing to this project you can execute ``` pip install -e . ``` in your git clone and then test your changes in Spyder. We follow PEP8 and PEP257 style guidelines. Keywords: spyder jupyter kernel ipython console Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Framework :: Jupyter Classifier: Framework :: IPython Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Software Development :: Interpreters Description-Content-Type: text/markdown Provides-Extra: test spyder-kernels-0.5.2/setup.py0000664000175000017500000000517713537412605017011 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """Jupyter Kernels for the Spyder consoles.""" # Standard library imports import ast import io import os # Third party imports from setuptools import find_packages, setup HERE = os.path.abspath(os.path.dirname(__file__)) with io.open('README.md', encoding='utf-8') as f: LONG_DESCRIPTION = f.read() def get_version(module='spyder_kernels'): """Get version.""" with open(os.path.join(HERE, module, '_version.py'), 'r') as f: data = f.read() lines = data.split('\n') for line in lines: if line.startswith('VERSION_INFO'): version_tuple = ast.literal_eval(line.split('=')[-1].strip()) version = '.'.join(map(str, version_tuple)) break return version REQUIREMENTS = ['ipykernel>=4.8.2', 'pyzmq>=17', 'jupyter-client>=5.2.3', 'cloudpickle', 'wurlitzer;platform_system!="Windows"'] TEST_REQUIREMENTS = ['numpy', 'pandas', 'scipy', 'pytest', 'pytest-cov', 'mock', 'cython', 'matplotlib', 'xarray'] setup( name='spyder-kernels', version=get_version(), keywords='spyder jupyter kernel ipython console', url='https://github.com/spyder-ide/spyder-kernels', download_url="https://www.spyder-ide.org/#fh5co-download", license='MIT', author='Spyder Development Team', author_email="spyderlib@googlegroups.com", description="Jupyter kernels for Spyder's console", long_description=LONG_DESCRIPTION, long_description_content_type='text/markdown', packages=find_packages(exclude=['docs', '*tests']), install_requires=REQUIREMENTS, extras_require={'test': TEST_REQUIREMENTS}, include_package_data=True, classifiers=['Development Status :: 5 - Production/Stable', 'Framework :: Jupyter', 'Framework :: IPython', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Topic :: Software Development :: Interpreters'] ) spyder-kernels-0.5.2/spyder_kernels/0000775000175000017500000000000013537413361020316 5ustar carloscarlos00000000000000spyder-kernels-0.5.2/spyder_kernels/_version.py0000664000175000017500000000062113537413276022520 0ustar carloscarlos00000000000000# # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """Version File.""" VERSION_INFO = (0, 5, 2) __version__ = '.'.join(map(str, VERSION_INFO)) spyder-kernels-0.5.2/spyder_kernels/py3compat.py0000664000175000017500000001673013537412605022616 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """ spyder.py3compat ---------------- Transitional module providing compatibility functions intended to help migrating from Python 2 to Python 3. This module should be fully compatible with: * Python >=v2.6 * Python 3 """ from __future__ import print_function import operator import os import sys PY2 = sys.version[0] == '2' PY3 = sys.version[0] == '3' #============================================================================== # Data types #============================================================================== if PY2: # Python 2 TEXT_TYPES = (str, unicode) INT_TYPES = (int, long) else: # Python 3 TEXT_TYPES = (str,) INT_TYPES = (int,) NUMERIC_TYPES = tuple(list(INT_TYPES) + [float, complex]) #============================================================================== # Renamed/Reorganized modules #============================================================================== if PY2: # Python 2 import __builtin__ as builtins import ConfigParser as configparser try: import _winreg as winreg except ImportError: pass from sys import maxint as maxsize try: import CStringIO as io except ImportError: import StringIO as io try: import cPickle as pickle except ImportError: import pickle from UserDict import DictMixin as MutableMapping import thread as _thread import repr as reprlib import Queue else: # Python 3 import builtins import configparser try: import winreg except ImportError: pass from sys import maxsize import io import pickle from collections import MutableMapping import _thread import reprlib import queue as Queue #============================================================================== # Strings #============================================================================== def is_type_text_string(obj): """Return True if `obj` is type text string, False if it is anything else, like an instance of a class that extends the basestring class.""" if PY2: # Python 2 return type(obj) in [str, unicode] else: # Python 3 return type(obj) in [str, bytes] def is_text_string(obj): """Return True if `obj` is a text string, False if it is anything else, like binary data (Python 3) or QString (Python 2, PyQt API #1)""" if PY2: # Python 2 return isinstance(obj, basestring) else: # Python 3 return isinstance(obj, str) def is_binary_string(obj): """Return True if `obj` is a binary string, False if it is anything else""" if PY2: # Python 2 return isinstance(obj, str) else: # Python 3 return isinstance(obj, bytes) def is_string(obj): """Return True if `obj` is a text or binary Python string object, False if it is anything else, like a QString (Python 2, PyQt API #1)""" return is_text_string(obj) or is_binary_string(obj) def is_unicode(obj): """Return True if `obj` is unicode""" if PY2: # Python 2 return isinstance(obj, unicode) else: # Python 3 return isinstance(obj, str) def to_text_string(obj, encoding=None): """Convert `obj` to (unicode) text string""" if PY2: # Python 2 if encoding is None: return unicode(obj) else: return unicode(obj, encoding) else: # Python 3 if encoding is None: return str(obj) elif isinstance(obj, str): # In case this function is not used properly, this could happen return obj else: return str(obj, encoding) def to_binary_string(obj, encoding=None): """Convert `obj` to binary string (bytes in Python 3, str in Python 2)""" if PY2: # Python 2 if encoding is None: return str(obj) else: return obj.encode(encoding) else: # Python 3 return bytes(obj, 'utf-8' if encoding is None else encoding) #============================================================================== # Function attributes #============================================================================== def get_func_code(func): """Return function code object""" if PY2: # Python 2 return func.func_code else: # Python 3 return func.__code__ def get_func_name(func): """Return function name""" if PY2: # Python 2 return func.func_name else: # Python 3 return func.__name__ def get_func_defaults(func): """Return function default argument values""" if PY2: # Python 2 return func.func_defaults else: # Python 3 return func.__defaults__ #============================================================================== # Special method attributes #============================================================================== def get_meth_func(obj): """Return method function object""" if PY2: # Python 2 return obj.im_func else: # Python 3 return obj.__func__ def get_meth_class_inst(obj): """Return method class instance""" if PY2: # Python 2 return obj.im_self else: # Python 3 return obj.__self__ def get_meth_class(obj): """Return method class""" if PY2: # Python 2 return obj.im_class else: # Python 3 return obj.__self__.__class__ #============================================================================== # Misc. #============================================================================== if PY2: # Python 2 input = raw_input getcwd = os.getcwdu cmp = cmp import string str_lower = string.lower from itertools import izip_longest as zip_longest else: # Python 3 input = input getcwd = os.getcwd def cmp(a, b): return (a > b) - (a < b) str_lower = str.lower from itertools import zip_longest def qbytearray_to_str(qba): """Convert QByteArray object to str in a way compatible with Python 2/3""" return str(bytes(qba.toHex().data()).decode()) # ============================================================================= # Dict funcs # ============================================================================= if PY3: def iterkeys(d, **kw): return iter(d.keys(**kw)) def itervalues(d, **kw): return iter(d.values(**kw)) def iteritems(d, **kw): return iter(d.items(**kw)) def iterlists(d, **kw): return iter(d.lists(**kw)) viewkeys = operator.methodcaller("keys") viewvalues = operator.methodcaller("values") viewitems = operator.methodcaller("items") else: def iterkeys(d, **kw): return d.iterkeys(**kw) def itervalues(d, **kw): return d.itervalues(**kw) def iteritems(d, **kw): return d.iteritems(**kw) def iterlists(d, **kw): return d.iterlists(**kw) viewkeys = operator.methodcaller("viewkeys") viewvalues = operator.methodcaller("viewvalues") viewitems = operator.methodcaller("viewitems") if __name__ == '__main__': pass spyder-kernels-0.5.2/spyder_kernels/console/0000775000175000017500000000000013537413361021760 5ustar carloscarlos00000000000000spyder-kernels-0.5.2/spyder_kernels/console/__main__.py0000664000175000017500000000064313423026501024043 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- if __name__ == '__main__': from spyder_kernels.console import start start.main() spyder-kernels-0.5.2/spyder_kernels/console/kernel.py0000664000175000017500000004113213537412605023613 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """ Spyder kernel for Jupyter """ # Standard library imports import os import os.path as osp import pickle import sys # Third-party imports from ipykernel.ipkernel import IPythonKernel PY2 = sys.version[0] == '2' # Excluded variables from the Variable Explorer (i.e. they are not # shown at all there) EXCLUDED_NAMES = ['In', 'Out', 'exit', 'get_ipython', 'quit'] # To be able to get and set variables between Python 2 and 3 PICKLE_PROTOCOL = 2 class SpyderKernel(IPythonKernel): """Spyder kernel for Jupyter""" def __init__(self, *args, **kwargs): super(SpyderKernel, self).__init__(*args, **kwargs) self.namespace_view_settings = {} self._pdb_obj = None self._pdb_step = None self._do_publish_pdb_state = True self._mpl_backend_error = None @property def _pdb_frame(self): """Return current Pdb frame if there is any""" if self._pdb_obj is not None and self._pdb_obj.curframe is not None: return self._pdb_obj.curframe @property def _pdb_locals(self): """ Return current Pdb frame locals if available. Otherwise return an empty dictionary """ if self._pdb_frame: return self._pdb_obj.curframe_locals else: return {} # -- Public API --------------------------------------------------- # --- For the Variable Explorer def get_namespace_view(self): """ Return the namespace view This is a dictionary with the following structure {'a': {'color': '#800000', 'size': 1, 'type': 'str', 'view': '1'}} Here: * 'a' is the variable name * 'color' is the color used to show it * 'size' and 'type' are self-evident * and'view' is its value or the text shown in the last column """ from spyder_kernels.utils.nsview import make_remote_view settings = self.namespace_view_settings if settings: ns = self._get_current_namespace() view = repr(make_remote_view(ns, settings, EXCLUDED_NAMES)) return view else: return repr(None) def get_var_properties(self): """ Get some properties of the variables in the current namespace """ from spyder_kernels.utils.nsview import get_remote_data settings = self.namespace_view_settings if settings: ns = self._get_current_namespace() data = get_remote_data(ns, settings, mode='editable', more_excluded_names=EXCLUDED_NAMES) properties = {} for name, value in list(data.items()): properties[name] = { 'is_list': isinstance(value, (tuple, list)), 'is_dict': isinstance(value, dict), 'len': self._get_len(value), 'is_array': self._is_array(value), 'is_image': self._is_image(value), 'is_data_frame': self._is_data_frame(value), 'is_series': self._is_series(value), 'array_shape': self._get_array_shape(value), 'array_ndim': self._get_array_ndim(value) } return repr(properties) else: return repr(None) def send_spyder_msg(self, spyder_msg_type, content=None, data=None): """ Publish custom messages to the Spyder frontend. Parameters ---------- spyder_msg_type: str The spyder message type content: dict The (JSONable) content of the message data: any Any object that is serializable by cloudpickle (should be most things). Will arrive as cloudpickled bytes in `.buffers[0]`. """ import cloudpickle if content is None: content = {} content['spyder_msg_type'] = spyder_msg_type msg = self.session.send( self.iopub_socket, 'spyder_msg', content=content, buffers=[cloudpickle.dumps(data, protocol=PICKLE_PROTOCOL)], parent=self._parent_header, ) self.log.debug(msg) def get_value(self, name): """Get the value of a variable""" ns = self._get_current_namespace() value = ns[name] try: self.send_spyder_msg('data', data=value) except: # * There is no need to inform users about # these errors. # * value = None makes Spyder to ignore # petitions to display a value self.send_spyder_msg('data', data=None) self._do_publish_pdb_state = False def set_value(self, name, value, PY2_frontend): """Set the value of a variable""" import cloudpickle ns = self._get_reference_namespace(name) # We send serialized values in a list of one element # from Spyder to the kernel, to be able to send them # at all in Python 2 svalue = value[0] # We need to convert svalue to bytes if the frontend # runs in Python 2 and the kernel runs in Python 3 if PY2_frontend and not PY2: svalue = bytes(svalue, 'latin-1') # Deserialize and set value in namespace dvalue = cloudpickle.loads(svalue) ns[name] = dvalue self.log.debug(ns) def remove_value(self, name): """Remove a variable""" ns = self._get_reference_namespace(name) ns.pop(name) def copy_value(self, orig_name, new_name): """Copy a variable""" ns = self._get_reference_namespace(orig_name) ns[new_name] = ns[orig_name] def load_data(self, filename, ext): """Load data from filename""" from spyder_kernels.utils.iofuncs import iofunctions from spyder_kernels.utils.misc import fix_reference_name glbs = self._mglobals() load_func = iofunctions.load_funcs[ext] data, error_message = load_func(filename) if error_message: return error_message for key in list(data.keys()): new_key = fix_reference_name(key, blacklist=list(glbs.keys())) if new_key != key: data[new_key] = data.pop(key) try: glbs.update(data) except Exception as error: return str(error) return None def save_namespace(self, filename): """Save namespace into filename""" from spyder_kernels.utils.nsview import get_remote_data from spyder_kernels.utils.iofuncs import iofunctions ns = self._get_current_namespace() settings = self.namespace_view_settings data = get_remote_data(ns, settings, mode='picklable', more_excluded_names=EXCLUDED_NAMES).copy() return iofunctions.save(data, filename) # --- For Pdb def publish_pdb_state(self): """ Publish Variable Explorer state and Pdb step through send_spyder_msg. """ if self._pdb_obj and self._do_publish_pdb_state: state = dict(namespace_view = self.get_namespace_view(), var_properties = self.get_var_properties(), step = self._pdb_step) self.send_spyder_msg('pdb_state', content={'pdb_state': state}) self._do_publish_pdb_state = True def pdb_continue(self): """ Tell the console to run 'continue' after entering a Pdb session to get to the first breakpoint. Fixes issue 2034 """ if self._pdb_obj: self.send_spyder_msg('pdb_continue') # --- For the Help plugin def is_defined(self, obj, force_import=False): """Return True if object is defined in current namespace""" from spyder_kernels.utils.dochelpers import isdefined ns = self._get_current_namespace(with_magics=True) return isdefined(obj, force_import=force_import, namespace=ns) def get_doc(self, objtxt): """Get object documentation dictionary""" try: import matplotlib matplotlib.rcParams['docstring.hardcopy'] = True except: pass from spyder_kernels.utils.dochelpers import getdoc obj, valid = self._eval(objtxt) if valid: return getdoc(obj) def get_source(self, objtxt): """Get object source""" from spyder_kernels.utils.dochelpers import getsource obj, valid = self._eval(objtxt) if valid: return getsource(obj) # --- Additional methods def set_cwd(self, dirname): """Set current working directory.""" os.chdir(dirname) def get_cwd(self): """Get current working directory.""" return os.getcwd() def get_syspath(self): """Return sys.path contents.""" return sys.path[:] def get_env(self): """Get environment variables.""" return os.environ.copy() def close_all_mpl_figures(self): """Close all Matplotlib figures.""" try: import matplotlib.pyplot as plt plt.close('all') del plt except: pass # -- Private API --------------------------------------------------- # --- For the Variable Explorer def _get_current_namespace(self, with_magics=False): """ Return current namespace This is globals() if not debugging, or a dictionary containing both locals() and globals() for current frame when debugging """ ns = {} glbs = self._mglobals() if self._pdb_frame is None: ns.update(glbs) else: ns.update(glbs) ns.update(self._pdb_locals) # Add magics to ns so we can show help about them on the Help # plugin if with_magics: line_magics = self.shell.magics_manager.magics['line'] cell_magics = self.shell.magics_manager.magics['cell'] ns.update(line_magics) ns.update(cell_magics) return ns def _get_reference_namespace(self, name): """ Return namespace where reference name is defined It returns the globals() if reference has not yet been defined """ glbs = self._mglobals() if self._pdb_frame is None: return glbs else: lcls = self._pdb_locals if name in lcls: return lcls else: return glbs def _mglobals(self): """Return current globals -- handles Pdb frames""" if self._pdb_frame is not None: return self._pdb_frame.f_globals else: return self.shell.user_ns def _get_len(self, var): """Return sequence length""" try: return len(var) except: return None def _is_array(self, var): """Return True if variable is a NumPy array""" try: import numpy return isinstance(var, numpy.ndarray) except: return False def _is_image(self, var): """Return True if variable is a PIL.Image image""" try: from PIL import Image return isinstance(var, Image.Image) except: return False def _is_data_frame(self, var): """Return True if variable is a DataFrame""" try: from pandas import DataFrame return isinstance(var, DataFrame) except: return False def _is_series(self, var): """Return True if variable is a Series""" try: from pandas import Series return isinstance(var, Series) except: return False def _get_array_shape(self, var): """Return array's shape""" try: if self._is_array(var): return var.shape else: return None except: return None def _get_array_ndim(self, var): """Return array's ndim""" try: if self._is_array(var): return var.ndim else: return None except: return None # --- For Pdb def _register_pdb_session(self, pdb_obj): """Register Pdb session to use it later""" self._pdb_obj = pdb_obj def _set_spyder_breakpoints(self, breakpoints): """Set all Spyder breakpoints in an active pdb session""" if not self._pdb_obj: return # Breakpoints come serialized from Spyder. We send them # in a list of one element to be able to send them at all # in Python 2 serialized_breakpoints = breakpoints[0] breakpoints = pickle.loads(serialized_breakpoints) self._pdb_obj.set_spyder_breakpoints(breakpoints) def _ask_spyder_for_breakpoints(self): if self._pdb_obj: self.send_spyder_msg('set_breakpoints') # --- For the Help plugin def _eval(self, text): """ Evaluate text and return (obj, valid) where *obj* is the object represented by *text* and *valid* is True if object evaluation did not raise any exception """ from spyder_kernels.py3compat import is_text_string assert is_text_string(text) ns = self._get_current_namespace(with_magics=True) try: return eval(text, ns), True except: return None, False # --- For Matplotlib def _set_mpl_backend(self, backend, pylab=False): """ Set a backend for Matplotlib. backend: A parameter that can be passed to %matplotlib (e.g. 'inline' or 'tk'). """ import traceback from IPython.core.getipython import get_ipython generic_error = ( "\n" + "="*73 + "\n" "NOTE: The following error appeared when setting " "your Matplotlib backend!!\n" + "="*73 + "\n\n" "{0}" ) magic = 'pylab' if pylab else 'matplotlib' error = None try: get_ipython().run_line_magic(magic, backend) except RuntimeError as err: # This catches errors generated by ipykernel when # trying to set a backend. See issue 5541 if "GUI eventloops" in str(err): import matplotlib previous_backend = matplotlib.get_backend() if not backend in previous_backend.lower(): # Only inform about an error if the user selected backend # and the one set by Matplotlib are different. Else this # message is very confusing. error = ( "\n" "NOTE: Spyder *can't* set your selected Matplotlib " "backend because there is a previous backend already " "in use.\n\n" "Your backend will be {0}".format(previous_backend) ) del matplotlib # This covers other RuntimeError's else: error = generic_error.format(traceback.format_exc()) except Exception: error = generic_error.format(traceback.format_exc()) self._mpl_backend_error = error def _show_mpl_backend_errors(self): """Show Matplotlib backend errors after the prompt is ready.""" if self._mpl_backend_error is not None: print(self._mpl_backend_error) # spyder: test-skip # --- Others def _load_autoreload_magic(self): """Load %autoreload magic.""" from IPython.core.getipython import get_ipython try: get_ipython().run_line_magic('reload_ext', 'autoreload') get_ipython().run_line_magic('autoreload', '2') except Exception: pass def _load_wurlitzer(self): """Load wurlitzer extension.""" # Wurlitzer has no effect on Windows if not os.name == 'nt': from IPython.core.getipython import get_ipython # Enclose this in a try/except because if it fails the # console will be totally unusable. # Fixes spyder-ide/spyder#8668 try: get_ipython().run_line_magic('reload_ext', 'wurlitzer') except Exception: pass spyder-kernels-0.5.2/spyder_kernels/console/start.py0000664000175000017500000002404313537412605023472 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """ File used to start kernels for the IPython Console """ # Standard library imports from distutils.version import LooseVersion import os import os.path as osp import sys import site PY2 = sys.version[0] == '2' def import_spydercustomize(): """Import our customizations into the kernel.""" here = osp.dirname(__file__) parent = osp.dirname(here) customize_dir = osp.join(parent, 'customize') # Remove current directory from sys.path to prevent kernel # crashes when people name Python files or modules with # the same name as standard library modules. # See spyder-ide/spyder#8007 while '' in sys.path: sys.path.remove('') # Import our customizations site.addsitedir(customize_dir) import spydercustomize # Remove our customize path from sys.path try: sys.path.remove(customize_dir) except ValueError: pass def is_module_installed(module_name): """ Simpler version of spyder.utils.programs.is_module_installed to improve startup time. """ try: __import__(module_name) return True except: # Module is not installed return False def sympy_config(mpl_backend): """Sympy configuration""" if mpl_backend is not None: lines = """ from sympy.interactive import init_session init_session() %matplotlib {0} """.format(mpl_backend) else: lines = """ from sympy.interactive import init_session init_session() """ return lines def kernel_config(): """Create a config object with IPython kernel options.""" import ipykernel from IPython.core.application import get_ipython_dir from traitlets.config.loader import Config, load_pyconfig_files # ---- IPython config ---- try: profile_path = osp.join(get_ipython_dir(), 'profile_default') cfg = load_pyconfig_files(['ipython_config.py', 'ipython_kernel_config.py'], profile_path) except: cfg = Config() # ---- Spyder config ---- spy_cfg = Config() # Enable/disable certain features for testing testing = os.environ.get('SPY_TESTING') == 'True' if testing: # Don't load nor save history in our IPython consoles. spy_cfg.HistoryAccessor.enabled = False # Until we implement Issue 1052 spy_cfg.InteractiveShell.xmode = 'Plain' # Jedi completer. It's only available in Python 3 jedi_o = os.environ.get('SPY_JEDI_O') == 'True' if not PY2: spy_cfg.IPCompleter.use_jedi = jedi_o # Run lines of code at startup run_lines_o = os.environ.get('SPY_RUN_LINES_O') if run_lines_o is not None: spy_cfg.IPKernelApp.exec_lines = [x.strip() for x in run_lines_o.split(',')] else: spy_cfg.IPKernelApp.exec_lines = [] # Clean terminal arguments input clear_argv = "import sys;sys.argv = [''];del sys" spy_cfg.IPKernelApp.exec_lines.append(clear_argv) # Load %autoreload magic spy_cfg.IPKernelApp.exec_lines.append( "get_ipython().kernel._load_autoreload_magic()") # Load wurlitzer extension spy_cfg.IPKernelApp.exec_lines.append( "get_ipython().kernel._load_wurlitzer()") # Default inline backend configuration # This is useful to have when people doesn't # use our config system to configure the # inline backend but want to use # '%matplotlib inline' at runtime if LooseVersion(ipykernel.__version__) < LooseVersion('4.5'): dpi_option = 'savefig.dpi' else: dpi_option = 'figure.dpi' spy_cfg.InlineBackend.rc = {'figure.figsize': (6.0, 4.0), dpi_option: 72, 'font.size': 10, 'figure.subplot.bottom': .125, 'figure.facecolor': 'white', 'figure.edgecolor': 'white'} # Pylab configuration mpl_backend = None if is_module_installed('matplotlib'): # Set Matplotlib backend with Spyder options pylab_o = os.environ.get('SPY_PYLAB_O') backend_o = os.environ.get('SPY_BACKEND_O') if pylab_o == 'True' and backend_o is not None: # Select the automatic backend if backend_o == '1': if is_module_installed('PyQt5'): auto_backend = 'qt5' elif is_module_installed('PyQt4'): auto_backend = 'qt4' elif is_module_installed('_tkinter'): auto_backend = 'tk' else: auto_backend = 'inline' else: auto_backend = '' # Mapping of Spyder options to backends backends = {'0': 'inline', '1': auto_backend, '2': 'qt5', '3': 'qt4', '4': 'osx', '5': 'gtk3', '6': 'gtk', '7': 'wx', '8': 'tk'} # Select backend mpl_backend = backends[backend_o] # Inline backend configuration if mpl_backend == 'inline': # Figure format format_o = os.environ.get('SPY_FORMAT_O') formats = {'0': 'png', '1': 'svg'} if format_o is not None: spy_cfg.InlineBackend.figure_format = formats[format_o] # Resolution resolution_o = os.environ.get('SPY_RESOLUTION_O') if resolution_o is not None: spy_cfg.InlineBackend.rc[dpi_option] = float(resolution_o) # Figure size width_o = float(os.environ.get('SPY_WIDTH_O')) height_o = float(os.environ.get('SPY_HEIGHT_O')) if width_o is not None and height_o is not None: spy_cfg.InlineBackend.rc['figure.figsize'] = (width_o, height_o) # Print figure kwargs bbox_inches_o = os.environ.get('SPY_BBOX_INCHES_O') bbox_inches = 'tight' if bbox_inches_o == 'True' else None spy_cfg.InlineBackend.print_figure_kwargs.update( {'bbox_inches': bbox_inches}) else: # Set Matplotlib backend to inline for external kernels. # Fixes issue 108 mpl_backend = 'inline' # Automatically load Pylab and Numpy, or only set Matplotlib # backend autoload_pylab_o = os.environ.get('SPY_AUTOLOAD_PYLAB_O') == 'True' command = "get_ipython().kernel._set_mpl_backend('{0}', {1})" spy_cfg.IPKernelApp.exec_lines.append( command.format(mpl_backend, autoload_pylab_o)) # Enable Cython magic run_cython = os.environ.get('SPY_RUN_CYTHON') == 'True' if run_cython and is_module_installed('Cython'): spy_cfg.IPKernelApp.exec_lines.append('%reload_ext Cython') # Run a file at startup use_file_o = os.environ.get('SPY_USE_FILE_O') run_file_o = os.environ.get('SPY_RUN_FILE_O') if use_file_o == 'True' and run_file_o is not None: spy_cfg.IPKernelApp.file_to_run = run_file_o # Autocall autocall_o = os.environ.get('SPY_AUTOCALL_O') if autocall_o is not None: spy_cfg.ZMQInteractiveShell.autocall = int(autocall_o) # To handle the banner by ourselves in IPython 3+ spy_cfg.ZMQInteractiveShell.banner1 = '' # Greedy completer greedy_o = os.environ.get('SPY_GREEDY_O') == 'True' spy_cfg.IPCompleter.greedy = greedy_o # Sympy loading sympy_o = os.environ.get('SPY_SYMPY_O') == 'True' if sympy_o and is_module_installed('sympy'): lines = sympy_config(mpl_backend) spy_cfg.IPKernelApp.exec_lines.append(lines) # Merge IPython and Spyder configs. Spyder prefs will have prevalence # over IPython ones cfg._merge(spy_cfg) return cfg def varexp(line): """ Spyder's variable explorer magic Used to generate plots, histograms and images of the variables displayed on it. """ ip = get_ipython() #analysis:ignore funcname, name = line.split() try: import guiqwt.pyplot as pyplot except: import matplotlib.pyplot as pyplot __fig__ = pyplot.figure(); __items__ = getattr(pyplot, funcname[2:])(ip.user_ns[name]) pyplot.show() del __fig__, __items__ def main(): # Remove this module's path from sys.path: try: sys.path.remove(osp.dirname(__file__)) except ValueError: pass try: locals().pop('__file__') except KeyError: pass __doc__ = '' __name__ = '__main__' # Import our customizations into the kernel import_spydercustomize() # Remove current directory from sys.path to prevent kernel # crashes when people name Python files or modules with # the same name as standard library modules. # See spyder-ide/spyder#8007 while '' in sys.path: sys.path.remove('') # Fire up the kernel instance. from ipykernel.kernelapp import IPKernelApp from spyder_kernels.console.kernel import SpyderKernel kernel = IPKernelApp.instance() kernel.kernel_class = SpyderKernel try: kernel.config = kernel_config() except: pass kernel.initialize() # Set our own magics kernel.shell.register_magic_function(varexp) # Set Pdb class to be used by %debug and %pdb. # This makes IPython consoles to use the class defined in our # sitecustomize instead of their default one. import pdb kernel.shell.InteractiveTB.debugger_cls = pdb.Pdb # Start the (infinite) kernel event loop. kernel.start() if __name__ == '__main__': main() spyder-kernels-0.5.2/spyder_kernels/console/__init__.py0000664000175000017500000000054113332371305024063 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """ Console kernel """ spyder-kernels-0.5.2/spyder_kernels/customize/0000775000175000017500000000000013537413361022340 5ustar carloscarlos00000000000000spyder-kernels-0.5.2/spyder_kernels/customize/spydercustomize.py0000664000175000017500000007247013537412605026175 0ustar carloscarlos00000000000000# # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- # # IMPORTANT NOTE: Don't add a coding line here! It's not necessary for # site files # # Spyder consoles sitecustomize # import bdb from distutils.version import LooseVersion import io import os import os.path as osp import pdb import re import shlex import sys import sysconfig import time import warnings from IPython.core.getipython import get_ipython # We are in Python 2? PY2 = sys.version[0] == '2' #============================================================================== # sys.argv can be missing when Python is embedded, taking care of it. # Fixes Issue 1473 and other crazy crashes with IPython 0.13 trying to # access it. #============================================================================== if not hasattr(sys, 'argv'): sys.argv = [''] #============================================================================== # Main constants #============================================================================== IS_EXT_INTERPRETER = os.environ.get('SPY_EXTERNAL_INTERPRETER') == "True" HIDE_CMD_WINDOWS = os.environ.get('SPY_HIDE_CMD') == "True" #============================================================================== # Important Note: # # We avoid importing spyder here, so we are handling Python 3 compatiblity # by hand. #============================================================================== def _print(*objects, **options): end = options.get('end', '\n') file = options.get('file', sys.stdout) sep = options.get('sep', ' ') string = sep.join([str(obj) for obj in objects]) if not PY2: # Python 3 local_dict = {} exec('printf = print', local_dict) # to avoid syntax error in Python 2 local_dict['printf'](string, file=file, end=end, sep=sep) else: # Python 2 if end: print >>file, string else: print >>file, string, #============================================================================== # Execfile functions # # The definitions for Python 2 on Windows were taken from the IPython project # Copyright (C) The IPython Development Team # Distributed under the terms of the modified BSD license #============================================================================== try: # Python 2 import __builtin__ as builtins if os.name == 'nt': def encode(u): return u.encode('utf8', 'replace') def execfile(fname, glob=None, loc=None): loc = loc if (loc is not None) else glob scripttext = builtins.open(fname).read()+ '\n' # compile converts unicode filename to str assuming # ascii. Let's do the conversion before calling compile if isinstance(fname, unicode): filename = encode(fname) else: filename = fname exec(compile(scripttext, filename, 'exec'), glob, loc) else: def execfile(fname, *where): if isinstance(fname, unicode): filename = fname.encode(sys.getfilesystemencoding()) else: filename = fname builtins.execfile(filename, *where) except ImportError: # Python 3 import builtins basestring = (str,) def execfile(filename, namespace): # Open a source file correctly, whatever its encoding is with open(filename, 'rb') as f: exec(compile(f.read(), filename, 'exec'), namespace) #============================================================================== # Setting console encoding (otherwise Python does not recognize encoding) # for Windows platforms #============================================================================== if os.name == 'nt' and PY2: try: import locale, ctypes _t, _cp = locale.getdefaultlocale('LANG') try: _cp = int(_cp[2:]) ctypes.windll.kernel32.SetConsoleCP(_cp) ctypes.windll.kernel32.SetConsoleOutputCP(_cp) except (ValueError, TypeError): # Code page number in locale is not valid pass except: pass #============================================================================== # Prevent subprocess.Popen calls to create visible console windows on Windows. # See issue #4932 #============================================================================== if os.name == 'nt' and HIDE_CMD_WINDOWS: import subprocess creation_flag = 0x08000000 # CREATE_NO_WINDOW class SubprocessPopen(subprocess.Popen): def __init__(self, *args, **kwargs): kwargs['creationflags'] = creation_flag super(SubprocessPopen, self).__init__(*args, **kwargs) subprocess.Popen = SubprocessPopen #============================================================================== # Importing user's sitecustomize #============================================================================== try: import sitecustomize #analysis:ignore except: pass #============================================================================== # Add default filesystem encoding on Linux to avoid an error with # Matplotlib 1.5 in Python 2 (Fixes Issue 2793) #============================================================================== if PY2 and sys.platform.startswith('linux'): def _getfilesystemencoding_wrapper(): return 'utf-8' sys.getfilesystemencoding = _getfilesystemencoding_wrapper #============================================================================== # Set PyQt API to #2 #============================================================================== if os.environ.get("QT_API") == 'pyqt': try: import sip for qtype in ('QString', 'QVariant', 'QDate', 'QDateTime', 'QTextStream', 'QTime', 'QUrl'): sip.setapi(qtype, 2) except: pass else: try: os.environ.pop('QT_API') except KeyError: pass #============================================================================== # IPython kernel adjustments #============================================================================== # Use ipydb as the debugger to patch on IPython consoles from IPython.core.debugger import Pdb as ipyPdb pdb.Pdb = ipyPdb # Patch unittest.main so that errors are printed directly in the console. # See http://comments.gmane.org/gmane.comp.python.ipython.devel/10557 # Fixes Issue 1370 import unittest from unittest import TestProgram class IPyTesProgram(TestProgram): def __init__(self, *args, **kwargs): test_runner = unittest.TextTestRunner(stream=sys.stderr) kwargs['testRunner'] = kwargs.pop('testRunner', test_runner) kwargs['exit'] = False TestProgram.__init__(self, *args, **kwargs) unittest.main = IPyTesProgram # Ignore some IPython/ipykernel warnings try: warnings.filterwarnings(action='ignore', category=DeprecationWarning, module='ipykernel.ipkernel') except: pass #============================================================================== # Turtle adjustments #============================================================================== # This is needed to prevent turtle scripts crashes after multiple runs in the # same IPython Console instance. # See Spyder issue #6278 try: import turtle from turtle import Screen, Terminator def spyder_bye(): try: Screen().bye() turtle.TurtleScreen._RUNNING = True except Terminator: pass turtle.bye = spyder_bye except: pass #============================================================================== # Pandas adjustments #============================================================================== try: import pandas as pd # Set Pandas output encoding pd.options.display.encoding = 'utf-8' # Filter warning that appears for DataFrames with np.nan values # Example: # >>> import pandas as pd, numpy as np # >>> pd.Series([np.nan,np.nan,np.nan],index=[1,2,3]) # Fixes Issue 2991 # For 0.18- warnings.filterwarnings(action='ignore', category=RuntimeWarning, module='pandas.core.format', message=".*invalid value encountered in.*") # For 0.18.1+ warnings.filterwarnings(action='ignore', category=RuntimeWarning, module='pandas.formats.format', message=".*invalid value encountered in.*") except: pass # ============================================================================= # Numpy adjustments # ============================================================================= try: # Filter warning that appears when users have 'Show max/min' # turned on and Numpy arrays contain a nan value. # Fixes Issue 7063 # Note: It only happens in Numpy 1.14+ warnings.filterwarnings(action='ignore', category=RuntimeWarning, module='numpy.core._methods', message=".*invalid value encountered in.*") except: pass # ============================================================================= # Multiprocessing adjustments # ============================================================================= # This patch is only needed on Windows and Python 3 if os.name == 'nt' and not PY2: # This could fail with changes in Python itself, so we protect it # with a try/except try: import multiprocessing.spawn _old_preparation_data = multiprocessing.spawn.get_preparation_data def _patched_preparation_data(name): """ Patched get_preparation_data to work when all variables are removed before execution. """ try: return _old_preparation_data(name) except AttributeError: main_module = sys.modules['__main__'] # Any string for __spec__ does the job main_module.__spec__ = '' return _old_preparation_data(name) multiprocessing.spawn.get_preparation_data = _patched_preparation_data except Exception: pass #============================================================================== # Pdb adjustments #============================================================================== class SpyderPdb(pdb.Pdb): send_initial_notification = True starting = True # --- Methods overriden by us def preloop(self): """Ask Spyder for berkpoints before the first prompt is created.""" if self.starting: get_ipython().kernel._ask_spyder_for_breakpoints() # --- Methods defined by us def set_spyder_breakpoints(self, breakpoints): self.clear_all_breaks() #------Really deleting all breakpoints: for bp in bdb.Breakpoint.bpbynumber: if bp: bp.deleteMe() bdb.Breakpoint.next = 1 bdb.Breakpoint.bplist = {} bdb.Breakpoint.bpbynumber = [None] #------ i = 0 for fname, data in list(breakpoints.items()): if osp.isfile(fname): for linenumber, condition in data: i += 1 self.set_break(self.canonic(fname), linenumber, cond=condition) # Jump to first breakpoint. # Fixes issue 2034 if self.starting: # Only run this after a Pdb session is created self.starting = False # Get all breakpoints for the file we're going to debug frame = self.curframe lineno = frame.f_lineno breaks = self.get_file_breaks(frame.f_code.co_filename) # Do 'continue' if the first breakpoint is *not* placed # where the debugger is going to land. # Fixes issue 4681 if breaks and lineno != breaks[0] and osp.isfile(fname): get_ipython().kernel.pdb_continue() def notify_spyder(self, frame): if not frame: return kernel = get_ipython().kernel # Get filename and line number of the current frame fname = self.canonic(frame.f_code.co_filename) if PY2: try: fname = unicode(fname, "utf-8") except TypeError: pass lineno = frame.f_lineno # Set step of the current frame (if any) step = {} if isinstance(fname, basestring) and isinstance(lineno, int): if osp.isfile(fname): step = dict(fname=fname, lineno=lineno) # Publish Pdb state so we can update the Variable Explorer # and the Editor on the Spyder side kernel._pdb_step = step kernel.publish_pdb_state() pdb.Pdb = SpyderPdb #XXX: I know, this function is now also implemented as is in utils/misc.py but # I'm kind of reluctant to import spyder in sitecustomize, even if this # import is very clean. def monkeypatch_method(cls, patch_name): # This function's code was inspired from the following thread: # "[Python-Dev] Monkeypatching idioms -- elegant or ugly?" # by Robert Brewer # (Tue Jan 15 19:13:25 CET 2008) """ Add the decorated method to the given class; replace as needed. If the named method already exists on the given class, it will be replaced, and a reference to the old method is created as cls._old. If the "_old__" attribute already exists, KeyError is raised. """ def decorator(func): fname = func.__name__ old_func = getattr(cls, fname, None) if old_func is not None: # Add the old func to a list of old funcs. old_ref = "_old_%s_%s" % (patch_name, fname) old_attr = getattr(cls, old_ref, None) if old_attr is None: setattr(cls, old_ref, old_func) else: raise KeyError("%s.%s already exists." % (cls.__name__, old_ref)) setattr(cls, fname, func) return func return decorator @monkeypatch_method(pdb.Pdb, 'Pdb') def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False): self._old_Pdb___init__() @monkeypatch_method(pdb.Pdb, 'Pdb') def user_return(self, frame, return_value): """This function is called when a return trap is set here.""" # This is useful when debugging in an active interpreter (otherwise, # the debugger will stop before reaching the target file) if self._wait_for_mainpyfile: if (self.mainpyfile != self.canonic(frame.f_code.co_filename) or frame.f_lineno<= 0): return self._wait_for_mainpyfile = 0 self._old_Pdb_user_return(frame, return_value) @monkeypatch_method(pdb.Pdb, 'Pdb') def interaction(self, frame, traceback): if frame is not None and "spydercustomize.py" in frame.f_code.co_filename: self.run('exit') else: self.setup(frame, traceback) if self.send_initial_notification: self.notify_spyder(frame) self.print_stack_entry(self.stack[self.curindex]) self._cmdloop() self.forget() @monkeypatch_method(pdb.Pdb, 'Pdb') def _cmdloop(self): while True: try: # keyboard interrupts allow for an easy way to cancel # the current command, so allow them during interactive input self.allow_kbdint = True self.cmdloop() self.allow_kbdint = False break except KeyboardInterrupt: _print("--KeyboardInterrupt--\n" "For copying text while debugging, use Ctrl+Shift+C", file=self.stdout) @monkeypatch_method(pdb.Pdb, 'Pdb') def reset(self): self._old_Pdb_reset() kernel = get_ipython().kernel kernel._register_pdb_session(self) #XXX: notify spyder on any pdb command (is that good or too lazy? i.e. is more # specific behaviour desired?) @monkeypatch_method(pdb.Pdb, 'Pdb') def postcmd(self, stop, line): if "_set_spyder_breakpoints" not in line: self.notify_spyder(self.curframe) return self._old_Pdb_postcmd(stop, line) # Breakpoints don't work for files with non-ascii chars in Python 2 # Fixes Issue 1484 if PY2: @monkeypatch_method(pdb.Pdb, 'Pdb') def break_here(self, frame): from bdb import effective filename = self.canonic(frame.f_code.co_filename) try: filename = unicode(filename, "utf-8") except TypeError: pass if not filename in self.breaks: return False lineno = frame.f_lineno if not lineno in self.breaks[filename]: # The line itself has no breakpoint, but maybe the line is the # first line of a function with breakpoint set by function name. lineno = frame.f_code.co_firstlineno if not lineno in self.breaks[filename]: return False # flag says ok to delete temp. bp (bp, flag) = effective(filename, lineno, frame) if bp: self.currentbp = bp.number if (flag and bp.temporary): self.do_clear(str(bp.number)) return True else: return False #============================================================================== # User module reloader #============================================================================== class UserModuleReloader(object): """ User Module Reloader (UMR) aims at deleting user modules to force Python to deeply reload them during import pathlist [list]: blacklist in terms of module path namelist [list]: blacklist in terms of module name """ def __init__(self, namelist=None, pathlist=None): if namelist is None: namelist = [] else: try: namelist = namelist.split(',') except Exception: namelist = [] # Spyder modules spy_modules = ['spyder_kernels'] # Matplotlib modules mpl_modules = ['matplotlib', 'tkinter', 'Tkinter'] # Add other, necessary modules to the UMR blacklist # astropy: see issue 6962 # pytorch: see issue 7041 # fastmat: see issue 7190 # pythoncom: see issue 7190 # tensorflow: see issue 8697 other_modules = ['pytorch', 'pythoncom', 'tensorflow'] if PY2: py2_modules = ['astropy', 'fastmat'] other_modules = other_modules + py2_modules self.namelist = namelist + spy_modules + mpl_modules + other_modules if pathlist is None: pathlist = [] self.pathlist = self.create_pathlist(pathlist) # List of previously loaded modules self.previous_modules = list(sys.modules.keys()) # List of module names to reload self.modnames_to_reload = [] # Activate Cython support self.has_cython = False self.activate_cython() # Check if the UMR is enabled or not enabled = os.environ.get("SPY_UMR_ENABLED", "") self.enabled = enabled.lower() == "true" # Check if the UMR should print the list of reloaded modules or not verbose = os.environ.get("SPY_UMR_VERBOSE", "") self.verbose = verbose.lower() == "true" def create_pathlist(self, initial_pathlist): """ Add to pathlist Python library paths to be skipped from module reloading. """ # Get standard installation paths try: paths = sysconfig.get_paths() standard_paths = [paths['stdlib'], paths['purelib'], paths['scripts'], paths['data']] except Exception: standard_paths = [] # Get user installation path # See Spyder issue 8776 try: import site if getattr(site, 'getusersitepackages', False): # Virtualenvs don't have this function but # conda envs do user_path = [site.getusersitepackages()] elif getattr(site, 'USER_SITE', False): # However, it seems virtualenvs have this # constant user_path = [site.USER_SITE] else: user_path = [] except Exception: user_path = [] return initial_pathlist + standard_paths + user_path def is_module_reloadable(self, module, modname): """Decide if a module is reloadable or not.""" if self.has_cython: # Don't return cached inline compiled .PYX files return False else: if (self.is_module_in_pathlist(module) or self.is_module_in_namelist(modname)): return False else: return True def is_module_in_namelist(self, modname): """Decide if a module can be reloaded or not according to its name.""" return set(modname.split('.')) & set(self.namelist) def is_module_in_pathlist(self, module): """Decide if a module can be reloaded or not according to its path.""" modpath = getattr(module, '__file__', None) # Skip module according to different criteria if modpath is None: # *module* is a C module that is statically linked into the # interpreter. There is no way to know its path, so we # choose to ignore it. return True elif any([p in modpath for p in self.pathlist]): # We don't want to reload modules that belong to the # standard library or installed to site-packages, # just modules created by the user. return True elif not os.name == 'nt': # Module paths containing the strings below can be ihherited # from the default Linux installation, Homebrew or the user # site-packages in a virtualenv. patterns = [r'^/usr/lib.*', r'^/usr/local/lib.*', r'^/usr/.*/dist-packages/.*', r'^/home/.*/.local/lib.*', r'^/Library/.*', r'^/Users/.*/Library/.*', r'^/Users/.*/.local/.*', ] if [p for p in patterns if re.search(p, modpath)]: return True else: return False else: return False def activate_cython(self): """ Activate Cython support. We need to run this here because if the support is active, we don't to run the UMR at all. """ run_cython = os.environ.get("SPY_RUN_CYTHON") == "True" if run_cython: try: __import__('Cython') self.has_cython = True except Exception: pass if self.has_cython: # Import pyximport to enable Cython files support for # import statement import pyximport pyx_setup_args = {} # Add Numpy include dir to pyximport/distutils try: import numpy pyx_setup_args['include_dirs'] = numpy.get_include() except Exception: pass # Setup pyximport and enable Cython files reload pyximport.install(setup_args=pyx_setup_args, reload_support=True) def run(self): """ Delete user modules to force Python to deeply reload them Do not del modules which are considered as system modules, i.e. modules installed in subdirectories of Python interpreter's binary Do not del C modules """ self.modnames_to_reload = [] for modname, module in list(sys.modules.items()): if modname not in self.previous_modules: # Decide if a module can be reloaded or not if self.is_module_reloadable(module, modname): self.modnames_to_reload.append(modname) del sys.modules[modname] else: continue # Report reloaded modules if self.verbose and self.modnames_to_reload: modnames = self.modnames_to_reload _print("\x1b[4;33m%s\x1b[24m%s\x1b[0m"\ % ("Reloaded modules", ": "+", ".join(modnames))) __umr__ = UserModuleReloader(namelist=os.environ.get("SPY_UMR_NAMELIST", None)) #============================================================================== # Handle Post Mortem Debugging and Traceback Linkage to Spyder #============================================================================== def clear_post_mortem(): """ Remove the post mortem excepthook and replace with a standard one. """ ipython_shell = get_ipython() ipython_shell.set_custom_exc((), None) def post_mortem_excepthook(type, value, tb): """ For post mortem exception handling, print a banner and enable post mortem debugging. """ clear_post_mortem() ipython_shell = get_ipython() ipython_shell.showtraceback((type, value, tb)) p = pdb.Pdb(ipython_shell.colors) if not type == SyntaxError: # wait for stderr to print (stderr.flush does not work in this case) time.sleep(0.1) _print('*' * 40) _print('Entering post mortem debugging...') _print('*' * 40) # add ability to move between frames p.send_initial_notification = False p.reset() frame = tb.tb_frame prev = frame while frame.f_back: prev = frame frame = frame.f_back frame = prev # wait for stdout to print time.sleep(0.1) p.interaction(frame, tb) def set_post_mortem(): """ Enable the post mortem debugging excepthook. """ def ipython_post_mortem_debug(shell, etype, evalue, tb, tb_offset=None): post_mortem_excepthook(etype, evalue, tb) ipython_shell = get_ipython() ipython_shell.set_custom_exc((Exception,), ipython_post_mortem_debug) # Add post mortem debugging if requested and in a dedicated interpreter # existing interpreters use "runfile" below if "SPYDER_EXCEPTHOOK" in os.environ: set_post_mortem() #============================================================================== # runfile and debugfile commands #============================================================================== def _get_globals(): """Return current namespace""" ipython_shell = get_ipython() return ipython_shell.user_ns def runfile(filename, args=None, wdir=None, namespace=None, post_mortem=False): """ Run filename args: command line arguments (string) wdir: working directory post_mortem: boolean, whether to enter post-mortem mode on error """ try: filename = filename.decode('utf-8') except (UnicodeError, TypeError, AttributeError): # UnicodeError, TypeError --> eventually raised in Python 2 # AttributeError --> systematically raised in Python 3 pass if __umr__.enabled: __umr__.run() if args is not None and not isinstance(args, basestring): raise TypeError("expected a character buffer object") if namespace is None: namespace = _get_globals() namespace['__file__'] = filename sys.argv = [filename] if args is not None: for arg in shlex.split(args): sys.argv.append(arg) if wdir is not None: try: wdir = wdir.decode('utf-8') except (UnicodeError, TypeError, AttributeError): # UnicodeError, TypeError --> eventually raised in Python 2 # AttributeError --> systematically raised in Python 3 pass os.chdir(wdir) if post_mortem: set_post_mortem() if __umr__.has_cython: # Cython files with io.open(filename, encoding='utf-8') as f: ipython_shell = get_ipython() ipython_shell.run_cell_magic('cython', '', f.read()) else: execfile(filename, namespace) clear_post_mortem() sys.argv = [''] # Avoid error when running `%reset -f` programmatically # See issue spyder-ide/spyder-kernels#91 try: namespace.pop('__file__') except KeyError: pass builtins.runfile = runfile def debugfile(filename, args=None, wdir=None, post_mortem=False): """ Debug filename args: command line arguments (string) wdir: working directory post_mortem: boolean, included for compatiblity with runfile """ debugger = pdb.Pdb() filename = debugger.canonic(filename) debugger._wait_for_mainpyfile = 1 debugger.mainpyfile = filename debugger._user_requested_quit = 0 if os.name == 'nt': filename = filename.replace('\\', '/') debugger.run("runfile(%r, args=%r, wdir=%r)" % (filename, args, wdir)) builtins.debugfile = debugfile #============================================================================== # Restoring original PYTHONPATH #============================================================================== try: os.environ['PYTHONPATH'] = os.environ['OLD_PYTHONPATH'] del os.environ['OLD_PYTHONPATH'] except KeyError: pass spyder-kernels-0.5.2/spyder_kernels/customize/__init__.py0000664000175000017500000000077713332371305024456 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """ Site package for the console kernel NOTE: This package shouldn't be imported at **any** place. It's only used to set additional functionality for our consoles. """ spyder-kernels-0.5.2/spyder_kernels/__init__.py0000664000175000017500000000270413332371305022424 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """ MIT License Copyright (c) 2009- Spyder Kernels Contributors (see AUTHORS.txt) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ from ._version import __version__ spyder-kernels-0.5.2/spyder_kernels/utils/0000775000175000017500000000000013537413361021456 5ustar carloscarlos00000000000000spyder-kernels-0.5.2/spyder_kernels/utils/dochelpers.py0000664000175000017500000002756713523051014024165 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """Utilities and wrappers around inspect module""" from __future__ import print_function import inspect import re # Local imports: from spyder_kernels.py3compat import (is_text_string, builtins, get_meth_func, get_meth_class_inst, get_meth_class, get_func_defaults, to_text_string, PY2) SYMBOLS = r"[^\'\"a-zA-Z0-9_.]" def getobj(txt, last=False): """Return the last valid object name in string""" txt_end = "" for startchar, endchar in ["[]", "()"]: if txt.endswith(endchar): pos = txt.rfind(startchar) if pos: txt_end = txt[pos:] txt = txt[:pos] tokens = re.split(SYMBOLS, txt) token = None try: while token is None or re.match(SYMBOLS, token): token = tokens.pop() if token.endswith('.'): token = token[:-1] if token.startswith('.'): # Invalid object name return None if last: #XXX: remove this statement as well as the "last" argument token += txt[ txt.rfind(token) + len(token) ] token += txt_end if token: return token except IndexError: return None def getobjdir(obj): """ For standard objects, will simply return dir(obj) In special cases (e.g. WrapITK package), will return only string elements of result returned by dir(obj) """ return [item for item in dir(obj) if is_text_string(item)] def getdoc(obj): """ Return text documentation from an object. This comes in a form of dictionary with four keys: name: The name of the inspected object argspec: It's argspec note: A phrase describing the type of object (function or method) we are inspecting, and the module it belongs to. docstring: It's docstring """ docstring = inspect.getdoc(obj) or inspect.getcomments(obj) or '' # Most of the time doc will only contain ascii characters, but there are # some docstrings that contain non-ascii characters. Not all source files # declare their encoding in the first line, so querying for that might not # yield anything, either. So assume the most commonly used # multi-byte file encoding (which also covers ascii). try: docstring = to_text_string(docstring) except: pass # Doc dict keys doc = {'name': '', 'argspec': '', 'note': '', 'docstring': docstring} if callable(obj): try: name = obj.__name__ except AttributeError: doc['docstring'] = docstring return doc if inspect.ismethod(obj): imclass = get_meth_class(obj) if get_meth_class_inst(obj) is not None: doc['note'] = 'Method of %s instance' \ % get_meth_class_inst(obj).__class__.__name__ else: doc['note'] = 'Unbound %s method' % imclass.__name__ obj = get_meth_func(obj) elif hasattr(obj, '__module__'): doc['note'] = 'Function of %s module' % obj.__module__ else: doc['note'] = 'Function' doc['name'] = obj.__name__ if inspect.isfunction(obj): if PY2: args, varargs, varkw, defaults = inspect.getargspec(obj) doc['argspec'] = inspect.formatargspec( args, varargs, varkw, defaults, formatvalue=lambda o:'='+repr(o)) else: (args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations) = inspect.getfullargspec(obj) doc['argspec'] = inspect.formatargspec( args, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations, formatvalue=lambda o:'='+repr(o)) if name == '': doc['name'] = name + ' lambda ' doc['argspec'] = doc['argspec'][1:-1] # remove parentheses else: argspec = getargspecfromtext(doc['docstring']) if argspec: doc['argspec'] = argspec # Many scipy and numpy docstrings begin with a function # signature on the first line. This ends up begin redundant # when we are using title and argspec to create the # rich text "Definition:" field. We'll carefully remove this # redundancy but only under a strict set of conditions: # Remove the starting charaters of the 'doc' portion *iff* # the non-whitespace characters on the first line # match *exactly* the combined function title # and argspec we determined above. signature = doc['name'] + doc['argspec'] docstring_blocks = doc['docstring'].split("\n\n") first_block = docstring_blocks[0].strip() if first_block == signature: doc['docstring'] = doc['docstring'].replace( signature, '', 1).lstrip() else: doc['argspec'] = '(...)' # Remove self from argspec argspec = doc['argspec'] doc['argspec'] = argspec.replace('(self)', '()').replace('(self, ', '(') return doc def getsource(obj): """Wrapper around inspect.getsource""" try: try: src = to_text_string(inspect.getsource(obj)) except TypeError: if hasattr(obj, '__class__'): src = to_text_string(inspect.getsource(obj.__class__)) else: # Bindings like VTK or ITK require this case src = getdoc(obj) return src except (TypeError, IOError): return def getsignaturefromtext(text, objname): """Get object signatures from text (object documentation) Return a list containing a single string in most cases Example of multiple signatures: PyQt5 objects""" if isinstance(text, dict): text = text.get('docstring', '') # Regexps oneline_re = objname + r'\([^\)].+?(?<=[\w\]\}\'"])\)(?!,)' multiline_re = objname + r'\([^\)]+(?<=[\w\]\}\'"])\)(?!,)' multiline_end_parenleft_re = r'(%s\([^\)]+(\),\n.+)+(?<=[\w\]\}\'"])\))' # Grabbing signatures if not text: text = '' sigs_1 = re.findall(oneline_re + '|' + multiline_re, text) sigs_2 = [g[0] for g in re.findall(multiline_end_parenleft_re % objname, text)] all_sigs = sigs_1 + sigs_2 # The most relevant signature is usually the first one. There could be # others in doctests but those are not so important if all_sigs: return all_sigs[0] else: return '' # Fix for Issue 1953 # TODO: Add more signatures and remove this hack in 2.4 getsignaturesfromtext = getsignaturefromtext def getargspecfromtext(text): """ Try to get the formatted argspec of a callable from the first block of its docstring This will return something like '(foo, bar, k=1)' """ blocks = text.split("\n\n") first_block = blocks[0].strip() return getsignaturefromtext(first_block, '') def getargsfromtext(text, objname): """Get arguments from text (object documentation)""" signature = getsignaturefromtext(text, objname) if signature: argtxt = signature[signature.find('(')+1:-1] return argtxt.split(',') def getargsfromdoc(obj): """Get arguments from object doc""" if obj.__doc__ is not None: return getargsfromtext(obj.__doc__, obj.__name__) def getargs(obj): """Get the names and default values of a function's arguments""" if inspect.isfunction(obj) or inspect.isbuiltin(obj): func_obj = obj elif inspect.ismethod(obj): func_obj = get_meth_func(obj) elif inspect.isclass(obj) and hasattr(obj, '__init__'): func_obj = getattr(obj, '__init__') else: return [] if not hasattr(func_obj, 'func_code'): # Builtin: try to extract info from doc args = getargsfromdoc(func_obj) if args is not None: return args else: # Example: PyQt5 return getargsfromdoc(obj) args, _, _ = inspect.getargs(func_obj.func_code) if not args: return getargsfromdoc(obj) # Supporting tuple arguments in def statement: for i_arg, arg in enumerate(args): if isinstance(arg, list): args[i_arg] = "(%s)" % ", ".join(arg) defaults = get_func_defaults(func_obj) if defaults is not None: for index, default in enumerate(defaults): args[index+len(args)-len(defaults)] += '='+repr(default) if inspect.isclass(obj) or inspect.ismethod(obj): if len(args) == 1: return None if 'self' in args: args.remove('self') return args def getargtxt(obj, one_arg_per_line=True): """ Get the names and default values of a function's arguments Return list with separators (', ') formatted for calltips """ args = getargs(obj) if args: sep = ', ' textlist = None for i_arg, arg in enumerate(args): if textlist is None: textlist = [''] textlist[-1] += arg if i_arg < len(args)-1: textlist[-1] += sep if len(textlist[-1]) >= 32 or one_arg_per_line: textlist.append('') if inspect.isclass(obj) or inspect.ismethod(obj): if len(textlist) == 1: return None if 'self'+sep in textlist: textlist.remove('self'+sep) return textlist def isdefined(obj, force_import=False, namespace=None): """Return True if object is defined in namespace If namespace is None --> namespace = locals()""" if namespace is None: namespace = locals() attr_list = obj.split('.') base = attr_list.pop(0) if len(base) == 0: return False if base not in builtins.__dict__ and base not in namespace: if force_import: try: module = __import__(base, globals(), namespace) if base not in globals(): globals()[base] = module namespace[base] = module except Exception: return False else: return False for attr in attr_list: try: attr_not_found = not hasattr(eval(base, namespace), attr) except (SyntaxError, AttributeError): return False if attr_not_found: if force_import: try: __import__(base+'.'+attr, globals(), namespace) except (ImportError, SyntaxError): return False else: return False base += '.'+attr return True if __name__ == "__main__": class Test(object): def method(self, x, y=2): pass print(getargtxt(Test.__init__)) # spyder: test-skip print(getargtxt(Test.method)) # spyder: test-skip print(isdefined('numpy.take', force_import=True)) # spyder: test-skip print(isdefined('__import__')) # spyder: test-skip print(isdefined('.keys', force_import=True)) # spyder: test-skip print(getobj('globals')) # spyder: test-skip print(getobj('globals().keys')) # spyder: test-skip print(getobj('+scipy.signal.')) # spyder: test-skip print(getobj('4.')) # spyder: test-skip print(getdoc(sorted)) # spyder: test-skip print(getargtxt(sorted)) # spyder: test-skip spyder-kernels-0.5.2/spyder_kernels/utils/iofuncs.py0000664000175000017500000004545113424112353023477 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """ Input/Output Utilities Note: 'load' functions has to return a dictionary from which a globals() namespace may be updated """ from __future__ import print_function # Standard library imports import sys import os import os.path as osp import tarfile import tempfile import shutil import types import warnings import json import inspect import dis import copy import glob # Third party imports # - If pandas fails to import here (for any reason), Spyder # will crash at startup (e.g. see Issue 2300) # - This also prevents Spyder to start IPython kernels # (see Issue 2456) try: import pandas as pd except: pd = None #analysis:ignore # Local imports from spyder_kernels.py3compat import getcwd, pickle, PY2, to_text_string class MatlabStruct(dict): """ Matlab style struct, enhanced. Supports dictionary and attribute style access. Can be pickled, and supports code completion in a REPL. Examples ======== >>> from spyder.utils.iofuncs import MatlabStruct >>> a = MatlabStruct() >>> a.b = 'spam' # a["b"] == 'spam' >>> a.c["d"] = 'eggs' # a.c.d == 'eggs' >>> print(a) {'c': {'d': 'eggs'}, 'b': 'spam'} """ def __getattr__(self, attr): """Access the dictionary keys for unknown attributes.""" try: return self[attr] except KeyError: msg = "'MatlabStruct' object has no attribute %s" % attr raise AttributeError(msg) def __getitem__(self, attr): """ Get a dict value; create a MatlabStruct if requesting a submember. Do not create a key if the attribute starts with an underscore. """ if attr in self.keys() or attr.startswith('_'): return dict.__getitem__(self, attr) frame = inspect.currentframe() # step into the function that called us if frame.f_back.f_back and self._is_allowed(frame.f_back.f_back): dict.__setitem__(self, attr, MatlabStruct()) elif self._is_allowed(frame.f_back): dict.__setitem__(self, attr, MatlabStruct()) return dict.__getitem__(self, attr) def _is_allowed(self, frame): """Check for allowed op code in the calling frame""" allowed = [dis.opmap['STORE_ATTR'], dis.opmap['LOAD_CONST'], dis.opmap.get('STOP_CODE', 0)] bytecode = frame.f_code.co_code instruction = bytecode[frame.f_lasti + 3] instruction = ord(instruction) if PY2 else instruction return instruction in allowed __setattr__ = dict.__setitem__ __delattr__ = dict.__delitem__ @property def __dict__(self): """Allow for code completion in a REPL""" return self.copy() def get_matlab_value(val): """ Extract a value from a Matlab file From the oct2py project, see https://pythonhosted.org/oct2py/conversions.html """ import numpy as np # Extract each item of a list. if isinstance(val, list): return [get_matlab_value(v) for v in val] # Ignore leaf objects. if not isinstance(val, np.ndarray): return val # Convert user defined classes. if hasattr(val, 'classname'): out = dict() for name in val.dtype.names: out[name] = get_matlab_value(val[name].squeeze().tolist()) cls = type(val.classname, (object,), out) return cls() # Extract struct data. elif val.dtype.names: out = MatlabStruct() for name in val.dtype.names: out[name] = get_matlab_value(val[name].squeeze().tolist()) val = out # Extract cells. elif val.dtype.kind == 'O': val = val.squeeze().tolist() if not isinstance(val, list): val = [val] val = get_matlab_value(val) # Compress singleton values. elif val.size == 1: val = val.item() # Compress empty values. elif val.size == 0: if val.dtype.kind in 'US': val = '' else: val = [] return val try: import numpy as np try: with warnings.catch_warnings(): warnings.simplefilter("ignore") import scipy.io as spio except AttributeError: # Python 2.5: warnings.catch_warnings was introduced in Python 2.6 import scipy.io as spio # analysis:ignore except: spio = None if spio is None: load_matlab = None save_matlab = None else: def load_matlab(filename): try: out = spio.loadmat(filename, struct_as_record=True) data = dict() for (key, value) in out.items(): data[key] = get_matlab_value(value) return data, None except Exception as error: return None, str(error) def save_matlab(data, filename): try: spio.savemat(filename, data, oned_as='row') except Exception as error: return str(error) except: load_matlab = None save_matlab = None try: import numpy as np # analysis:ignore def load_array(filename): try: name = osp.splitext(osp.basename(filename))[0] data = np.load(filename) if hasattr(data, 'keys'): return data, None else: return {name: data}, None except Exception as error: return None, str(error) def __save_array(data, basename, index): """Save numpy array""" fname = basename + '_%04d.npy' % index np.save(fname, data) return fname except: load_array = None try: from spyder.pil_patch import Image if sys.byteorder == 'little': _ENDIAN = '<' else: _ENDIAN = '>' DTYPES = { "1": ('|b1', None), "L": ('|u1', None), "I": ('%si4' % _ENDIAN, None), "F": ('%sf4' % _ENDIAN, None), "I;16": ('|u2', None), "I;16S": ('%si2' % _ENDIAN, None), "P": ('|u1', None), "RGB": ('|u1', 3), "RGBX": ('|u1', 4), "RGBA": ('|u1', 4), "CMYK": ('|u1', 4), "YCbCr": ('|u1', 4), } def __image_to_array(filename): img = Image.open(filename) try: dtype, extra = DTYPES[img.mode] except KeyError: raise RuntimeError("%s mode is not supported" % img.mode) shape = (img.size[1], img.size[0]) if extra is not None: shape += (extra,) return np.array(img.getdata(), dtype=np.dtype(dtype)).reshape(shape) def load_image(filename): try: name = osp.splitext(osp.basename(filename))[0] return {name: __image_to_array(filename)}, None except Exception as error: return None, str(error) except: load_image = None def load_pickle(filename): """Load a pickle file as a dictionary""" try: if pd: return pd.read_pickle(filename), None else: with open(filename, 'rb') as fid: data = pickle.load(fid) return data, None except Exception as err: return None, str(err) def load_json(filename): """Load a json file as a dictionary""" try: if PY2: args = 'rb' else: args = 'r' with open(filename, args) as fid: data = json.load(fid) return data, None except Exception as err: return None, str(err) def save_dictionary(data, filename): """Save dictionary in a single file .spydata file""" filename = osp.abspath(filename) old_cwd = getcwd() os.chdir(osp.dirname(filename)) error_message = None skipped_keys = [] data_copy = {} try: # Copy dictionary before modifying it to fix #6689 for obj_name, obj_value in data.items(): # Skip modules, since they can't be pickled, users virtually never # would want them to be and so they don't show up in the skip list. # Skip callables, since they are only pickled by reference and thus # must already be present in the user's environment anyway. if not (callable(obj_value) or isinstance(obj_value, types.ModuleType)): # If an object cannot be deepcopied, then it cannot be pickled. # Ergo, we skip it and list it later. try: data_copy[obj_name] = copy.deepcopy(obj_value) except Exception: skipped_keys.append(obj_name) data = data_copy if not data: raise RuntimeError('No supported objects to save') saved_arrays = {} if load_array is not None: # Saving numpy arrays with np.save arr_fname = osp.splitext(filename)[0] for name in list(data.keys()): try: if isinstance(data[name], np.ndarray) and data[name].size > 0: # Save arrays at data root fname = __save_array(data[name], arr_fname, len(saved_arrays)) saved_arrays[(name, None)] = osp.basename(fname) data.pop(name) elif isinstance(data[name], (list, dict)): # Save arrays nested in lists or dictionaries if isinstance(data[name], list): iterator = enumerate(data[name]) else: iterator = iter(list(data[name].items())) to_remove = [] for index, value in iterator: if isinstance(value, np.ndarray) and value.size > 0: fname = __save_array(value, arr_fname, len(saved_arrays)) saved_arrays[(name, index)] = ( osp.basename(fname)) to_remove.append(index) for index in sorted(to_remove, reverse=True): data[name].pop(index) except (RuntimeError, pickle.PicklingError, TypeError, AttributeError, IndexError): # If an array can't be saved with numpy for some reason, # leave the object intact and try to save it normally. pass if saved_arrays: data['__saved_arrays__'] = saved_arrays pickle_filename = osp.splitext(filename)[0] + '.pickle' # Attempt to pickle everything. # If pickling fails, iterate through to eliminate problem objs & retry. with open(pickle_filename, 'w+b') as fdesc: try: pickle.dump(data, fdesc, protocol=2) except (pickle.PicklingError, AttributeError, TypeError, ImportError, IndexError, RuntimeError): data_filtered = {} for obj_name, obj_value in data.items(): try: pickle.dumps(obj_value, protocol=2) except Exception: skipped_keys.append(obj_name) else: data_filtered[obj_name] = obj_value if not data_filtered: raise RuntimeError('No supported objects to save') pickle.dump(data_filtered, fdesc, protocol=2) # Use PAX (POSIX.1-2001) format instead of default GNU. # This improves interoperability and UTF-8/long variable name support. with tarfile.open(filename, "w", format=tarfile.PAX_FORMAT) as tar: for fname in ([pickle_filename] + [fn for fn in list(saved_arrays.values())]): tar.add(osp.basename(fname)) os.remove(fname) except (RuntimeError, pickle.PicklingError, TypeError) as error: error_message = to_text_string(error) else: if skipped_keys: skipped_keys.sort() error_message = ('Some objects could not be saved: ' + ', '.join(skipped_keys)) finally: os.chdir(old_cwd) return error_message def load_dictionary(filename): """Load dictionary from .spydata file""" filename = osp.abspath(filename) old_cwd = getcwd() tmp_folder = tempfile.mkdtemp() os.chdir(tmp_folder) data = None error_message = None try: with tarfile.open(filename, "r") as tar: tar.extractall() pickle_filename = glob.glob('*.pickle')[0] # 'New' format (Spyder >=2.2 for Python 2 and Python 3) with open(pickle_filename, 'rb') as fdesc: data = pickle.loads(fdesc.read()) saved_arrays = {} if load_array is not None: # Loading numpy arrays saved with np.save try: saved_arrays = data.pop('__saved_arrays__') for (name, index), fname in list(saved_arrays.items()): arr = np.load( osp.join(tmp_folder, fname) ) if index is None: data[name] = arr elif isinstance(data[name], dict): data[name][index] = arr else: data[name].insert(index, arr) except KeyError: pass # Except AttributeError from e.g. trying to load function no longer present except (AttributeError, EOFError, ValueError) as error: error_message = to_text_string(error) # To ensure working dir gets changed back and temp dir wiped no matter what finally: os.chdir(old_cwd) try: shutil.rmtree(tmp_folder) except OSError as error: error_message = to_text_string(error) return data, error_message class IOFunctions(object): def __init__(self): self.load_extensions = None self.save_extensions = None self.load_filters = None self.save_filters = None self.load_funcs = None self.save_funcs = None def setup(self): iofuncs = self.get_internal_funcs()+self.get_3rd_party_funcs() load_extensions = {} save_extensions = {} load_funcs = {} save_funcs = {} load_filters = [] save_filters = [] load_ext = [] for ext, name, loadfunc, savefunc in iofuncs: filter_str = to_text_string(name + " (*%s)" % ext) if loadfunc is not None: load_filters.append(filter_str) load_extensions[filter_str] = ext load_funcs[ext] = loadfunc load_ext.append(ext) if savefunc is not None: save_extensions[filter_str] = ext save_filters.append(filter_str) save_funcs[ext] = savefunc load_filters.insert(0, to_text_string("Supported files"+" (*"+\ " *".join(load_ext)+")")) load_filters.append(to_text_string("All files (*.*)")) self.load_filters = "\n".join(load_filters) self.save_filters = "\n".join(save_filters) self.load_funcs = load_funcs self.save_funcs = save_funcs self.load_extensions = load_extensions self.save_extensions = save_extensions def get_internal_funcs(self): return [ ('.spydata', "Spyder data files", load_dictionary, save_dictionary), ('.npy', "NumPy arrays", load_array, None), ('.npz', "NumPy zip arrays", load_array, None), ('.mat', "Matlab files", load_matlab, save_matlab), ('.csv', "CSV text files", 'import_wizard', None), ('.txt', "Text files", 'import_wizard', None), ('.jpg', "JPEG images", load_image, None), ('.png', "PNG images", load_image, None), ('.gif', "GIF images", load_image, None), ('.tif', "TIFF images", load_image, None), ('.pkl', "Pickle files", load_pickle, None), ('.pickle', "Pickle files", load_pickle, None), ('.json', "JSON files", load_json, None), ] def get_3rd_party_funcs(self): other_funcs = [] try: from spyder.otherplugins import get_spyderplugins_mods for mod in get_spyderplugins_mods(io=True): try: other_funcs.append((mod.FORMAT_EXT, mod.FORMAT_NAME, mod.FORMAT_LOAD, mod.FORMAT_SAVE)) except AttributeError as error: print("%s: %s" % (mod, str(error)), file=sys.stderr) except ImportError: pass return other_funcs def save(self, data, filename): ext = osp.splitext(filename)[1].lower() if ext in self.save_funcs: return self.save_funcs[ext](data, filename) else: return "Unsupported file type '%s'" % ext def load(self, filename): ext = osp.splitext(filename)[1].lower() if ext in self.load_funcs: return self.load_funcs[ext](filename) else: return None, "Unsupported file type '%s'" % ext iofunctions = IOFunctions() iofunctions.setup() def save_auto(data, filename): """Save data into filename, depending on file extension""" pass if __name__ == "__main__": import datetime testdict = {'d': 1, 'a': np.random.rand(10, 10), 'b': [1, 2]} testdate = datetime.date(1945, 5, 8) example = {'str': 'kjkj kj k j j kj k jkj', 'unicode': u'éù', 'list': [1, 3, [4, 5, 6], 'kjkj', None], 'tuple': ([1, testdate, testdict], 'kjkj', None), 'dict': testdict, 'float': 1.2233, 'array': np.random.rand(4000, 400), 'empty_array': np.array([]), 'date': testdate, 'datetime': datetime.datetime(1945, 5, 8), } import time t0 = time.time() save_dictionary(example, "test.spydata") print(" Data saved in %.3f seconds" % (time.time()-t0)) # spyder: test-skip t0 = time.time() example2, ok = load_dictionary("test.spydata") os.remove("test.spydata") print("Data loaded in %.3f seconds" % (time.time()-t0)) # spyder: test-skip spyder-kernels-0.5.2/spyder_kernels/utils/test_utils.py0000664000175000017500000000262113522062007024217 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2018- Spyder Kernels Contributors # Taken from the tests utils in the Metakernel package # See utils.py at https://github.com/Calysto/metakernel/metakernel/tests # Licensed under the terms of the BSD License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- try: from jupyter_client import session as ss except ImportError: from IPython.kernel.zmq import session as ss import zmq import logging try: from StringIO import StringIO except ImportError: from io import StringIO from spyder_kernels.console.kernel import SpyderKernel def get_kernel(kernel_class=SpyderKernel): """Get an instance of a kernel with the kernel class given.""" log = logging.getLogger('test') log.setLevel(logging.DEBUG) for hdlr in log.handlers: log.removeHandler(hdlr) hdlr = logging.StreamHandler(StringIO()) hdlr.setLevel(logging.DEBUG) log.addHandler(hdlr) context = zmq.Context.instance() iopub_socket = context.socket(zmq.PUB) kernel = kernel_class(session=ss.Session(), iopub_socket=iopub_socket, log=log) return kernel def get_log_text(kernel): """Get the log of the given kernel.""" return kernel.log.handlers[0].stream.getvalue() spyder-kernels-0.5.2/spyder_kernels/utils/misc.py0000664000175000017500000000200013423026502022742 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """Miscellaneous utilities""" import re def fix_reference_name(name, blacklist=None): """Return a syntax-valid Python reference name from an arbitrary name""" name = "".join(re.split(r'[^0-9a-zA-Z_]', name)) while name and not re.match(r'([a-zA-Z]+[0-9a-zA-Z_]*)$', name): if not re.match(r'[a-zA-Z]', name[0]): name = name[1:] continue name = str(name) if not name: name = "data" if blacklist is not None and name in blacklist: get_new_name = lambda index: name+('%03d' % index) index = 0 while get_new_name(index) in blacklist: index += 1 name = get_new_name(index) return name spyder-kernels-0.5.2/spyder_kernels/utils/nsview.py0000664000175000017500000005670413537412605023357 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """ Utilities """ from __future__ import print_function from itertools import islice import re # Local imports from spyder_kernels.py3compat import (NUMERIC_TYPES, INT_TYPES, TEXT_TYPES, to_text_string, is_text_string, is_type_text_string, is_binary_string, PY2, to_binary_string, iteritems) #============================================================================== # FakeObject #============================================================================== class FakeObject(object): """Fake class used in replacement of missing modules""" pass #============================================================================== # Numpy arrays and numeric types support #============================================================================== try: from numpy import (ndarray, array, matrix, recarray, int64, int32, int16, int8, uint64, uint32, uint16, uint8, float64, float32, float16, complex64, complex128, bool_) from numpy.ma import MaskedArray from numpy import savetxt as np_savetxt from numpy import get_printoptions, set_printoptions except: ndarray = array = matrix = recarray = MaskedArray = np_savetxt = \ int64 = int32 = int16 = int8 = uint64 = uint32 = uint16 = uint8 = \ float64 = float32 = float16 = complex64 = complex128 = bool_ = FakeObject def get_numpy_dtype(obj): """Return NumPy data type associated to obj Return None if NumPy is not available or if obj is not a NumPy array or scalar""" if ndarray is not FakeObject: # NumPy is available import numpy as np if isinstance(obj, np.generic) or isinstance(obj, np.ndarray): # Numpy scalars all inherit from np.generic. # Numpy arrays all inherit from np.ndarray. # If we check that we are certain we have one of these # types then we are less likely to generate an exception below. try: return obj.dtype.type except (AttributeError, RuntimeError): # AttributeError: some NumPy objects have no dtype attribute # RuntimeError: happens with NetCDF objects (Issue 998) return #============================================================================== # Pandas support #============================================================================== try: from pandas import DataFrame, DatetimeIndex, Series except: DataFrame = DatetimeIndex = Series = FakeObject #============================================================================== # PIL Images support #============================================================================== try: from spyder import pil_patch Image = pil_patch.Image.Image except: Image = FakeObject # analysis:ignore #============================================================================== # BeautifulSoup support (see Issue 2448) #============================================================================== try: import bs4 NavigableString = bs4.element.NavigableString except: NavigableString = FakeObject # analysis:ignore #============================================================================== # Misc. #============================================================================== def address(obj): """Return object address as a string: ''""" return "<%s @ %s>" % (obj.__class__.__name__, hex(id(obj)).upper().replace('X', 'x')) def try_to_eval(value): """Try to eval value""" try: return eval(value) except (NameError, SyntaxError, ImportError): return value def get_size(item): """Return size of an item of arbitrary type""" if isinstance(item, (list, tuple, dict)): return len(item) elif isinstance(item, (ndarray, MaskedArray)): return item.shape elif isinstance(item, Image): return item.size if isinstance(item, (DataFrame, DatetimeIndex, Series)): return item.shape else: return 1 def get_object_attrs(obj): """ Get the attributes of an object using dir. This filters protected attributes """ attrs = [k for k in dir(obj) if not k.startswith('__')] if not attrs: attrs = dir(obj) return attrs #============================================================================== # Date and datetime objects support #============================================================================== import datetime try: from dateutil.parser import parse as dateparse except: def dateparse(datestr): # analysis:ignore """Just for 'year, month, day' strings""" return datetime.datetime( *list(map(int, datestr.split(','))) ) def datestr_to_datetime(value): rp = value.rfind('(')+1 v = dateparse(value[rp:-1]) print(value, "-->", v) # spyder: test-skip return v def str_to_timedelta(value): """Convert a string to a datetime.timedelta value. The following strings are accepted: - 'datetime.timedelta(1, 5, 12345)' - 'timedelta(1, 5, 12345)' - '(1, 5, 12345)' - '1, 5, 12345' - '1' if there are less then three parameters, the missing parameters are assumed to be 0. Variations in the spacing of the parameters are allowed. Raises: ValueError for strings not matching the above criterion. """ m = re.match(r'^(?:(?:datetime\.)?timedelta)?' r'\(?' r'([^)]*)' r'\)?$', value) if not m: raise ValueError('Invalid string for datetime.timedelta') args = [int(a.strip()) for a in m.group(1).split(',')] return datetime.timedelta(*args) #============================================================================== # Background colors for supported types #============================================================================== ARRAY_COLOR = "#00ff00" SCALAR_COLOR = "#0000ff" COLORS = { bool: "#ff00ff", NUMERIC_TYPES: SCALAR_COLOR, list: "#ffff00", dict: "#00ffff", tuple: "#c0c0c0", TEXT_TYPES: "#800000", (ndarray, MaskedArray, matrix, DataFrame, Series, DatetimeIndex): ARRAY_COLOR, Image: "#008000", datetime.date: "#808000", datetime.timedelta: "#808000", } CUSTOM_TYPE_COLOR = "#7755aa" UNSUPPORTED_COLOR = "#ffffff" def get_color_name(value): """Return color name depending on value type""" if not is_known_type(value): return CUSTOM_TYPE_COLOR for typ, name in list(COLORS.items()): if isinstance(value, typ): return name else: np_dtype = get_numpy_dtype(value) if np_dtype is None or not hasattr(value, 'size'): return UNSUPPORTED_COLOR elif value.size == 1: return SCALAR_COLOR else: return ARRAY_COLOR def is_editable_type(value): """Return True if data type is editable with a standard GUI-based editor, like CollectionsEditor, ArrayEditor, QDateEdit or a simple QLineEdit""" return get_color_name(value) not in (UNSUPPORTED_COLOR, CUSTOM_TYPE_COLOR) #============================================================================== # Sorting #============================================================================== def sort_against(list1, list2, reverse=False): """ Arrange items of list1 in the same order as sorted(list2). In other words, apply to list1 the permutation which takes list2 to sorted(list2, reverse). """ try: return [item for _, item in sorted(zip(list2, list1), key=lambda x: x[0], reverse=reverse)] except: return list1 def unsorted_unique(lista): """Removes duplicates from lista neglecting its initial ordering""" return list(set(lista)) #============================================================================== # Display <--> Value #============================================================================== def default_display(value, with_module=True): """Default display for unknown objects.""" object_type = type(value) try: name = object_type.__name__ module = object_type.__module__ if with_module: return name + ' object of ' + module + ' module' else: return name except: type_str = to_text_string(object_type) return type_str[1:-1] def collections_display(value, level): """Display for collections (i.e. list, tuple and dict).""" is_dict = isinstance(value, dict) # Get elements if is_dict: elements = iteritems(value) else: elements = value # Truncate values truncate = False if level == 1 and len(value) > 10: elements = islice(elements, 10) if is_dict else value[:10] truncate = True elif level == 2 and len(value) > 5: elements = islice(elements, 5) if is_dict else value[:5] truncate = True # Get display of each element if level <= 2: if is_dict: displays = [value_to_display(k, level=level) + ':' + value_to_display(v, level=level) for (k, v) in list(elements)] else: displays = [value_to_display(e, level=level) for e in elements] if truncate: displays.append('...') display = ', '.join(displays) else: display = '...' # Return display if is_dict: display = '{' + display + '}' elif isinstance(value, list): display = '[' + display + ']' else: display = '(' + display + ')' return display def value_to_display(value, minmax=False, level=0): """Convert value for display purpose""" # To save current Numpy threshold np_threshold = FakeObject try: numeric_numpy_types = (int64, int32, int16, int8, uint64, uint32, uint16, uint8, float64, float32, float16, complex128, complex64, bool_) if ndarray is not FakeObject: # Save threshold np_threshold = get_printoptions().get('threshold') # Set max number of elements to show for Numpy arrays # in our display set_printoptions(threshold=10) if isinstance(value, recarray): if level == 0: fields = value.names display = 'Field names: ' + ', '.join(fields) else: display = 'Recarray' elif isinstance(value, MaskedArray): display = 'Masked array' elif isinstance(value, ndarray): if level == 0: if minmax: try: display = 'Min: %r\nMax: %r' % (value.min(), value.max()) except (TypeError, ValueError): if value.dtype.type in numeric_numpy_types: display = str(value) else: display = default_display(value) elif value.dtype.type in numeric_numpy_types: display = str(value) else: display = default_display(value) else: display = 'Numpy array' elif any([type(value) == t for t in [list, tuple, dict]]): display = collections_display(value, level+1) elif isinstance(value, Image): if level == 0: display = '%s Mode: %s' % (address(value), value.mode) else: display = 'Image' elif isinstance(value, DataFrame): if level == 0: cols = value.columns if PY2 and len(cols) > 0: # Get rid of possible BOM utf-8 data present at the # beginning of a file, which gets attached to the first # column header when headers are present in the first # row. # Fixes Issue 2514 try: ini_col = to_text_string(cols[0], encoding='utf-8-sig') except: ini_col = to_text_string(cols[0]) cols = [ini_col] + [to_text_string(c) for c in cols[1:]] else: cols = [to_text_string(c) for c in cols] display = 'Column names: ' + ', '.join(list(cols)) else: display = 'Dataframe' elif isinstance(value, NavigableString): # Fixes Issue 2448 display = to_text_string(value) if level > 0: display = u"'" + display + u"'" elif isinstance(value, DatetimeIndex): if level == 0: try: display = value._summary() except AttributeError: display = value.summary() else: display = 'DatetimeIndex' elif is_binary_string(value): # We don't apply this to classes that extend string types # See issue 5636 if is_type_text_string(value): try: display = to_text_string(value, 'utf8') if level > 0: display = u"'" + display + u"'" except: display = value if level > 0: display = b"'" + display + b"'" else: display = default_display(value) elif is_text_string(value): # We don't apply this to classes that extend string types # See issue 5636 if is_type_text_string(value): display = value if level > 0: display = u"'" + display + u"'" else: display = default_display(value) elif (isinstance(value, datetime.date) or isinstance(value, datetime.timedelta)): display = str(value) elif (isinstance(value, NUMERIC_TYPES) or isinstance(value, bool) or isinstance(value, numeric_numpy_types)): display = repr(value) else: if level == 0: display = default_display(value) else: display = default_display(value, with_module=False) except: display = default_display(value) # Truncate display at 70 chars to avoid freezing Spyder # because of large displays if len(display) > 70: if is_binary_string(display): ellipses = b' ...' else: ellipses = u' ...' display = display[:70].rstrip() + ellipses # Restore Numpy threshold if np_threshold is not FakeObject: set_printoptions(threshold=np_threshold) return display def display_to_value(value, default_value, ignore_errors=True): """Convert back to value""" from qtpy.compat import from_qvariant value = from_qvariant(value, to_text_string) try: np_dtype = get_numpy_dtype(default_value) if isinstance(default_value, bool): # We must test for boolean before NumPy data types # because `bool` class derives from `int` class try: value = bool(float(value)) except ValueError: value = value.lower() == "true" elif np_dtype is not None: if 'complex' in str(type(default_value)): value = np_dtype(complex(value)) else: value = np_dtype(value) elif is_binary_string(default_value): value = to_binary_string(value, 'utf8') elif is_text_string(default_value): value = to_text_string(value) elif isinstance(default_value, complex): value = complex(value) elif isinstance(default_value, float): value = float(value) elif isinstance(default_value, int): try: value = int(value) except ValueError: value = float(value) elif isinstance(default_value, datetime.datetime): value = datestr_to_datetime(value) elif isinstance(default_value, datetime.date): value = datestr_to_datetime(value).date() elif isinstance(default_value, datetime.timedelta): value = str_to_timedelta(value) elif ignore_errors: value = try_to_eval(value) else: value = eval(value) except (ValueError, SyntaxError): if ignore_errors: value = try_to_eval(value) else: return default_value return value # ============================================================================= # Types # ============================================================================= def get_type_string(item): """Return type string of an object.""" if isinstance(item, DataFrame): return "DataFrame" if isinstance(item, DatetimeIndex): return "DatetimeIndex" if isinstance(item, Series): return "Series" found = re.findall(r"<(?:type|class) '(\S*)'>", to_text_string(type(item))) if found: return found[0] def is_known_type(item): """Return True if object has a known type""" # Unfortunately, the masked array case is specific return isinstance(item, MaskedArray) or get_type_string(item) is not None def get_human_readable_type(item): """Return human-readable type string of an item""" if isinstance(item, (ndarray, MaskedArray)): return item.dtype.name elif isinstance(item, Image): return "Image" else: text = get_type_string(item) if text is None: text = to_text_string('unknown') else: return text[text.find('.')+1:] #============================================================================== # Globals filter: filter namespace dictionaries (to be edited in # CollectionsEditor) #============================================================================== def is_supported(value, check_all=False, filters=None, iterate=False): """Return True if the value is supported, False otherwise""" assert filters is not None if value is None: return True if not is_editable_type(value): return False elif not isinstance(value, filters): return False elif iterate: if isinstance(value, (list, tuple, set)): valid_count = 0 for val in value: if is_supported(val, filters=filters, iterate=check_all): valid_count += 1 if not check_all: break return valid_count > 0 elif isinstance(value, dict): for key, val in list(value.items()): if not is_supported(key, filters=filters, iterate=check_all) \ or not is_supported(val, filters=filters, iterate=check_all): return False if not check_all: break return True def globalsfilter(input_dict, check_all=False, filters=None, exclude_private=None, exclude_capitalized=None, exclude_uppercase=None, exclude_unsupported=None, excluded_names=None): """Keep only objects that can be pickled""" output_dict = {} for key, value in list(input_dict.items()): excluded = (exclude_private and key.startswith('_')) or \ (exclude_capitalized and key[0].isupper()) or \ (exclude_uppercase and key.isupper() and len(key) > 1 and not key[1:].isdigit()) or \ (key in excluded_names) or \ (exclude_unsupported and \ not is_supported(value, check_all=check_all, filters=filters)) if not excluded: output_dict[key] = value return output_dict #============================================================================== # Create view to be displayed by NamespaceBrowser #============================================================================== REMOTE_SETTINGS = ('check_all', 'exclude_private', 'exclude_uppercase', 'exclude_capitalized', 'exclude_unsupported', 'excluded_names', 'minmax') def get_supported_types(): """ Return a dictionnary containing types lists supported by the namespace browser. Note: If you update this list, don't forget to update variablexplorer.rst in spyder-docs """ from datetime import date, timedelta editable_types = [int, float, complex, list, dict, tuple, date, timedelta ] + list(TEXT_TYPES) + list(INT_TYPES) try: from numpy import ndarray, matrix, generic editable_types += [ndarray, matrix, generic] except: pass try: from pandas import DataFrame, Series, DatetimeIndex editable_types += [DataFrame, Series, DatetimeIndex] except: pass picklable_types = editable_types[:] try: from spyder.pil_patch import Image editable_types.append(Image.Image) except: pass return dict(picklable=picklable_types, editable=editable_types) def get_remote_data(data, settings, mode, more_excluded_names=None): """ Return globals according to filter described in *settings*: * data: data to be filtered (dictionary) * settings: variable explorer settings (dictionary) * mode (string): 'editable' or 'picklable' * more_excluded_names: additional excluded names (list) """ supported_types = get_supported_types() assert mode in list(supported_types.keys()) excluded_names = settings['excluded_names'] if more_excluded_names is not None: excluded_names += more_excluded_names return globalsfilter(data, check_all=settings['check_all'], filters=tuple(supported_types[mode]), exclude_private=settings['exclude_private'], exclude_uppercase=settings['exclude_uppercase'], exclude_capitalized=settings['exclude_capitalized'], exclude_unsupported=settings['exclude_unsupported'], excluded_names=excluded_names) def make_remote_view(data, settings, more_excluded_names=None): """ Make a remote view of dictionary *data* -> globals explorer """ data = get_remote_data(data, settings, mode='editable', more_excluded_names=more_excluded_names) remote = {} for key, value in list(data.items()): view = value_to_display(value, minmax=settings['minmax']) remote[key] = {'type': get_human_readable_type(value), 'size': get_size(value), 'color': get_color_name(value), 'view': view} return remote spyder-kernels-0.5.2/spyder_kernels/utils/__init__.py0000664000175000017500000000053413332371305023563 0ustar carloscarlos00000000000000# -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (c) 2009- Spyder Kernels Contributors # # Licensed under the terms of the MIT License # (see spyder_kernels/__init__.py for details) # ----------------------------------------------------------------------------- """ Utilities """