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
dialogs
module (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.
-
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
sk
module: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
sk.LightNode()
do anything. - In
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.node
attribute 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 thelighting_bit_mask
attribute manually after creating the copy. To make the contact callback work properly, you'd probably need to create a newPhysicsBody
instead 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", setdynamic
to False instead ofpinned
toTrue
.
-
I must say, after being out of the Python world for a while, this makes me very excited to get back in!!
-
@omz There seems to be some issue affecting the
canvas
module. In both the recent betas (160013 and 160014), your turtle.py example crashes Pythonista immediately. But other simple canvas usage does not. In released versions like 1.5, and the earlier betas, I have only observed canvas crashes when I edited the script while it was running.
-
https://github.com/cclauss/pythonista-module-versions is still throwing warnings on
requests
calls in 160014.
-
@ccc I mentioned in the release notes why I rolled back to an older version of
requests
.
-
I read that but
Pythonista_module_versions.py
is still throwing warnings like it would if you did NOT roll back the version ofrequests
.Requests is indeed fairly current according to
Pythonista_module_versions.py
:| module | local | PyPI | | name | version | version | | ------------- | -------- | ---------- | | requests | 2.6.0 | 2.6.2 |
-
Hmm, looks like something went wrong in my deployment script, should be 2.5.1.
-
This has been a problem for a looong time, but I never got around to reporting it: in the interpreter input field you cannot use the tab key on an external keyboard. It probably tries to switch to the next input field instead, which does nothing, because there is no other input field.
-
P.S. No Watch folder. Not that I am buying a watch. I did the Testflight install over the previous beta, not fresh.
-
misha,
regarding your issue.
new = particle_tpl.copy() #does not correctly copy the physics body.
new.physics_body = particle_tpl.physics_body.copy() #should fix your problem.
-
By the way if I have zero scripts is there any reason not to try the beta? I assume any I do create while using the beta might need rescuing by cut and paste (or whatever).
-
@polymerchm Are you running Pythonista on an iPhone? The Watch folder is not created on iPad because the watch can't be paired with that anyway.
-
Gotcha. Haven't installed it on my iPhone yet. So far all else is good on this build. Thanks.
-
@omz, @Gcarver, I've managed to make the
did_begin_contact
work correctly by changingtouch_began
to this:def touch_began(self, node, touch): new = particle_tpl.__copy__() new.physics_body = new.physics_body.__copy__() new.lighting_bit_mask = 1 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) self.add_child(new)
However, although this makes
did_begin_contact
work correctly, none of the particles are actually appearing. It seems that they have an alpha value of 0, however I know that this isn't true. The node count in the bottom corner tells me that they exist, but they just don't show up. I have tried changing the background color, but it made no difference.
-
Misha, your posted code works fine for me, are you sure you didn't make other changes?
Maybe try restarting pythonista?If you also set
new.shadow_cast_bit_mask=1
, then the shadows show up too.Shadows on top of textures seem to be stuck as white, If I add a texture background.. Also, light falloff doesn't seem to affect shadows, which is strange
-
@OMZ Sorry to report the autocomplete bug is stll there. Seems to happen write after typing the "." after an instance of a class. Highly unreproducible.
-
@polymerchm What kind of device are you using?
-
Ipad 2air with external Bluetooth keyboard