def test_app_dir_use_sys_prefix(self):
        app_dir = self.tempdir()
        if os.path.exists(get_app_dir()):
            os.removedirs(get_app_dir())

        install_extension(self.source_dir)
        path = pjoin(app_dir, 'extensions', '*python-tests*.tgz')
        assert not glob.glob(path)
        assert '@jupyterlab/python-tests' in list_extensions(app_dir)
示例#2
0
    def test_app_dir_use_sys_prefix(self):
        app_dir = self.tempdir()
        if os.path.exists(get_app_dir()):
            os.removedirs(get_app_dir())

        install_extension(self.source_dir)
        path = pjoin(app_dir, 'extensions', '*python-tests*.tgz')
        assert not glob.glob(path)
        assert '@jupyterlab/python-tests' in list_extensions(app_dir)
示例#3
0
    def setUp(self):
        # Any TemporaryDirectory objects appended to this list will be cleaned
        # up at the end of the test run.
        self.tempdirs = []
        self._mock_extensions = []
        self.devnull = open(os.devnull, 'w')

        @self.addCleanup
        def cleanup_tempdirs():
            for d in self.tempdirs:
                d.cleanup()

        self.test_dir = self.tempdir()

        self.data_dir = pjoin(self.test_dir, 'data')
        self.config_dir = pjoin(self.test_dir, 'config')

        # Copy in the mock packages.
        for name in ['extension', 'incompat', 'package', 'mimeextension']:
            src = pjoin(here, 'mock_packages', name)
            shutil.copytree(src, pjoin(self.test_dir, name))
            setattr(self, 'mock_' + name, pjoin(self.test_dir, name))

        self.patches = []
        p = patch.dict(
            'os.environ', {
                'JUPYTER_CONFIG_DIR': self.config_dir,
                'JUPYTER_DATA_DIR': self.data_dir,
                'JUPYTERLAB_DIR': pjoin(self.data_dir, 'lab')
            })
        self.patches.append(p)
        for mod in [paths]:
            if hasattr(mod, 'ENV_JUPYTER_PATH'):
                p = patch.object(mod, 'ENV_JUPYTER_PATH', [self.data_dir])
                self.patches.append(p)
            if hasattr(mod, 'ENV_CONFIG_PATH'):
                p = patch.object(mod, 'ENV_CONFIG_PATH', [self.config_dir])
                self.patches.append(p)
            if hasattr(mod, 'CONFIG_PATH'):
                p = patch.object(mod, 'CONFIG_PATH', self.config_dir)
                self.patches.append(p)
            if hasattr(mod, 'BUILD_PATH'):
                p = patch.object(mod, 'BUILD_PATH', self.data_dir)
                self.patches.append(p)
        for p in self.patches:
            p.start()
            self.addCleanup(p.stop)

        # verify our patches
        self.assertEqual(paths.ENV_CONFIG_PATH, [self.config_dir])
        self.assertEqual(paths.ENV_JUPYTER_PATH, [self.data_dir])
        self.assertEqual(commands.get_app_dir(),
                         os.path.realpath(pjoin(self.data_dir, 'lab')))

        self.app_dir = commands.get_app_dir()
示例#4
0
    def setUp(self):
        # Any TemporaryDirectory objects appended to this list will be cleaned
        # up at the end of the test run.
        self.tempdirs = []
        self._mock_extensions = []
        self.devnull = open(os.devnull, 'w')

        @self.addCleanup
        def cleanup_tempdirs():
            for d in self.tempdirs:
                d.cleanup()

        self.test_dir = self.tempdir()
        self.data_dir = pjoin(self.test_dir, 'data')
        self.config_dir = pjoin(self.test_dir, 'config')
        self.source_dir = pjoin(here, 'mockextension')
        self.incompat_dir = pjoin(here, 'mockextension-incompat')
        self.mock_package = pjoin(here, 'mockpackage')
        self.mime_renderer_dir = pjoin(here, 'mock-mimeextension')

        self.patches = []
        p = patch.dict(
            'os.environ', {
                'JUPYTER_CONFIG_DIR': self.config_dir,
                'JUPYTER_DATA_DIR': self.data_dir,
            })
        self.patches.append(p)
        for mod in (paths, commands):
            if hasattr(mod, 'ENV_JUPYTER_PATH'):
                p = patch.object(mod, 'ENV_JUPYTER_PATH', [self.data_dir])
                self.patches.append(p)
            if hasattr(mod, 'ENV_CONFIG_PATH'):
                p = patch.object(mod, 'ENV_CONFIG_PATH', [self.config_dir])
                self.patches.append(p)
            if hasattr(mod, 'CONFIG_PATH'):
                p = patch.object(mod, 'CONFIG_PATH', self.config_dir)
                self.patches.append(p)
            if hasattr(mod, 'BUILD_PATH'):
                p = patch.object(mod, 'BUILD_PATH', self.data_dir)
                self.patches.append(p)
        for p in self.patches:
            p.start()
            self.addCleanup(p.stop)

        # verify our patches
        self.assertEqual(paths.ENV_CONFIG_PATH, [self.config_dir])
        self.assertEqual(paths.ENV_JUPYTER_PATH, [self.data_dir])
        self.assertEqual(commands.ENV_JUPYTER_PATH, [self.data_dir])
        self.assertEqual(commands.get_app_dir(),
                         os.path.realpath(pjoin(self.data_dir, 'lab')))

        self.app_dir = commands.get_app_dir()
