-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First stab at adding a generic __new__
This just adds some machinery with just enough support in data structures to be able to instantiate classes without keyword arguments. TODO: - Add machinery for framework bindings - Add support code to _transform (automaticly initialize the data structure based on init methods) - Add tests - Finally: update framework bindings
- Loading branch information
1 parent
04a7a59
commit 334a7a6
Showing
3 changed files
with
64 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
""" | ||
Implementation of `__new__` for arbitrary Cocoa classes | ||
""" | ||
|
||
__all__ = () | ||
|
||
NEW_MAP = {} | ||
UNSET = object() | ||
|
||
# XXX: Need to find a way to dynamically set the docstring | ||
|
||
|
||
def _make_new(cls): | ||
def __new__(cls, **kwds): | ||
""" | ||
Generic implementation for Objective-C `__new__`. | ||
""" | ||
# XXX: should this sort the keywords? | ||
key = tuple(kwds.keys()) | ||
|
||
for c in cls.__mro__: | ||
new_map = NEW_MAP.get(c, UNSET) | ||
if new_map is UNSET: | ||
continue | ||
|
||
name = new_map.get(key, UNSET) | ||
if name is UNSET: | ||
continue | ||
|
||
if name is None: | ||
if key: | ||
raise TypeError( | ||
f"{cls.__name__}() does not support keyword arguments {', '.join(repr(k) for k in key)}" | ||
) | ||
else: | ||
raise TypeError(f"{cls.__name__}() requires keyword arguments") | ||
|
||
if name.startswith("init") and len(name) == 4 or name[4].isupper(): | ||
return getattr(cls.alloc(), name)(**kwds) | ||
|
||
else: | ||
return getattr(cls, name)(**kwds) | ||
|
||
if key: | ||
raise TypeError( | ||
f"{cls.__name__}() does not support keyword arguments {', '.join(repr(k) for k in key)}" | ||
) | ||
else: | ||
raise TypeError(f"{cls.__name__}() requires keyword arguments") | ||
|
||
__new__.__name__ = cls.__name__ + ".__new__" | ||
__new__.__qualname__ = cls.__name__ + ".__new__" | ||
__new__.__module__ = cls.__module__ | ||
return __new__ |