-1

I have a case where I receive objects from another module. The object type can be JSON String, dict or of Google Protobuf. I can use isinstance in python to determine whether it is JSON String or dict, but finding it difficult to use isinstance to check if it is protobuf. I am not even sure if isinstance can be used for non-primitive types like Google Protobuf.

So, Is there a way to check the given object is of Google Protobuf type in Python?

martineau
  • 119,623
  • 25
  • 170
  • 301
user2896235
  • 339
  • 3
  • 17
  • If the types can be only one of three, why not check for the first two and assume it’s Protobuf in the associated `else`? – esqew Oct 12 '21 at 23:10
  • One approach (not sure if best in this case) is to just try deserializing the value and wrapping it with `try ... except` to catch the error if it isn't valid Protobuf. – JanLikar Oct 12 '21 at 23:17
  • 1
    `I am not even sure if isinstance can be used for non primitive types like Google Protobuf.` ... can you think of a way to find out? – Danielle M. Oct 12 '21 at 23:29
  • 1
    `isinstance()` will work on non-primitive types. – martineau Oct 13 '21 at 00:00
  • @esqew I don’t want assume like that and instead want to check specifically and conclude. Danielle, martineau Do you guys what type to pass for Protobuf ?? I couldn’t figure this out either from documentation or from Google/StackOverflow – user2896235 Oct 13 '21 at 00:02
  • 1
    user2896235: The documentation for [`isinstance()`](https://docs.python.org/3/library/functions.html#isinstance) says that the *`classinfo`* argument can be a tuple of type objects which implies you can check for multiple types in one call to it. As far as @Danielle's comment goes, you could just try it on a `protobuf` and see if it works. – martineau Oct 13 '21 at 00:07
  • you can try creating a dummy ```protobuf``` variable with name ```dummy``` and then compare ```type(your_var)==type(dummy)``` – L F Oct 13 '21 at 00:28

1 Answers1

1

Are you receiving Protobuf objects or serialized (binary) strings?

If you're receiving objects then these should be subclasses of Message and isinstance using your object for Message should be true for protobufs.

If your incoming object is o and:

assert isinstance(json.loads(o), dict)
assert isinstance(o, dict)

from google.protobuf.message import Message
assert isinstance(o, Message)
assert issubclass(o, Message)

Even though it's more effort to test for each type (JSON, dict, proto), I think it would be better to confirm the object's type before proceeding.

You can short-circuit the tests by only testing until you find a match but you want to avoid some 4th type being added in the future and your code assuming that anything that's not JSON or dict is a proto.

DazWilkin
  • 32,823
  • 5
  • 47
  • 88
  • Passing Message, message, protobuf, proto as type to isinstance didn't work. All the case got a response as name 'x' is not defined. x is Message, message or protobuf etc. – user2896235 Oct 13 '21 at 04:09
  • 1
    If your incoming object is `o` and your `json.loads(o)` and `isinstance(o, dict)` then you should be able to `from google.protobuf.message import Message` and `isinstance(o, Message)` and `issubclass(o, Message)` – DazWilkin Oct 13 '21 at 04:31
  • Excellent. This works. May be you should update your answer with this information. – user2896235 Oct 13 '21 at 04:52
  • @DazWilkin how we can use isinstance with protobuf binary message? – ImranRazaKhan Dec 02 '21 at 03:53
  • Then deserialize it first (`ParseFromString`). Please don't ask new questions in comments. – DazWilkin Dec 02 '21 at 13:53