示例#5
0
    def test_build(self):
        install_extension(self.source_dir)
        build()
        # check staging directory.
        entry = pjoin(get_app_dir(), 'staging', 'build', 'index.out.js')
        with open(entry) as fid:
            data = fid.read()
        assert '@jupyterlab/python-tests' in data

        # check static directory.
        entry = pjoin(get_app_dir(), 'static', 'index.out.js')
        with open(entry) as fid:
            data = fid.read()
        assert '@jupyterlab/python-tests' in data
    def test_build(self):
        install_extension(self.source_dir)
        build()
        # check staging directory.
        entry = pjoin(get_app_dir(), 'staging', 'build', 'index.out.js')
        with open(entry) as fid:
            data = fid.read()
        assert '@jupyterlab/python-tests' in data

        # check static directory.
        entry = pjoin(get_app_dir(), 'static', 'index.out.js')
        with open(entry) as fid:
            data = fid.read()
        assert '@jupyterlab/python-tests' in data
    def setUp(self):
        # Any TemporaryDirectory objects appended to this list will be cleaned
        # up at the end of the test run.
        self.tempdirs = []
        self._mock_extensions = []
        self.devnull = open(os.devnull, 'w')

        @self.addCleanup
        def cleanup_tempdirs():
            for d in self.tempdirs:
                d.cleanup()

        self.test_dir = self.tempdir()
        self.data_dir = pjoin(self.test_dir, 'data')
        self.config_dir = pjoin(self.test_dir, 'config')
        self.source_dir = pjoin(here, 'mockextension')
        self.incompat_dir = pjoin(here, 'mockextension-incompat')
        self.mock_package = pjoin(here, 'mockpackage')
        self.mime_renderer_dir = pjoin(here, 'mock-mimeextension')

        self.patches = []
        p = patch.dict('os.environ', {
            'JUPYTER_CONFIG_DIR': self.config_dir,
            'JUPYTER_DATA_DIR': self.data_dir,
        })
        self.patches.append(p)
        for mod in (paths, commands):
            if hasattr(mod, 'ENV_JUPYTER_PATH'):
                p = patch.object(mod, 'ENV_JUPYTER_PATH', [self.data_dir])
                self.patches.append(p)
            if hasattr(mod, 'ENV_CONFIG_PATH'):
                p = patch.object(mod, 'ENV_CONFIG_PATH', [self.config_dir])
                self.patches.append(p)
            if hasattr(mod, 'CONFIG_PATH'):
                p = patch.object(mod, 'CONFIG_PATH', self.config_dir)
                self.patches.append(p)
            if hasattr(mod, 'BUILD_PATH'):
                p = patch.object(mod, 'BUILD_PATH', self.data_dir)
                self.patches.append(p)
        for p in self.patches:
            p.start()
            self.addCleanup(p.stop)

        # verify our patches
        self.assertEqual(paths.ENV_CONFIG_PATH, [self.config_dir])
        self.assertEqual(paths.ENV_JUPYTER_PATH, [self.data_dir])
        self.assertEqual(commands.ENV_JUPYTER_PATH, [self.data_dir])
        self.assertEqual(commands.get_app_dir(), os.path.realpath(pjoin(self.data_dir, 'lab')))

        self.app_dir = commands.get_app_dir()
示例#8
0
    def _default_node_roots(self):
        """get the "usual suspects" for where `node_modules` may be found

        - where this was launch (usually the same as NotebookApp.notebook_dir)
        - the JupyterLab staging folder (if available)
        - wherever conda puts it
        - wherever some other conventions put it
        """

        # check where the server was started first
        roots = [pathlib.Path.cwd()]

        # try jupyterlab staging next
        try:
            from jupyterlab import commands

            roots += [pathlib.Path(commands.get_app_dir()) / "staging"]
        except ImportError:  # pragma: no cover
            pass

        # conda puts stuff in $PREFIX/lib on POSIX systems
        roots += [pathlib.Path(sys.prefix) / "lib"]

        # ... but right in %PREFIX% on nt
        roots += [pathlib.Path(sys.prefix)]

        return roots
def load_jupyter_server_extension(nbapp):
    """
    Called when the extension is loaded.

    Args:
        nbapp (NotebookWebApplication): handle to the Notebook webserver instance.
    """

    from notebook.utils import url_path_join

    from jupyterlab.commands import get_app_dir

    from .handlers import (
        ExtensionHandler,
        ExtensionManager,
        extensions_handler_path,
    )
    web_app = nbapp.web_app

    app_dir = getattr(nbapp, 'app_dir', get_app_dir())

    extension_manager = ExtensionManager(nbapp.log, app_dir)
    handlers = [
        (extensions_handler_path, ExtensionHandler, {
            'manager': extension_manager
        }),
    ]

    # Prefix routes with base_url:
    base_url = web_app.settings.get('base_url', '/')
    handlers = [(url_path_join(base_url, h[0]), h[1], h[2]) for h in handlers]

    host_pattern = '.*$'
    web_app.add_handlers(host_pattern, handlers)
示例#10
0
 def test_install_twice(self):
     install_extension(self.mock_extension)
     path = pjoin(commands.get_app_dir(), 'extensions',
                  '*python-tests*.tgz')
     install_extension(self.mock_extension)
     assert glob.glob(path)
     assert '@jupyterlab/python-tests' in _get_extensions(self.app_dir)
示例#11
0
def load_config(nbapp):
    config = LabConfig(app_url='/phoila', tree_url='/voila/tree')
    app_dir = getattr(nbapp, 'app_dir', get_app_dir())
    info = get_app_info(app_dir)
    static_url = info['staticUrl']
    user_settings_dir = getattr(nbapp, 'user_settings_dir',
                                get_user_settings_dir())
    workspaces_dir = getattr(nbapp, 'workspaces_dir', get_workspaces_dir())

    config.app_dir = app_dir
    config.app_name = 'Phoila'
    config.app_namespace = 'phoila'
    config.app_settings_dir = os.path.join(app_dir, 'settings')
    config.cache_files = True
    config.schemas_dir = os.path.join(app_dir, 'schemas')
    config.templates_dir = os.path.join(app_dir, 'static')
    config.themes_dir = os.path.join(app_dir, 'themes')
    config.user_settings_dir = user_settings_dir
    config.workspaces_dir = os.path.join(app_dir, 'workspaces')

    if getattr(nbapp, 'override_static_url', ''):
        static_url = nbapp.override_static_url
    if getattr(nbapp, 'override_theme_url', ''):
        config.themes_url = nbapp.override_theme_url
        config.themes_dir = ''

    if static_url:
        config.static_url = static_url
    else:
        config.static_dir = os.path.join(app_dir, 'static')

    return config
示例#12
0
 def test_install_twice(self):
     install_extension(self.mock_extension)
     path = pjoin(commands.get_app_dir(), 'extensions', '*.tgz')
     install_extension(self.mock_extension)
     assert glob.glob(path)
     extensions = get_app_info(self.app_dir)['extensions']
     assert self.pkg_names['extension'] in extensions
