internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: python/typeshed

Issue:
Replace isort with ruff?
I think @AlexWaygood suggested this originally and I pushed back against it. I've come around to the idea to using ruff for sorting imports, iff ruff has feature parity with and same sort order as isort (for our use case).


Discussion:

Resolving patch:
diff --git a/scripts/create_baseline_stubs.py b/scripts/create_baseline_stubs.py
--- a/scripts/create_baseline_stubs.py
+++ b/scripts/create_baseline_stubs.py
@@ -65,14 +65,9 @@ def run_black(stub_dir: str) -> None:
     subprocess.run(["black", stub_dir])
 
 
-def run_isort(stub_dir: str) -> None:
-    print(f"Running isort: isort {stub_dir}")
-    subprocess.run([sys.executable, "-m", "isort", stub_dir])
-
-
 def run_ruff(stub_dir: str) -> None:
-    print(f"Running Ruff: ruff {stub_dir}")
-    subprocess.run([sys.executable, "-m", "ruff", stub_dir])
+    print(f"Running Ruff: ruff check {stub_dir} --fix-only")
+    subprocess.run([sys.executable, "-m", "ruff", "check", stub_dir, "--fix-only"])
 
 
 async def get_project_urls_from_pypi(project: str, session: aiohttp.ClientSession) -> dict[str, str]:
@@ -189,7 +184,7 @@ def add_pyright_exclusion(stub_dir: str) -> None:
 def main() -> None:
     parser = argparse.ArgumentParser(
         description="""Generate baseline stubs automatically for an installed pip package
-                       using stubgen. Also run Black, isort and Ruff. If the name of
+                       using stubgen. Also run Black and Ruff. If the name of
                        the project is different from the runtime Python package name, you may
                        need to use --package (example: --package yaml PyYAML)."""
     )
@@ -239,7 +234,6 @@ def main() -> None:
     run_stubdefaulter(stub_dir)
 
     run_ruff(stub_dir)
-    run_isort(stub_dir)
     run_black(stub_dir)
 
     create_metadata(project, stub_dir, version)
diff --git a/scripts/runtests.py b/scripts/runtests.py
--- a/scripts/runtests.py
+++ b/scripts/runtests.py
@@ -83,9 +83,7 @@ def main() -> None:
 
     # Run formatters first. Order matters.
     print("\nRunning Ruff...")
-    subprocess.run([sys.executable, "-m", "ruff", path])
-    print("\nRunning isort...")
-    subprocess.run([sys.executable, "-m", "isort", path])
+    subprocess.run([sys.executable, "-m", "ruff", "check", path])
     print("\nRunning Black...")
     black_result = subprocess.run([sys.executable, "-m", "black", path])
     if black_result.returncode == 123:


Test patch:
diff --git a/tests/check_consistent.py b/tests/check_consistent.py
--- a/tests/check_consistent.py
+++ b/tests/check_consistent.py
@@ -23,7 +23,7 @@
 
 # These type checkers and linters must have exact versions in the requirements file to ensure
 # consistent CI runs.
-linters = {"black", "flake8", "flake8-bugbear", "flake8-noqa", "flake8-pyi", "isort", "ruff", "mypy", "pytype"}
+linters = {"black", "flake8", "flake8-bugbear", "flake8-noqa", "flake8-pyi", "ruff", "mypy", "pytype"}
 
 
 def assert_consistent_filetypes(
Repository: google/mobly

Issue:
Snippet client is unable to make connection on mac
Because the convoluted timeout scheme of JsonRpcClientBase.connect.



Discussion:

Resolving patch:
diff --git a/mobly/controllers/android_device_lib/jsonrpc_client_base.py b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
--- a/mobly/controllers/android_device_lib/jsonrpc_client_base.py
+++ b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
@@ -176,14 +176,13 @@ def start_app(self, wait_time=APP_START_WAIT_TIME):
             '%s failed to start on %s.' % (self.app_name, self._adb.serial))
 
     def connect(self, port, addr='localhost', uid=UNKNOWN_UID,
-                connection_timeout=None, cmd=JsonRpcCommand.INIT):
-        """
-        Opens a connection to the remote client.
+                cmd=JsonRpcCommand.INIT):
+        """Opens a connection to a JSON RPC server.
 
-        Opens a connection to a remote client. The connection will error out if
-        it takes longer than the connection_timeout time. Once connected if the
-        socket takes longer than _SOCKET_TIMEOUT to respond the connection will
-        be closed.
+        Opens a connection to a remote client. The connection attempt will time
+        out if it takes longer than _SOCKET_TIMEOUT seconds. Each subsequent
+        operation over this socket will time out after _SOCKET_TIMEOUT seconds
+        as well.
 
         Args:
             port: int, The port this client should connect to.
