Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Pythonista 1.6 Beta #160020
-
Build #160020 is now available via TestFlight. Please use this thread for feedback.
I've just added a couple of new people to the TestFlight list – if you didn't get an invite, but would like to participate, please fill out this form: → Beta Signup.
-
Is there some sort of list which classes we can use? I tried to use
example = ObjCClass('SCNScene')
, but it tells me it cant find the class, so I assume the app has to specify in before what it wants to use and does not import Scenekit. -
question on latest beta... does the fix of
ctypes.FUNCTYPE
mean we can now pass callback functions to objc classes? -
@Moe You can use classes from all frameworks that Pythonista links against (which doesn't include SceneKit at the moment), I don't have a full list of that handy right now, I'm afraid.
@JonB Yes, this should be fixed now. I'll probably post an example here soon (it's not completely trivial to do this correctly).
-
I see the option to not clear globals when running a script has gone away.... is this a change for good? i for one really liked having that feature off ... made hacking away at code much easier, since you could run the main script, then run some additional aux commands.
also, the problem with the lack of this option is that it breaks things like Stash, or really i think any ui.View that is presented in a panel, or which use threads inside a view. when the globals get cleared, the code still runs, because the view is in a panel, but the references are now junk.
if this is expected to be the new norm, we will have to investigate alternatives with stash (perhaps detecting this condition, and reexporting the needed globals... not sure if that is even possible.
-
by the way, i love the new ObjC utils! one question, would it be possible to add some of the introspection features from
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/index.html
such as
class_copyMethodList
, etc, so that the list of available selectors is visible, perhaps when doing a dir(object)? as far as i can tell, ctypes wont let us call runtime methods directly, will it?edit: looking at the old ctypes examples, i think i see how this is done...will try later
-
one more... selectors which return structures (such as .frame() on a UIView ) crash. do i need to use the older ctypes mechanisms where return types are specified?
-
need need ! :-)
Is there any expected official release date ?
Oh also, is there an associated Xcode template yet ? -
one question, would it be possible to add some of the introspection features from
https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/index.html
such as class_copyMethodList, etc, so that the list of available selectors is visible, perhaps when doing a dir(object)? as far as i can tell, ctypes wont let us call runtime methods directly, will it?Interesting idea... I think it might make sense to implement
__dir__
forObjCInstance
and return the list of available methods from there... I've played around withclass_copyMethodList
a little bit, and came up with this:from objc_util import * import ctypes def get_methods(objc_class): free = c.free free.argtypes = [c_void_p] free.restype = None class_copyMethodList = c.class_copyMethodList class_copyMethodList.restype = ctypes.POINTER(c_void_p) class_copyMethodList.argtypes = [c_void_p, ctypes.POINTER(ctypes.c_uint)] method_getName = c.method_getName method_getName.restype = c_void_p method_getName.argtypes = [c_void_p] py_methods = [] num_methods = c_uint(0) method_list_ptr = class_copyMethodList(objc_class.ptr, ctypes.byref(num_methods)) for i in xrange(num_methods.value): selector = method_getName(method_list_ptr[i]) sel_name = sel_getName(selector) py_method_name = sel_name.replace(':', '_') py_methods.append(py_method_name) free(method_list_ptr) return py_methods UIDevice = ObjCClass('UIDevice') print get_methods(UIDevice)
It doesn't return methods from superclasses yet, but that shouldn't be too hard to do... The results also highlight a problem that I didn't think about before: It's currently not possible to call private APIs because all underscores in method names are replaced with colons internally, and the selector names of private methods usually begin with an underscore...
-
one more... selectors which return structures (such as .frame() on a UIView ) crash. do i need to use the older ctypes mechanisms where return types are specified?
Do you have an example of this? I just tried the following code, and it seemed to work fine:
from objc_util import * UIView = ObjCClass('UIView') v = UIView.alloc().initWithFrame_(CGRect(CGPoint(0, 0), CGSize(100, 100))) print v.bounds() # => <objc_util.CGRect object at 0x10b7a59c8> print v.bounds().size.width # => 100.0
-
as far as i can tell, ctypes wont let us call runtime methods directly, will it?
You sure can! If you're curious about how
objc_util
works internally, just turn on "Show Standard Library" in the settings, and openobjc_util.py
(in Standard Library/site-packages) – in fact, my favorite thing aboutobjc_util
is that I was able to write this directly on my iPad, within Pythonista (it would have been possible with the previous beta as well). -
I see the option to not clear globals when running a script has gone away.... is this a change for good? i for one really liked having that feature off ... made hacking away at code much easier, since you could run the main script, then run some additional aux commands.
Not sure yet, I might bring it back, though I think it's generally not a good idea to rely on it being enabled. For things like panel views, I would recommend that you import the modules you need directly within the (action) methods where you need them. The overhead should be minimal as the imported modules are cached anyway.
-
Here's an example of using
objc_util
to query your Apple Music database. This script just prints the 25 artists you have the most songs of, but you could obviously extend this to get all sorts of statistics about your music... (yes, this does work with the new iCloud Music Library).from objc_util import * from collections import Counter MPMediaQuery = ObjCClass('MPMediaQuery') query = MPMediaQuery.songsQuery() items = query.items() print '%i songs found, collecting artist info...' % len(items) song_counter = Counter() for item in items: artist = str(item.valueForProperty_(ns('artist'))) song_counter[artist] += 1 print '\n'.join('%i. %s: %i songs' % (i+1, x[0], x[1]) for i, x in enumerate(song_counter.most_common(25)))
-
Not sure yet, I might bring it back
Please do. Before the new beta I had an
_init.py
script that I would run every time I started Pythonista, which loaded various things into the global namespace that I would use a lot interactively. Those were mostly modules likesys
,os
andmath
, but I also had a niftyfor
loop that made every built-in Python class available as a global. Admittedly that isn't too useful, but it's nice to be able to writeinstancemethod
instead oftype(someobj.somemethod)
.(
_init.py
was also a nice test subject for spontaneous file clearing, which by the way has not happened anymore in the recent betas, even with lots of open tabs.) -
Do you have an example of this? I just tried the following code, and it seemed to work fine:
that example crashes my ipad 3, running 8.3! do you want me to send the crash report?
-
Bug: had the ui editor opened and I put Pythonista in the background. Now when I try to open it it just crashes - doesn't open.
-
Seem the ui.load_view does not like my fairly complicated pyui file. Worked fine but now:
Traceback (most recent call last): File "/var/mobile/Containers/Data/Application/9EC48B68-E4CB-454A-B52E-3E92C934916F/Documents/chordcalc/chordCalc/chordcalc.py", line 3314, in <module> mainView = ui.load_view('chordcalc') File "/private/var/mobile/Containers/Bundle/Application/743EA4AB-23E2-4CB0-BE78-8FAE0E9A2A89/Pythonista.app/pylib/site-packages/ui.py", line 373, in load_view return load_view_str(json_str, bindings, stackframe) File "/private/var/mobile/Containers/Bundle/Application/743EA4AB-23E2-4CB0-BE78-8FAE0E9A2A89/Pythonista.app/pylib/site-packages/ui.py", line 359, in load_view_str return _view_from_dict(root_view_dict, g, l) File "/private/var/mobile/Containers/Bundle/Application/743EA4AB-23E2-4CB0-BE78-8FAE0E9A2A89/Pythonista.app/pylib/site-packages/ui.py", line 342, in _view_from_dict subview = _view_from_dict(d, f_globals, f_locals) File "/private/var/mobile/Containers/Bundle/Application/743EA4AB-23E2-4CB0-BE78-8FAE0E9A2A89/Pythonista.app/pylib/site-packages/ui.py", line 342, in _view_from_dict subview = _view_from_dict(d, f_globals, f_locals) File "/private/var/mobile/Containers/Bundle/Application/743EA4AB-23E2-4CB0-BE78-8FAE0E9A2A89/Pythonista.app/pylib/site-packages/ui.py", line 258, in _view_from_dict v.text = attrs.get('text') TypeError: Expected a string
Help please.
-
Interesting, I guess I haven't really tested this on a 32 bit device. Looks like I have to use
objc_msgSend_stret
there (which doesn't even exist in the 64-bit runtime for some reason).Could you send me the pyui file somehow? It looks like an easy fix, but in the meantime you can use:
import _ui _ui._load_view(...)
to get the old implementation. This will go away, but I left it in there for now, in case there are problems with the new one.
@hyshai
Could you send me the pyui file you had open (that probably caused the crash)? You can transfer it to your Mac/PC via iTunes file sharing. Let me know if you need more details.
-
@omz email sent
-
@omz email sent. Works fine with legacy
_ui._load_view
.