示例#13
0
    def test_app_dir_shadowing(self):
        app_dir = self.tempdir()
        sys_dir = get_app_dir()
        if os.path.exists(sys_dir):
            os.removedirs(sys_dir)

        install_extension(self.source_dir)
        sys_path = pjoin(sys_dir, 'extensions', '*python-tests*.tgz')
        assert glob.glob(sys_path)
        app_path = pjoin(app_dir, 'extensions', '*python-tests*.tgz')
        assert not glob.glob(app_path)
        assert '@jupyterlab/python-tests' in list_extensions(app_dir)

        install_extension(self.source_dir, app_dir)
        assert glob.glob(app_path)
        assert '@jupyterlab/python-tests' in list_extensions(app_dir)

        uninstall_extension('@jupyterlab/python-tests', app_dir)
        assert not glob.glob(app_path)
        assert glob.glob(sys_path)
        assert '@jupyterlab/python-tests' in list_extensions(app_dir)

        uninstall_extension('@jupyterlab/python-tests', app_dir)
        assert not glob.glob(app_path)
        assert not glob.glob(sys_path)
        assert '@jupyterlab/python-tests' not in list_extensions(app_dir)
    def test_app_dir_shadowing(self):
        app_dir = self.tempdir()
        sys_dir = get_app_dir()
        if os.path.exists(sys_dir):
            os.removedirs(sys_dir)

        install_extension(self.source_dir)
        sys_path = pjoin(sys_dir, 'extensions', '*python-tests*.tgz')
        assert glob.glob(sys_path)
        app_path = pjoin(app_dir, 'extensions', '*python-tests*.tgz')
        assert not glob.glob(app_path)
        assert '@jupyterlab/python-tests' in list_extensions(app_dir)

        install_extension(self.source_dir, app_dir)
        assert glob.glob(app_path)
        assert '@jupyterlab/python-tests' in list_extensions(app_dir)

        uninstall_extension('@jupyterlab/python-tests', app_dir)
        assert not glob.glob(app_path)
        assert glob.glob(sys_path)
        assert '@jupyterlab/python-tests' in list_extensions(app_dir)

        uninstall_extension('@jupyterlab/python-tests', app_dir)
        assert not glob.glob(app_path)
        assert not glob.glob(sys_path)
        assert '@jupyterlab/python-tests' not in list_extensions(app_dir)
示例#15
0
 def test_uninstall_core_extension(self):
     uninstall_extension('@jupyterlab/console-extension')
     app_dir = get_app_dir()
     _ensure_package(app_dir)
     with open(pjoin(app_dir, 'staging', 'package.json')) as fid:
         data = json.load(fid)
     extensions = data['jupyterlab']['extensions']
     assert '@jupyterlab/console-extension' not in extensions
 def test_uninstall_core_extension(self):
     uninstall_extension('@jupyterlab/console-extension')
     app_dir = get_app_dir()
     _ensure_package(app_dir)
     with open(pjoin(app_dir, 'staging', 'package.json')) as fid:
         data = json.load(fid)
     extensions = data['jupyterlab']['extensions']
     assert '@jupyterlab/console-extension' not in extensions
示例#17
0
 def test_install_twice(self):
     assert install_extension(self.mock_extension) is True
     path = pjoin(commands.get_app_dir(), 'extensions', '*.tgz')
     assert install_extension(self.mock_extension) is True
     assert glob.glob(path)
     extensions = get_app_info(self.app_dir)['extensions']
     name = self.pkg_names['extension']
     assert name in extensions
     assert check_extension(name)
示例#18
0
 def test_install_twice(self):
     assert install_extension(self.mock_extension) is True
     path = pjoin(commands.get_app_dir(), 'extensions', '*.tgz')
     assert install_extension(self.mock_extension) is True
     assert glob.glob(path)
     extensions = get_app_info(self.app_dir)['extensions']
     name = self.pkg_names['extension']
     assert name in extensions
     assert check_extension(name)
示例#19
0
    ExtensionHandlerMixin,
    ExtensionHandlerJinjaMixin,
)
from jupyter_server.utils import url_path_join as ujoin
from jupyterlab.commands import get_app_dir, get_user_settings_dir, get_workspaces_dir
from jupyterlab_server import LabServerApp
from jupyterlab_server.config import get_page_config, recursive_update, LabConfig
from jupyterlab_server.handlers import is_url, _camelCase
from nbclassic.shim import NBClassicConfigShimMixin
from tornado import web

from ._version import __version__

HERE = os.path.dirname(__file__)

app_dir = get_app_dir()
version = __version__


