Skip to content

Commit 52de802

Browse files
authored
Add ignore globs for hidden files in CM config (#1396)
* Add additional glob pattern to hide files. * Commit changes and precommit fixes.
1 parent 484fd20 commit 52de802

File tree

3 files changed

+43
-21
lines changed

3 files changed

+43
-21
lines changed

packages/jupyter-ai/jupyter_ai/extension.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,5 +441,21 @@ def _link_jupyter_server_extension(self, server_app: ServerApp):
441441
"""Setup custom config needed by this extension."""
442442
c = Config()
443443
c.ContentsManager.allow_hidden = True
444+
c.ContentsManager.hide_globs = [
445+
"__pycache__", # Python bytecode cache directories
446+
"*.pyc", # Compiled Python files
447+
"*.pyo", # Optimized Python files
448+
".DS_Store", # macOS system files
449+
"*~", # Editor backup files
450+
".ipynb_checkpoints", # Jupyter notebook checkpoint files
451+
".git", # Git version control directory
452+
".venv", # Python virtual environment directory
453+
"venv", # Python virtual environment directory
454+
".env", # Environment variable files
455+
"node_modules", # Node.js dependencies directory
456+
".pytest_cache", # PyTest cache directory
457+
".mypy_cache", # MyPy type checker cache directory
458+
"*.egg-info", # Python package metadata directories
459+
]
444460
server_app.update_config(c)
445461
super()._link_jupyter_server_extension(server_app)

packages/jupyter-ai/jupyter_ai/personas/persona_manager.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from logging import Logger
1010
from pathlib import Path
1111
from time import time_ns
12-
from typing import TYPE_CHECKING, Any, ClassVar
12+
from typing import TYPE_CHECKING, Any
1313

1414
from importlib_metadata import entry_points
1515
from jupyterlab_chat.models import Message
@@ -60,7 +60,6 @@ class PersonaManager(LoggingConfigurable):
6060
_personas: dict[str, BasePersona]
6161
file_id: str
6262

63-
6463
def __init__(
6564
self,
6665
*args,
@@ -319,7 +318,7 @@ def load_from_dir(root_dir: str, log: Logger) -> list[type[BasePersona]]:
319318
`PersonaManager`.
320319
321320
Scans the root_dir for .py files containing `persona` in their name that do
322-
_not_ start with a single `_` (i.e. private modules are skipped). Then, it
321+
_not_ start with a single `_` (i.e. private modules are skipped). Then, it
323322
dynamically imports them, and extracts any class declarations that are
324323
subclasses of `BasePersona`.
325324
@@ -343,22 +342,26 @@ def load_from_dir(root_dir: str, log: Logger) -> list[type[BasePersona]]:
343342
py_files = []
344343
for f in all_py_files:
345344
fname_lower = Path(f).stem.lower()
346-
if "persona" in fname_lower and not (fname_lower.startswith("_") or fname_lower.startswith(".")):
345+
if "persona" in fname_lower and not (
346+
fname_lower.startswith("_") or fname_lower.startswith(".")
347+
):
347348
py_files.append(f)
348349

349350
except Exception as e:
350351
# On exception with glob operation, return empty list
351-
log.error(f"{type(e).__name__} occurred while searching for Python files in {root_dir}")
352+
log.error(
353+
f"{type(e).__name__} occurred while searching for Python files in {root_dir}"
354+
)
352355
return persona_classes
353356

354357
if py_files:
355358
log.info(f"Found files from {root_dir}: {[Path(f).name for f in py_files]}")
356-
359+
357360
# Temporarily add root_dir to sys.path for imports
358361
root_dir_in_path = root_dir in sys.path
359362
if not root_dir_in_path:
360363
sys.path.insert(0, root_dir)
361-
364+
362365
try:
363366
# For each .py file, dynamically import the module and extract all
364367
# BasePersona subclasses.
@@ -386,14 +389,15 @@ def load_from_dir(root_dir: str, log: Logger) -> list[type[BasePersona]]:
386389
log.info(f"Found persona class '{obj.__name__}' in '{py_file}'")
387390
persona_classes.append(obj)
388391

389-
except Exception as e:
392+
except Exception:
390393
# On exception, log error and continue to next file
391-
log.exception(f"Unable to load persona classes from '{py_file}', exception details printed below.")
394+
log.exception(
395+
f"Unable to load persona classes from '{py_file}', exception details printed below."
396+
)
392397
continue
393398
finally:
394399
# Remove root_dir from sys.path if we added it
395400
if not root_dir_in_path and root_dir in sys.path:
396401
sys.path.remove(root_dir)
397402

398403
return persona_classes
399-

packages/jupyter-ai/jupyter_ai/tests/test_personas.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,19 @@ def test_empty_directory_returns_empty_list(self, tmp_persona_dir, mock_logger):
3131
"""Test that an empty directory returns an empty list of persona classes."""
3232
result = load_from_dir(str(tmp_persona_dir), mock_logger)
3333
assert result == []
34-
34+
3535
def test_non_persona_file_returns_empty_list(self, tmp_persona_dir, mock_logger):
3636
"""Test that a Python file without persona classes returns an empty list."""
3737
# Create a file that doesn't contain "persona" in the name
3838
non_persona_file = tmp_persona_dir / "no_personas.py"
3939
non_persona_file.write_text("pass")
40-
40+
4141
result = load_from_dir(str(tmp_persona_dir), mock_logger)
4242
assert result == []
43-
44-
def test_simple_persona_file_returns_persona_class(self, tmp_persona_dir, mock_logger):
43+
44+
def test_simple_persona_file_returns_persona_class(
45+
self, tmp_persona_dir, mock_logger
46+
):
4547
"""Test that a file with a BasePersona subclass returns that class."""
4648
# Create a simple persona file
4749
persona_file = tmp_persona_dir / "simple_personas.py"
@@ -52,24 +54,24 @@ class TestPersona(BasePersona):
5254
id = "test_persona"
5355
name = "Test Persona"
5456
description = "A simple test persona"
55-
57+
5658
def process_message(self, message):
5759
pass
5860
"""
5961
persona_file.write_text(persona_content)
60-
62+
6163
result = load_from_dir(str(tmp_persona_dir), mock_logger)
62-
64+
6365
assert len(result) == 1
6466
assert result[0].__name__ == "TestPersona"
6567
assert issubclass(result[0], BasePersona)
66-
68+
6769
def test_bad_persona_file_returns_empty_list(self, tmp_persona_dir, mock_logger):
6870
"""Test that a file with syntax errors returns empty list."""
6971
# Create a file with invalid Python code
70-
bad_persona_file = tmp_persona_dir / "bad_persona.py"
72+
bad_persona_file = tmp_persona_dir / "bad_persona.py"
7173
bad_persona_file.write_text("1/0")
72-
74+
7375
result = load_from_dir(str(tmp_persona_dir), mock_logger)
74-
76+
7577
assert result == []

0 commit comments

Comments
 (0)