Beta Status Update
Unfortunately, I've recently been unable to provide a new beta version of Pythonista 1.6. This is partly my own fault, and partly due to unexpected difficulties with TestFlight.
First off, I've been working on two different branches of Pythonista for quite some time, one being the current (expired) 1.6 beta, a relatively minor update with new Python modules but not much else, the other a more significant update with a major UI refresh and quite a few other new features that I'm pretty excited about (more on that soon).
This approach has sometimes made it difficult to keep both versions in a working state. When I changed something in version B, I sometimes ended up accidentally breaking stuff in version A... So a couple of weeks ago, I decided to ditch the current beta branch, and exclusively focus on the new version instead, but I have to admit that I vastly underestimated the amount of work that this would take – a lot of basic things were still missing in the new branch, and even though it had some nice new features, it would have been a step down in terms of stability and basic functionality that you'd expect, even if you were coming from 1.5.
Right now, it's still a bit rough around the edges, but definitely usable and an improvement over the current version. Unfortunately, I haven't been able to get TestFlight to work with it yet. I continue running into server-side issues with builds not processing properly after I upload them. In order to make some new features work, I had to change the App ID (for code-signing), and it seems that this is a scenario that just doesn't work very well with TestFlight – it's difficult to go back now because that would mean sacrificing new functionality that I spent quite a lot of time on... At first, the only reason for the new App ID requirement was the document picker support in the new
dialogsmodule (requires iCloud entitlements), but the new version also contains an app extension (for running scripts from the share sheet in other apps), and I've realized now that this also doesn't work with the old App ID, and while the document picker support wasn't that important to me, the app extension is a major feature that I really want to ship.
If you do have the current (expired) beta installed and would like to get your data out of it, here are two options you can use:
Option 1 (if you have a Mac with Xcode):
- Connect your device via USB
- Start Xcode and select Devices from the Window menu, then select the connected device in the sidebar
- Under Installed Apps, select Pythonista
- Click on the "Gear" icon and select Download Container...
The downloaded container is a package (i.e. folder), so you can view the individual files in Finder by selecting Show Package Contents from the context menu.
Option 2 (if you're on a PC or don't want to install Xcode):
- Make an unencrypted(!) backup of your device using iTunes
- Download the iBackup Viewer tool (Mac or Windows) – (the free version will do, if you have the paid version, you could also encrypt your backup)
- Go to "(your device)/Applications" (this may take a while to load)
- Select Pythonista in the list of apps, then click the "gear" button and select Save all Files.... I would recommend that you create a new folder for this because the app will create multiple folders while extracting the backup files.
Edit: You can also try downgrading by downloading 1.5 from the App Store. Apparently, this didn't result in data loss for some people, but I'm not quite sure if this always works.
That's all I have for now. I'm very sorry this took so long. When I know more, I'll post it here.
Does clearing the code completion cache change anything? If not, mind uploading the code in question to Gist? Interestingly I don't get any code completion at all for a
AFAICT it isn't possible to disable code completion (or switch it to "simple" mode) anymore in the latest beta. There isn't even an option for that in the
I do get TableView instances to code complete, though the first time takes a few seconds.
I have observed
Gittleobjects take a really really long time to complete(like minutes....I think the innards of these are very dynamic) in 1.5, which locked everything up until a completion popped up! The workaround was to type a space, then period followed by your attribute, then go back as backspace out the space. This prevents autocomplete from happening, at least in the console. Misspelling the object name also works,etc.
Blmacbeth, where are you setting the physics? Make sure you are setting it AFTER calling sk.load, otherwise load overwrites anything you have set already.
node.copy() does not copy the physics body correctly. The node copy points to a physics body but I think it's the same as the original. I have to manually make a copy.
More on autocompletion explosions. I opening up
tvCapos.delegate = fred
When I went to the file menu to switch files, the app crashed.
Re: platformer grey screen. I found on IOS 8.2 that removing the [`orientations='landscape'] from the last line, then rotating my device after pressing play, the game was playable.
It's fine in 8.3.
@JonB, I am setting up the physics through the sprite kit editor, not through the script editor. The first thing I do in the script is
things = sk.load('things.pysk, sk.Node()). I would assume that the numbers I set in
things.pyskwould load there. However, when I run the following: (where I have set
ball = things['ball'] print ball.physics_body.restitution
0.5. I found a work around by setting the restitution in the script editor.
Hooked up to my Mac and used XCODE to look for a crash report. None.
(Thought I had posted this before...)
I manually imported
jediand tried to get a code completion on one of the problematic spots. At some point it ends up in an infinite recursion loop, until the interpreter throws an exception due to exceeding the recursion limit. Why exactly this happens I can't say though.
An off switch would be nice. This was not a problem (in 1.5). @degelessus: Which version of jedi did you try? The installed jedi in 1.6 is 0.9.0. Perhaps a rollback to 0.8.1?
@polymerchm It seems that only crash reports with file names ending in ".ips" are shown in Xcode. Those that have been transferred are renamed on the device to ".ips-transferred" or similar. Those from the Pythonista beta end in ".ips-beta" or so. Fortunately, they call all be viewed on the device, if you go to Settings -> Privacy -> Diagnosis ... -> Diagnosis ... (or something close to that).
@OMZ Do you automatically get crash logs, or can I send them to you? Will sync device tonight and see if I have logs relevant to the autocomplete bug (now that I know where to find them).
I've found an issue where
editor.make_new_file()causes the app to crash. It doesn't seem to matter what arguments I pass to it the app just shuts down.
works fine for me (iOS 8.3, beta 1.6).
import editor editor.make_new_file('test.py','this is a test')
create a file in the root directory each time its run, adding a number to the end to avoid a duplicate name.
I love the updates!!! especially tabs and search. Also love the purplish theme. And most of all love the improved traceback readout. And the consolidated keyboard is a great idea.
Great job OMZ you've created the premier development platform for (on) iOS!
Just an observation - the yellow dot to the left of "Pythonista" under the icon doesn't go away for me. I believe it's supposed to indicate that there's a new version of the app on your device that you haven't opened yet...but I have. Pythonista is the only app I have in test flight so forgive me if I'm wrong - either way sounds like it would be a test flight issue.
Also one gripe - if you have a script in the foreground and it runs, you can click the x in the upper right while in console view to stop it. You can't press play(run) from the same place - instead it's a greyed out x and you have to backup to the script to press play again. It wasn't like this in previous versions, and while I can see the logic in making sure you're at the script before you can run it, being able to run a script multiple times while looking at the console without backing out of it is very useful to quickly try code modifications out during development...for me at least. Perhaps a toggle for this functionality deserves to exist in settings?
ALSO, since the new version I get this error all the time. Everything still works, but this error shows up in red in the console.
D96-4218-87C0-D09DA5054558/Pythonista2.app/pylib/site-packages/requests/packages/urllib3/util/ssl_.py:79: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning. InsecurePlatformWarning
I believe the yellow dot means the app is in testing/beta state.
The lack of a run button on the console is explained in the Beta readme and/or in a post above.
The insecure platform thing is tied to new security checks in the requests module.
Just another bug report (maybe it's just me doing everything wrong) for the
Here is the code I'm using:
# coding: utf-8 import sk import random MAXSPD = 700 MAXLIFE = 15 TEXTURE = 'shp:Circle' MINLIFED = -350 MAXLIFED = 350 SCALE = 2 decayrate = 0.005 collider_f = 0.35 def randvec(maxspd): return (random.randint(-maxspd, maxspd), random.randint(-maxspd, maxspd)) particle_tpl = sk.SpriteNode(sk.Texture(TEXTURE)) particle_tpl.name = 'particle' particle_tpl.color_blend_factor = 1 particle_tpl.age = 0 particle_tpl.lighting_bit_mask = 1 particle_tpl.x_scale = SCALE particle_tpl.y_scale = SCALE particle_tpl.alpha = 0.5 particle_tpl.shadow_cast_bit_mask = 1 physics = sk.PhysicsBody.circle(particle_tpl.size.x/2 * collider_f) physics.restitution = 1.2 physics.affected_by_gravity = False physics.allows_rotation = True physics.mass = 2 physics.pinned = False physics.angular_velocity = 0 physics.category_bit_mask = 1 physics.contact_test_bit_mask = 1 particle_tpl.physics_body = physics class Game (sk.Scene): def __init__(self): sk.Scene.__init__(self) self.name = 'scene' self.particles = set() self.img = sk.Texture(TEXTURE) self.maxspd = MAXSPD self.handles_node_touches = False self.maxlife = MAXLIFE * 60 # convert to frames self.selected = None # init walls for y in [768, 0]: wall = sk.Node() wall.position = (512, y) physics = sk.PhysicsBody.rect(1024, 100) physics.affected_by_gravity = False physics.allows_rotation = False physics.restitution = 1.2 physics.pinned = True wall.physics_body = physics self.add_child(wall) for x in [0, 1024]: wall = sk.Node() wall.position = (x, 384) physics = sk.PhysicsBody.rect(100, 768) physics.affected_by_gravity = False physics.allows_rotation = False physics.restitution = 1.2 physics.pinned = True wall.physics_body = physics self.add_child(wall) # lighting light = sk.LightNode() light.position = (10, 758) light.shadow_color = (1, 0, 0) light.ambient_color = (0, 0, 1) light.light_color = (0, 1, 0) light.enabled = True light.category_bit_mask = 1 light.alpha = 1 light.falloff = 0.4 light.name = 'light' self.add_child(light) def update(self): for p in self['particle']: p.age += 1 if p.age >= p.lifespan: # if exceeded life, reduce alpha by 1 p.alpha -= decayrate if p.alpha <= 0: p.run_action(sk.Action.call(p.remove_from_parent)) def touch_began(self, node, touch): self.selected = None new = particle_tpl.__copy__() new.position = touch.location new.physics_body.velocity = randvec(MAXSPD) new.color = (random.random(), random.random(), random.random()) new.lifespan = self.maxlife + random.randint(MINLIFED, MAXLIFED) #new.z_position = random.randint(0, len(self.get_children_with_name('particle'))) self.add_child(new) def touch_moved(self, node, touch): self.touch_began(node, touch) def did_begin_contact(self, collison): # Make the color change on collison collison.body_a.node.color = (random.random(), random.random(), random.random()) collison.body_b.node.color = (random.random(), random.random(), random.random()) def main(): game = Game() scene_view = sk.View(game) scene_view.shows_fps = True scene_view.shows_node_count = True scene_view.present() return game if __name__ == '__main__': g = main()
It's similar to the old Particles example, however using physics. I'm running into two problems:
- No matter what I do, I can't make the
did_begin_contact, I'm getting the following error:
AttributeError: 'NoneType' has no attribute 'color'
It says in the docs that the
collison.body_a.nodeattribute should be the node it is attached to, but for me it seems to be just None.
- No matter what I do, I can't make the
@misha_turnbull It looks like both issues are caused by bugs in
sk.Node.__copy__. Try setting the
lighting_bit_maskattribute manually after creating the copy. To make the contact callback work properly, you'd probably need to create a new
PhysicsBodyinstead of relying on the one that gets copied along with the node. I'm looking into this. One other thing: If you want to make your physics bodies "immovable", set
dynamicto False instead of