Ignore:
Timestamp:
Nov 18, 2020 7:58:58 PM (14 months ago)
Author:
toby
Message:

implement package version checking; fix broken mpl pick code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/GSASIIdataGUI.py

    r4645 r4658  
    3333        print('Warning: failed to import the optimized Py3 pickle (_pickle)')
    3434        import pickle as cPickle
     35import re
    3536import numpy as np
    3637import numpy.ma as ma
     
    325326    sys.stderr = sys.stdout
    326327
     328def convVersion(version):
     329    '''Convert a version string ("x", "x.y", "x.y.z") into a series of
     330    ints.
     331
     332    :returns: [i0, i1, i2] where None is used if a value is not specified
     333       and 0 is used if a field cannot be parsed.
     334    '''
     335    vIntList = [None,None,None]
     336    for i,v in enumerate(version.split('.')):
     337        if i >= 3: break
     338        if len(v) == 0: break
     339        v = list(filter(None,re.split('(\\d+)',v)))[0]   # conv '1b2' to '1'
     340        try:
     341            vIntList[i] = int(v)
     342        except:
     343            vIntList[i] = 0
     344    return vIntList
     345
     346def compareVersions(version1,version2):
     347    '''Compare two version strings ("x", "x.y", "x.y.z")
     348    Note that '3.' matches '3.1', and '3.0' matches '3.0.1'
     349    but '3.0.0' does not match '3.0.1'
     350
     351    :returns: 0 if the versions match, -1 if version1 < version2,
     352       or 1 if version1 > version2
     353    '''
     354    for v1,v2 in zip(convVersion(version1),convVersion(version2)):
     355        if v1 is None or v2 is None:
     356            return 0
     357        if v1 < v2: return -1
     358        if v1 > v2: return 1
     359    return 0
     360
     361# tabulate package versions that users should be warned about
     362versionDict = {}
     363'''Variable versionDict is used to designate versions of packages that
     364should generate warnings or error messages.
     365
     366* ``versionDict['tooOld']`` is a dict with module versions that are too old and are
     367  known to cause serious errors
     368* ``versionDict['tooOldWarn']`` is a dict with module versions that are
     369  significantly out of date and should be updated, but will probably function OK.
     370* ``versionDict['badVersionWarn']`` is a dict of with lists of package
     371  versions that are known to have bugs. One should select an older or
     372  newer version of the package.
     373* ``versionDict['tooNewWarn']`` is a dict with module versions that have not
     374  been tested but have changes that lead us to believe that errors are
     375  likely to happen.
     376
     377**Packages/versions to be avoided**
     378
     379* wxPython:
     380
     381 * <=2.x.x: while most of GSAS-II has been written to be
     382    compatible with older versions of wxpython, we are now testing with
     383    version 4.0 only. Version 3.0 is pretty similar to 4.0 and should not
     384    have problems.
     385
     386* Matplotlib:
     387
     388  * 1.x: there have been significant API changes since these versions and
     389    significant graphics errors will occur.
     390  * 3.1.x and 3.2.x: these versions have a known bug for plotting
     391    3-D surfaces, such as microstrain vs crystal axes. The plots may appear
     392    distorted as the lengths of x, y & z will not be constrained as equal.
     393    Preferably use 3.0.x as 3.3.x is not fully tested.
     394
     395* numpy:
     396
     397  * 1.16.0: produces .gpx files that are not compatible with older
     398    version numpy versions. This is a pretty outmoded version; upgrade.
     399
     400'''
     401# add comments above when changing anything below
     402versionDict['tooOld'] = {'matplotlib': '1.'}
     403'modules that will certainly fail'
     404versionDict['tooOldWarn'] = {'wx': '2.'}
     405'modules that may fail but should be updated'
     406versionDict['badVersionWarn'] = {'numpy':['1.16.0'],
     407                                 'matplotlib': ['3.1','3.2']}
     408'versions of modules that are known to have bugs'
     409versionDict['tooNewWarn'] = {'matplotlib': '3.3'}
     410'module versions newer than what we have tested where problems are suspected'
     411   
    327412def ShowVersions():
    328413    '''Show the versions all of required Python packages, etc.
     
    337422    print ("Python module versions loaded:")
    338423    print ("  Python:     %s from %s"%(sys.version.split()[0],sys.executable))
    339     print ("  wx:         %s"%wx.__version__)
    340     print ("  matplotlib: %s"%mpl.__version__)
    341     print ("  numpy:      %s"%np.__version__)
    342     print ("  scipy:      %s"%sp.__version__)
    343     print ("  OpenGL:     %s"%ogl.__version__)
    344424    Image = None
    345425    version = '?'
     426    versionDict['errors'] = ''
     427    warn = False
     428    for s,m in [('wx',wx), ('matplotlib', mpl), ('numpy',np),
     429                    ('scipy',sp), ('OpenGL',ogl)]:
     430        msg = ''
     431        if s in versionDict['tooOld']:
     432            match = compareVersions(m.__version__,versionDict['tooOld'][s])
     433            if match <= 0:
     434                msg = "version will cause problems"
     435                warn = True
     436                if versionDict['errors']: versionDict['errors'] += '\n'
     437                versionDict['errors'] += 'Package {} version {} is too old for GSAS-II. An update is required'.format(s,m.__version__)
     438        if s in versionDict['tooOldWarn']:
     439            match = compareVersions(m.__version__,versionDict['tooOldWarn'][s])
     440            if match <= 0:
     441                msg = "version can cause problems"
     442                warn = True
     443        if s in versionDict['tooNewWarn']:
     444            match = compareVersions(m.__version__,versionDict['tooNewWarn'][s])
     445            if match >= 0:
     446                msg = "version is too new and could cause problems"
     447                warn = True
     448        if s in versionDict['badVersionWarn']:
     449            for v in versionDict['badVersionWarn'][s]:
     450                if compareVersions(m.__version__,v) == 0:
     451                    msg = "version is known to be buggy"
     452                    warn = True
     453                    break
     454        print("  {:12s}{}  {}".format(s+':',m.__version__,msg))
    346455    try:
    347456        from PIL import Image
     
    386495        print('Warning GSAS-II incompletely updated. Please contact toby@anl.gov')
    387496    # end patch
    388 
    389 def warnNumpyVersion(application):
    390     dlg = wx.MessageDialog(application.main,
    391                 'version '+ np.__version__ +
    392                 ' of numpy produces .gpx files that are not compatible with older versions: please upgrade or downgrade numpy to avoid this version',
    393                 'numpy Warning',wx.OK)
    394     try:
    395         dlg.CenterOnParent()
    396         dlg.ShowModal()
    397     finally:
    398         dlg.Destroy()
    399        
     497    if warn:
     498        print('You are suggested to install a new version of GSAS-II.\nSee https://bit.ly/G2install',
     499              '\n\nFor information on packages see\nhttps://gsas-ii.readthedocs.io/en/latest/packages.html and',
     500              '\nhttps://gsas-ii.readthedocs.io/en/latest/GSASIIGUI.html#GSASIIdataGUI.versionDict')
     501
    400502###############################################################################
    401503#### GUI creation
     
    405507    ShowVersions()
    406508    GUIpatches()
    407     knownVersions = ['2.7','3.6','3.7','3.8']
    408     if platform.python_version()[:3] not in knownVersions:
    409         dlg = wx.MessageDialog(None,
    410                 'GSAS-II requires Python 2.7.x or 3.6+\n Yours is '+sys.version.split()[0],
    411                 'Python version error',  wx.OK)
    412         try:
    413             dlg.ShowModal()
    414         finally:
    415             dlg.Destroy()
    416         sys.exit()
    417 
     509   
    418510    if platform.python_version()[:3] == '2.7':
    419511        msg = '''The end-of-life for python 2.7 was January 1, 2020.
     
    451543        txt = wx.StaticText(dlg,wx.ID_ANY,G2G.StripIndents(msg))
    452544        mainSizer.Add(txt)
    453         txt.Wrap(600)
     545        txt.Wrap(400)
    454546        dlg.SetSizer(mainSizer)
    455547        btnsizer = wx.BoxSizer(wx.HORIZONTAL)
     
    504596                GSASIIpath.runScript(cmds, wait=True)   
    505597                sys.exit()
     598    if versionDict['errors']:
     599        dlg = wx.MessageDialog(None, versionDict['errors']+
     600             '\n\nThe simplest solution is to install a new version of GSAS-II. '+
     601             'See https://bit.ly/G2install',
     602                'Python package problem',  wx.OK)
     603        try:
     604            dlg.ShowModal()
     605        finally:
     606            dlg.Destroy()
     607        sys.exit()
     608    elif platform.python_version()[:3] not in ['2.7','3.6','3.7','3.8','3.9']:
     609        dlg = wx.MessageDialog(None,
     610                'GSAS-II requires Python 2.7.x or 3.6+\n Yours is '+sys.version.split()[0],
     611                'Python version error',  wx.OK)
     612        try:
     613            dlg.ShowModal()
     614        finally:
     615            dlg.Destroy()
     616        sys.exit()
     617               
    506618    application.main = GSASII(None)  # application.main is the main wx.Frame (G2frame in most places)
    507619    application.SetTopWindow(application.main)
    508620    # save the current package versions
    509621    application.main.PackageVersions = G2fil.get_python_versions([wx, mpl, np, sp, ogl])
    510     if np.__version__ == '1.16.0':
    511         wx.CallLater(100,warnNumpyVersion,application)
    512622    if GSASIIpath.GetConfigValue('wxInspector'):
    513623        import wx.lib.inspection as wxeye
     
    89279037    else:
    89289038        G2frame.SetMenuBar(menu)
     9039
     9040if __name__ == '__main__':
     9041    ShowVersions()
Note: See TracChangeset for help on using the changeset viewer.