diff --git a/README.md b/README.md index c9b868615..bbe3f5b8a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [Website](https://tuplex.cs.brown.edu/) [Documentation](https://tuplex.cs.brown.edu/python-api.html) -Tuplex is a parallel big data processing framework that runs data science pipelines written in Python at the speed of compiled code. +Tuplex is a parallel big data processing framework that runs data science pipelines written in Python at the speed of compiled code. Tuplex has similar Python APIs to [Apache Spark](https://spark.apache.org/) or [Dask](https://dask.org/), but rather than invoking the Python interpreter, Tuplex generates optimized LLVM bytecode for the given pipeline and input data set. Under the hood, Tuplex is based on data-driven compilation and dual-mode processing, two key techniques that make it possible for Tuplex to provide speed comparable to a pipeline written in hand-optimized C++. You can join the discussion on Tuplex on our [Gitter community](https://gitter.im/tuplex/community) or read up more on the background of Tuplex in our [SIGMOD'21 paper](https://dl.acm.org/doi/abs/10.1145/3448016.3457244). @@ -47,7 +47,7 @@ To install Tuplex, simply install the dependencies first and then build the pack To build Tuplex, you need several other packages first which can be easily installed via [brew](https://brew.sh/). ``` brew install llvm@9 boost boost-python3 aws-sdk-cpp pcre2 antlr4-cpp-runtime googletest gflags yaml-cpp celero protobuf libmagic -python3 -m pip cloudpickle numpy +python3 -m pip install cloudpickle numpy python3 setup.py install ``` @@ -55,7 +55,7 @@ python3 setup.py install To faciliate installing the dependencies for Ubuntu, we do provide two scripts (`scripts/ubuntu1804/install_reqs.sh` for Ubuntu 18.04, or `scripts/ubuntu2004/install_reqs.sh` for Ubuntu 20.04). To create an up to date version of Tuplex, simply run ``` ./scripts/ubuntu1804/install_reqs.sh -python3 -m pip cloudpickle numpy +python3 -m pip install cloudpickle numpy python3 setup.py install ``` @@ -77,6 +77,7 @@ To customize the cmake build, the following options are available to be passed v | `CMAKE_BUILD_TYPE` | `Release` (default), `Debug`, `RelWithDebInfo`, `tsan`, `asan`, `ubsan` | select compile mode. Tsan/Asan/Ubsan correspond to Google Sanitizers. | | `BUILD_WITH_AWS` | `ON` (default), `OFF` | build with AWS SDK or not. On Ubuntu this will build the Lambda executor. | | `BUILD_WITH_ORC` | `ON`, `OFF` (default) | build with ORC file format support. | +| `BUILD_NATIVE` | `ON`, `OFF` (default) | build with `-march=native` to target platform architecture. | | `SKIP_AWS_TESTS` | `ON` (default), `OFF` | skip aws tests, helpful when no AWS credentials/AWS Tuplex chain is setup. | | `GENERATE_PDFS` | `ON`, `OFF` (default) | output in Debug mode PDF files if graphviz is installed (e.g., `brew install graphviz`) for ASTs of UDFs, query plans, ...| | `PYTHON3_VERSION` | `3.6`, ... | when trying to select a python3 version to build against, use this by specifying `major.minor`. To specify the python executable, use the options provided by [cmake](https://cmake.org/cmake/help/git-stage/module/FindPython3.html). | diff --git a/scripts/build_wheel_linux.sh b/scripts/build_wheel_linux.sh index 694c80b27..543d9c0f1 100755 --- a/scripts/build_wheel_linux.sh +++ b/scripts/build_wheel_linux.sh @@ -16,6 +16,11 @@ export CIBW_MANYLINUX_X86_64_IMAGE='registry-1.docker.io/tuplex/ci:latest' # Use the following line to build only python3.9 wheel export CIBW_BUILD="cp39-*" + +# For Google Colab compatible wheel, use the following: +export CIBW_BUILD="cp37-*" +export CIBW_ARCHS_LINUX="x86_64" + # to test the others from 3.7-3.9, use these two lines: #export CIBW_BUILD="cp3{7,8,9}-*" #export CIBW_SKIP="cp3{5,6,7,8}-macosx* pp*" diff --git a/scripts/docker/colab/Dockerfile b/scripts/docker/colab/Dockerfile new file mode 100644 index 000000000..d21957f1a --- /dev/null +++ b/scripts/docker/colab/Dockerfile @@ -0,0 +1,24 @@ +# Docker image mimicking Google Colab setup for testing purposes +# Certain large dependencies like torch (~2G) are not installed +FROM ubuntu:18.04 + +# Fix timezone to US +ENV TZ=America/New_York +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# Python version used is 3.7.12 +RUN apt-get update && apt-get install -y wget curl build-essential zlib1g-dev libssl1.0-dev libncurses-dev libgdbm-dev libz-dev tk-dev libsqlite3-dev libreadline-dev liblzma-dev libffi-dev + +WORKDIR /usr/src +RUN cd /usr/src && curl https://www.openssl.org/source/openssl-1.0.2o.tar.gz | tar xz && cd openssl-1.0.2o && ./config shared zlib --prefix=/usr/local/ && make && make install -j8 + +RUN wget https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz + +# DO not use enable-optimizations because it gets stuck... +RUN tar xf Python-3.7.12.tgz && cd Python-3.7.12 && ./configure --prefix=/usr --with-openssl=/usr/local --with-ensurepip=install && make install -j8 + +WORKDIR /work +ADD requirements.txt /work/requirements.txt + +RUN apt-get install -y libgdal-dev libcairo2-dev libjpeg-dev libgif-dev +RUN pip3 install -r /work/requirements.txt diff --git a/scripts/docker/colab/README.md b/scripts/docker/colab/README.md new file mode 100644 index 000000000..71e7b265b --- /dev/null +++ b/scripts/docker/colab/README.md @@ -0,0 +1,15 @@ +## Docker image to mimick Google's Colab environment +This folder contains a docker image mimicking (best-effort) the environment of Google's Colab. + +To create the image, simply use +``` +docker build -t tuplex/colab . +``` + +Then, start the container via +``` +docker run -it tuplex/colab bash +``` + +--- +(c) 2021 Tuplex team diff --git a/scripts/docker/colab/requirements.txt b/scripts/docker/colab/requirements.txt new file mode 100644 index 000000000..d99a94e35 --- /dev/null +++ b/scripts/docker/colab/requirements.txt @@ -0,0 +1,390 @@ +python-apt +cmake==3.12.0 +#dlib @ file:///dlib-19.18.0-cp37-cp37m-linux_x86_64.whl +dlib +google-colab +#google-colab @ file:///colabtools/dist/google-colab-1.0.0.tar.gz +#tensorflow @ file:///tensorflow-2.6.0-cp37-cp37m-linux_x86_64.whl +absl-py==0.12.0 +alabaster==0.7.12 +albumentations==0.1.12 +altair==4.1.0 +appdirs==1.4.4 +argcomplete==1.12.3 +argon2-cffi==21.1.0 +arviz==0.11.4 +astor==0.8.1 +astropy==4.3.1 +astunparse==1.6.3 +atari-py==0.2.9 +atomicwrites==1.4.0 +attrs==21.2.0 +audioread==2.1.9 +autograd==1.3 +Babel==2.9.1 +backcall==0.2.0 +beautifulsoup4==4.6.3 +bleach==4.1.0 +blis==0.4.1 +bokeh==2.3.3 +Bottleneck==1.3.2 +branca==0.4.2 +bs4==0.0.1 +CacheControl==0.12.6 +cached-property==1.5.2 +cachetools==4.2.4 +catalogue==1.0.0 +certifi==2021.5.30 +cffi==1.14.6 +cftime==1.5.1 +chardet==3.0.4 +charset-normalizer==2.0.6 +clang==5.0 +click==7.1.2 +cloudpickle==1.3.0 +cmake==3.12.0 +cmdstanpy==0.9.5 +colorcet==2.0.6 +colorlover==0.3.0 +community==1.0.0b1 +contextlib2==0.5.5 +convertdate==2.3.2 +coverage==3.7.1 +coveralls==0.5 +crcmod==1.7 +cufflinks==0.17.3 +cvxopt==1.2.7 +#cvxpy==1.0.31 +cvxpy +cycler==0.10.0 +cymem==2.0.5 +Cython==0.29.24 +daft==0.0.4 +dask==2.12.0 +datascience==0.10.6 +debugpy==1.0.0 +decorator==4.4.2 +defusedxml==0.7.1 +descartes==1.1.0 +dill==0.3.4 +distributed==1.25.3 +dm-tree==0.1.6 +docopt==0.6.2 +docutils==0.17.1 +dopamine-rl==1.0.5 +earthengine-api==0.1.284 +easydict==1.9 +ecos==2.0.7.post1 +editdistance==0.5.3 +en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.2.5/en_core_web_sm-2.2.5.tar.gz +entrypoints==0.3 +ephem==4.1 +et-xmlfile==1.1.0 +fa2==0.3.5 +fastai==1.0.61 +fastdtw==0.3.4 +fastprogress==1.0.0 +fastrlock==0.6 +fbprophet==0.7.1 +feather-format==0.4.1 +filelock==3.3.0 +firebase-admin==4.4.0 +fix-yahoo-finance==0.0.22 +Flask==1.1.4 +flatbuffers==1.12 +folium==0.8.3 +future==0.16.0 +gast==0.4.0 +GDAL==2.2.2 +gdown==3.6.4 +gensim==3.6.0 +geographiclib==1.52 +geopy==1.17.0 +gin-config==0.4.0 +glob2==0.7 +google==2.0.3 +google-api-core==1.26.3 +google-api-python-client==1.12.8 +google-auth==1.35.0 +google-auth-httplib2==0.0.4 +google-auth-oauthlib==0.4.6 +google-cloud-bigquery==1.21.0 +google-cloud-bigquery-storage==1.1.0 +google-cloud-core==1.0.3 +google-cloud-datastore==1.8.0 +google-cloud-firestore==1.7.0 +google-cloud-language==1.2.0 +google-cloud-storage==1.18.1 +google-cloud-translate==1.5.0 +google-pasta==0.2.0 +google-resumable-media==0.4.1 +googleapis-common-protos==1.53.0 +googledrivedownloader==0.4 +graphviz==0.10.1 +greenlet==1.1.2 +grpcio==1.41.0 +gspread==3.0.1 +gspread-dataframe==3.0.8 +gym==0.17.3 +h5py==3.1.0 +HeapDict==1.0.1 +hijri-converter==2.2.2 +holidays==0.10.5.2 +holoviews==1.14.6 +html5lib==1.0.1 +httpimport==0.5.18 +httplib2==0.17.4 +httplib2shim==0.0.3 +humanize==0.5.1 +hyperopt==0.1.2 +ideep4py==2.0.0.post3 +idna==2.10 +imageio==2.4.1 +imagesize==1.2.0 +imbalanced-learn==0.4.3 +imblearn==0.0 +imgaug==0.2.9 +importlib-metadata==4.8.1 +importlib-resources==5.2.2 +imutils==0.5.4 +inflect==2.1.0 +iniconfig==1.1.1 +intel-openmp==2021.4.0 +intervaltree==2.1.0 +ipykernel==4.10.1 +ipython==5.5.0 +ipython-genutils==0.2.0 +ipython-sql==0.3.9 +ipywidgets==7.6.5 +itsdangerous==1.1.0 +jax==0.2.21 +jaxlib @ https://storage.googleapis.com/jax-releases/cuda111/jaxlib-0.1.71+cuda111-cp37-none-manylinux2010_x86_64.whl +jdcal==1.4.1 +jedi==0.18.0 +jieba==0.42.1 +Jinja2==2.11.3 +joblib==1.0.1 +jpeg4py==0.1.4 +jsonschema==2.6.0 +jupyter==1.0.0 +jupyter-client==5.3.5 +jupyter-console==5.2.0 +jupyter-core==4.8.1 +jupyterlab-pygments==0.1.2 +jupyterlab-widgets==1.0.2 +kaggle==1.5.12 +kapre==0.3.5 +keras==2.6.0 +Keras-Preprocessing==1.1.2 +keras-vis==0.4.1 +kiwisolver==1.3.2 +korean-lunar-calendar==0.2.1 +librosa==0.8.1 +lightgbm==2.2.3 +llvmlite==0.34.0 +lmdb==0.99 +LunarCalendar==0.0.9 +lxml==4.2.6 +Markdown==3.3.4 +MarkupSafe==2.0.1 +matplotlib==3.2.2 +matplotlib-inline==0.1.3 +matplotlib-venn==0.11.6 +missingno==0.5.0 +mistune==0.8.4 +mizani==0.6.0 +mkl==2019.0 +mlxtend==0.14.0 +more-itertools==8.10.0 +moviepy==0.2.3.5 +mpmath==1.2.1 +msgpack==1.0.2 +multiprocess==0.70.12.2 +multitasking==0.0.9 +murmurhash==1.0.5 +music21==5.5.0 +natsort==5.5.0 +nbclient==0.5.4 +nbconvert==5.6.1 +nbformat==5.1.3 +nest-asyncio==1.5.1 +netCDF4==1.5.7 +networkx==2.6.3 +nibabel==3.0.2 +nltk==3.2.5 +notebook==5.3.1 +numba==0.51.2 +numexpr==2.7.3 +numpy==1.19.5 +nvidia-ml-py3==7.352.0 +oauth2client==4.1.3 +oauthlib==3.1.1 +okgrade==0.4.3 +opencv-contrib-python==4.1.2.30 +opencv-python==4.1.2.30 +openpyxl==2.5.9 +opt-einsum==3.3.0 +osqp==0.6.2.post0 +packaging==21.0 +palettable==3.3.0 +pandas==1.1.5 +pandas-datareader==0.9.0 +pandas-gbq==0.13.3 +pandas-profiling==1.4.1 +pandocfilters==1.5.0 +panel==0.12.1 +param==1.11.1 +parso==0.8.2 +pathlib==1.0.1 +patsy==0.5.2 +pep517==0.11.0 +pexpect==4.8.0 +pickleshare==0.7.5 +Pillow==7.1.2 +pip-tools==6.2.0 +plac==1.1.3 +plotly==4.4.1 +plotnine==0.6.0 +pluggy==0.7.1 +pooch==1.5.1 +portpicker==1.3.9 +prefetch-generator==1.0.1 +preshed==3.0.5 +prettytable==2.2.1 +progressbar2==3.38.0 +prometheus-client==0.11.0 +promise==2.3 +prompt-toolkit==1.0.18 +protobuf==3.17.3 +psutil==5.4.8 +psycopg2==2.7.6.1 +ptyprocess==0.7.0 +py==1.10.0 +pyarrow==3.0.0 +pyasn1==0.4.8 +pyasn1-modules==0.2.8 +pycocotools==2.0.2 +pycparser==2.20 +pyct==0.4.8 +pydata-google-auth==1.2.0 +pydot==1.3.0 +pydot-ng==2.0.0 +pydotplus==2.0.2 +PyDrive==1.3.1 +pyemd==0.5.1 +pyerfa==2.0.0 +pyglet==1.5.0 +Pygments==2.6.1 +#pygobject==3.26.1 +pygobject +pymc3==3.11.4 +PyMeeus==0.5.11 +pymongo==3.12.0 +pymystem3==0.2.0 +PyOpenGL==3.1.5 +pyparsing==2.4.7 +pyrsistent==0.18.0 +pysndfile==1.3.8 +PySocks==1.7.1 +pystan==2.19.1.1 +pytest==3.6.4 +python-apt==0.0.0 +python-chess==0.23.11 +python-dateutil==2.8.2 +python-louvain==0.15 +python-slugify==5.0.2 +python-utils==2.5.6 +pytz==2018.9 +pyviz-comms==2.1.0 +PyWavelets==1.1.1 +PyYAML==3.13 +pyzmq==22.3.0 +qdldl==0.1.5.post0 +qtconsole==5.1.1 +QtPy==1.11.2 +regex==2019.12.20 +requests==2.23.0 +requests-oauthlib==1.3.0 +resampy==0.2.2 +retrying==1.3.3 +rpy2==3.4.5 +rsa==4.7.2 +scikit-image==0.16.2 +scikit-learn==0.22.2.post1 +scipy==1.4.1 +screen-resolution-extra==0.0.0 +scs==2.1.4 +seaborn==0.11.2 +semver==2.13.0 +Send2Trash==1.8.0 +setuptools-git==1.2 +Shapely==1.7.1 +simplegeneric==0.8.1 +six==1.15.0 +sklearn==0.0 +sklearn-pandas==1.8.0 +smart-open==5.2.1 +snowballstemmer==2.1.0 +sortedcontainers==2.4.0 +SoundFile==0.10.3.post1 +spacy==2.2.4 +Sphinx==1.8.5 +sphinxcontrib-serializinghtml==1.1.5 +sphinxcontrib-websupport==1.2.4 +SQLAlchemy==1.4.25 +sqlparse==0.4.2 +srsly==1.0.5 +statsmodels==0.10.2 +sympy==1.7.1 +tables==3.4.4 +tabulate==0.8.9 +tblib==1.7.0 +tensorboard==2.6.0 +tensorboard-data-server==0.6.1 +tensorboard-plugin-wit==1.8.0 +tensorflow-datasets==4.0.1 +tensorflow-estimator==2.6.0 +tensorflow-gcs-config==2.6.0 +tensorflow-hub==0.12.0 +tensorflow-metadata==1.2.0 +tensorflow-probability==0.14.1 +termcolor==1.1.0 +terminado==0.12.1 +testpath==0.5.0 +text-unidecode==1.3 +textblob==0.15.3 +Theano-PyMC==1.1.2 +thinc==7.4.0 +tifffile==2021.8.30 +toml==0.10.2 +tomli==1.2.1 +toolz==0.11.1 +#torch @ https://download.pytorch.org/whl/cu111/torch-1.9.0%2Bcu111-cp37-cp37m-linux_x86_64.whl +torchsummary==1.5.1 +torchtext==0.10.0 +#torchvision @ https://download.pytorch.org/whl/cu111/torchvision-0.10.0%2Bcu111-cp37-cp37m-linux_x86_64.whl +tornado==5.1.1 +tqdm==4.62.3 +traitlets==5.1.0 +tweepy==3.10.0 +typeguard==2.7.1 +typing-extensions==3.7.4.3 +tzlocal==1.5.1 +uritemplate==3.0.1 +urllib3==1.24.3 +vega-datasets==0.9.0 +wasabi==0.8.2 +wcwidth==0.2.5 +webencodings==0.5.1 +Werkzeug==1.0.1 +widgetsnbextension==3.5.1 +wordcloud==1.5.0 +wrapt==1.12.1 +xarray==0.18.2 +xgboost==0.90 +xkit==0.0.0 +xlrd==1.1.0 +xlwt==1.3.0 +yellowbrick==0.9.1 +zict==2.0.0 +zipp==3.6.0 diff --git a/setup.py b/setup.py index fdb635522..4e3ef39a1 100644 --- a/setup.py +++ b/setup.py @@ -16,6 +16,28 @@ import fnmatch import re +# TODO: add option to install these +test_dependencies = [ +'jupyter', +'nbformat', +'prompt_toolkit>=2.0.7', +'pytest>=5.3.2', +] + +install_dependencies = [ + 'attrs>=19.2.0', + 'dill>=0.2.7.1', + 'pluggy', + 'py>=1.5.2', + 'pygments>=2.4.1', + 'six>=1.11.0', + 'wcwidth>=0.1.7', + 'astor>=0.7.1', + 'jedi>=0.13.2', + 'cloudpickle>=0.6.1', + 'PyYAML>=3.13' +] + def find_files(pattern, path): result = [] for root, dirs, files in os.walk(path): @@ -120,6 +142,7 @@ def find_pkg_path(lines): # Set Python_EXECUTABLE instead if you use PYBIND11_FINDPYTHON cmake_args = [ + "-DBUILD_NATIVE=OFF", # disable march=native to avoid issues. # "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={}".format(extdir), "-DPYTHON_EXECUTABLE={}".format(sys.executable), "-DCMAKE_BUILD_TYPE={}".format(cfg), # not used on MSVC, but no harm @@ -324,23 +347,7 @@ def read_readme(): cmdclass={"build_ext": CMakeBuild}, # deactivate for now, first fix python sources to work properly! zip_safe=False, - install_requires=[ - 'jupyter', - 'nbformat', - 'attrs>=19.2.0', - 'dill>=0.2.7.1', - 'pluggy>=0.6.0, <1.0.0', - 'py>=1.5.2', - 'pygments>=2.4.1', - 'pytest>=5.3.2', - 'six>=1.11.0', - 'wcwidth>=0.1.7', - 'astor>=0.7.1', - 'prompt_toolkit>=2.0.7', - 'jedi>=0.13.2', - 'cloudpickle>=0.6.1', - 'PyYAML>=3.13' - ], + install_requires=install_dependencies, # metadata for upload to PyPI url="https://tuplex.cs.brown.edu", license="Apache 2.0", diff --git a/tuplex/CMakeLists.txt b/tuplex/CMakeLists.txt index f96e12f5e..531d8cbc4 100755 --- a/tuplex/CMakeLists.txt +++ b/tuplex/CMakeLists.txt @@ -41,7 +41,7 @@ set(CMAKE_MACOSX_RPATH 1) # fix for gtest warning option(SKIP_AWS_TESTS "Skip AWS tests" ON) option(BUILD_WITH_ORC "Build with Orc file support" OFF) - +option(BUILD_NATIVE "Build with -march=native" OFF) # translate to C++ flags if(SKIP_AWS_TESTS) @@ -568,14 +568,16 @@ if(USE_LD_GOLD AND "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") endif() endif() - -# use march=native if available +# DO NOT USE MARCH=NATIVE for wheels... => option should be disabled per default +# use march=native if available and NOT building wheels include(CheckCXXCompilerFlag) +if(BUILD_NATIVE) CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE) if(COMPILER_SUPPORTS_MARCH_NATIVE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native") endif() - +message(STATUS "Building Tuplex for native platform") message(STATUS "Using following CMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}") message(STATUS "Using following CMAKE_C_FLAGS=${CMAKE_C_FLAGS}") +endif() \ No newline at end of file diff --git a/tuplex/python/tuplex/repl/__init__.py b/tuplex/python/tuplex/repl/__init__.py index 06e54e015..058b111ca 100644 --- a/tuplex/python/tuplex/repl/__init__.py +++ b/tuplex/python/tuplex/repl/__init__.py @@ -13,9 +13,10 @@ import sys from tuplex.utils.common import is_in_interactive_mode, in_jupyter_notebook, in_google_colab -from tuplex.utils.interactive_shell import TuplexShell - -from tuplex.utils.version import __version__ +try: + from tuplex.utils.version import __version__ +except: + __version__ = 'dev' def TuplexBanner(): banner = '''Welcome to\n @@ -34,6 +35,7 @@ def TuplexBanner(): # else, provide code-closure functionality through readline module if is_in_interactive_mode() and not in_jupyter_notebook() and not in_google_colab(): + from tuplex.utils.interactive_shell import TuplexShell os.system('clear') from tuplex.context import Context diff --git a/tuplex/python/tuplex/utils/reflection.py b/tuplex/python/tuplex/utils/reflection.py index 50aed36a8..78009273e 100644 --- a/tuplex/python/tuplex/utils/reflection.py +++ b/tuplex/python/tuplex/utils/reflection.py @@ -26,7 +26,6 @@ from tuplex.utils.globs import get_globals from tuplex.utils.source_vault import SourceVault, supports_lambda_closure from tuplex.utils.common import in_jupyter_notebook, in_google_colab, is_in_interactive_mode -from tuplex.utils.interactive_shell import TuplexShell # only export get_source function, rest shall be private. __all__ = ['get_source', 'get_globals', 'supports_lambda_closure'] @@ -167,10 +166,13 @@ def get_source(f): # use inspect module # need to clean out lambda... if f.__name__ == '': - # interpreter in interactive mode or not? # beware jupyter notebook also returns true for interactive mode! - if is_in_interactive_mode() and not in_jupyter_notebook(): + if is_in_interactive_mode() and not in_jupyter_notebook() and not in_google_colab(): + + # import here, avoids also trouble with jupyter notebooks + from tuplex.utils.interactive_shell import TuplexShell + # for this to work, a dummy shell has to be instantiated # through which all typing occurs. Thus, the history can # be properly captured for source code lookup.