omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    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.


    Determining Pythonista's Version

    Pythonista
    version
    4
    13
    8817
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Phuket2
      Phuket2 last edited by

      After reading around, to the best of my knowledge currently this is the best way to determine Pythonista's Version.
      No imports required.

      def PythonistaVersion():
      	try:
      		__import__('imp').find_module('dialogs')
      		return 1.6
      	except ImportError:
      		return 1.5
      	
      print 'Pythonista Version is {}'.format(PythonistaVersion())
      		
      

      From what I have read it's not Python 3 friendly, and also we are relying on in the case 'dialogs' does not contain an ImportError. I think we can safely say it will not.

      I have been just using import 'dialogs', but it has to actually load the module. As far as I am aware, this does not.

      If there is a better way, would love to know.

      1 Reply Last reply Reply Quote 0
      • Phuket2
        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()
        
        
        1 Reply Last reply Reply Quote 0
        • JonB
          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']'
          
          Phuket2 1 Reply Last reply Reply Quote 2
          • Phuket2
            Phuket2 @JonB last edited by

            @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!

            1 Reply Last reply Reply Quote 0
            • dgelessus
              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.

              Phuket2 1 Reply Last reply Reply Quote 0
              • Phuket2
                Phuket2 @dgelessus last edited by

                @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 😎

                1 Reply Last reply Reply Quote 0
                • JonB
                  JonB last edited by

                  I was working quickly, and didnt notice
                  plist['CFBundleVersion']
                  would give the actual build number (e.g. 160037).

                  1 Reply Last reply Reply Quote 2
                  • Phuket2
                    Phuket2 last edited by

                    This post is deleted!
                    1 Reply Last reply Reply Quote 0
                    • Phuket2
                      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()[0],
                      		machine_model = machine_model,
                      		
                      		)
                      
                      if __name__ == '__main__':
                      	print pythonista_info()
                      
                      1 Reply Last reply Reply Quote 0
                      • ccc
                        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.

                        1 Reply Last reply Reply Quote 1
                        • ccc
                          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
                          1 Reply Last reply Reply Quote 1
                          • dgelessus
                            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")
                            
                            1 Reply Last reply Reply Quote 0
                            • ccc
                              ccc last edited by

                              Cool, @dgelessus !!

                              print(get_python_version('PythonistaKit'))
                              print(get_python_version('PythonistaKit3'))
                              
                              1 Reply Last reply Reply Quote 0
                              • First post
                                Last post
                              Powered by NodeBB Forums | Contributors