Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python ServiceDescriptor.FindMethodByName raises exception (inconsistent behavior between C extension and native Python + documentation) #9592

Closed
tomerv opened this issue Mar 7, 2022 · 4 comments
Assignees
Labels
bug inactive Denotes the issue/PR has not seen activity in the last 90 days. python

Comments

@tomerv
Copy link
Contributor

tomerv commented Mar 7, 2022

What version of protobuf and what language are you using?
Version: master
Language: Python

What operating system (Linux, Windows, ...) and version?
Ubuntu 20

What runtime / compiler are you using (e.g., python version or gcc version)
Python 3.8.10

What did you do?

service_desc = desc_pool.FindServiceByName(service_name)
service_desc.FindMethodByName(_INVALID_SYMBOL_NAME)

This raises a KeyError exception.
However, the documentation says:

Returns: the descriptor for the requested method, if found.
Return type: MethodDescriptor or None

More specifically, the native Python implementation & documentation is:

  def FindMethodByName(self, name):
    """Searches for the specified method, and returns its descriptor.
    Args:
      name (str): Name of the method.
    Returns:
      MethodDescriptor or None: the descriptor for the requested method, if
      found.
    """
    return self.methods_by_name.get(name, None)

While the C-extension implementation is:

static PyObject* FindMethodByName(PyBaseDescriptor *self, PyObject* arg) {
  Py_ssize_t name_size;
  char* name;
  if (PyString_AsStringAndSize(arg, &name, &name_size) < 0) {
    return nullptr;
  }

  const MethodDescriptor* method_descriptor =
      _GetDescriptor(self)->FindMethodByName(StringParam(name, name_size));
  if (method_descriptor == nullptr) {
    PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
    return nullptr;
  }

  return PyMethodDescriptor_FromDescriptor(method_descriptor);
}

Note the PyExc_KeyError part in this code.

What did you expect to see
Consistency between Python and C-extension implementation (and the documentation).

What did you see instead?
They are not consistent.

Despite the title, I tend to think that the exception is the more correct behavior, based on these aspects:

  • It feels more Pythonic.
  • DescriptorPool.FindMethodByName raises a KeyError in this case. There are also tests for this behavior python/google/protobuf/internal/descriptor_pool_test.py, while there are no corresponding tests for ServiceDescriptor.FindMethodByName.
  • Fixing this inconsistency will be a breaking change for either the C-extension or Python users, depending on the fix. I assume that most environments are using the C-extension version, so changing to an exception will be less harmful.

I can try to submit a patch, but I want to check first that this is the correct direction, i.e. change the native Python code to raise an exception, update the documentation accordingly, and add an appropriate test.

@tomerv
Copy link
Contributor Author

tomerv commented Mar 15, 2022

@anandolee - please see my comment above

I can try to submit a patch, but I want to check first that this is the correct direction, i.e. change the native Python code to raise an exception, update the documentation accordingly, and add an appropriate test.

I'm willing to do the legwork to fix this, but I want to check first that this is the right direction.
Thanks.

@anandolee
Copy link
Contributor

change pure python to raise key error is right direction. Thank you tomerv

tomerv added a commit to tomerv/protobuf that referenced this issue May 19, 2022
…buffers#9592)

* Align Python version with C-extension version
  (python/google/protobuf/pyext/descriptor.cc)
* Update documentation accordingly
* Add unit test
tomerv added a commit to tomerv/protobuf that referenced this issue Jun 7, 2022
…buffers#9592)

* Align Python version with C-extension version
  (python/google/protobuf/pyext/descriptor.cc)
* Update documentation accordingly
* Add unit test
esorot added a commit that referenced this issue Jun 27, 2022
Raise KeyError in Python ServiceDescriptor.FindMethodByName (#9592)
Copy link

We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please add a comment.

This issue is labeled inactive because the last activity was over 90 days ago.

@github-actions github-actions bot added the inactive Denotes the issue/PR has not seen activity in the last 90 days. label Jan 29, 2024
Copy link

We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please reopen it.

This issue was closed and archived because there has been no new activity in the 14 days since the inactive label was added.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Feb 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug inactive Denotes the issue/PR has not seen activity in the last 90 days. python
Projects
None yet
Development

No branches or pull requests

4 participants