From 4f8f9b3fc84e3a0d503ba7fe277c009086b6a8ba Mon Sep 17 00:00:00 2001 From: Dominik Jain Date: Wed, 22 Jul 2026 18:19:25 +0200 Subject: [PATCH] Refactoring: Rename ProjectConfig.languages to language_servers --- .serena/project.yml | 30 +++++++++------ CHANGELOG.md | 2 + scripts/demo_diagnostics.py | 2 +- scripts/demo_find_defining_symbol.py | 2 +- scripts/demo_find_implementing_symbol.py | 2 +- src/serena/agent.py | 2 +- src/serena/cli.py | 11 ++++-- src/serena/config/serena_config.py | 36 +++++++++--------- src/serena/dashboard.py | 6 +-- src/serena/project.py | 2 +- src/serena/resources/project.template.yml | 12 +++--- .../config/test_global_ignored_paths.py | 10 ++--- test/serena/config/test_serena_config.py | 38 +++++++++---------- test/serena/test_activation_command.py | 2 +- test/serena/test_cli_project_commands.py | 4 +- test/serena/test_dashboard.py | 2 +- test/serena/test_serena_agent.py | 2 +- 17 files changed, 90 insertions(+), 75 deletions(-) diff --git a/.serena/project.yml b/.serena/project.yml index e2cafdba..4ff8806a 100644 --- a/.serena/project.yml +++ b/.serena/project.yml @@ -1,7 +1,8 @@ # the name by which the project can be referenced within Serena/when chatting with the LLM. project_name: "serena" -# list of languages for which language servers are started (LSP backend only); choose from: + +# list of language servers to start when using the LSP backend; choose from: # ada al angular ansible bash # bsl clojure cpp cpp_ccls crystal # csharp csharp_omnisharp cue dart elixir @@ -19,7 +20,7 @@ project_name: "serena" # (This list may be outdated; generated with scripts/print_language_list.py; # For the current list, see values of Language enum here: # https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py) -# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) +# For some languages, there are several alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) # Note: # - For C, use cpp # - For JavaScript, use typescript @@ -28,20 +29,27 @@ project_name: "serena" # - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three) # - For Free Pascal/Lazarus, use pascal # Special requirements: -# Some languages require additional setup/installations. +# Some language servers require additional setup/installations. # See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers -# When using multiple languages, the first language server that supports a given file will be used for that file. -# The first language is the default language and the respective language server will be used as a fallback. +# When using multiple language servers, the first language server that supports a given file will be used for that file. +# The first language server is the default language and the respective language server will be used as a fallback. # Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored. -languages: -- python -- typescript +language_servers: + - python + - typescript # whether to use project's .gitignore files to ignore files ignore_all_files_in_gitignore: true # list of additional paths to ignore in this project. # Same syntax as gitignore, so you can use * and **. +# Important: quote patterns that start with `*`, otherwise YAML treats them as aliases. +# Example: +# ignored_paths: +# - "examples/**" +# - ".worktrees/**" +# - "**/bin/**" +# - "**/obj/**" # Note: global ignored_paths from serena_config.yml are also applied additively. ignored_paths: [] @@ -179,9 +187,9 @@ ls_workspace_folders: # Paths can be absolute or relative to the project root. # Each folder is registered as an LSP workspace folder, enabling language servers to discover # symbols and references across package boundaries, but these folders are not indexed by Serena, -# i.e. the respective symbols will not be found using Serena's symbol search tool. +# i.e. the respective symbols will not be found using Serena's symbol search tools. # Example: # additional_workspace_folders: -# - "../sibling-package" -# - "../shared-lib" +# - ../sibling-package +# - ../shared-lib ls_additional_workspace_folders: [] diff --git a/CHANGELOG.md b/CHANGELOG.md index 4939f1f4..45d794e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ Status of the `main` branch. Changes prior to the next official version change w * General: - Add Grok Build support (context `grok`, setup CLI, hooks) + - The `languages` key in project configurations was changed to `language_servers` to better reflect + the actual semantics (configurations are automatically migrated) * Language Servers: - Allow language server priorities to be configured in `serena_config.yml` (for auto-detection during diff --git a/scripts/demo_diagnostics.py b/scripts/demo_diagnostics.py index e5c73603..5dc2f824 100644 --- a/scripts/demo_diagnostics.py +++ b/scripts/demo_diagnostics.py @@ -40,7 +40,7 @@ def make_agent() -> SerenaAgent: project_root=str(REPO_PATH), project_config=ProjectConfig( project_name="demo_serena_repo", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], ignored_paths=[], excluded_tools=[], read_only=False, diff --git a/scripts/demo_find_defining_symbol.py b/scripts/demo_find_defining_symbol.py index 339a6502..31957dd3 100644 --- a/scripts/demo_find_defining_symbol.py +++ b/scripts/demo_find_defining_symbol.py @@ -29,7 +29,7 @@ def make_agent(project_root: Path, language: LanguageServerId, project_name: str project_root=str(project_root), project_config=ProjectConfig( project_name=project_name, - languages=[language], + language_servers=[language], ignored_paths=[], excluded_tools=[], read_only=False, diff --git a/scripts/demo_find_implementing_symbol.py b/scripts/demo_find_implementing_symbol.py index 4bce7915..34393479 100644 --- a/scripts/demo_find_implementing_symbol.py +++ b/scripts/demo_find_implementing_symbol.py @@ -27,7 +27,7 @@ def make_agent(project_root: Path, language: LanguageServerId, project_name: str project_root=str(project_root), project_config=ProjectConfig( project_name=project_name, - languages=[language], + language_servers=[language], ignored_paths=[], excluded_tools=[], read_only=False, diff --git a/src/serena/agent.py b/src/serena/agent.py index 30aebb35..aed7dc65 100644 --- a/src/serena/agent.py +++ b/src/serena/agent.py @@ -1028,7 +1028,7 @@ class SerenaAgent: else: msg = f"The project with name '{proj.project_name}' at {proj.project_root} is activated." if self._language_backend == LanguageBackend.LSP: - languages_str = ", ".join([lang.value for lang in proj.project_config.languages]) + languages_str = ", ".join([lang.value for lang in proj.project_config.language_servers]) msg += f"\nProgramming languages: {languages_str}." msg += f"File encoding: {proj.project_config.encoding}." diff --git a/src/serena/cli.py b/src/serena/cli.py index 797930c6..c53c341e 100644 --- a/src/serena/cli.py +++ b/src/serena/cli.py @@ -717,8 +717,8 @@ class ProjectCommands(AutoRegisteringGroup): languages=languages if languages else None, interactive=True, ) - languages_str = ", ".join([lang.value for lang in generated_conf.languages]) if generated_conf.languages else "N/A" - click.echo(f"Generated project with languages {{{languages_str}}} at {yml_path}.") + languages_str = ", ".join([lang.value for lang in generated_conf.language_servers]) if generated_conf.language_servers else "N/A" + click.echo(f"Generated project with language servers {{{languages_str}}} at {yml_path}.") registered_project = serena_config.get_registered_project(str(project_root)) if registered_project is None: registered_project = RegisteredProject(str(project_root), generated_conf) @@ -731,7 +731,11 @@ class ProjectCommands(AutoRegisteringGroup): @click.argument("project_path", type=click.Path(exists=True, file_okay=False), default=os.getcwd()) @click.option("--name", type=str, default=None, help="Project name; defaults to directory name if not specified.") @click.option( - "--language", type=str, multiple=True, help="Programming language(s); inferred if not specified. Can be passed multiple times." + "--ls", + "--language", + type=str, + multiple=True, + help="Programming language(s); inferred if not specified. Can be passed multiple times.", ) @click.option("--index", is_flag=True, help="Index the project after creation.") @click.option( @@ -761,6 +765,7 @@ class ProjectCommands(AutoRegisteringGroup): @click.argument("project", type=PROJECT_TYPE, default=os.getcwd(), required=False) @click.option("--name", type=str, default=None, help="Project name (only used if auto-creating project.yml).") @click.option( + "--ls", "--language", type=str, multiple=True, diff --git a/src/serena/config/serena_config.py b/src/serena/config/serena_config.py index bf2898a1..063cc658 100644 --- a/src/serena/config/serena_config.py +++ b/src/serena/config/serena_config.py @@ -321,7 +321,7 @@ class ProjectConfigAutoGenerationMode(Enum): @dataclass(kw_only=True) class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes): project_name: str - languages: list[LanguageServerId] + language_servers: list[LanguageServerId] ignored_paths: list[str] = field(default_factory=list) ls_workspace_folders: list[str] = field(default_factory=lambda: ["."]) ls_additional_workspace_folders: list[str] = field(default_factory=list) @@ -338,8 +338,8 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes): # class-level members SERENA_PROJECT_FILE = "project.yml" SERENA_LOCAL_PROJECT_FILE = "project.local.yml" - FIELDS_WITHOUT_DEFAULTS = {"project_name", "languages"} - RENAMED_FIELDS = {"additional_workspace_folders": "ls_additional_workspace_folders"} + FIELDS_WITHOUT_DEFAULTS = {"project_name", "language_servers"} + RENAMED_FIELDS = {"additional_workspace_folders": "ls_additional_workspace_folders", "languages": "language_servers"} YAML_COMMENT_NORMALISATION = YamlCommentNormalisation.LEADING """ the comment normalisation strategy to use when loading/saving project configuration files. @@ -457,7 +457,7 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes): languages_to_use = [lang.value for lang in languages] config_with_comments, _ = cls._load_yaml_dict(PROJECT_TEMPLATE_FILE) config_with_comments["project_name"] = project_name - config_with_comments["languages"] = languages_to_use + config_with_comments["language_servers"] = languages_to_use project_yml_path = serena_config.get_project_yml_location(str(project_root)) if save_to_disk: @@ -478,7 +478,7 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes): def async_language_determination(): try: with LogTime("Asynchronous language determination", logger=log): - project_config.languages = cls._determine_project_language_servers( + project_config.language_servers = cls._determine_project_language_servers( str(project_root), interactive=False, serena_config=serena_config ) if save_to_disk: @@ -540,8 +540,8 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes): # backward compatibility # NOTE: This must also work for project.local.yml files, which may be highly incomplete # * handle single "language" field - if "languages" not in data and "language" in data: - data["languages"] = [data["language"]] + if "language" in data and not ("languages" in data or "language_servers" in data): + data["language_servers"] = [data["language"]] del data["language"] # * handle renamed fields for old_key, new_key in cls.RENAMED_FIELDS.items(): @@ -580,18 +580,18 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes): """ # map languages to list of enum items, checking for errors lang_name_mapping = {"javascript": "typescript"} - languages: list[LanguageServerId] = [] - for language_str in data["languages"]: - orig_language_str = language_str + ls_ids: list[LanguageServerId] = [] + for ls_str in data["language_servers"]: + orig_language_str = ls_str try: - language_str = language_str.lower() - if language_str in lang_name_mapping: - language_str = lang_name_mapping[language_str] - language = LanguageServerId(language_str) - languages.append(language) + ls_str = ls_str.lower() + if ls_str in lang_name_mapping: + ls_str = lang_name_mapping[ls_str] + ls_id = LanguageServerId(ls_str) + ls_ids.append(ls_id) except ValueError as e: raise ValueError( - f"Invalid language: {orig_language_str}.\nValid language_strings are: {[l.value for l in LanguageServerId]}" + f"Invalid language server: '{orig_language_str}'.\nValid values are: {[l.value for l in LanguageServerId]}" ) from e # Validate activation_command_timeout @@ -632,7 +632,7 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes): return cls( project_name=data["project_name"], - languages=languages, + language_servers=ls_ids, ignored_paths=ignored_paths, ls_workspace_folders=data["ls_workspace_folders"], ls_additional_workspace_folders=additional_workspace_folders, @@ -669,7 +669,7 @@ class ProjectConfig(SharedConfig, ModeSelectionDefinitionWithAddedModes): del d[k] # map fields using non-primitive types to a YAML-compatible representation - d["languages"] = [lang.value for lang in self.languages] + d["language_servers"] = [lang.value for lang in self.language_servers] d["language_backend"] = self.language_backend.value if self.language_backend is not None else None d["line_ending"] = self.line_ending.value if self.line_ending is not None else None diff --git a/src/serena/dashboard.py b/src/serena/dashboard.py index 4b6637b6..33c97b83 100644 --- a/src/serena/dashboard.py +++ b/src/serena/dashboard.py @@ -514,7 +514,7 @@ class SerenaDashboardAPI: active_project_name = project.project_name if project else None project_info = { "name": active_project_name, - "language": ", ".join([l.value for l in project.project_config.languages]) if project else None, + "language": ", ".join([l.value for l in project.project_config.language_servers]) if project else None, "path": str(project.project_root) if project else None, } @@ -608,7 +608,7 @@ class SerenaDashboardAPI: # Get list of languages for the active project languages = [] if project is not None: - languages = [lang.value for lang in project.project_config.languages] + languages = [lang.value for lang in project.project_config.language_servers] # Get file encoding for the active project encoding = None @@ -646,7 +646,7 @@ class SerenaDashboardAPI: # Filter out already added languages for the active project project = self._agent.get_active_project() if project: - current_languages = [lang.value for lang in project.project_config.languages] + current_languages = [lang.value for lang in project.project_config.language_servers] available_languages = [lang for lang in all_languages if lang not in current_languages] else: available_languages = all_languages diff --git a/src/serena/project.py b/src/serena/project.py index 0323eebd..97d091c4 100644 --- a/src/serena/project.py +++ b/src/serena/project.py @@ -238,7 +238,7 @@ class Project(ToStringMixin): if self.language_backend.is_lsp(): if os.path.isfile(abs_path): is_file_in_supported_language = False - for language in self.project_config.languages: + for language in self.project_config.language_servers: fn_matcher = language.get_source_fn_matcher() if fn_matcher.is_relevant_filename(abs_path): is_file_in_supported_language = True diff --git a/src/serena/resources/project.template.yml b/src/serena/resources/project.template.yml index f163424c..2cf2a0f9 100644 --- a/src/serena/resources/project.template.yml +++ b/src/serena/resources/project.template.yml @@ -1,7 +1,7 @@ # the name by which the project can be referenced within Serena/when chatting with the LLM. project_name: "project_name" -# list of languages for which language servers are started (LSP backend only); choose from: +# list of language servers to start when using the LSP backend; choose from: # ada al angular ansible bash # bsl clojure cpp cpp_ccls crystal # csharp csharp_omnisharp cue dart elixir @@ -19,7 +19,7 @@ project_name: "project_name" # (This list may be outdated; generated with scripts/print_language_list.py; # For the current list, see values of Language enum here: # https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py) -# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) +# For some languages, there are several alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.) # Note: # - For C, use cpp # - For JavaScript, use typescript @@ -28,12 +28,12 @@ project_name: "project_name" # - For SCSS / Sass / plain CSS, use scss (some-sass-language-server handles all three) # - For Free Pascal/Lazarus, use pascal # Special requirements: -# Some languages require additional setup/installations. +# Some language servers require additional setup/installations. # See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers -# When using multiple languages, the first language server that supports a given file will be used for that file. -# The first language is the default language and the respective language server will be used as a fallback. +# When using multiple language servers, the first language server that supports a given file will be used for that file. +# The first language server is the default language and the respective language server will be used as a fallback. # Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored. -languages: ["python"] +language_servers: ["python"] # the encoding used by text files in the project # For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings diff --git a/test/serena/config/test_global_ignored_paths.py b/test/serena/config/test_global_ignored_paths.py index 4bee1e4b..c9fdb6b5 100644 --- a/test/serena/config/test_global_ignored_paths.py +++ b/test/serena/config/test_global_ignored_paths.py @@ -16,7 +16,7 @@ def _create_test_project( """Helper to create a Project with the given ignored paths configuration.""" config = ProjectConfig( project_name="test_project", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], ignored_paths=project_ignored_paths or [], ignore_all_files_in_gitignore=False, ) @@ -145,7 +145,7 @@ class TestRegisteredProjectGlobalIgnoredPaths: """RegisteredProject.get_project_instance() passes global_ignored_paths to Project.""" config = ProjectConfig( project_name="test_project", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], ignored_paths=[], ignore_all_files_in_gitignore=False, ) @@ -161,7 +161,7 @@ class TestRegisteredProjectGlobalIgnoredPaths: """RegisteredProject without global_ignored_paths defaults to empty.""" config = ProjectConfig( project_name="test_project", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], ignored_paths=[], ignore_all_files_in_gitignore=False, ) @@ -193,7 +193,7 @@ class TestRegisteredProjectGlobalIgnoredPaths: """RegisteredProject.from_project_instance() threads global_ignored_paths to Project.""" config = ProjectConfig( project_name="test_project", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], ignored_paths=[], ignore_all_files_in_gitignore=False, ) @@ -233,7 +233,7 @@ class TestGlobalIgnoredPathsWithGitignore: """Global patterns, project patterns, and .gitignore patterns are all applied together.""" config = ProjectConfig( project_name="test_project", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], ignored_paths=["build"], ignore_all_files_in_gitignore=True, ) diff --git a/test/serena/config/test_serena_config.py b/test/serena/config/test_serena_config.py index d6372205..c0b4cf20 100644 --- a/test/serena/config/test_serena_config.py +++ b/test/serena/config/test_serena_config.py @@ -42,7 +42,7 @@ class TestProjectConfigAutogenerate: config = ProjectConfig.autogenerate(self.project_path, self.serena_config, save_to_disk=False) assert config.project_name == self.project_path.name - assert config.languages == [] + assert config.language_servers == [] def test_autogenerate_empty_directory_logs_warning(self, caplog): """Test that autogenerate logs a warning when no language files are found.""" @@ -62,7 +62,7 @@ class TestProjectConfigAutogenerate: # Verify the configuration assert config.project_name == self.project_path.name - assert config.languages == [LanguageServerId.PYTHON] + assert config.language_servers == [LanguageServerId.PYTHON] def test_autogenerate_with_python_files_and_custom_ls_priorities(self): """Test successful autogeneration with Python source files, using custom language server priorities.""" @@ -78,7 +78,7 @@ class TestProjectConfigAutogenerate: # Verify the configuration assert config.project_name == self.project_path.name - assert config.languages == [LanguageServerId.PYTHON_TY] + assert config.language_servers == [LanguageServerId.PYTHON_TY] def test_autogenerate_with_js_files(self): """Test successful autogeneration with JavaScript source files.""" @@ -88,7 +88,7 @@ class TestProjectConfigAutogenerate: # Run autogenerate - should pick Python as dominant config = ProjectConfig.autogenerate(self.project_path, self.serena_config, save_to_disk=False) - assert config.languages == [LanguageServerId.TYPESCRIPT] + assert config.language_servers == [LanguageServerId.TYPESCRIPT] def test_autogenerate_with_multiple_languages(self): """Test autogeneration picks dominant language when multiple are present.""" @@ -100,7 +100,7 @@ class TestProjectConfigAutogenerate: # Run autogenerate - should pick Python as dominant config = ProjectConfig.autogenerate(self.project_path, self.serena_config, save_to_disk=False) - assert config.languages == [LanguageServerId.PYTHON] + assert config.language_servers == [LanguageServerId.PYTHON] def test_autogenerate_saves_to_disk(self): """Test that autogenerate can save the configuration to disk.""" @@ -116,7 +116,7 @@ class TestProjectConfigAutogenerate: assert config_path.exists() # Verify the content - assert config.languages == [LanguageServerId.GO] + assert config.language_servers == [LanguageServerId.GO] def test_autogenerate_nonexistent_path(self): """Test that autogenerate raises FileNotFoundError for non-existent path.""" @@ -140,7 +140,7 @@ class TestProjectConfigAutogenerate: config = ProjectConfig.autogenerate(self.project_path, self.serena_config, save_to_disk=False) assert config.project_name == self.project_path.name - assert config.languages == [] + assert config.language_servers == [] def test_autogenerate_custom_project_name(self): """Test autogenerate with custom project name.""" @@ -153,7 +153,7 @@ class TestProjectConfigAutogenerate: config = ProjectConfig.autogenerate(self.project_path, self.serena_config, project_name=custom_name, save_to_disk=False) assert config.project_name == custom_name - assert config.languages == [LanguageServerId.TYPESCRIPT] + assert config.language_servers == [LanguageServerId.TYPESCRIPT] class TestProjectConfig: @@ -168,14 +168,14 @@ class TestProjectConfigLanguageBackend: def test_language_backend_defaults_to_none(self): config = ProjectConfig( project_name="test", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], ) assert config.language_backend is None def test_language_backend_can_be_set(self): config = ProjectConfig( project_name="test", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], language_backend=LanguageBackend.JETBRAINS, ) assert config.language_backend == LanguageBackend.JETBRAINS @@ -183,7 +183,7 @@ class TestProjectConfigLanguageBackend: def test_language_backend_roundtrips_through_yaml(self): config = ProjectConfig( project_name="test", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], language_backend=LanguageBackend.JETBRAINS, ) d = config._to_yaml_dict() @@ -192,7 +192,7 @@ class TestProjectConfigLanguageBackend: def test_language_backend_none_roundtrips_through_yaml(self): config = ProjectConfig( project_name="test", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], ) d = config._to_yaml_dict() assert d["language_backend"] is None @@ -232,7 +232,7 @@ def _make_config_with_project( project_root=str(Path(__file__).parent.parent / "resources" / "repos" / "python" / "test_repo"), project_config=ProjectConfig( project_name=project_name, - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], language_backend=language_backend, ), serena_config=config, @@ -286,7 +286,7 @@ class TestEffectiveLanguageBackend: project_root=str(Path(__file__).parent.parent / "resources" / "repos" / "java" / "test_repo"), project_config=ProjectConfig( project_name="jb_proj", - languages=[LanguageServerId.JAVA], + language_servers=[LanguageServerId.JAVA], language_backend=LanguageBackend.JETBRAINS, ), serena_config=config, @@ -309,7 +309,7 @@ class TestEffectiveLanguageBackend: project_root=str(Path(__file__).parent.parent / "resources" / "repos" / "python" / "test_repo"), project_config=ProjectConfig( project_name="lsp_proj2", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], language_backend=LanguageBackend.LSP, ), serena_config=config, @@ -332,7 +332,7 @@ class TestEffectiveLanguageBackend: project_root=str(Path(__file__).parent.parent / "resources" / "repos" / "python" / "test_repo"), project_config=ProjectConfig( project_name="proj2", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], language_backend=None, ), serena_config=config, @@ -432,7 +432,7 @@ class TestProjectSerenaDataFolder: def _make_project(self, serena_config: "SerenaConfig | None" = None) -> Project: project_config = ProjectConfig( project_name="myproject", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], ) project = Project( project_root=str(self.project_path), @@ -679,11 +679,11 @@ class TestProjectConfigActivationCommand: return data def test_activation_command_defaults_to_none(self): - config = ProjectConfig(project_name="test", languages=[LanguageServerId.PYTHON]) + config = ProjectConfig(project_name="test", language_servers=[LanguageServerId.PYTHON]) assert config.activation_command is None def test_activation_command_timeout_default(self): - config = ProjectConfig(project_name="test", languages=[LanguageServerId.PYTHON]) + config = ProjectConfig(project_name="test", language_servers=[LanguageServerId.PYTHON]) assert config.activation_command_timeout == 180.0 def test_activation_command_parsed_from_dict(self): diff --git a/test/serena/test_activation_command.py b/test/serena/test_activation_command.py index 58f33e21..541ce318 100644 --- a/test/serena/test_activation_command.py +++ b/test/serena/test_activation_command.py @@ -25,7 +25,7 @@ def _make_project( ) project_config = ProjectConfig( project_name="test-activation", - languages=[LanguageServerId.PYTHON], + language_servers=[LanguageServerId.PYTHON], activation_command=activation_command, activation_command_timeout=activation_command_timeout, ) diff --git a/test/serena/test_cli_project_commands.py b/test/serena/test_cli_project_commands.py index ff6fd7ec..13359c87 100644 --- a/test/serena/test_cli_project_commands.py +++ b/test/serena/test_cli_project_commands.py @@ -245,13 +245,13 @@ class TestProjectCreateHelper: config = ProjectCommands._create_project(temp_project_dir_with_python_file, "my-project", ()).project_config assert isinstance(config, ProjectConfig) assert config.project_name == "my-project" - assert len(config.languages) >= 1 + assert len(config.language_servers) >= 1 def test_create_project_helper_with_languages(self, temp_project_dir): """Test _create_project with language specification.""" config = ProjectCommands._create_project(temp_project_dir, None, ("python", "typescript")).project_config assert isinstance(config, ProjectConfig) - assert len(config.languages) >= 1 + assert len(config.language_servers) >= 1 def test_create_project_helper_file_exists_error(self, temp_project_dir): """Test _create_project raises error if project.yml exists.""" diff --git a/test/serena/test_dashboard.py b/test/serena/test_dashboard.py index fb553a0a..7f003c5b 100644 --- a/test/serena/test_dashboard.py +++ b/test/serena/test_dashboard.py @@ -31,7 +31,7 @@ class _DummyAgent: def _make_dashboard(project_languages: list[LanguageServerId] | None) -> SerenaDashboardAPI: project = None if project_languages is not None: - project = SimpleNamespace(project_config=SimpleNamespace(languages=project_languages)) + project = SimpleNamespace(project_config=SimpleNamespace(language_servers=project_languages)) agent = _DummyAgent(project) return SerenaDashboardAPI(memory_log_handler=_DummyMemoryLogHandler(), tool_names=[], agent=agent, tool_usage_stats=None) diff --git a/test/serena/test_serena_agent.py b/test/serena/test_serena_agent.py index b6a65dd3..933c5568 100644 --- a/test/serena/test_serena_agent.py +++ b/test/serena/test_serena_agent.py @@ -799,7 +799,7 @@ def serena_config(): project_root=str(repo_path), project_config=ProjectConfig( project_name=project_name, - languages=[language], + language_servers=[language], ignored_paths=[], excluded_tools=[], read_only=False,