@@ -199,28 +198,14 @@ def connect(self, port, addr='localhost', uid=UNKNOWN_UID,
             socket.timeout: Raised when the socket waits to long for connection.
             ProtocolError: Raised when there is an error in the protocol.
         """
-        if connection_timeout:
-            timeout_time = time.time() + connection_timeout
-        else:
-            timeout_time = sys.maxsize
         self._counter = self._id_counter()
-        while True:
-            try:
-                self._conn = socket.create_connection(
-                    (addr, port), max(1, timeout_time - time.time()))
-                self._conn.settimeout(_SOCKET_TIMEOUT)
-                break
-            except socket.timeout:
-                logging.exception("Failed to create socket connection!")
-                raise
-            except (socket.error, IOError):
-                # TODO: optimize to only forgive some errors here
-                # error values are OS-specific so this will require
-                # additional tuning to fail faster
-                if time.time() + 1 >= timeout_time:
-                    logging.exception("Failed to create socket connection!")
-                    raise
-                time.sleep(1)
+        try:
+            self._conn = socket.create_connection((addr, port),
+                                                  _SOCKET_TIMEOUT)
+            self._conn.settimeout(_SOCKET_TIMEOUT)
+        except (socket.timeout, socket.error, IOError):
+            logging.exception("Failed to create socket connection!")
+            raise
         self.port = port
         self._client = self._conn.makefile(mode="brw")
 


Test patch:
Repository: google/mobly

Issue:
sl4a_client attempts to close the same SL4A session twice
This causes a stacktrace to be printed every time the user exists sl4a_client.

>>> ^D
Traceback (most recent call last):
  File "/usr/local/bin/sl4a_shell.py", line 8, in <module>
    execfile(__file__)
  File "/Users/angli/Developer/mobly/tools/sl4a_shell.py", line 66, in <module>
    Sl4aShell().main(args.serial)
  File "/Users/angli/Developer/mobly/mobly/controllers/android_device_lib/jsonrpc_shell_base.py", line 86, in main
    self.start_console()
  File "/Users/angli/Developer/mobly/mobly/controllers/android_device_lib/jsonrpc_shell_base.py", line 78, in start_console
    self._ad.stop_services()
  File "/Users/angli/Developer/mobly/mobly/controllers/android_device.py", line 415, in stop_services
    self._terminate_sl4a()
  File "/Users/angli/Developer/mobly/mobly/controllers/android_device.py", line 721, in _terminate_sl4a
    self._terminate_jsonrpc_client(self.sl4a)
  File "/Users/angli/Developer/mobly/mobly/controllers/android_device.py", line 574, in _terminate_jsonrpc_client
    client.closeSl4aSession()
  File "/Users/angli/Developer/mobly/mobly/controllers/android_device_lib/jsonrpc_client_base.py", line 277, in rpc_call
    return self._rpc(name, *args)
  File "/Users/angli/Developer/mobly/mobly/controllers/android_device_lib/jsonrpc_client_base.py", line 266, in _rpc
    raise ProtocolError(ProtocolError.NO_RESPONSE_FROM_SERVER)
mobly.controllers.android_device_lib.jsonrpc_client_base.ProtocolError: No response from server.


Discussion:

Resolving patch:
diff --git a/mobly/controllers/android_device.py b/mobly/controllers/android_device.py
--- a/mobly/controllers/android_device.py
+++ b/mobly/controllers/android_device.py
@@ -712,14 +712,11 @@ def _terminate_sl4a(self):
         the session. Clear corresponding droids and dispatchers from cache.
         """
         if self.sl4a:
-            self.sl4a.closeSl4aSession()
-            self.sl4a.close()
+            self._terminate_jsonrpc_client(self.sl4a)
+            self.sl4a = None
         if self.ed:
             self.ed.clean_up()
             self.ed = None
-        if self.sl4a:
-            self._terminate_jsonrpc_client(self.sl4a)
-            self.sl4a = None
 
     def run_iperf_client(self, server_host, extra_args=""):
         """Start iperf client on the device.


Test patch:
Repository: google/mobly

Issue:
ad.is_rootable fails to identify the build properly if adb server isn't running already
There is an edge case where `ad.is_rootable` incorrectly returns 'True', in which case we issue `adb root` call, causing some NBU devices to stop responding to adb commands.

The edge case is: adb server is not running prior to starting the test.
In this situation, the following steps occur:

1. Starting the test
2. `AndroidDevice` controller obj issues adb call to determine build type
3. adb server gets started, printing extra strings to stdout
4. is_rootable tries to match the string 'user' to the stdout, which evaluates to 'False' due to the extra output.
5. The user build device is deemed 'rootable'.

Sample output from such a case:
```
# Beginning of the test
$ adb -s <serial> shell getprop ro.build.type
# Results in the following stdout:
# * daemon not running. starting it now on port 5037 *
# * daemon started successfully *
# user^M
```

`ad.adb.getprop` is the first adb call made during the lifecycle of an `AndroidDevice` obj, so it's critical to handle this check correctly.
Other adb-based check may also fail if adb server somehow gets restarted and stdout is polluted. As a less urgent item, we should consider making checks based on adb's stdout more robust.


Discussion:

Resolving patch:
diff --git a/mobly/controllers/android_device.py b/mobly/controllers/android_device.py
--- a/mobly/controllers/android_device.py
+++ b/mobly/controllers/android_device.py
@@ -463,8 +463,15 @@ def is_adb_root(self):
 
     @property
     def is_rootable(self):
-        build_type = self.adb.getprop("ro.build.type").lower()
-        return build_type != 'user'
+        """If the build type is 'user', the device is not rootable.
+
+        Other possible build types are 'userdebug' and 'eng', both are rootable.
+        We are checking the last four chars of the clean stdout because the
+        stdout of the adb command could be polluted with other info like adb
+        server startup message.
+        """
+        build_type_output = self.adb.getprop("ro.build.type").lower()
+        return build_type_output[-4:] != 'user'
 
     @property
     def model(self):


Test patch:
diff --git a/tests/lib/mock_android_device.py b/tests/lib/mock_android_device.py
--- a/tests/lib/mock_android_device.py
+++ b/tests/lib/mock_android_device.py
@@ -75,8 +75,6 @@ def getprop(self, params):
             return "FakeModel"
         elif params == "sys.boot_completed":
             return "1"
-        elif params == "ro.build.type":
-            return "userdebug"
 
     def bugreport(self, params):
         expected = os.path.join(logging.log_path,
Repository: google/mobly

Issue:
Refresh adb connection to a device at the end of AndroidDevice teardown.
Execute `adb -s <serial> reconnect` at the end of AndroidDevice controller object cleanup.

It has several benefits:
1. Kills any lingering adb processes/cmds that the test may have started and does not clean up properly.
2. Releases all forwarded adb ports.
3. Recovers unresponsive devices in some cases. Some devices may stop responding to all adb commands due to adb calls made by tests, leaving the device in an unusable state. Refreshing adb connection fixes the problem.

Overall this seems to be a good approach since it can clears any baggage a test may have left with adb and makes the execution cleaner.
The command does not affect other devices connected to the same host.


Discussion:

Resolving patch:
diff --git a/mobly/controllers/android_device.py b/mobly/controllers/android_device.py
--- a/mobly/controllers/android_device.py
+++ b/mobly/controllers/android_device.py
@@ -98,6 +98,10 @@ def destroy(ads):
     for ad in ads:
         try:
             ad.stop_services()
+            # Refresh the adb connection to this device so we don't have any
+            # adb processes/ports started by the test lingering on after test
+            # stops. It also recovers unresponsive devices in some cases.
+            ad.adb.reconnect()
         except:
             ad.log.exception("Failed to clean up properly.")
 


Test patch:
Repository: google/mobly

Issue:
Properly handle snippet in ad.reboot
Right now AndroidDevice.reboot does not restore any snippet.
It should reload the snippet loaded before reboot and make their aliases available.


Discussion:

Resolving patch:
diff --git a/mobly/controllers/android_device.py b/mobly/controllers/android_device.py
--- a/mobly/controllers/android_device.py
+++ b/mobly/controllers/android_device.py
@@ -795,6 +795,22 @@ def wait_for_boot_completion(self):
             time.sleep(5)
         raise Error('Device %s booting process timed out.' % self.serial)
 
+    def _get_active_snippet_info(self):
+        """Collects information on currently active snippet clients.
+
+        The info is used for restoring the snippet clients after rebooting the
+        device.
+
+        Returns:
+            A list of tuples, each tuple's first element is the name of the
+            snippet client's attribute, the second element is the package name
+            of the snippet.
+        """
+        snippet_info = []
+        for attr_name, client in self._snippet_clients.items():
+            snippet_info.append((attr_name, client.package))
+        return snippet_info
+
     def reboot(self):
         """Reboots the device.
 
@@ -812,12 +828,16 @@ def reboot(self):
         if self.is_bootloader:
             self.fastboot.reboot()
             return
+        snippet_info = self._get_active_snippet_info()
         self.stop_services()
         self.adb.reboot()
         self.wait_for_boot_completion()
         if self.is_rootable:
             self.root_adb()
-        self.start_services(skip_sl4a=getattr(self, KEY_SKIP_SL4A, False))
+        skip_sl4a = getattr(self, KEY_SKIP_SL4A, False) or self.sl4a is None
+        self.start_services(skip_sl4a=skip_sl4a)
+        for attr_name, package_name in snippet_info:
+            self.load_snippet(attr_name, package_name)
 
 
 class AndroidDeviceLoggerAdapter(logging.LoggerAdapter):


Test patch:
Repository: google/mobly

Issue:
logging.exception("Failed to create socket connection!") results in double stracktrace
In jsonrpc_client_base:

        try:
            self._conn = socket.create_connection(('127.0.0.1', self.host_port),
                                                  _SOCKET_TIMEOUT)
            self._conn.settimeout(_SOCKET_TIMEOUT)
        except (socket.timeout, socket.error, IOError):
            logging.exception("Failed to create socket connection!")
            raise

Would result in the trace being printed twice.


Discussion:

Resolving patch:
diff --git a/mobly/controllers/android_device_lib/jsonrpc_client_base.py b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
--- a/mobly/controllers/android_device_lib/jsonrpc_client_base.py
+++ b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
@@ -39,7 +39,6 @@
 from builtins import str
 
 import json
-import logging
 import socket
 import threading
 import time
@@ -193,13 +192,9 @@ def connect(self, uid=UNKNOWN_UID, cmd=JsonRpcCommand.INIT):
             ProtocolError: Raised when there is an error in the protocol.
         """
         self._counter = self._id_counter()
-        try:
-            self._conn = socket.create_connection(('127.0.0.1', self.host_port),
-                                                  _SOCKET_TIMEOUT)
-            self._conn.settimeout(_SOCKET_TIMEOUT)
-        except (socket.timeout, socket.error, IOError):
-            logging.exception("Failed to create socket connection!")
-            raise
+        self._conn = socket.create_connection(('127.0.0.1', self.host_port),
+                                              _SOCKET_TIMEOUT)
+        self._conn.settimeout(_SOCKET_TIMEOUT)
         self._client = self._conn.makefile(mode="brw")
 
         resp = self._cmd(cmd, uid)


Test patch:
Repository: google/mobly

Issue:
Race condition in JsonRpcClientBase._rpc
If the test spawns additional thread that use the rpc client, the following race case could happen:

> client thread 1: sock.write 1
> client thread 2: sock.write 2
> server side: 2 finished before 1
> client thread 1: sock.read 2 
> client thread 2: sock.read 1


Discussion:

Resolving patch:
diff --git a/mobly/controllers/android_device_lib/jsonrpc_client_base.py b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
--- a/mobly/controllers/android_device_lib/jsonrpc_client_base.py
+++ b/mobly/controllers/android_device_lib/jsonrpc_client_base.py
@@ -258,11 +258,11 @@ def _rpc(self, method, *args):
         """
         with self._lock:
             apiid = next(self._counter)
-        data = {'id': apiid, 'method': method, 'params': args}
-        request = json.dumps(data)
-        self._client.write(request.encode("utf8") + b'\n')
-        self._client.flush()
-        response = self._client.readline()
+            data = {'id': apiid, 'method': method, 'params': args}
+            request = json.dumps(data)
+            self._client.write(request.encode("utf8") + b'\n')
+            self._client.flush()
+            response = self._client.readline()
         if not response:
             raise ProtocolError(ProtocolError.NO_RESPONSE_FROM_SERVER)
         result = json.loads(str(response, encoding="utf8"))


Test patch:
Repository: google/mobly

Issue:
logcat is empty for some NBU devices
When starting adb logcat, we use `-b all` to catch all buffers.

But some NBU devices (like HTC Desire 526g+) don't have the buffer option "all", and their adb logcat would only have one line saying "Unable to open log device '/dev/log/all': No such file or directory".

We need to handle this properly so we get the logs from the buffers the device does have, like 'main', 'system', 'radio', and 'events'.


Discussion:
Can you override with "adb_logcat_param" in the config?

Resolving patch:
diff --git a/mobly/controllers/android_device.py b/mobly/controllers/android_device.py
--- a/mobly/controllers/android_device.py
+++ b/mobly/controllers/android_device.py
@@ -759,11 +759,11 @@ def start_adb_logcat(self):
         try:
             extra_params = self.adb_logcat_param
         except AttributeError:
-            extra_params = '-b all'
+            extra_params = ''
         cmd = 'adb -s %s logcat -v threadtime %s >> %s' % (
             self.serial, extra_params, logcat_file_path)
-        self._adb_logcat_process = utils.start_standing_subprocess(
-            cmd, shell=True)
+        process = utils.start_standing_subprocess(cmd, shell=True)
+        self._adb_logcat_process = process
         self.adb_logcat_file_path = logcat_file_path
 
     def stop_adb_logcat(self):


Test patch:
diff --git a/tests/mobly/controllers/android_device_test.py b/tests/mobly/controllers/android_device_test.py
--- a/tests/mobly/controllers/android_device_test.py
+++ b/tests/mobly/controllers/android_device_test.py
@@ -280,7 +280,7 @@ def test_AndroidDevice_take_logcat(self, stop_proc_mock, start_proc_mock,
                                          "AndroidDevice%s" % ad.serial,
                                          "adblog,fakemodel,%s.txt" % ad.serial)
         creat_dir_mock.assert_called_with(os.path.dirname(expected_log_path))
-        adb_cmd = 'adb -s %s logcat -v threadtime -b all >> %s'
+        adb_cmd = 'adb -s %s logcat -v threadtime  >> %s'
         start_proc_mock.assert_called_with(
               adb_cmd % (ad.serial, expected_log_path), shell=True)
         self.assertEqual(ad.adb_logcat_file_path, expected_log_path)
Repository: google/mobly

Issue:
Exceptions from `CallbackHandler` should include timeout value
Right now some timeout exceptions thrown by `CallbackHandler` do not include how long the timeout was, making debugging more difficult.


Discussion:

Resolving patch:
diff --git a/mobly/controllers/android_device_lib/callback_handler.py b/mobly/controllers/android_device_lib/callback_handler.py
--- a/mobly/controllers/android_device_lib/callback_handler.py
+++ b/mobly/controllers/android_device_lib/callback_handler.py
@@ -83,13 +83,14 @@ def waitAndGet(self, event_name, timeout=DEFAULT_TIMEOUT):
                     (timeout, MAX_TIMEOUT))
             timeout *= 1000  # convert to milliseconds for java side
         try:
