simplefix
simplefix copied to clipboard
Mismatch method call and method displayed.
I am using simplefix version 1.0.14. And it gives me error calling get with the nth parameter.
Traceback (most recent call last):
File "/usr/local/Cellar/[email protected]/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 954, in _bootstrap_inner
self.run()
File "/usr/local/Cellar/[email protected]/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 892, in run
self._target(*self._args, **self._kwargs)
File "/Users/recapital/Git/tt-fix/client.py", line 59, in run
self._reader.on_message(msg)
File "/Users/recapital/Git/tt-fix/message_handler.py", line 31, in on_message
self.handle_logon(message)
File "/Users/recapital/Git/tt-fix/message_handler.py", line 39, in handle_logon
logon.decode(message)
File "/Users/recapital/Git/tt-fix/tt_messages.py", line 9517, in decode
if (val := message.get(FIELD_ENCRYPT_METHOD, nth)) is not None:
TypeError: <lambda>() takes 1 positional argument but 2 were given
Here is the code called:
def decode(self, message: FixMessage, nth: int = 1):
if (val := message.get(FIELD_ENCRYPT_METHOD, nth)) is not None:
self.encrypt_method = EncryptMethod(int(val))
Here is the field constant:
FIELD_ENCRYPT_METHOD = b'98'
And here is the get method in simplefix:
def get(self, tag, nth=1):
"""Return n-th value for tag.
:param tag: FIX field tag number.
:param nth: Index of tag if repeating, first is 1.
:return: None if nothing found, otherwise value matching tag.
Defaults to returning the first matching value of 'tag', but if
the 'nth' parameter is overridden, can get repeated fields."""
tag = fix_tag(tag)
nth = int(nth)
for t, v in self.pairs:
if t == tag:
nth -= 1
if nth == 0:
return v
return None
It works if I don't pass the nth parameter, but providing this (that I have to due to repetitions) gives this weird error.
Message that I received before the decode error.
8=FIX.4.4|9=00080|35=A|49=NOTHING|56=CAPITALAS_MD|34=1|52=20210622-13:59:02.752|98=0|108=30|141=Y|10=085
That's curious. It appears as if message.get
is a lambda?
In your decode()
method, can you add a first line something like:
print(message.get, type(message.get))
In a quick test, mine shows:
<bound method FixMessage.get of <simplefix.message.FixMessage object at 0x10c72ddc0>> <class 'method'>
2021-06-24 15:52:07,803 INFO connection send: b'8=FIX.4.4|9=92|35=A|49=CAPITALAS_MD|56=NOTHING|34=1|98=0|108=30|96=12345678|141=Y|52=20210624-13:52:07.802|10=021|'
<function Connection._validate_message.<locals>.<lambda> at 0x10581d1f0> <class 'function'>
That looks like the 'message' parameter to your decode() method is not actually a FixMessage instance?
I am using a static method for that message now that makes it work:
def get_field(message: FixMessage, tag, nth=1):
tag = fix_tag(tag)
nth = int(nth)
for t, v in message.pairs:
if t == tag:
nth -= 1
if nth == 0:
return v
return None
So the decode now is:
def decode(self, message: FixMessage, nth: int = 1):
if (val := get_field(message, FIELD_ENCRYPT_METHOD, nth)) is not None:
And that works. And I can read the message type from it before. As I do a assert message.message_type == MESSAGE_LOGON
right before.
Glad it's working now, at least.
I appreciate it might not be possible, but if it is, could you send me the source code file? I'd like to investigate this a little more to see if I can understand what was happening ...
https://gitlab.com/recapital/tasks/-/snippets/2140207 I can give you this, the Client is one of the example applications out there that I built from. Enums is more or less the standard types and constants. Its the path from your decode more or less.