Skip to content

Commit 1c51e6b

Browse files
authored
Change name from LocalCommandlineCodeExecutor to LocalCommandLineCodeExecutor (microsoft#1873)
* Change name from LocalCommandlineCodeExecutor to LocalCommandLineCodeExecutor * formatting * name * name * CommandLineCodeResult rename too * formatting
1 parent 9123070 commit 1c51e6b

File tree

3 files changed

+91
-24
lines changed

3 files changed

+91
-24
lines changed

autogen/coding/factory.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ def create(code_execution_config: Dict[str, Any]) -> CodeExecutor:
3434

3535
return EmbeddedIPythonCodeExecutor(**code_execution_config.get("ipython-embedded", {}))
3636
elif executor == "commandline-local":
37-
from .local_commandline_code_executor import LocalCommandlineCodeExecutor
37+
from .local_commandline_code_executor import LocalCommandLineCodeExecutor
3838

39-
return LocalCommandlineCodeExecutor(**code_execution_config.get("commandline-local", {}))
39+
return LocalCommandLineCodeExecutor(**code_execution_config.get("commandline-local", {}))
4040
else:
4141
raise ValueError(f"Unknown code executor {executor}")

autogen/coding/local_commandline_code_executor.py

+78-11
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
from .markdown_code_extractor import MarkdownCodeExtractor
1212

1313
__all__ = (
14-
"LocalCommandlineCodeExecutor",
15-
"CommandlineCodeResult",
14+
"LocalCommandLineCodeExecutor",
15+
"CommandLineCodeResult",
1616
)
1717

1818

19-
class CommandlineCodeResult(CodeResult):
19+
class CommandLineCodeResult(CodeResult):
2020
"""(Experimental) A code result class for command line code executor."""
2121

2222
code_file: Optional[str] = Field(
@@ -25,7 +25,7 @@ class CommandlineCodeResult(CodeResult):
2525
)
2626

2727

28-
class LocalCommandlineCodeExecutor(BaseModel):
28+
class LocalCommandLineCodeExecutor(BaseModel):
2929
"""(Experimental) A code executor class that executes code through a local command line
3030
environment.
3131
@@ -49,7 +49,7 @@ class LocalCommandlineCodeExecutor(BaseModel):
4949
directory is the current directory ".".
5050
system_message_update (str): The system message update for agent that
5151
produces code to run on this executor.
52-
Default is `LocalCommandlineCodeExecutor.DEFAULT_SYSTEM_MESSAGE_UPDATE`.
52+
Default is `LocalCommandLineCodeExecutor.DEFAULT_SYSTEM_MESSAGE_UPDATE`.
5353
"""
5454

5555
DEFAULT_SYSTEM_MESSAGE_UPDATE: ClassVar[
@@ -92,10 +92,10 @@ def _check_work_dir(cls, v: str) -> str:
9292
raise ValueError(f"Working directory {v} does not exist.")
9393

9494
@property
95-
def user_capability(self) -> "LocalCommandlineCodeExecutor.UserCapability":
95+
def user_capability(self) -> "LocalCommandLineCodeExecutor.UserCapability":
9696
"""Export a user capability for this executor that can be added to
9797
an agent that produces code to be executed by this executor."""
98-
return LocalCommandlineCodeExecutor.UserCapability(self.system_message_update)
98+
return LocalCommandLineCodeExecutor.UserCapability(self.system_message_update)
9999

100100
@property
101101
def code_extractor(self) -> CodeExtractor:
@@ -124,19 +124,19 @@ def sanitize_command(lang: str, code: str) -> None:
124124
if re.search(pattern, code):
125125
raise ValueError(f"Potentially dangerous command detected: {message}")
126126

127-
def execute_code_blocks(self, code_blocks: List[CodeBlock]) -> CommandlineCodeResult:
127+
def execute_code_blocks(self, code_blocks: List[CodeBlock]) -> CommandLineCodeResult:
128128
"""(Experimental) Execute the code blocks and return the result.
129129
130130
Args:
131131
code_blocks (List[CodeBlock]): The code blocks to execute.
132132
133133
Returns:
134-
CommandlineCodeResult: The result of the code execution."""
134+
CommandLineCodeResult: The result of the code execution."""
135135
logs_all = ""
136136
for i, code_block in enumerate(code_blocks):
137137
lang, code = code_block.language, code_block.code
138138

139-
LocalCommandlineCodeExecutor.sanitize_command(lang, code)
139+
LocalCommandLineCodeExecutor.sanitize_command(lang, code)
140140
filename_uuid = uuid.uuid4().hex
141141
filename = None
142142
if lang in ["bash", "shell", "sh", "pwsh", "powershell", "ps1"]:
@@ -166,8 +166,75 @@ def execute_code_blocks(self, code_blocks: List[CodeBlock]) -> CommandlineCodeRe
166166
if exitcode != 0:
167167
break
168168
code_filename = os.path.join(self.work_dir, filename) if filename is not None else None
169-
return CommandlineCodeResult(exit_code=exitcode, output=logs_all, code_file=code_filename)
169+
return CommandLineCodeResult(exit_code=exitcode, output=logs_all, code_file=code_filename)
170170

171171
def restart(self) -> None:
172172
"""(Experimental) Restart the code executor."""
173173
warnings.warn("Restarting local command line code executor is not supported. No action is taken.")
174+
175+
176+
# From stack overflow: https://stackoverflow.com/a/52087847/2214524
177+
class _DeprecatedClassMeta(type):
178+
def __new__(cls, name, bases, classdict, *args, **kwargs):
179+
alias = classdict.get("_DeprecatedClassMeta__alias")
180+
181+
if alias is not None:
182+
183+
def new(cls, *args, **kwargs):
184+
alias = getattr(cls, "_DeprecatedClassMeta__alias")
185+
186+
if alias is not None:
187+
warnings.warn(
188+
"{} has been renamed to {}, the alias will be "
189+
"removed in the future".format(cls.__name__, alias.__name__),
190+
DeprecationWarning,
191+
stacklevel=2,
192+
)
193+
194+
return alias(*args, **kwargs)
195+
196+
classdict["__new__"] = new
197+
classdict["_DeprecatedClassMeta__alias"] = alias
198+
199+
fixed_bases = []
200+
201+
for b in bases:
202+
alias = getattr(b, "_DeprecatedClassMeta__alias", None)
203+
204+
if alias is not None:
205+
warnings.warn(
206+
"{} has been renamed to {}, the alias will be "
207+
"removed in the future".format(b.__name__, alias.__name__),
208+
DeprecationWarning,
209+
stacklevel=2,
210+
)
211+
212+
# Avoid duplicate base classes.
213+
b = alias or b
214+
if b not in fixed_bases:
215+
fixed_bases.append(b)
216+
217+
fixed_bases = tuple(fixed_bases)
218+
219+
return super().__new__(cls, name, fixed_bases, classdict, *args, **kwargs)
220+
221+
def __instancecheck__(cls, instance):
222+
return any(cls.__subclasscheck__(c) for c in {type(instance), instance.__class__})
223+
224+
def __subclasscheck__(cls, subclass):
225+
if subclass is cls:
226+
return True
227+
else:
228+
return issubclass(subclass, getattr(cls, "_DeprecatedClassMeta__alias"))
229+
230+
231+
class LocalCommandlineCodeExecutor(metaclass=_DeprecatedClassMeta):
232+
"""LocalCommandlineCodeExecutor renamed to LocalCommandLineCodeExecutor"""
233+
234+
_DeprecatedClassMeta__alias = LocalCommandLineCodeExecutor
235+
236+
237+
class CommandlineCodeResult(metaclass=_DeprecatedClassMeta):
238+
"""CommandlineCodeResult renamed to CommandLineCodeResult"""
239+
240+
_DeprecatedClassMeta__alias = CommandLineCodeResult

test/coding/test_commandline_code_executor.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from autogen.agentchat.conversable_agent import ConversableAgent
55
from autogen.coding.base import CodeBlock, CodeExecutor
66
from autogen.coding.factory import CodeExecutorFactory
7-
from autogen.coding.local_commandline_code_executor import LocalCommandlineCodeExecutor
7+
from autogen.coding.local_commandline_code_executor import LocalCommandLineCodeExecutor
88
from autogen.oai.openai_utils import config_list_from_json
99

1010
from conftest import MOCK_OPEN_AI_API_KEY, skip_openai
@@ -13,25 +13,25 @@
1313
def test_create() -> None:
1414
config = {"executor": "commandline-local"}
1515
executor = CodeExecutorFactory.create(config)
16-
assert isinstance(executor, LocalCommandlineCodeExecutor)
16+
assert isinstance(executor, LocalCommandLineCodeExecutor)
1717

18-
config = {"executor": LocalCommandlineCodeExecutor()}
18+
config = {"executor": LocalCommandLineCodeExecutor()}
1919
executor = CodeExecutorFactory.create(config)
2020
assert executor is config["executor"]
2121

2222

2323
def test_local_commandline_executor_init() -> None:
24-
executor = LocalCommandlineCodeExecutor(timeout=10, work_dir=".")
24+
executor = LocalCommandLineCodeExecutor(timeout=10, work_dir=".")
2525
assert executor.timeout == 10 and executor.work_dir == "."
2626

2727
# Try invalid working directory.
2828
with pytest.raises(ValueError, match="Working directory .* does not exist."):
29-
executor = LocalCommandlineCodeExecutor(timeout=111, work_dir="/invalid/directory")
29+
executor = LocalCommandLineCodeExecutor(timeout=111, work_dir="/invalid/directory")
3030

3131

3232
def test_local_commandline_executor_execute_code() -> None:
3333
with tempfile.TemporaryDirectory() as temp_dir:
34-
executor = LocalCommandlineCodeExecutor(work_dir=temp_dir)
34+
executor = LocalCommandLineCodeExecutor(work_dir=temp_dir)
3535
_test_execute_code(executor=executor)
3636

3737

@@ -81,7 +81,7 @@ def _test_execute_code(executor: CodeExecutor) -> None:
8181
@pytest.mark.skipif(sys.platform in ["win32"], reason="do not run on windows")
8282
def test_local_commandline_code_executor_timeout() -> None:
8383
with tempfile.TemporaryDirectory() as temp_dir:
84-
executor = LocalCommandlineCodeExecutor(timeout=1, work_dir=temp_dir)
84+
executor = LocalCommandLineCodeExecutor(timeout=1, work_dir=temp_dir)
8585
_test_timeout(executor)
8686

8787

@@ -92,7 +92,7 @@ def _test_timeout(executor: CodeExecutor) -> None:
9292

9393

9494
def test_local_commandline_code_executor_restart() -> None:
95-
executor = LocalCommandlineCodeExecutor()
95+
executor = LocalCommandLineCodeExecutor()
9696
_test_restart(executor)
9797

9898

@@ -105,7 +105,7 @@ def _test_restart(executor: CodeExecutor) -> None:
105105
@pytest.mark.skipif(skip_openai, reason="requested to skip openai tests")
106106
def test_local_commandline_executor_conversable_agent_capability() -> None:
107107
with tempfile.TemporaryDirectory() as temp_dir:
108-
executor = LocalCommandlineCodeExecutor(work_dir=temp_dir)
108+
executor = LocalCommandLineCodeExecutor(work_dir=temp_dir)
109109
_test_conversable_agent_capability(executor=executor)
110110

111111

@@ -150,7 +150,7 @@ def _test_conversable_agent_capability(executor: CodeExecutor) -> None:
150150

151151
def test_local_commandline_executor_conversable_agent_code_execution() -> None:
152152
with tempfile.TemporaryDirectory() as temp_dir:
153-
executor = LocalCommandlineCodeExecutor(work_dir=temp_dir)
153+
executor = LocalCommandLineCodeExecutor(work_dir=temp_dir)
154154
with pytest.MonkeyPatch.context() as mp:
155155
mp.setenv("OPENAI_API_KEY", MOCK_OPEN_AI_API_KEY)
156156
_test_conversable_agent_code_execution(executor)
@@ -192,7 +192,7 @@ def _test_conversable_agent_code_execution(executor: CodeExecutor) -> None:
192192
)
193193
def test_dangerous_commands(lang, code, expected_message):
194194
with pytest.raises(ValueError) as exc_info:
195-
LocalCommandlineCodeExecutor.sanitize_command(lang, code)
195+
LocalCommandLineCodeExecutor.sanitize_command(lang, code)
196196
assert expected_message in str(
197197
exc_info.value
198198
), f"Expected message '{expected_message}' not found in '{str(exc_info.value)}'"

0 commit comments

Comments
 (0)