class ClassicPageConfigMixin:
    def get_page_config(self):
        config = LabConfig()
        app = self.extensionapp
        base_url = self.settings.get("base_url")

        page_config = {
            "appVersion": version,
            "baseUrl": self.base_url,
            "token": self.settings["token"],
            "fullStaticUrl": ujoin(self.base_url, "static", self.name),
            "frontendUrl": ujoin(self.base_url, "classic/"),
 def test_uninstall_extension(self):
     install_extension(self.source_dir)
     uninstall_extension('@jupyterlab/python-tests')
     path = pjoin(get_app_dir(), 'extensions', '*python_tests*.tgz')
     assert not glob.glob(path)
     assert '@jupyterlab/python-tests' not in list_extensions()
示例#21
0
 def test_install_twice(self):
     install_extension(self.source_dir)
     path = pjoin(commands.get_app_dir(), 'extensions', '*python-tests*.tgz')
     install_extension(self.source_dir)
     assert glob.glob(path)
     assert '@jupyterlab/python-tests' in _get_extensions(self.app_dir)
示例#22
0
    def setUp(self):
        # Any TemporaryDirectory objects appended to this list will be cleaned
        # up at the end of the test run.
        self.tempdirs = []
        self.devnull = open(os.devnull, 'w')

        @self.addCleanup
        def cleanup_tempdirs():
            for d in self.tempdirs:
                d.cleanup()

        self.test_dir = self.tempdir()

        self.data_dir = pjoin(self.test_dir, 'data')
        self.config_dir = pjoin(self.test_dir, 'config')
        self.pkg_names = dict()

        # Copy in the mock packages.
        for name in ['extension', 'incompat', 'package', 'mimeextension']:
            src = pjoin(here, 'mock_packages', name)

            def ignore(dname, files):
                if 'node_modules' in dname:
                    files = []
                if 'node_modules' in files:
                    files.remove('node_modules')
                return dname, files

            dest = pjoin(self.test_dir, name)
            shutil.copytree(src, dest, ignore=ignore)

            # Make a node modules folder so npm install is not called.
            os.makedirs(pjoin(dest, 'node_modules'))

            setattr(self, 'mock_' + name, dest)
            with open(pjoin(dest, 'package.json')) as fid:
                data = json.load(fid)
            self.pkg_names[name] = data['name']

        self.patches = []
        p = patch.dict('os.environ', {
            'JUPYTER_CONFIG_DIR': self.config_dir,
            'JUPYTER_DATA_DIR': self.data_dir,
            'JUPYTERLAB_DIR': pjoin(self.data_dir, 'lab')
        })
        self.patches.append(p)
        for mod in [paths]:
            if hasattr(mod, 'ENV_JUPYTER_PATH'):
                p = patch.object(mod, 'ENV_JUPYTER_PATH', [self.data_dir])
                self.patches.append(p)
            if hasattr(mod, 'ENV_CONFIG_PATH'):
                p = patch.object(mod, 'ENV_CONFIG_PATH', [self.config_dir])
                self.patches.append(p)
            if hasattr(mod, 'CONFIG_PATH'):
                p = patch.object(mod, 'CONFIG_PATH', self.config_dir)
                self.patches.append(p)
            if hasattr(mod, 'BUILD_PATH'):
                p = patch.object(mod, 'BUILD_PATH', self.data_dir)
                self.patches.append(p)
        for p in self.patches:
            p.start()
            self.addCleanup(p.stop)

        # verify our patches
        self.assertEqual(paths.ENV_CONFIG_PATH, [self.config_dir])
        self.assertEqual(paths.ENV_JUPYTER_PATH, [self.data_dir])
        self.assertEqual(
            commands.get_app_dir(),
            os.path.realpath(pjoin(self.data_dir, 'lab'))
        )

        self.app_dir = commands.get_app_dir()
示例#23
0
 def test_uninstall_extension(self):
     install_extension(self.source_dir)
     uninstall_extension('@jupyterlab/python-tests')
     path = pjoin(get_app_dir(), 'extensions', '*python_tests*.tgz')
     assert not glob.glob(path)
     assert '@jupyterlab/python-tests' not in list_extensions()
示例#24
0
    def setUp(self):
        # Any TemporaryDirectory objects appended to this list will be cleaned
        # up at the end of the test run.
        self.tempdirs = []
        self.devnull = open(os.devnull, 'w')

        @self.addCleanup
        def cleanup_tempdirs():
            for d in self.tempdirs:
                d.cleanup()

        self.test_dir = self.tempdir()

        self.data_dir = pjoin(self.test_dir, 'data')
        self.config_dir = pjoin(self.test_dir, 'config')
        self.pkg_names = dict()

        # Copy in the mock packages.
        for name in ['extension', 'incompat', 'package', 'mimeextension']:
            src = pjoin(here, 'mock_packages', name)

            def ignore(dname, files):
                if 'node_modules' in dname:
                    files = []
                if 'node_modules' in files:
                    files.remove('node_modules')
                return dname, files

            dest = pjoin(self.test_dir, name)
            shutil.copytree(src, dest, ignore=ignore)

            # Make a node modules folder so npm install is not called.
            os.makedirs(pjoin(dest, 'node_modules'))

            setattr(self, 'mock_' + name, dest)
            with open(pjoin(dest, 'package.json')) as fid:
                data = json.load(fid)
            self.pkg_names[name] = data['name']

        self.patches = []
        p = patch.dict(
            'os.environ', {
                'JUPYTER_CONFIG_DIR': self.config_dir,
                'JUPYTER_DATA_DIR': self.data_dir,
                'JUPYTERLAB_DIR': pjoin(self.data_dir, 'lab')
            })
        self.patches.append(p)
        for mod in [paths]:
            if hasattr(mod, 'ENV_JUPYTER_PATH'):
                p = patch.object(mod, 'ENV_JUPYTER_PATH', [self.data_dir])
                self.patches.append(p)
            if hasattr(mod, 'ENV_CONFIG_PATH'):
                p = patch.object(mod, 'ENV_CONFIG_PATH', [self.config_dir])
                self.patches.append(p)
            if hasattr(mod, 'CONFIG_PATH'):
                p = patch.object(mod, 'CONFIG_PATH', self.config_dir)
                self.patches.append(p)
            if hasattr(mod, 'BUILD_PATH'):
                p = patch.object(mod, 'BUILD_PATH', self.data_dir)
                self.patches.append(p)
        for p in self.patches:
            p.start()
            self.addCleanup(p.stop)

        # verify our patches
        self.assertEqual(paths.ENV_CONFIG_PATH, [self.config_dir])
        self.assertEqual(paths.ENV_JUPYTER_PATH, [self.data_dir])
        self.assertEqual(commands.get_app_dir(),
                         os.path.realpath(pjoin(self.data_dir, 'lab')))

        self.app_dir = commands.get_app_dir()
示例#25
0
    def setUp(self):
        # Any TemporaryDirectory objects appended to this list will be cleaned
        # up at the end of the test run.
        self.tempdirs = []
        self.devnull = open(os.devnull, "w")

        @self.addCleanup
        def cleanup_tempdirs():
            for d in self.tempdirs:
                d.cleanup()

        self.test_dir = self.tempdir()

        self.data_dir = pjoin(self.test_dir, "data")
        self.config_dir = pjoin(self.test_dir, "config")
        self.pkg_names = {}

        # Copy in the mock packages.
        for name in ["extension", "incompat", "package", "mimeextension"]:
            src = pjoin(here, "mock_packages", name)

            def ignore(dname, files):
                if "node_modules" in dname:
                    files = []
                if "node_modules" in files:
                    files.remove("node_modules")
                return dname, files

            dest = pjoin(self.test_dir, name)
            shutil.copytree(src, dest, ignore=ignore)

            # Make a node modules folder so npm install is not called.
            if not os.path.exists(pjoin(dest, "node_modules")):
                os.makedirs(pjoin(dest, "node_modules"))

            setattr(self, "mock_" + name, dest)
            with open(pjoin(dest, "package.json")) as fid:
                data = json.load(fid)
            self.pkg_names[name] = data["name"]

        self.patches = []
        p = patch.dict(
            "os.environ",
            {
                "JUPYTER_CONFIG_DIR": self.config_dir,
                "JUPYTER_DATA_DIR": self.data_dir,
                "JUPYTERLAB_DIR": pjoin(self.data_dir, "lab"),
            },
        )
        self.patches.append(p)
        for mod in [paths]:
            if hasattr(mod, "ENV_JUPYTER_PATH"):
                p = patch.object(mod, "ENV_JUPYTER_PATH", [self.data_dir])
                self.patches.append(p)
            if hasattr(mod, "ENV_CONFIG_PATH"):
                p = patch.object(mod, "ENV_CONFIG_PATH", [self.config_dir])
                self.patches.append(p)
            if hasattr(mod, "CONFIG_PATH"):
                p = patch.object(mod, "CONFIG_PATH", self.config_dir)
                self.patches.append(p)
            if hasattr(mod, "BUILD_PATH"):
                p = patch.object(mod, "BUILD_PATH", self.data_dir)
                self.patches.append(p)
        for p in self.patches:
            p.start()
            self.addCleanup(p.stop)

        # verify our patches
        self.assertEqual(paths.ENV_CONFIG_PATH, [self.config_dir])
        self.assertEqual(paths.ENV_JUPYTER_PATH, [self.data_dir])
        self.assertEqual(
            Path(commands.get_app_dir()).resolve(),
            (Path(self.data_dir) / "lab").resolve())

        self.app_dir = commands.get_app_dir()

        # Set pinned extension names
        self.pinned_packages = [
            "[email protected]", "[email protected]"
        ]