internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: pymodbus-dev/pymodbus

Issue:
pymodbus.server does not start with its default parameters
<!--

Before opening a new issue, make sure you do the following:
    * check that your issue isn't already filed: https://github.com/pymodbus-dev/pymodbus/issues
    * check the discussions forum https://github.com/pymodbus-dev/pymodbus/discussions
    * prepare a short, runnable example that reproduce the issue with the latest development version of Pymodbus

    Before opening a new issue, make sure you do the following
-->

### Versions

* Python: 3.10.9
* OS: Fedora 36
* Pymodbus: 3.1.3

### Description

- starting "pymodbus.server run" fails, but starting it with "pymodbus.server run -s tcp" works ("-s tcp" should not be needed, it is the default)
- might be related to #1118 and #1139 
- it looks like that in https://github.com/pymodbus-dev/pymodbus/blob/dev/pymodbus/repl/server/main.py#L124 there is a mismatch between the expected type for that option ("str") and the used default parameter (the enum  ModbusServerTypes.tcp (which evaluates to "ModbusServerTypes.tcp" in a string context))




### Code and Logs
```
$ pymodbus.server run
20:21:10 ERROR logging:92 Invalid server ModbusServerTypes.tcp
$
$ pymodbus.server run -s tcp

__________                          .______.                    _________
\______   \___.__. _____   ____   __| _/\_ |__  __ __  ______  /   _____/ ______________  __ ___________
 |     ___<   |  |/     \ /  _ \ / __ |  | __ \|  |  \/  ___/  \_____  \_/ __ \_  __ \  \/ // __ \_  __ \\
 |    |    \___  |  Y Y  (  <_> ) /_/ |  | \_\ \  |  /\___ \   /        \  ___/|  | \/\   /\  ___/|  | \/
 |____|    / ____|__|_|  /\____/\____ |  |___  /____//____  > /_______  /\___  >__|    \_/  \___  >__|
           \/          \/            \/      \/           \/          \/     \/                 \/


SERVER >
```



Discussion:
This looks a lot like a bug, thanks for reporting it.

@dhoomakethu  can you please take a look ?


