Determining Pythonista's Version
Phuket2 last edited by Phuket2
Ok, I am stupid....
I should test these things first before posting. Even though I read that the previous example does not load anything, I guess it's clear it's loading the imp module, also with a string. I can see with following, faster just to load dialogs. One thing I found though, if you just say except without Import error is slightly longer to execute. Makes sense in a way, a known error can be delt with quicker than everything else I guess.
# coding: utf-8 import timeit def PythonistaVersion(): try: __import__('imp').find_module('dialogs') return 1.6 except ImportError: return 1.5 def PythonistaVersion2(): try: import dialogs return 1.6 except ImportError: return 1.5 print timeit.Timer('PythonistaVersion',setup="from __main__ import PythonistaVersion").timeit() print timeit.Timer('PythonistaVersion2',setup="from __main__ import PythonistaVersion2").timeit()
JonB last edited by
Not sure that timeit captures the time of imports... since modules are cached.
It seems to me you should just be testing for whatever feature you think you need, unless you are trying to workaround a specific bug in a specific version. Note also that the beta, when released, will be called 2.0, not 1.6. Here is, I think, a robust and futureproof approach tor getting the specific version.
def checkversion(): import os, sys, plistlib plist=plistlib.readPlist(os.path.abspath(os.path.join(sys.executable,'../Info.plist'))) return plist['CFBundleShortVersionString']'
@JonB , that is great. But I have never got that answer before. That's why I asserted something as my solution. Like a dare. but it's the only answer, I am guessing there is no more correct answer than this if you just want the version number. I understand what you say about checking for features. I didn't want to check for features, just want to know if I was working with 1.5 or 1.6. And as you say, this will be insufficient in the future. It will be like float(ver) >= 1.6 then we know we have this functionality without further tests. Of course if omz does not go alphanumeric on versions.
But being pragmatic as I am It drives me crazy. This important info should not be buried here in this post.
I don't expect omz to cover every detail like the this, but I wish we could.
I have been looking around for collaboration tools that could help in maintaining information like this. But, I haven't found anything yet that compelling, well even workable 😰
Another collaborate tool I would love to find is a specification tool. Have an idea for a class or a tool menu item etc.. Start a spec doc, get input on the spec before starting to code. In my mind, very simlar idea as having a managed document to store the answer you have provided here.
It seriously frustrates me. I wish I had the skill to write such applications, I just don't. Another thought might be, well how many programmers in iOS. Well with a little thought, these types of apps could be easily be broadened to service many types of customers not just programmers.
Oh well, I got that off my chest 😇👍 maybe a doc set in dash, search for: 'the best way to do x in Pythonista'. Well, not a great example given dash docs are not dynamic....thinking.......
But again, thanks for the answer!
dgelessus last edited by
It might be better to return the version number as a tuple of ints, or at least as a string. Floats are a very bad data type for version numbers, because they only work properly with versions that have two parts that are exactly one decimal digit long, and even then you might have issues because of floating-point rounding and such.
Strings are okay as long as you aren't comparing them, because that will fail for
"2.7.9" < "2.7.11". Tuples like
(2, 7, 11)are best if you want to compare them, but you might have to use some workarounds if there are non-number parts in the version. But even then
(2, 7, 11, "final")should work fine.
@dgelessus , thanks. Great point. I have not looked at the version info in a plist before. I incorrectly assumed it would be (major. minor . sub) or something close to that. I guess the fact a string is being returned, should have been a hint 😁. I also see it says ...ShortVersionString, I will go in and look at the other possibilities, I assume there must be others.
So much to learn, only so many years left 😎
JonB last edited by
I was working quickly, and didnt notice
would give the actual build number (e.g. 160037).
This post is deleted!
Phuket2 last edited by Phuket2
useful utility function, pythonista_info - from @ccc
@ccc, you did a entry in response to this thread in https://github.com/cclauss/Ten-lines-or-less/blob/master/pythonista_version.py
I was just looking through some things to try and centralize some helpful code. I know your 10 lines or less is for a different reason. That's why I didn't try to suggest this back via Github.
Just consolidated your code into a func, returning a dict.
Does it look ok? Any improvements you can think of using other information in the plist that could also be useful? Given you wrote it, I thought I would ask given you wrote it
# coding: utf-8 # from @ccc omz forums # Output: Pythonista version 1.6 (160037) on iOS 9.2 on an iPad3,4. # Pythonista version 2.0.1 (201000) on iOS 9.2.1 on a 64-bit iPad5,4 with a screen size of (1024 x 768) * 2 # built on https://forum.omz-software.com/topic/2444/determining-pythonista-s-version/3 import os, platform, plistlib, scene, sys def pythonista_info(): # 2.0.1 (201000) plist = plistlib.readPlist(os.path.abspath(os.path.join(sys.executable, '..', 'Info.plist'))) ios_ver, _, machine_model = platform.mac_ver() return dict( pythonista_ver_str = plist['CFBundleShortVersionString'], pythonista_ver_num = plist['CFBundleVersion'], ios_ver_str = ios_ver, screen_resoultion = scene.get_screen_size(), screen_scale = scene.get_screen_scale(), machine_architecture = platform.architecture(), machine_model = machine_model, ) if __name__ == '__main__': print pythonista_info()
ccc last edited by ccc
Hi @Phuket2 the approach above looks good to me... You might want to adjust your comment lines to match the code.
For these kind of device info functions, the question is what info are you after. Ususally you know exactly which data elements are required so you go directly after those. platform_info.py tries to get everything that can be gotten from the platform module but there are tons of other modules (locale, os, sys, etc.) that help you to understand the machine that you are on.
Retuning a dict is cool but might be overkill when you know exactly which few data elements you need. (See stash/version.py) A dict has the advantage that it can be sorted() for display and an OrderedDict could be considered if you had some opinionated ordering of elements that is different from A-Z. Lastly, never forget the NamedTuple as a possibility for your return value as this data should be read-only for the caller and tuples will be slightly more efficient that dicts.
ccc last edited by
I updated pythonista_version.py to deal with the fact that one version of Pythonista can now run two versions of Python:
- Pythonista version 3.0 (300007) running Python 3.5.1 on iOS 9.3.1 on a 64-bit iPad5,4 with a screen size of (1024 x 768) * 2
- Pythonista version 3.0 (300007) running Python 2.7.5 on iOS 9.3.1 on a 64-bit iPad5,4 with a screen size of (1024 x 768) * 2
dgelessus last edited by dgelessus
@ccc You could also check all available Python versions at once. The different PythonistaKit frameworks can be accessed using
ctypes, so you can do something like this:
import ctypes import os import sys FRAMEWORKS = os.path.join(os.path.dirname(sys.executable), "Frameworks") def get_python_version(name): dll = ctypes.CDLL(os.path.join(FRAMEWORKS, name + ".framework", name)) dll.Py_GetVersion.argtypes =  dll.Py_GetVersion.restype = ctypes.c_char_p return dll.Py_GetVersion().decode("ascii")
ccc last edited by
Cool, @dgelessus !!