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

getattr() doesn't work on a cppclass #2604

Open
pitrou opened this Issue Sep 13, 2018 · 11 comments

Comments

Projects
None yet
3 participants
@pitrou
Contributor

pitrou commented Sep 13, 2018

I have a C++ class (mostly a simple struct) that I'd like to mirror in Python:

struct ParseOptions {
  // Parsing options

  // Field delimiter
  char delimiter = ',';
  // Whether quoting is used
  bool quoting = true;
  // Quoting character (if `quoting` is true)
  char quote_char = '"';
  // Whether a quote inside a value is double-quoted
  bool double_quote = true;
  // Whether escaping is used
  bool escaping = false;
  // Escaping character (if `escaping` is true)
  char escape_char = '\\';

  static ParseOptions Defaults();
};

I find myself writing something like the below:

cdef class CSVParseOptions:
    cdef:
        ParseOptions options

    @property
    def delimiter(self):
        return chr(self.options.delimiter)

    @delimiter.setter
    def delimiter(self, value):
        self.options.delimiter = ord(value)

    @property
    def double_quote(self):
        return self.options.double_quote

    @double_quote.setter
    def double_quote(self, value):
        self.options.double_quote = value

    # etc.

Writing all those properties by hand is quite tedious. If I could call getattr and setattr (or something similar) on the underlying C struct, I could generate those properties programmatically. Note: I don't exactly care about speed here.

@scoder

This comment has been minimized.

Show comment
Hide comment
@scoder

scoder Sep 13, 2018

Contributor

Code generation would be one way of doing it. See #2596.

If you really don't care about speed, then Cython's automatic struct-to-dict conversion might be an option. I don't think it's available for C++ classes, though, only for actual structs. Allowing an explicit cast from a C++ object to a <dict> could be an option, though.

Contributor

scoder commented Sep 13, 2018

Code generation would be one way of doing it. See #2596.

If you really don't care about speed, then Cython's automatic struct-to-dict conversion might be an option. I don't think it's available for C++ classes, though, only for actual structs. Allowing an explicit cast from a C++ object to a <dict> could be an option, though.

@pitrou

This comment has been minimized.

Show comment
Hide comment
@pitrou

pitrou Sep 13, 2018

Contributor

Hmm, I didn't know about struct-to-dict conversion. Exploiting it sounds a bit hackish (I would have to convert the whole struct back-and-forth just to set an attribute, right?). And it would have to work with C++ classes anyway.

Contributor

pitrou commented Sep 13, 2018

Hmm, I didn't know about struct-to-dict conversion. Exploiting it sounds a bit hackish (I would have to convert the whole struct back-and-forth just to set an attribute, right?). And it would have to work with C++ classes anyway.

@robertwb

This comment has been minimized.

Show comment
Hide comment
@robertwb

robertwb Sep 13, 2018

Contributor
Contributor

robertwb commented Sep 13, 2018

@pitrou

This comment has been minimized.

Show comment
Hide comment
@pitrou

pitrou Sep 15, 2018

Contributor

I don't see the point of immutability here. Being able to change parameters via attribute setting is convenient.

Contributor

pitrou commented Sep 15, 2018

I don't see the point of immutability here. Being able to change parameters via attribute setting is convenient.

@robertwb

This comment has been minimized.

Show comment
Hide comment
@robertwb

robertwb Sep 17, 2018

Contributor
Contributor

robertwb commented Sep 17, 2018

@pitrou

This comment has been minimized.

Show comment
Hide comment
@pitrou

pitrou Sep 17, 2018

Contributor

Let's not exagerate the benefits of immutability here. And just because I can pass parameters by keyword arguments doesn't mean it's always practical to do so. Most Python data structures and objects are actually mutable.

Contributor

pitrou commented Sep 17, 2018

Let's not exagerate the benefits of immutability here. And just because I can pass parameters by keyword arguments doesn't mean it's always practical to do so. Most Python data structures and objects are actually mutable.

@robertwb

This comment has been minimized.

Show comment
Hide comment
@robertwb

robertwb Sep 17, 2018

Contributor
Contributor

robertwb commented Sep 17, 2018

@pitrou

This comment has been minimized.

Show comment
Hide comment
@pitrou

pitrou Sep 17, 2018

Contributor

My point was more that using keywords arguments rather than having users create an object on which they manually set attributes [...]

It's not either/or. I'm doing both. Changing a single parameter is a reasonable need.

Contributor

pitrou commented Sep 17, 2018

My point was more that using keywords arguments rather than having users create an object on which they manually set attributes [...]

It's not either/or. I'm doing both. Changing a single parameter is a reasonable need.

@scoder

This comment has been minimized.

Show comment
Hide comment
@scoder

scoder Sep 17, 2018

Contributor

Calm down, everyone … I think it is a reasonable feature request to improve this use case.
Not sure if getattr() is the right tool, though. And I'm also not sure if it's special enough to not "just use code generation".

Maybe we could special case (<dict>struct)[fieldname] somehow? I mean, Python semantics dictate that the dict must be created first because it might have side effects or fail, but I wouldn't really mind bending the rules here, since we control the semantics of the dict coercion.

Contributor

scoder commented Sep 17, 2018

Calm down, everyone … I think it is a reasonable feature request to improve this use case.
Not sure if getattr() is the right tool, though. And I'm also not sure if it's special enough to not "just use code generation".

Maybe we could special case (<dict>struct)[fieldname] somehow? I mean, Python semantics dictate that the dict must be created first because it might have side effects or fail, but I wouldn't really mind bending the rules here, since we control the semantics of the dict coercion.

@robertwb

This comment has been minimized.

Show comment
Hide comment
@robertwb

robertwb Sep 18, 2018

Contributor
Contributor

robertwb commented Sep 18, 2018

@scoder

This comment has been minimized.

Show comment
Hide comment
@scoder

scoder Sep 18, 2018

Contributor
Contributor

scoder commented Sep 18, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment