Closed GoogleCodeExporter closed 8 years ago
Mmmm interesting. I wouldn't know how to fix this off hand. I will try to think
about this later.
For the record: you should use psutil.CONN_LISTEN, not
psutil._common.CONN_LISTEN.
Original comment by g.rodola
on 18 Jul 2013 at 2:09
I'm not directly referencing psutil.CONN_LISTEN, it's being returned as part of
the process attributes.
For example:
process_list = [proc.as_dict() for proc in psutil.process_iter()]
return json.dumps(process_list)
I have a work around which involves stack inspection for the __str__ call but
it's not pretty. It's good enough for me to use right now. It's not 100%
correct either since strings are supposed to be passed through
json._iterencode._encode.
def __str__(self):
frame, filename, lineno, funcname, lines, idx = inspect.stack()[1]
if 'json' in filename and funcname == 'iterencode':
return '"%s"' % self._name
return self._name
The real fix would be some how make isinstance(psutil._common.constants,
basestring) return true as that's how the json encoder is iterating through
elements:
if isinstance(value, basestring):
yield buf + _encoder(value)
elif value is None:
yield buf + 'null'
elif value is True:
yield buf + 'true'
elif value is False:
yield buf + 'false'
elif isinstance(value, (int, long)):
yield buf + str(value)
elif isinstance(value, float):
yield buf + _floatstr(value)
Original comment by thep...@gmail.com
on 18 Jul 2013 at 2:33
It seems we migth use __instancecheck__ special method in order to make
json.loads() believe it's dealing with a string.
I'm looking into how to make it work now as apparently you have to use a
metaclass (if I just define it never gets invoked).
It's not an easy problem to fix though, also because __instancecheck__ works on
python >= 2.6 only.
Original comment by g.rodola
on 18 Jul 2013 at 4:15
The other side of this is how to unserialize? if loads() gets "LISTEN" and
returns the string "LISTEN" instead of the constant psutil.CONN_LISTEN, is that
going to be correct?
Original comment by ethan.st...@gmail.com
on 18 Jul 2013 at 6:37
It seems__instancecheck__ won't help either as it would have to be applied to
str/basestring, not the constant class.
Also, it looks like they're facing the same problem with Python 3.4's Enum, see:
http://bugs.python.org/issue18264.
As of now I'm not seeing any completely satisying solution to solve this
problem except maybe turning constants into strings and be done with it. That
way we would also preserve backward compatibility.
Other solutions such as making as_dict() cast constants to int or str, using
inspect from within __str__ or writing a custom json handler all look
sub-optimal to me for one reason or another.
Side note for the sake of completeness: the same problem applies for
psutil.STATUS_* constants returned by Process.status.
Original comment by g.rodola
on 18 Jul 2013 at 11:42
I found myself thinking about this issue. My first idea would be to use an
integer for representing the connection state (e. g. short and easy). However,
after I checked the TCP protocol specification:
http://tools.ietf.org/html/rfc793
It doesn't really uses "int" but a very well know collection of labels. Could
be possible that instead of using constants or integer/string representations
of constantes, to use strings of those labels for representing connection
states?
Regards,
Original comment by renatosa...@gmail.com
on 27 Jul 2013 at 1:20
Yes, using plain python strings looks like the best way to go.
Original comment by g.rodola
on 29 Jul 2013 at 2:19
Change committed in revision ab4a1f9dc57c.
Original comment by g.rodola
on 9 Aug 2013 at 7:59
Original comment by g.rodola
on 28 Sep 2013 at 10:06
Original issue reported on code.google.com by
thep...@gmail.com
on 17 Jul 2013 at 11:47