Resolving patch:
diff --git a/pymodbus/repl/server/main.py b/pymodbus/repl/server/main.py
--- a/pymodbus/repl/server/main.py
+++ b/pymodbus/repl/server/main.py
@@ -121,7 +121,7 @@ def server(
 def run(
     ctx: typer.Context,
     modbus_server: str = typer.Option(
-        ModbusServerTypes.tcp,
+        ModbusServerTypes.tcp.value,
         "--modbus-server",
         "-s",
         case_sensitive=False,
@@ -129,7 +129,7 @@ def run(
         help="Modbus Server",
     ),
     modbus_framer: str = typer.Option(
-        ModbusFramerTypes.socket,
+        ModbusFramerTypes.socket.value,
         "--framer",
         "-f",
         case_sensitive=False,


Test patch:
Repository: pymodbus-dev/pymodbus

Issue:
pip show pymodbus, misses information.
```
pymodbus) pymodbus %  pip show pymodbus

Name: pymodbus
Version: 3.1.x
Summary: A fully featured modbus protocol stack in python
Home-page: https://github.com/pymodbus-dev/pymodbus/
Author: attr: pymodbus.__author__
Author-email: 
License: BSD-3-Clause
Location: /Users/jan/repos/pymodbus
Editable project location: /Users/jan/repos/pymodbus
Requires: setuptools
Required-by: 
```
Normally it gets the information from setup.cfg, but for some reason it does not work with "pip show".


Discussion:
`setuptools` apparently does not allow the use of `attr:`  for `author` or `maintainer`.

https://setuptools.pypa.io/en/latest/userguide/declarative_config.html#metadata.

I suggest moving them as strings directly into `setup.cfg`
Sounds like a good idea, thanks for investigating.

Resolving patch:
diff --git a/pymodbus/__init__.py b/pymodbus/__init__.py
--- a/pymodbus/__init__.py
+++ b/pymodbus/__init__.py
@@ -10,7 +10,7 @@
 
 
 __version__ = __version.version.short()
-__author__ = "Galen Collins"
+__author__ = "Galen Collins, Jan Iversen"
 __maintainer__ = "dhoomakethu, janiversen"
 
 


Test patch:
Repository: pymodbus-dev/pymodbus

Issue:
py.typed missing in pip install

### Versions

- Python: 3.11
- OS: macOS
- Pymodbus: 3.2.0 (pip install)
- Modbus Hardware (if used):

### Description

running mypy on my project complains about missing 

```
artisanlib/modbusport.py:68: error: Skipping analyzing "pymodbus.constants": module is installed, but missing library stubs or py.typed marker  [import]
artisanlib/modbusport.py:69: error: Skipping analyzing "pymodbus.payload": module is installed, but missing library stubs or py.typed marker  [import]
artisanlib/modbusport.py:241: error: Skipping analyzing "pymodbus.client": module is installed, but missing library stubs or py.typed marker  [import]
artisanlib/modbusport.py:385: error: Skipping analyzing "pymodbus.pdu": module is installed, but missing library stubs or py.typed marker  [import]
```

despite all your nice work on adding type annotations. The file py.typed id not get installed along via

```
# sudo -H python3 -m pip install pymodbus --upgrade
```

```
# cd /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/pymodbus
# ls ./py.typed
ls: ./py.typed: No such file or directory
```

I added it as follows and the mypy errors went away.

```
# cd /Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/pymodbus
# sudo touch py.typed
```


Discussion:
@alexrudd2 this one is for you.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -30,4 +30,5 @@
 setup(
     install_requires=install_req,
     extras_require=dependencies,
+    package_data={"pymodbus": ["py.typed"]},
 )


Test patch:
Repository: pymodbus-dev/pymodbus

Issue:
REPL server needs CTRL+C twice to exit
- Python: 3.11
- OS: MacOS
- Pymodbus: 9f66ab52bb98931dc260b65275ba3b77bb5122c8

REPL server needs to be exited twice; non-REPL server exits fine.  I think this was introduced in https://github.com/pymodbus-dev/pymodbus/pull/1141/commits/c395566ff697ad5087f83764a25af03b717ceb65.  
https://github.com/pymodbus-dev/pymodbus/blob/9f66ab52bb98931dc260b65275ba3b77bb5122c8/pymodbus/repl/server/main.py#L207-L208

```
❯ pymodbus.server run --modbus-server tcp --framer socket --slave-id 1 --slave-id 4 --random 2

__________                          .______.                    _________
\______   \___.__. _____   ____   __| _/\_ |__  __ __  ______  /   _____/ ______________  __ ___________
 |     ___<   |  |/     \ /  _ \ / __ |  | __ \|  |  \/  ___/  \_____  \_/ __ \_  __ \  \/ // __ \_  __ \\
 |    |    \___  |  Y Y  (  <_> ) /_/ |  | \_\ \  |  /\___ \   /        \  ___/|  | \/\   /\  ___/|  | \/
 |____|    / ____|__|_|  /\____/\____ |  |___  /____//____  > /_______  /\___  >__|    \_/  \___  >__|
           \/          \/            \/      \/           \/          \/     \/                 \/


SERVER >
```
Enter `CTRL+C`  (or type `exit`)
`Bye Bye!!!` 
Enter `CTRL+C` again to actually exit

```
^C
Aborted.
```

The non-REPL server exits correctly on a single CTRL+C:
```
❯ pymodbus.server --no-repl --verbose run  --modbus-server tcp --framer socket --slave-id 1 --slave-id 4 --random 2 --modbus-port 5020
2023-04-18 00:05:52,276 INFO  logging:96 Modbus server started

Reactive Modbus Server started.
======== Running on http://localhost:8080 ========

===========================================================================
Example Usage:
curl -X POST http://localhost:8080 -d "{"response_type": "error", "error_code": 4}"
===========================================================================

2023-04-18 00:05:52,279 INFO  logging:96 Server(TCP) listening.
^C
Aborted.
```

Also, there's a useless try/except block that never gets called.
https://github.com/pymodbus-dev/pymodbus/blob/dev/pymodbus/repl/server/main.py#L207-L208



Discussion:

Resolving patch:
diff --git a/pymodbus/repl/server/main.py b/pymodbus/repl/server/main.py
--- a/pymodbus/repl/server/main.py
+++ b/pymodbus/repl/server/main.py
@@ -198,15 +198,12 @@ def run(
         **web_app_config,
         **modbus_config,
     )
-    try:
+    if repl:
+        loop.run_until_complete(run_repl(app))
+    else:
         loop.run_until_complete(app.run_async(repl))
-        if repl:
-            loop.run_until_complete(run_repl(app))
         loop.run_forever()
 
-    except CANCELLED_ERROR:
-        print("Done!!!!!")
-
 
 if __name__ == "__main__":
     app()


Test patch:
Repository: pymodbus-dev/pymodbus

Issue:
New mypy error with asyncio.Task
```
❯ git checkout 67d875b785d4f79da7b76413ae62ad71a1259fc3
Note: switching to '67d875b785d4f79da7b76413ae62ad71a1259fc3'.
❯ python3.11 -m mypy pymodbus
Success: no issues found in 58 source files
❯ git checkout dev
Previous HEAD position was 67d875b7 Solve serial close raise problem.
Switched to branch 'dev'
Your branch is up to date with 'upstream/dev'.

❯ python3.11 -m mypy pymodbus
pymodbus/client/base.py:267: error: Statement is unreachable  [unreachable]
pymodbus/client/base.py:274: error: Incompatible types in assignment (expression has type "Task[Any]", variable has type "None")  [assignment]
Found 2 errors in 1 file (checked 60 source files)

❯ python3.8 -m mypy pymodbus
Success: no issues found in 60 source files
```

It appears that Python3.11 `mypy` catches this, but Python3.8 does not (which is why the CI didn't flag it).  My guess is that `asyncio` has improved its type definitions.  Anyways, it's an easy fix with a hint; I'll prepare a PR.


Discussion:

Resolving patch:
diff --git a/pymodbus/client/base.py b/pymodbus/client/base.py
--- a/pymodbus/client/base.py
+++ b/pymodbus/client/base.py
@@ -119,7 +119,7 @@ def __init__(  # pylint: disable=too-many-arguments
         self.state = ModbusTransactionState.IDLE
         self.last_frame_end: float = 0
         self.silent_interval: float = 0
-        self._reconnect_task = None
+        self._reconnect_task: asyncio.Task = None
 
         # Initialize  mixin
         ModbusClientMixin.__init__(self)


Test patch:
Repository: pymodbus-dev/pymodbus

Issue:
REPL client help is missing some commands
The help for the REPL client is missing some commands from `help`, and instead has `client.{c[0]}`.

```
pymodbus.console tcp
❯ pymodbus.console tcp

----------------------------------------------------------------------------
__________          _____             .___  __________              .__
\______   \___.__. /     \   ____   __| _/  \______   \ ____ ______ |  |
 |     ___<   |  |/  \ /  \ /  _ \ / __ |    |       _// __ \\\____ \|  |
 |    |    \___  /    Y    (  <_> ) /_/ |    |    |   \  ___/|  |_> >  |__
 |____|    / ____\____|__  /\____/\____ | /\ |____|_  /\___  >   __/|____/
           \/            \/            \/ \/        \/     \/|__|
                                        v1.3.0 - 3.5.0dev
----------------------------------------------------------------------------

> help
Available commands:
<...>
client.{c[0]}
```

This was caught by a `ruff` rule.
> RUF011 Dictionary comprehension uses static key: `"client.{c[0]}"`



Discussion:

Resolving patch:
diff --git a/pymodbus/repl/client/helper.py b/pymodbus/repl/client/helper.py
--- a/pymodbus/repl/client/helper.py
+++ b/pymodbus/repl/client/helper.py
@@ -179,8 +179,8 @@ def _get_client_methods(members):
         filter(lambda x: (x[0] not in EXCLUDE and x[0] in CLIENT_METHODS), members)
     )
     commands = {
-        "client.{c[0]}": Command(
-            "client.{c[0]}", argspec(c[1]), inspect.getdoc(c[1]), slave=False
+        f"client.{c[0]}": Command(
+            f"client.{c[0]}", argspec(c[1]), inspect.getdoc(c[1]), slave=False
         )
         for c in commands
         if not c[0].startswith("_")


Test patch:
Repository: pymodbus-dev/pymodbus

Issue:
AsyncModbusTcpClient can't connect to non-local server (pymodbus 3.4.0)
The `source_address` parameter of `AsyncModbusTcpClient.__init__()` is not passed to `ModbusBaseClient.__init__()`, so the default `("127.0.0.1", 0)` is used, which causes an `Invalid argument` error when connecting to a non-local Modbus server.

- Python: 3.10.9
- OS: Ubuntu 22.04.2 LTS
- Pymodbus: 3.4.0



Discussion:
Yes solved on dev, and we will release 3.4.1 very soon.

Resolving patch:
diff --git a/pymodbus/client/tcp.py b/pymodbus/client/tcp.py
--- a/pymodbus/client/tcp.py
+++ b/pymodbus/client/tcp.py
@@ -47,6 +47,8 @@ def __init__(
         asyncio.Protocol.__init__(self)
         if "CommType" not in kwargs:
             kwargs["CommType"] = CommType.TCP
+        if source_address:
+            kwargs["source_address"] = source_address
         ModbusBaseClient.__init__(
             self,
             framer=framer,
diff --git a/pymodbus/transport/transport.py b/pymodbus/transport/transport.py
--- a/pymodbus/transport/transport.py
+++ b/pymodbus/transport/transport.py
@@ -37,7 +37,7 @@ class CommParams:
     timeout_connect: float = None
     host: str = "127.0.0.1"
     port: int = 0
-    source_address: tuple[str, int] = ("127.0.0.1", 0)
+    source_address: tuple[str, int] = ("0.0.0.0", 0)
     handle_local_echo: bool = False
 
     # tls


Test patch:
Repository: pymodbus-dev/pymodbus

Issue:
Empty result in REPL
The documentation says that I should have a value in the `result` variable after successful running a command, which does not holds True.

```
➜ pymodbus.console tcp --host 0.0.0.0 --port 5020

----------------------------------------------------------------------------
__________          _____             .___  __________              .__
\______   \___.__. /     \   ____   __| _/  \______   \ ____ ______ |  |
 |     ___<   |  |/  \ /  \ /  _ \ / __ |    |       _// __ \\\____ \|  |
 |    |    \___  /    Y    (  <_> ) /_/ |    |    |   \  ___/|  |_> >  |__
 |____|    / ____\____|__  /\____/\____ | /\ |____|_  /\___  >   __/|____/
           \/            \/            \/ \/        \/     \/|__|
                                        v1.3.0 - 3.4.1
----------------------------------------------------------------------------

> client.connect
true

> client.read_holding_registers count=2 address=4 slave=1
{
    "registers": [
        9,
        27177
    ]
}

> result.data
> result.raw
```



Discussion:
@dhoomakethu you are the local specialist, any comments ?

@raphapassini which version of pymodbus are you using, on what system ?
I will take a look the coming week, may be something has changed in the latest version. Thanks
I just verified the problem on current dev, seems result is not assigned.

The result of the request is correctly shown in the display, but result is empty.
you cannot run "result.decode" without parameters:

from documentation:
```
> result.decode word_order=little byte_order=little formatters=float64
28.17

>
```



Resolving patch:
diff --git a/pymodbus/repl/client/main.py b/pymodbus/repl/client/main.py
--- a/pymodbus/repl/client/main.py
+++ b/pymodbus/repl/client/main.py
@@ -197,7 +197,7 @@ def _print_command_help(self, commands):
                     )
                 )
 
-    def _process_client(self, text, client):
+    def _process_client(self, text, client) -> Result:
         """Process client commands."""
         text = text.strip().split()
         cmd = text[0].split(".")[1]
@@ -209,6 +209,7 @@ def _process_client(self, text, client):
             else:
                 result = Result(getattr(client, cmd)(**kwargs))
             result.print_result()
+        return result
 
     def _process_result(self, text, result):
         """Process result commands."""
@@ -233,7 +234,7 @@ def run(self):
                 elif text.strip().lower() == "exit":
                     raise EOFError()
                 elif text.strip().lower().startswith("client."):
-                    self._process_client(text, self.client)
+                    result = self._process_client(text, self.client)
                 elif text.strip().lower().startswith("result.") and result:
                     self._process_result(text, result)
             except KeyboardInterrupt:


Test patch:
Repository: pymodbus-dev/pymodbus

Issue:
Invalid `stopbits=0` for serial connection
In the following [docstring](https://github.com/pymodbus-dev/pymodbus/blob/8d3e36fe78ed5ec8bcf94b024df1125ee2b1f015/pymodbus/client/serial.py#L121) valid values for stop bits is 0-2:
```
:param stopbits: Number of stop bits 0-2.
```
Is this a typo? I don't think you can have a serial connection without stop bits. Also I don't think the underlying serial library [`pyserial`](https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.STOPBITS_ONE) supports no stop bits !
```
Stop bits

serial.STOPBITS_ONE
serial.STOPBITS_ONE_POINT_FIVE
serial.STOPBITS_TWO
```
I tried setting `stopbits=0` and got the following **expected** error:
```
ValueError: Not a valid stop bit size: 0
```

I propose if this needs to be fixed, instead of changing `0-2` to `1-2`, it is better to have explicit valid values like `1, 1.5, 2`.


Discussion:

Resolving patch:
diff --git a/pymodbus/client/serial.py b/pymodbus/client/serial.py
--- a/pymodbus/client/serial.py
+++ b/pymodbus/client/serial.py
@@ -34,7 +34,7 @@ class AsyncModbusSerialClient(ModbusBaseClient, asyncio.Protocol):
     :param baudrate: Bits per second.
     :param bytesize: Number of bits per byte 7-8.
     :param parity: 'E'ven, 'O'dd or 'N'one
-    :param stopbits: Number of stop bits 0-2.
+    :param stopbits: Number of stop bits 1, 1.5, 2.
     :param handle_local_echo: Discard local echo from dongle.
 
     Common optional parameters:


Test patch:
Repository: pymodbus-dev/pymodbus

Issue:
Solve bytes return in base.py
Reminder for myself,

This should be changed to None or an empty ModbusResponse
line 163-165 in base.py

if self.broadcast_enable and not request.slave_id:
    resp = b"Broadcast write sent - no response expected"
    break
these are the lines in async_execute which cause there to be a bytes return
i declared async_execute as returning ModbusResponse to allow type: ignore to work on the return type. Otherwise mypy would complain a lot about this. I do not know why this code was accepted in the first place


Discussion:

Resolving patch:
diff --git a/pymodbus/client/base.py b/pymodbus/client/base.py
--- a/pymodbus/client/base.py
+++ b/pymodbus/client/base.py
@@ -161,7 +161,7 @@ async def async_execute(self, request=None) -> ModbusResponse:
             if not count or not self.no_resend_on_retry:
                 self.transport_send(packet)
             if self.broadcast_enable and not request.slave_id:
-                resp = b"Broadcast write sent - no response expected"
+                resp = None
                 break
             try:
                 resp = await asyncio.wait_for(


Test patch:
diff --git a/test/sub_client/test_client.py b/test/sub_client/test_client.py
--- a/test/sub_client/test_client.py
+++ b/test/sub_client/test_client.py
@@ -424,8 +424,7 @@ async def test_client_execute_broadcast():
     transport = MockTransport(base, request)
     base.connection_made(transport=transport)
 
-    response = await base.async_execute(request)
-    assert  response == b'Broadcast write sent - no response expected'
+    assert not await base.async_execute(request)
 
 async def test_client_protocol_retry():
     """Test the client protocol execute method with retries."""
Repository: pymodbus-dev/pymodbus

Issue:
ModbusException 0x07 is missing in pdu.py
In pdu.py is ModbusException NegativeAcknowledge missing. Is it possible to add: NegativeAcknowledge  = 0x07 ?


class ModbusExceptions:  

    IllegalFunction = 0x01
    IllegalAddress = 0x02
    IllegalValue = 0x03
    SlaveFailure = 0x04
    Acknowledge = 0x05
    SlaveBusy = 0x06
    MemoryParityError = 0x08
    GatewayPathUnavailable = 0x0A
    GatewayNoResponse = 0x0B


Discussion:
Pull requests are welcome.

Resolving patch:
diff --git a/pymodbus/pdu.py b/pymodbus/pdu.py
--- a/pymodbus/pdu.py
+++ b/pymodbus/pdu.py
@@ -164,6 +164,7 @@ class ModbusExceptions:  # pylint: disable=too-few-public-methods
     SlaveFailure = 0x04
     Acknowledge = 0x05
     SlaveBusy = 0x06
+    NegativeAcknowledge = 0x07
     MemoryParityError = 0x08
     GatewayPathUnavailable = 0x0A
     GatewayNoResponse = 0x0B


Test patch:
Repository: cognitedata/cognite-sdk-python

Issue:
TimeSeries isStep property is always false
TimeSeries.step should be TimeSeries.isStep? Unless it is converted somewhere - the API docs state isStep: 
https://doc.cognitedata.com/#schemaposttimeseriesv2dto




Discussion:

Resolving patch:
diff --git a/cognite/v05/depthseries.py b/cognite/v05/depthseries.py
--- a/cognite/v05/depthseries.py
+++ b/cognite/v05/depthseries.py
@@ -263,8 +263,8 @@ def _has_depth_index_changes(ds: TimeSeries) -> bool:
         ds.metadata is None
         and ds.assetId is None
         and ds.description is None
-        and ds.security_categories is None
-        and ds.step is None
+        and ds.securityCategories is None
+        and ds.isStep is None
     ):
         return False
     return True
diff --git a/cognite/v05/dto.py b/cognite/v05/dto.py
--- a/cognite/v05/dto.py
+++ b/cognite/v05/dto.py
@@ -268,13 +268,13 @@ class TimeSeries(object):
 
     Attributes:
         name (str):       Unique name of time series.
-        is_string (bool):    Whether the time series is string valued or not.
+        isString (bool):    Whether the time series is string valued or not.
         metadata (dict):    Metadata.
         unit (str):         Physical unit of the time series.
-        asset_id (str):     Asset that this time series belongs to.
+        assetId (str):     Asset that this time series belongs to.
         description (str):  Description of the time series.
         securityCategories (list(int)): Security categories required in order to access this time series.
-        step (bool):        Whether or not the time series is a step series.
+        isStep (bool):        Whether or not the time series is a step series.
 
     """
 
@@ -287,7 +287,7 @@ def __init__(
         asset_id=None,
         description=None,
         security_categories=None,
-        step=None,
+        is_step=None,
     ):
         self.name = name
         self.isString = is_string
@@ -295,8 +295,8 @@ def __init__(
         self.unit = unit
         self.assetId = asset_id
         self.description = description
-        self.security_categories = security_categories
-        self.step = step
+        self.securityCategories = security_categories
+        self.isStep = is_step
 
 
 class AssetListResponse(CogniteDataObject):


Test patch: