-1

I am trying to parse a string rep of a NamedTuple for connection parameters generated remotely by the psutil library (process.connections())

The string looks like this:

pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip=\'192.168.10.26\', port=23368), raddr=addr(ip=\'1.2.3.4\', port=8883), status=\'ESTABLISHED\')

Problem is that if I declare the NamedTuple and then use eval to build it it is unable to parse the string.

Here is some sample code:

from collections import namedtuple
from socket import AddressFamily, SocketKind

inputstr = 'pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip=\'192.168.10.26\', port=23368), raddr=addr(ip=\'1.2.3.4\', port=8883), status=\'ESTABLISHED\')'
simplifiedstr = 'pconn(fd=-1, family=2, type=3, laddr=addr(ip=\'192.168.10.26\', port=23368), raddr=addr(ip=\'1.2.3.4\', port=8883), status=\'ESTABLISHED\')'

pconn = namedtuple('pconn', 'fd family type laddr raddr status')
addr = namedtuple('addr', 'ip port')


# Simplified works
conn1 = eval (simplifiedstr)
print(conn1)

# input does not
conn2 = eval( inputstr)
print(conn2)

Since simplified works, it appears that eval does not like the family and type complex values( which I don't care about anyway!) Is there a way to make this work? All I really need is the local address and port (in this case 192.168.10.26, 8883)

khelwood
  • 55,782
  • 14
  • 81
  • 108
Bill
  • 618
  • 6
  • 15
  • This isn't a problem with `namedtuple` or with `eval`. `` isn't a valid expression inside or outside of `eval`. – khelwood Apr 28 '21 at 19:00
  • I thought the same when I saw these - I have never seen angle brackets used this way but they are shown in the library documentation. Here is an example line from https://psutil.readthedocs.io/en/latest/#processes pconn(fd=115, family=, type=, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED', pid=1254), – Bill Apr 28 '21 at 22:46
  • @Bill: Classes that produce `repr` output that can't be `eval`ed to produce the original object often wrap in angle brackets to make it clear it's not programmatically useful, just for human consumption, even if it is a friendlier `repr` than ``. – ShadowRanger Apr 28 '21 at 23:35

1 Answers1

0

Your basic problem is that not all reprs in Python follow the guidelines; sometimes, they produce string versions that can't be evaled to reproduce the original value. There is no simple solution here that will work without cooperation from the remote machine (without that cooperation, you're stuck writing your own parser).

If you do have cooperation from the remote machine, I'd suggest having it pickle the data, not repr it, which, assuming all classes involved are available both on the remote and local side, with the same qualified names (will be a problem if pconn is being hand-defined locally, but provided from an installed module remotely), will allow you to unpickle it locally.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Thanks - I guess I will just have to do klunky substring manipulation - won't be pretty but will get the job done! – Bill Apr 28 '21 at 23:03