-            raw_event = self._event_client.eventWaitAndGet(self._id,
-                                                           event_name, timeout)
+            raw_event = self._event_client.eventWaitAndGet(
+                self._id, event_name, timeout)
         except Exception as e:
             if 'EventSnippetException: timeout.' in str(e):
                 raise TimeoutError(
-                    'Timeout waiting for event "%s" triggered by %s (%s).' %
-                    (event_name, self._method_name, self._id))
+                    'Timed out after waiting %ss for event "%s" triggered by'
+                    ' %s (%s).' % (timeout, event_name, self._method_name,
+                                   self._id))
             raise
         return snippet_event.from_dict(raw_event)
 


Test patch:
diff --git a/tests/mobly/controllers/android_device_lib/callback_handler_test.py b/tests/mobly/controllers/android_device_lib/callback_handler_test.py
--- a/tests/mobly/controllers/android_device_lib/callback_handler_test.py
+++ b/tests/mobly/controllers/android_device_lib/callback_handler_test.py
@@ -34,6 +34,7 @@
 class CallbackHandlerTest(unittest.TestCase):
     """Unit tests for mobly.controllers.android_device_lib.callback_handler.
     """
+
     def test_timeout_value(self):
         self.assertGreaterEqual(jsonrpc_client_base._SOCKET_READ_TIMEOUT,
                                 callback_handler.MAX_TIMEOUT)
@@ -64,9 +65,9 @@ def test_wait_and_get_timeout(self):
             event_client=mock_event_client,
             ret_value=None,
             method_name=None)
-        expected_msg = 'Timeout waiting for event "ha" .*'
+        expected_msg = 'Timed out after waiting .*s for event "ha" .*'
         with self.assertRaisesRegex(callback_handler.TimeoutError,
-                                     expected_msg):
+                                    expected_msg):
             handler.waitAndGet('ha')
 
     def test_wait_for_event(self):
@@ -101,7 +102,7 @@ def some_condition(event):
             return False
 
         with self.assertRaisesRegex(callback_handler.TimeoutError,
-                                     expected_msg):
+                                    expected_msg):
             handler.waitForEvent('AsyncTaskResult', some_condition, 0.01)