Skip to content

Commit 02a43c6

Browse files
Merge pull request #81 from ContextLab/paper-rev
major update to paper, some bug fixes, new readme into, updates for new colab version
2 parents e15cece + 4326dbd commit 02a43c6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+4294
-595
lines changed

.github/workflows/ci-tests-colab.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ defaults:
2828

2929
jobs:
3030
run-tests:
31-
name: "Run Colab CI Tests (Python 3.7, IPython 5.5.0)"
31+
name: "Run Colab CI Tests (Python 3.7, IPython 7.9.0)"
3232
runs-on: ubuntu-latest
3333
# run if triggered by any of the following:
3434
# - a workflow_dispatch event (manual or from trigger-colab-tests-pr workflow)
@@ -46,7 +46,7 @@ jobs:
4646
GMAIL_ADDRESS: ${{ secrets.DAVOS_GMAIL_ADDRESS }}
4747
GMAIL_PASSWORD: ${{ secrets.DAVOS_GMAIL_PASSWORD }}
4848
HEAD_FORK: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.fork || github.repository_owner }}
49-
IPYTHON_VERSION: 5.5.0
49+
IPYTHON_VERSION: 7.9.0
5050
NOTEBOOK_TYPE: colab
5151
PYTHON_VERSION: 3.7
5252
RECOVERY_GMAIL_ADDRESS: ${{ secrets.DAVOS_RECOVERY_GMAIL_ADDRESS }}

.github/workflows/ci-tests-jupyter.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
sudo apt-get install firefox
7979
8080
# install python packages
81-
pip install pytest==6.2 "selenium>=3.141" geckodriver-autoinstaller
81+
pip install pytest==6.2 "selenium==3.141" geckodriver-autoinstaller
8282
8383
# install geckodriver
8484
driver_path=$(python -c '
@@ -112,7 +112,7 @@ jobs:
112112
pip install typing-extensions
113113
fi
114114
[[ "$PYTHON_VERSION" == "3.6" ]] || pip install numpy==1.20.3
115-
pip install "ipykernel==5.0.0" ipython-genutils requests scipy fastdtw==0.3.4 tqdm==4.41.1
115+
pip install "ipykernel==5.0.0" ipython-genutils requests "scipy<=1.7.3" fastdtw==0.3.4 tqdm==4.41.1
116116
if [[ "$IPYTHON_VERSION" == "latest" ]]; then
117117
pip install --upgrade IPython
118118
else

.gitignore

+24-13
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# Mac Finder display config
22
*.DS_Store
33

4-
# PyCharm project config dir
5-
*.idea
4+
# PyCharm & VS Code project config dirs
5+
*.idea/
6+
*.vscode/
67

78
# Python bytecode
8-
*__pycache__
9+
*__pycache__/
910

1011
# IPython notebook checkpoints
11-
*.ipynb_checkpoints
12+
*.ipynb_checkpoints/
1213

13-
# Python package distribution egg
14-
davos.egg-info
15-
16-
# build dir for non-editable installs
17-
build
14+
# Package distribution dirs for wheels & eggs
15+
dist/
16+
build/
17+
davos.egg-info/
1818

1919
# Mypy daemon status file
2020
.dmypy.json
@@ -24,7 +24,18 @@ tests/geckodriver
2424
**/geckodriver.log
2525

2626
# scripts & notebooks for scratch/debugging
27-
scratch
28-
29-
# Illustrator source for snippets
30-
paper/snippets/snippets.ai
27+
scratch/
28+
29+
# LaTeX generated files
30+
paper/**/*.aux
31+
paper/**/*.bbl
32+
paper/**/*.blg
33+
paper/**/*.log
34+
paper/**/*.out
35+
paper/**/*.spl
36+
paper/**/*.synctex.gz
37+
38+
# Illustrator source files
39+
paper/figs/*.ai
40+
paper/main.fdb_latexmk
41+
paper/main.fls

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "paper/CDL-bibliography"]
2+
path = paper/CDL-bibliography
3+
url = https://github.com/ContextLab/CDL-bibliography.git

README.md

+281-230
Large diffs are not rendered by default.

davos/core/config.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,13 @@ def __init__(self):
153153
self._environment = 'Python'
154154
else:
155155
import IPython
156-
if IPython.version_info[0] < 7:
156+
if IPython.version_info[0] >= 7:
157157
if 'google.colab' in str(self._ipython_shell):
158158
self._environment = 'Colaboratory'
159159
else:
160-
self._environment = 'IPython<7.0'
160+
self._environment = 'IPython>=7.0'
161161
else:
162-
self._environment = 'IPython>=7.0'
162+
self._environment = 'IPython<7.0'
163163
self._conda_avail = None
164164
self._conda_envs_dirs = None
165165
self._ipy_showsyntaxerror_orig = None
@@ -215,11 +215,12 @@ def __init__(self):
215215
self._pip_executable = f'{sys.executable} -m pip'
216216
else:
217217
self._pip_executable = pip_exe
218+
self._pip_executable_orig = self._pip_executable
218219

219220
def __repr__(self):
220221
cls_name = self.__class__.__name__
221222
base_indent = len(cls_name) + 1
222-
attrs_in_repr = ['active', 'auto_rerun', 'conda_avail']
223+
attrs_in_repr = ['active', 'auto_rerun']
223224
if self._conda_avail is not None:
224225
attrs_in_repr.append('conda_avail')
225226
if self._conda_avail is True:

davos/core/core.py

+71-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import importlib
1818
import itertools
1919
import sys
20-
from contextlib import redirect_stdout
20+
from contextlib import contextmanager, redirect_stdout
2121
from io import StringIO
2222
from pathlib import Path
2323
from subprocess import CalledProcessError
@@ -247,6 +247,69 @@ def get_previously_imported_pkgs(install_cmd_stdout, installer):
247247
return prev_imported_pkgs
248248

249249

250+
@contextmanager
251+
def handle_alternate_pip_executable(installed_name):
252+
"""
253+
Context manager that makes it possible to load packages installed
254+
into a different Python environment by changing the `pip` executable
255+
(`davos.config.pip_executable`).
256+
257+
Parameters
258+
----------
259+
installed_name : str
260+
Package name as passed to the `pip install` command. This is the
261+
value of self.install_name for the Onion object for the
262+
just-installed package.
263+
264+
Notes
265+
-----
266+
super-duper edge case not handled by this: user has used alternate
267+
pip_executable to smuggle local package from CWD and supplies
268+
relative path in onion comment (i.e., "# pip: . <args>").
269+
"""
270+
if '/' in installed_name:
271+
# handle local paths, local/remote VCS, PEP 440 direct ref, etc.
272+
dist_name = installed_name.split('@')[0].split('#')[0].split('/')[-1]
273+
else:
274+
# common case
275+
dist_name = installed_name
276+
277+
# get install location from `pip show ___` command.
278+
# In most cases, this will be davos.config.pip_executable with
279+
# trailing 'bin/pip' replaced with python<major.minor>/site-packages
280+
# but since this runs only if non-default pip_executable is set,
281+
# it's worth the extra run time to check the safer way in order to
282+
# handle various edge cases (e.g., installing from VCS, etc.)
283+
pip_show_cmd = f'{config._pip_executable} show {dist_name}'
284+
try:
285+
pip_show_stdout = run_shell_command(pip_show_cmd, live_stdout=False)
286+
location_line = next(
287+
l for l in pip_show_stdout.strip().splitlines()
288+
if l.startswith('Location')
289+
)
290+
except (CalledProcessError, StopIteration) as e:
291+
msg = (
292+
"Unable to locate package installed installed with non-default "
293+
f"'pip' executable: {dist_name}. Package has been successfully "
294+
"installed but not loaded."
295+
)
296+
raise SmugglerError(msg) from e
297+
298+
install_location = location_line.split(': ', maxsplit=1)[1].strip()
299+
sys.path.insert(0, install_location)
300+
try:
301+
# reload pkg_resources so import system will search dir
302+
# containing just-installed package
303+
importlib.reload(sys.modules['pkg_resources'])
304+
yield
305+
finally:
306+
# remove temporary dir from path
307+
sys.path.pop(0)
308+
# reload pkg_resources again so import system no longer searches
309+
# dir used by alternate pip_executable
310+
importlib.reload(sys.modules['pkg_resources'])
311+
312+
250313
def import_name(name):
251314
"""
252315
Import an object by its qualified name.
@@ -458,6 +521,8 @@ def install_cmd(self):
458521
args = self.args_str.replace("<", "'<'").replace(">", "'>'")
459522
if self.installer == 'pip':
460523
install_exe = config._pip_executable
524+
if config.noninteractive:
525+
args = f'{args} --no-input'
461526
else:
462527
install_exe = self.installer
463528

@@ -945,7 +1010,11 @@ def smuggle(
9451010
else:
9461011
prompt_restart_rerun_buttons(failed_reloads)
9471012

948-
smuggled_obj = import_name(name)
1013+
if config._pip_executable != config._pip_executable_orig:
1014+
with handle_alternate_pip_executable(onion.install_name):
1015+
smuggled_obj = import_name(name)
1016+
else:
1017+
smuggled_obj = import_name(name)
9491018

9501019
# add the object name/alias to the notebook's global namespace
9511020
if as_ is None:

davos/core/core.pyi

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ from typing import (
2525
__all__: list[
2626
Literal[
2727
'capture_stdout',
28+
'check_conda',
2829
'Onion',
2930
'parse_line',
3031
'prompt_input',

davos/implementations/__init__.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@
7070

7171
_set_custom_showsyntaxerror()
7272

73-
if import_environment == 'IPython>=7.0':
74-
from davos.implementations.ipython_post7 import (
73+
if import_environment == 'IPython<7.0':
74+
from davos.implementations.ipython_pre7 import (
7575
_activate_helper,
7676
_deactivate_helper,
7777
generate_parser_func
@@ -81,7 +81,7 @@
8181
prompt_restart_rerun_buttons
8282
)
8383
else:
84-
from davos.implementations.ipython_pre7 import (
84+
from davos.implementations.ipython_post7 import (
8585
_activate_helper,
8686
_deactivate_helper,
8787
generate_parser_func

davos/implementations/ipython_common.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ def _showsyntaxerror_davos(
221221
The `running_compiled_code` argument was added in `IPython` 6.1.0,
222222
and setting it to `True` accomplishes (something close to) the same
223223
thing this workaround does. However, since `davos` needs to support
224-
`IPython` versions back to v5.5.0 (which is used by Colab), we can't
225-
rely on it being available.
224+
`IPython` versions back to v5.5.0, we can't rely on it being
225+
available.
226226
"""
227227
etype, value, tb = ipy_shell._get_exc_info()
228228
if issubclass(etype, DavosParserError):

davos/implementations/jupyter.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,18 @@ def auto_restart_rerun(pkgs):
4848
1. The message displayed before restarting the kernel can be
4949
silenced by setting `davos.config.suppress_stdout` to `True`.
5050
2. After calling `JS_FUNCTIONS.jupyter.restartRunCellsAbove`, this
51-
function sleeps until until the kernel restarts to prevent any
52-
further code in the current cell or other queued cells from
53-
executing. Restarting the kernel is often not instantaneous;
54-
there's generally a 1-2s delay while the kernel sends & receives
55-
various shutdown messages, but it can take significantly
56-
longer on a slow machine, with older Python/Jupyter/ipykernel
57-
versions, if a large amount of data was loaded into memory, if
58-
multiple notebook kernels are running at once, etc. If this
59-
function returned immediately, it's likely subsequent lines of
60-
code would be run before the kernel disconnected. This can cause
61-
problems if those lines of code use the package(s) that prompted
62-
the restart, or have effects that persist across kernel sessions.
51+
function sleeps until the kernel restarts to prevent any further
52+
code in the current cell or other queued cells from executing.
53+
Restarting the kernel is often not instantaneous; there's
54+
generally a 1-2s delay while the kernel sends & receives various
55+
shutdown messages, but it can take significantly longer on a slow
56+
machine, with older Python/Jupyter/ipykernel versions, if a large
57+
amount of data was loaded into memory, if multiple notebook
58+
kernels are running at once, etc. If this function returned
59+
immediately, it's likely subsequent lines of code would be run
60+
before the kernel disconnected. This can cause problems if those
61+
lines of code use the package(s) that prompted the restart, or
62+
have effects that persist across kernel sessions.
6363
"""
6464
msg = (
6565
"Restarting kernel and rerunning cells (required to smuggle "

paper/CDL-bibliography

Submodule CDL-bibliography added at 1403d48

paper/admin/cover_letter.pdf

47.9 KB
Binary file not shown.

0 commit comments

Comments
 (0)