-
-
Notifications
You must be signed in to change notification settings - Fork 54
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
Add mechanism for invoking methods with duplicated argument names. #148
Comments
Some ideas:
Downsides: you won't be able to invoke any argument that actually has a double underscore in it's name. Objective C tends towards camelCase naming, though, so this is probably a low risk.
This allows for an explicit mapping of names - or even a complete re-mapping of names. For example, you could completely change the API to use snake case, rather than camelCase:
The downside to this approach is that the mapping from Objective C documentation to Python documentation isn't completely transparent - you need to provide documentation for how Python maps each specific affected API. |
I like this one for the most part - it's very simple (doesn't need any manual declarations) and it reads nicely IMHO. I see three issues with this variant though:
A possible solution for both of these issues would be to use numbers as suffixes (i. e.
I'm not a huge fan of this solution - I'd prefer to avoid manual declarations where possible, because they are less convenient to write and more confusing to read. My first point regarding the previous solution (allowing free choice of names leads to unnecessary naming differences) also applies here.
I don't think this is a good idea - if you start doing that, you would need to be consistent and write declarations like that for every Objective-C method you use, which simply takes too much work for a very small benefit. In general I think there are limits to how much Rubicon should try to make Objective-C APIs look like Python. Of course we want to make it as convenient as possible to interface between Python and Objective-C, so we implement some automatic conversions, wrapper classes, operators, etc. to make the Python-side calls less verbose. But in the end, the user still needs to remember that they're interfacing with a different language. A proper Python API around an Objective-C class/library needs to do much more than just changing names from camelCase to snake_case. I think supporting this kind of renaming natively in Rubicon would just give people false ideas that properly wrapping an API takes less work than it actually does. |
By the way, as a workaround for the line length issue, you can use the send_message(
NSLayoutConstraint,
(
"constraintWithItem:attribute:relatedBy:"
+ "toItem:attribute:multiplier:constant:"
),
..., # the actual arguments
) This doesn't look very nice and I think we should find a better solution, but it would be an acceptable workaround for now if line length is an issue. |
Also, here's another possible solution, using a terrible syntax hack: send_message[NSLayoutConstraint,
"constraintWithItem":item1,
"attribute":attr1,
"relatedBy":rel,
"toItem":item2,
"attribute":attr2,
"multiplier":mult,
"constant":const,
] You see, this looks like Objective-C's method call syntax, with the square brackets and colons and all. :P This works because of Python's slice syntax ( send_message[(NSLayoutConstraint,
slice("constraintWithItem", item1),
slice("attribute", attr1),
slice("relatedBy", rel),
slice("toItem", item2),
slice("attribute", attr2),
slice("multiplier", mult),
slice("constant", const),
)] I haven't decided yet if this idea is good or bad, but it would definitely work. |
I generally agree with your analysis regarding (1) vs (2). There's also the added bonus that (1) should be a lot easier to implement :-) Regarding the specifics of (1): The dictionary ordering problem you mention is almost a non-issue; Python 3.5 reaches end of life in October. I can see the point you're making regarding the naming convention for post-underscore text; however, I'm not convinced it's as big an issue as you make out. No matter what suffix is used, an end user who encounters the double underscore syntax will need to go looking for details on how to decode what it means, because it the name won't map in obvious ways to the Objective C documentation. As long as we make the documentation for the double underscore convention prominent, it's easy to impart the interpretation rule that the suffixes will be be ignored, and users should stop looking for any deep meaning, and internalize an "ignore suffix" reading behavior. We could possibly suggest that absent of any better convention, integers make a good suffix; and/or, if necessary for Python 3.5 support, use sorting of suffixes to provide order disambiguation (with 'no suffix' being sorted first). |
Good point - we could require at least Python 3.6 for this specific feature, or even decide to drop 3.5 early. (I don't expect there to be many Rubicon users who still need 3.5 specifically.)
That's true - the syntax isn't fully self-explanatory either way, and we definitely need to document this feature in the usual places (how-to and reference docs). Hopefully the double-underscore syntax is unusually-looking enough that people will go look at the Rubicon docs rather than searching for the exact identifier in Apple's documentation. |
I think enforcing integer suffixes is better than allowing a free choice, both for these reasons:
... and also because it would allow the dict used in a |
Being sensitive to dict insertion order is definitely a concern; but I don't know that I'd consider it a particularly high priority. At the point you're interfacing with an Objective C API, I don't think it would be reasonable to assume that all Pythonic invocation conventions (such as invoking a method with |
Fixed by #462. |
Objective C arguments are all named, but ordered. As a result, it is entirely legal for argument names to be duplicated. For example,
NSLayoutConstraint
has a method+constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:
- theattribute
argument name is duplicated.This is a problem for Rubicon, because the obvious mapping to keyword arguments wont work:
These methods can be accessed using the "older" underscore-based API mapping:
but this will almost always violate line length constraints.
We need a way to the more Pythonic invocation style on methods that have duplicated arguments.
The text was updated successfully, but these errors were encountered: