鱼C论坛

 找回密码
 立即注册
查看: 1361|回复: 1

[已解决]求wxversion.py文件,哭哭哭

[复制链接]
发表于 2016-1-7 20:07:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
求大神帮下一个,实在是找不到了,我的py是3.3版本的,这个东西是用来判断wxpython版本的一个脚本
最佳答案
2016-1-7 21:51:01
看看是不是这个?
  1. #----------------------------------------------------------------------
  2. # Name:        wxversion
  3. # Purpose:     Allows a wxPython program to search for alternate
  4. #              installations of the wxPython packages and modify sys.path
  5. #              so they will be found when "import wx" is done.
  6. #
  7. # Author:      Robin Dunn
  8. #
  9. # Created:     24-Sept-2004
  10. # RCS-ID:      $Id: wxversion.py,v 1.12.4.1 2006/01/20 17:32:43 RD Exp $
  11. # Copyright:   (c) 2004 by Total Control Software
  12. # Licence:     wxWindows license
  13. #----------------------------------------------------------------------

  14. """
  15. If you have more than one version of wxPython installed this module
  16. allows your application to choose which version of wxPython will be
  17. imported when it does 'import wx'.  The main function of this module
  18. is `select` and you use it like this::

  19.     import wxversion
  20.     wxversion.select('2.4')
  21.     import wx

  22. Or additional build options can also be selected, although they will
  23. not be required if they are not installed, like this::

  24.     import wxversion
  25.     wxversion.select('2.5.3-unicode')
  26.     import wx

  27. Or you can require an exact match on the build options like this::

  28.     import wxversion
  29.     wxversion.select('2.5.3-unicode', optionsRequired=True)
  30.     import wx

  31. Finally you can also specify a collection of versions that are allowed
  32. by your application, like this::

  33.     import wxversion
  34.     wxversion.select(['2.5.4', '2.5.5', '2.6'])
  35.     import wx


  36. Of course the default wxPython version can also be controlled by
  37. setting PYTHONPATH or by editing the wx.pth path configuration file,
  38. but using wxversion will allow an application to manage the version
  39. selection itself rather than depend on the user to setup the
  40. environment correctly.

  41. It works by searching the sys.path for directories matching wx-* and
  42. then comparing them to what was passed to the select function.  If a
  43. match is found then that path is inserted into sys.path.

  44. NOTE: If you are making a 'bundle' of your application with a tool
  45. like py2exe then you should *not* use the wxversion module since it
  46. looks at the filesystem for the directories on sys.path, it will fail
  47. in a bundled environment.  Instead you should simply ensure that the
  48. version of wxPython that you want is found by default on the sys.path
  49. when making the bundled version by setting PYTHONPATH.  Then that
  50. version will be included in your bundle and your app will work as
  51. expected.  Py2exe and the others usually have a way to tell at runtime
  52. if they are running from a bundle or running raw, so you can check
  53. that and only use wxversion if needed.  For example, for py2exe::

  54.     if not hasattr(sys, 'frozen'):
  55.         import wxversion
  56.         wxversion.select('2.5')
  57.     import wx

  58. More documentation on wxversion and multi-version installs can be
  59. found at: http://wiki.wxpython.org/index.cgi/MultiVersionInstalls

  60. """

  61. import re, sys, os, glob, fnmatch


  62. _selected = None
  63. class VersionError(Exception):
  64.     pass

  65. #----------------------------------------------------------------------

  66. def select(versions, optionsRequired=False):
  67.     """
  68.     Search for a wxPython installation that matches version.  If one
  69.     is found then sys.path is modified so that version will be
  70.     imported with a 'import wx', otherwise a VersionError exception is
  71.     raised.  This funciton should only be caled once at the begining
  72.     of the application before wxPython is imported.

  73.         :param versions: Specifies the version to look for, it can
  74.             either be a string or a list of strings.  Each string is
  75.             compared to the installed wxPythons and the best match is
  76.             inserted into the sys.path, allowing an 'import wx' to
  77.             find that version.

  78.             The version string is composed of the dotted version
  79.             number (at least 2 of the 4 components) optionally
  80.             followed by hyphen ('-') separated options (wx port,
  81.             unicode/ansi, flavour, etc.)  A match is determined by how
  82.             much of the installed version matches what is given in the
  83.             version parameter.  If the version number components don't
  84.             match then the score is zero, otherwise the score is
  85.             increased for every specified optional component that is
  86.             specified and that matches.

  87.             Please note, however, that it is possible for a match to
  88.             be selected that doesn't exactly match the versions
  89.             requested.  The only component that is required to be
  90.             matched is the version number.  If you need to require a
  91.             match on the other components as well, then please use the
  92.             optional ``optionsRequired`` parameter described next.

  93.         :param optionsRequired: Allows you to specify that the other
  94.              components of the version string (such as the port name
  95.              or character type) are also required to be present for an
  96.              installed version to be considered a match.  Using this
  97.              parameter allows you to change the selection from a soft,
  98.              as close as possible match to a hard, exact match.
  99.         
  100.     """
  101.     if type(versions) == str:
  102.         versions = [versions]

  103.     global _selected
  104.     if _selected is not None:
  105.         # A version was previously selected, ensure that it matches
  106.         # this new request
  107.         for ver in versions:
  108.             if _selected.Score(_wxPackageInfo(ver), optionsRequired) > 0:
  109.                 return
  110.         # otherwise, raise an exception
  111.         raise VersionError("A previously selected wx version does not match the new request.")

  112.     # If we get here then this is the first time wxversion is used,
  113.     # ensure that wxPython hasn't been imported yet.
  114.     if sys.modules.has_key('wx') or sys.modules.has_key('wxPython'):
  115.         raise VersionError("wxversion.select() must be called before wxPython is imported")
  116.    
  117.     # Look for a matching version and manipulate the sys.path as
  118.     # needed to allow it to be imported.
  119.     installed = _find_installed(True)
  120.     bestMatch = _get_best_match(installed, versions, optionsRequired)
  121.    
  122.     if bestMatch is None:
  123.         raise VersionError("Requested version of wxPython not found")

  124.     sys.path.insert(0, bestMatch.pathname)
  125.     # q.v. Bug #1409256
  126.     path64 = re.sub('/lib/','/lib64/',bestMatch.pathname)
  127.     if os.path.isdir(path64):
  128.         sys.path.insert(0, path64)
  129.     _selected = bestMatch
  130.         
  131. #----------------------------------------------------------------------

  132. UPDATE_URL = "http://wxPython.org/"
  133. #UPDATE_URL = "http://sourceforge.net/project/showfiles.php?group_id=10718"

  134. _EM_DEBUG=0

  135. def ensureMinimal(minVersion, optionsRequired=False):
  136.     """
  137.     Checks to see if the default version of wxPython is greater-than
  138.     or equal to `minVersion`.  If not then it will try to find an
  139.     installed version that is >= minVersion.  If none are available
  140.     then a message is displayed that will inform the user and will
  141.     offer to open their web browser to the wxPython downloads page,
  142.     and will then exit the application.
  143.     """
  144.     assert type(minVersion) == str

  145.     # ensure that wxPython hasn't been imported yet.
  146.     if sys.modules.has_key('wx') or sys.modules.has_key('wxPython'):
  147.         raise VersionError("wxversion.ensureMinimal() must be called before wxPython is imported")

  148.     bestMatch = None
  149.     minv = _wxPackageInfo(minVersion)

  150.     # check the default version first
  151.     defaultPath = _find_default()
  152.     if defaultPath:
  153.         defv = _wxPackageInfo(defaultPath, True)
  154.         if defv >= minv and minv.CheckOptions(defv, optionsRequired):
  155.             bestMatch = defv

  156.     # if still no match then check look at all installed versions
  157.     if bestMatch is None:
  158.         installed = _find_installed()
  159.         # The list is in reverse sorted order, so find the first
  160.         # one that is big enough and optionally matches the
  161.         # options
  162.         for inst in installed:
  163.             if inst >= minv and minv.CheckOptions(inst, optionsRequired):
  164.                 bestMatch = inst
  165.                 break

  166.     # if still no match then prompt the user
  167.     if bestMatch is None:
  168.         if _EM_DEBUG: # We'll do it this way just for the test code below
  169.             raise VersionError("Requested version of wxPython not found")
  170.         
  171.         import wx, webbrowser
  172.         versions = "\n".join(["      "+ver for ver in getInstalled()])
  173.         app = wx.PySimpleApp()
  174.         result = wx.MessageBox("This application requires a version of wxPython "
  175.                                "greater than or equal to %s, but a matching version "
  176.                                "was not found.\n\n"
  177.                                "You currently have these version(s) installed:\n%s\n\n"
  178.                                "Would you like to download a new version of wxPython?\n"
  179.                                % (minVersion, versions),
  180.                       "wxPython Upgrade Needed", style=wx.YES_NO)
  181.         if result == wx.YES:
  182.             webbrowser.open(UPDATE_URL)
  183.         app.MainLoop()
  184.         sys.exit()

  185.     sys.path.insert(0, bestMatch.pathname)
  186.     # q.v. Bug #1409256
  187.     path64 = re.sub('/lib/','/lib64/',bestMatch.pathname)
  188.     if os.path.isdir(path64):
  189.         sys.path.insert(0, path64)
  190.     global _selected
  191.     _selected = bestMatch
  192.         

  193. #----------------------------------------------------------------------

  194. def checkInstalled(versions, optionsRequired=False):
  195.     """
  196.     Check if there is a version of wxPython installed that matches one
  197.     of the versions given.  Returns True if so, False if not.  This
  198.     can be used to determine if calling `select` will succeed or not.

  199.         :param versions: Same as in `select`, either a string or a list
  200.             of strings specifying the version(s) to check for.

  201.         :param optionsRequired: Same as in `select`.
  202.     """
  203.    
  204.     if type(versions) == str:
  205.         versions = [versions]
  206.     installed = _find_installed()
  207.     bestMatch = _get_best_match(installed, versions, optionsRequired)
  208.     return bestMatch is not None

  209. #----------------------------------------------------------------------

  210. def getInstalled():
  211.     """
  212.     Returns a list of strings representing the installed wxPython
  213.     versions that are found on the system.
  214.     """
  215.     installed = _find_installed()
  216.     return [os.path.basename(p.pathname)[3:] for p in installed]



  217. #----------------------------------------------------------------------
  218. # private helpers...

  219. def _get_best_match(installed, versions, optionsRequired):
  220.     bestMatch = None
  221.     bestScore = 0
  222.     for pkg in installed:
  223.         for ver in versions:
  224.             score = pkg.Score(_wxPackageInfo(ver), optionsRequired)
  225.             if score > bestScore:
  226.                 bestMatch = pkg
  227.                 bestScore = score
  228.     return bestMatch


  229. _pattern = "wx-[0-9].*"
  230. def _find_installed(removeExisting=False):
  231.     installed = []
  232.     toRemove = []
  233.     for pth in sys.path:

  234.         # empty means to look in the current dir
  235.         if not pth:
  236.             pth = '.'

  237.         # skip it if it's not a package dir
  238.         if not os.path.isdir(pth):
  239.             continue
  240.         
  241.         base = os.path.basename(pth)

  242.         # if it's a wx path that's already in the sys.path then mark
  243.         # it for removal and then skip it
  244.         if fnmatch.fnmatchcase(base, _pattern):
  245.             toRemove.append(pth)
  246.             continue

  247.         # now look in the dir for matching subdirs
  248.         for name in glob.glob(os.path.join(pth, _pattern)):
  249.             # make sure it's a directory
  250.             if not os.path.isdir(name):
  251.                 continue
  252.             # and has a wx subdir
  253.             if not os.path.exists(os.path.join(name, 'wx')):
  254.                 continue
  255.             installed.append(_wxPackageInfo(name, True))

  256.     if removeExisting:
  257.         for rem in toRemove:
  258.             del sys.path[sys.path.index(rem)]
  259.         
  260.     installed.sort()
  261.     installed.reverse()
  262.     return installed


  263. # Scan the sys.path looking for either a directory matching _pattern,
  264. # or a wx.pth file
  265. def _find_default():
  266.     for pth in sys.path:
  267.         # empty means to look in the current dir
  268.         if not pth:
  269.             pth = '.'

  270.         # skip it if it's not a package dir
  271.         if not os.path.isdir(pth):
  272.             continue
  273.         
  274.         # does it match the pattern?
  275.         base = os.path.basename(pth)
  276.         if fnmatch.fnmatchcase(base, _pattern):
  277.             return pth

  278.     for pth in sys.path:
  279.         if not pth:
  280.             pth = '.'
  281.         if not os.path.isdir(pth):
  282.             continue
  283.         if os.path.exists(os.path.join(pth, 'wx.pth')):
  284.             base = open(os.path.join(pth, 'wx.pth')).read()
  285.             return os.path.join(pth, base)

  286.     return None


  287. class _wxPackageInfo(object):
  288.     def __init__(self, pathname, stripFirst=False):
  289.         self.pathname = pathname
  290.         base = os.path.basename(pathname)
  291.         segments = base.split('-')
  292.         if stripFirst:
  293.             segments = segments[1:]
  294.         self.version = tuple([int(x) for x in segments[0].split('.')])
  295.         self.options = segments[1:]


  296.     def Score(self, other, optionsRequired):
  297.         score = 0
  298.         
  299.         # whatever number of version components given in other must
  300.         # match exactly
  301.         minlen = min(len(self.version), len(other.version))
  302.         if self.version[:minlen] != other.version[:minlen]:
  303.             return 0        
  304.         score += 1

  305.         # check for matching options, if optionsRequired then the
  306.         # options are not optional ;-)
  307.         for opt in other.options:
  308.             if opt in self.options:
  309.                 score += 1
  310.             elif optionsRequired:
  311.                 return 0
  312.             
  313.         return score

  314.    
  315.     def CheckOptions(self, other, optionsRequired):
  316.         # if options are not required then this always succeeds
  317.         if not optionsRequired:
  318.             return True
  319.         # otherwise, if we have any option not present in other, then
  320.         # the match fails.
  321.         for opt in self.options:
  322.             if opt not in other.options:
  323.                 return False
  324.         return True

  325.             
  326.    
  327.     def __lt__(self, other):
  328.         return self.version < other.version or \
  329.                (self.version == other.version and self.options < other.options)
  330.     def __le__(self, other):
  331.         return self.version <= other.version or \
  332.                (self.version == other.version and self.options <= other.options)
  333.    
  334.     def __gt__(self, other):
  335.         return self.version > other.version or \
  336.                (self.version == other.version and self.options > other.options)
  337.     def __ge__(self, other):
  338.         return self.version >= other.version or \
  339.                (self.version == other.version and self.options >= other.options)
  340.    
  341.     def __eq__(self, other):
  342.         return self.version == other.version and self.options == other.options
  343.         
  344.    

  345. #----------------------------------------------------------------------

  346. if __name__ == '__main__':
  347.     import pprint

  348.     #ensureMinimal('2.5')
  349.     #pprint.pprint(sys.path)
  350.     #sys.exit()
  351.    
  352.    
  353.     def test(version, optionsRequired=False):
  354.         # setup
  355.         savepath = sys.path[:]

  356.         #test
  357.         select(version, optionsRequired)
  358.         print "Asked for %s, (%s):\t got: %s" % (version, optionsRequired, sys.path[0])

  359.         # reset
  360.         sys.path = savepath[:]
  361.         global _selected
  362.         _selected = None


  363.     def testEM(version, optionsRequired=False):
  364.         # setup
  365.         savepath = sys.path[:]

  366.         #test
  367.         ensureMinimal(version, optionsRequired)
  368.         print "EM: Asked for %s, (%s):\t got: %s" % (version, optionsRequired, sys.path[0])

  369.         # reset
  370.         sys.path = savepath[:]
  371.         global _selected
  372.         _selected = None
  373.         
  374.         
  375.     # make some test dirs
  376.     names = ['wx-2.4-gtk-ansi',
  377.              'wx-2.5.2-gtk2-unicode',
  378.              'wx-2.5.3-gtk-ansi',
  379.              'wx-2.6-gtk2-unicode',
  380.              'wx-2.6-gtk2-ansi',
  381.              'wx-2.6-gtk-ansi',
  382.              'wx-2.7.1-gtk2-ansi',
  383.              ]
  384.     for name in names:
  385.         d = os.path.join('/tmp', name)
  386.         os.mkdir(d)
  387.         os.mkdir(os.path.join(d, 'wx'))

  388.     # setup sys.path to see those dirs
  389.     sys.path.append('/tmp')
  390.    

  391.     # now run some tests
  392.     pprint.pprint( getInstalled())
  393.     print checkInstalled("2.4")
  394.     print checkInstalled("2.5-unicode")
  395.     print checkInstalled("2.99-bogus")
  396.     print "Current sys.path:"
  397.     pprint.pprint(sys.path)
  398.     print
  399.    
  400.     test("2.4")
  401.     test("2.5")
  402.     test("2.5-gtk2")
  403.     test("2.5.2")
  404.     test("2.5-ansi")
  405.     test("2.5-unicode")
  406.     test("2.6")
  407.     test("2.6-ansi")
  408.     test(["2.6-unicode", "2.7-unicode"])
  409.     test(["2.6", "2.7"])
  410.     test(["2.6-unicode", "2.7-unicode"], optionsRequired=True)
  411.    
  412.    
  413.    
  414.     # There isn't a unicode match for this one, but it will give the best
  415.     # available 2.4.  Should it give an error instead?  I don't think so...
  416.     test("2.4-unicode")

  417.     # Try asking for multiple versions
  418.     test(["2.5.2", "2.5.3", "2.6"])

  419.     try:
  420.         # expecting an error on this one
  421.         test("2.9")
  422.     except VersionError, e:
  423.         print "Asked for 2.9:\t got Exception:", e

  424.     # check for exception when incompatible versions are requested
  425.     try:
  426.         select("2.4")
  427.         select("2.5")
  428.     except VersionError, e:
  429.         print "Asked for incompatible versions, got Exception:", e

  430.     _EM_DEBUG=1
  431.     testEM("2.6")
  432.     testEM("2.6-unicode")
  433.     testEM("2.6-unicode", True)
  434.     try:
  435.         testEM("2.9")
  436.     except VersionError, e:
  437.         print "EM: Asked for 2.9:\t got Exception:", e

  438.     # cleanup
  439.     for name in names:
  440.         d = os.path.join('/tmp', name)
  441.         os.rmdir(os.path.join(d, 'wx'))
  442.         os.rmdir(d)

  443.         
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-1-7 21:51:01 | 显示全部楼层    本楼为最佳答案   
看看是不是这个?
  1. #----------------------------------------------------------------------
  2. # Name:        wxversion
  3. # Purpose:     Allows a wxPython program to search for alternate
  4. #              installations of the wxPython packages and modify sys.path
  5. #              so they will be found when "import wx" is done.
  6. #
  7. # Author:      Robin Dunn
  8. #
  9. # Created:     24-Sept-2004
  10. # RCS-ID:      $Id: wxversion.py,v 1.12.4.1 2006/01/20 17:32:43 RD Exp $
  11. # Copyright:   (c) 2004 by Total Control Software
  12. # Licence:     wxWindows license
  13. #----------------------------------------------------------------------

  14. """
  15. If you have more than one version of wxPython installed this module
  16. allows your application to choose which version of wxPython will be
  17. imported when it does 'import wx'.  The main function of this module
  18. is `select` and you use it like this::

  19.     import wxversion
  20.     wxversion.select('2.4')
  21.     import wx

  22. Or additional build options can also be selected, although they will
  23. not be required if they are not installed, like this::

  24.     import wxversion
  25.     wxversion.select('2.5.3-unicode')
  26.     import wx

  27. Or you can require an exact match on the build options like this::

  28.     import wxversion
  29.     wxversion.select('2.5.3-unicode', optionsRequired=True)
  30.     import wx

  31. Finally you can also specify a collection of versions that are allowed
  32. by your application, like this::

  33.     import wxversion
  34.     wxversion.select(['2.5.4', '2.5.5', '2.6'])
  35.     import wx


  36. Of course the default wxPython version can also be controlled by
  37. setting PYTHONPATH or by editing the wx.pth path configuration file,
  38. but using wxversion will allow an application to manage the version
  39. selection itself rather than depend on the user to setup the
  40. environment correctly.

  41. It works by searching the sys.path for directories matching wx-* and
  42. then comparing them to what was passed to the select function.  If a
  43. match is found then that path is inserted into sys.path.

  44. NOTE: If you are making a 'bundle' of your application with a tool
  45. like py2exe then you should *not* use the wxversion module since it
  46. looks at the filesystem for the directories on sys.path, it will fail
  47. in a bundled environment.  Instead you should simply ensure that the
  48. version of wxPython that you want is found by default on the sys.path
  49. when making the bundled version by setting PYTHONPATH.  Then that
  50. version will be included in your bundle and your app will work as
  51. expected.  Py2exe and the others usually have a way to tell at runtime
  52. if they are running from a bundle or running raw, so you can check
  53. that and only use wxversion if needed.  For example, for py2exe::

  54.     if not hasattr(sys, 'frozen'):
  55.         import wxversion
  56.         wxversion.select('2.5')
  57.     import wx

  58. More documentation on wxversion and multi-version installs can be
  59. found at: http://wiki.wxpython.org/index.cgi/MultiVersionInstalls

  60. """

  61. import re, sys, os, glob, fnmatch


  62. _selected = None
  63. class VersionError(Exception):
  64.     pass

  65. #----------------------------------------------------------------------

  66. def select(versions, optionsRequired=False):
  67.     """
  68.     Search for a wxPython installation that matches version.  If one
  69.     is found then sys.path is modified so that version will be
  70.     imported with a 'import wx', otherwise a VersionError exception is
  71.     raised.  This funciton should only be caled once at the begining
  72.     of the application before wxPython is imported.

  73.         :param versions: Specifies the version to look for, it can
  74.             either be a string or a list of strings.  Each string is
  75.             compared to the installed wxPythons and the best match is
  76.             inserted into the sys.path, allowing an 'import wx' to
  77.             find that version.

  78.             The version string is composed of the dotted version
  79.             number (at least 2 of the 4 components) optionally
  80.             followed by hyphen ('-') separated options (wx port,
  81.             unicode/ansi, flavour, etc.)  A match is determined by how
  82.             much of the installed version matches what is given in the
  83.             version parameter.  If the version number components don't
  84.             match then the score is zero, otherwise the score is
  85.             increased for every specified optional component that is
  86.             specified and that matches.

  87.             Please note, however, that it is possible for a match to
  88.             be selected that doesn't exactly match the versions
  89.             requested.  The only component that is required to be
  90.             matched is the version number.  If you need to require a
  91.             match on the other components as well, then please use the
  92.             optional ``optionsRequired`` parameter described next.

  93.         :param optionsRequired: Allows you to specify that the other
  94.              components of the version string (such as the port name
  95.              or character type) are also required to be present for an
  96.              installed version to be considered a match.  Using this
  97.              parameter allows you to change the selection from a soft,
  98.              as close as possible match to a hard, exact match.
  99.         
  100.     """
  101.     if type(versions) == str:
  102.         versions = [versions]

  103.     global _selected
  104.     if _selected is not None:
  105.         # A version was previously selected, ensure that it matches
  106.         # this new request
  107.         for ver in versions:
  108.             if _selected.Score(_wxPackageInfo(ver), optionsRequired) > 0:
  109.                 return
  110.         # otherwise, raise an exception
  111.         raise VersionError("A previously selected wx version does not match the new request.")

  112.     # If we get here then this is the first time wxversion is used,
  113.     # ensure that wxPython hasn't been imported yet.
  114.     if sys.modules.has_key('wx') or sys.modules.has_key('wxPython'):
  115.         raise VersionError("wxversion.select() must be called before wxPython is imported")
  116.    
  117.     # Look for a matching version and manipulate the sys.path as
  118.     # needed to allow it to be imported.
  119.     installed = _find_installed(True)
  120.     bestMatch = _get_best_match(installed, versions, optionsRequired)
  121.    
  122.     if bestMatch is None:
  123.         raise VersionError("Requested version of wxPython not found")

  124.     sys.path.insert(0, bestMatch.pathname)
  125.     # q.v. Bug #1409256
  126.     path64 = re.sub('/lib/','/lib64/',bestMatch.pathname)
  127.     if os.path.isdir(path64):
  128.         sys.path.insert(0, path64)
  129.     _selected = bestMatch
  130.         
  131. #----------------------------------------------------------------------

  132. UPDATE_URL = "http://wxPython.org/"
  133. #UPDATE_URL = "http://sourceforge.net/project/showfiles.php?group_id=10718"

  134. _EM_DEBUG=0

  135. def ensureMinimal(minVersion, optionsRequired=False):
  136.     """
  137.     Checks to see if the default version of wxPython is greater-than
  138.     or equal to `minVersion`.  If not then it will try to find an
  139.     installed version that is >= minVersion.  If none are available
  140.     then a message is displayed that will inform the user and will
  141.     offer to open their web browser to the wxPython downloads page,
  142.     and will then exit the application.
  143.     """
  144.     assert type(minVersion) == str

  145.     # ensure that wxPython hasn't been imported yet.
  146.     if sys.modules.has_key('wx') or sys.modules.has_key('wxPython'):
  147.         raise VersionError("wxversion.ensureMinimal() must be called before wxPython is imported")

  148.     bestMatch = None
  149.     minv = _wxPackageInfo(minVersion)

  150.     # check the default version first
  151.     defaultPath = _find_default()
  152.     if defaultPath:
  153.         defv = _wxPackageInfo(defaultPath, True)
  154.         if defv >= minv and minv.CheckOptions(defv, optionsRequired):
  155.             bestMatch = defv

  156.     # if still no match then check look at all installed versions
  157.     if bestMatch is None:
  158.         installed = _find_installed()
  159.         # The list is in reverse sorted order, so find the first
  160.         # one that is big enough and optionally matches the
  161.         # options
  162.         for inst in installed:
  163.             if inst >= minv and minv.CheckOptions(inst, optionsRequired):
  164.                 bestMatch = inst
  165.                 break

  166.     # if still no match then prompt the user
  167.     if bestMatch is None:
  168.         if _EM_DEBUG: # We'll do it this way just for the test code below
  169.             raise VersionError("Requested version of wxPython not found")
  170.         
  171.         import wx, webbrowser
  172.         versions = "\n".join(["      "+ver for ver in getInstalled()])
  173.         app = wx.PySimpleApp()
  174.         result = wx.MessageBox("This application requires a version of wxPython "
  175.                                "greater than or equal to %s, but a matching version "
  176.                                "was not found.\n\n"
  177.                                "You currently have these version(s) installed:\n%s\n\n"
  178.                                "Would you like to download a new version of wxPython?\n"
  179.                                % (minVersion, versions),
  180.                       "wxPython Upgrade Needed", style=wx.YES_NO)
  181.         if result == wx.YES:
  182.             webbrowser.open(UPDATE_URL)
  183.         app.MainLoop()
  184.         sys.exit()

  185.     sys.path.insert(0, bestMatch.pathname)
  186.     # q.v. Bug #1409256
  187.     path64 = re.sub('/lib/','/lib64/',bestMatch.pathname)
  188.     if os.path.isdir(path64):
  189.         sys.path.insert(0, path64)
  190.     global _selected
  191.     _selected = bestMatch
  192.         

  193. #----------------------------------------------------------------------

  194. def checkInstalled(versions, optionsRequired=False):
  195.     """
  196.     Check if there is a version of wxPython installed that matches one
  197.     of the versions given.  Returns True if so, False if not.  This
  198.     can be used to determine if calling `select` will succeed or not.

  199.         :param versions: Same as in `select`, either a string or a list
  200.             of strings specifying the version(s) to check for.

  201.         :param optionsRequired: Same as in `select`.
  202.     """
  203.    
  204.     if type(versions) == str:
  205.         versions = [versions]
  206.     installed = _find_installed()
  207.     bestMatch = _get_best_match(installed, versions, optionsRequired)
  208.     return bestMatch is not None

  209. #----------------------------------------------------------------------

  210. def getInstalled():
  211.     """
  212.     Returns a list of strings representing the installed wxPython
  213.     versions that are found on the system.
  214.     """
  215.     installed = _find_installed()
  216.     return [os.path.basename(p.pathname)[3:] for p in installed]



  217. #----------------------------------------------------------------------
  218. # private helpers...

  219. def _get_best_match(installed, versions, optionsRequired):
  220.     bestMatch = None
  221.     bestScore = 0
  222.     for pkg in installed:
  223.         for ver in versions:
  224.             score = pkg.Score(_wxPackageInfo(ver), optionsRequired)
  225.             if score > bestScore:
  226.                 bestMatch = pkg
  227.                 bestScore = score
  228.     return bestMatch


  229. _pattern = "wx-[0-9].*"
  230. def _find_installed(removeExisting=False):
  231.     installed = []
  232.     toRemove = []
  233.     for pth in sys.path:

  234.         # empty means to look in the current dir
  235.         if not pth:
  236.             pth = '.'

  237.         # skip it if it's not a package dir
  238.         if not os.path.isdir(pth):
  239.             continue
  240.         
  241.         base = os.path.basename(pth)

  242.         # if it's a wx path that's already in the sys.path then mark
  243.         # it for removal and then skip it
  244.         if fnmatch.fnmatchcase(base, _pattern):
  245.             toRemove.append(pth)
  246.             continue

  247.         # now look in the dir for matching subdirs
  248.         for name in glob.glob(os.path.join(pth, _pattern)):
  249.             # make sure it's a directory
  250.             if not os.path.isdir(name):
  251.                 continue
  252.             # and has a wx subdir
  253.             if not os.path.exists(os.path.join(name, 'wx')):
  254.                 continue
  255.             installed.append(_wxPackageInfo(name, True))

  256.     if removeExisting:
  257.         for rem in toRemove:
  258.             del sys.path[sys.path.index(rem)]
  259.         
  260.     installed.sort()
  261.     installed.reverse()
  262.     return installed


  263. # Scan the sys.path looking for either a directory matching _pattern,
  264. # or a wx.pth file
  265. def _find_default():
  266.     for pth in sys.path:
  267.         # empty means to look in the current dir
  268.         if not pth:
  269.             pth = '.'

  270.         # skip it if it's not a package dir
  271.         if not os.path.isdir(pth):
  272.             continue
  273.         
  274.         # does it match the pattern?
  275.         base = os.path.basename(pth)
  276.         if fnmatch.fnmatchcase(base, _pattern):
  277.             return pth

  278.     for pth in sys.path:
  279.         if not pth:
  280.             pth = '.'
  281.         if not os.path.isdir(pth):
  282.             continue
  283.         if os.path.exists(os.path.join(pth, 'wx.pth')):
  284.             base = open(os.path.join(pth, 'wx.pth')).read()
  285.             return os.path.join(pth, base)

  286.     return None


  287. class _wxPackageInfo(object):
  288.     def __init__(self, pathname, stripFirst=False):
  289.         self.pathname = pathname
  290.         base = os.path.basename(pathname)
  291.         segments = base.split('-')
  292.         if stripFirst:
  293.             segments = segments[1:]
  294.         self.version = tuple([int(x) for x in segments[0].split('.')])
  295.         self.options = segments[1:]


  296.     def Score(self, other, optionsRequired):
  297.         score = 0
  298.         
  299.         # whatever number of version components given in other must
  300.         # match exactly
  301.         minlen = min(len(self.version), len(other.version))
  302.         if self.version[:minlen] != other.version[:minlen]:
  303.             return 0        
  304.         score += 1

  305.         # check for matching options, if optionsRequired then the
  306.         # options are not optional ;-)
  307.         for opt in other.options:
  308.             if opt in self.options:
  309.                 score += 1
  310.             elif optionsRequired:
  311.                 return 0
  312.             
  313.         return score

  314.    
  315.     def CheckOptions(self, other, optionsRequired):
  316.         # if options are not required then this always succeeds
  317.         if not optionsRequired:
  318.             return True
  319.         # otherwise, if we have any option not present in other, then
  320.         # the match fails.
  321.         for opt in self.options:
  322.             if opt not in other.options:
  323.                 return False
  324.         return True

  325.             
  326.    
  327.     def __lt__(self, other):
  328.         return self.version < other.version or \
  329.                (self.version == other.version and self.options < other.options)
  330.     def __le__(self, other):
  331.         return self.version <= other.version or \
  332.                (self.version == other.version and self.options <= other.options)
  333.    
  334.     def __gt__(self, other):
  335.         return self.version > other.version or \
  336.                (self.version == other.version and self.options > other.options)
  337.     def __ge__(self, other):
  338.         return self.version >= other.version or \
  339.                (self.version == other.version and self.options >= other.options)
  340.    
  341.     def __eq__(self, other):
  342.         return self.version == other.version and self.options == other.options
  343.         
  344.    

  345. #----------------------------------------------------------------------

  346. if __name__ == '__main__':
  347.     import pprint

  348.     #ensureMinimal('2.5')
  349.     #pprint.pprint(sys.path)
  350.     #sys.exit()
  351.    
  352.    
  353.     def test(version, optionsRequired=False):
  354.         # setup
  355.         savepath = sys.path[:]

  356.         #test
  357.         select(version, optionsRequired)
  358.         print "Asked for %s, (%s):\t got: %s" % (version, optionsRequired, sys.path[0])

  359.         # reset
  360.         sys.path = savepath[:]
  361.         global _selected
  362.         _selected = None


  363.     def testEM(version, optionsRequired=False):
  364.         # setup
  365.         savepath = sys.path[:]

  366.         #test
  367.         ensureMinimal(version, optionsRequired)
  368.         print "EM: Asked for %s, (%s):\t got: %s" % (version, optionsRequired, sys.path[0])

  369.         # reset
  370.         sys.path = savepath[:]
  371.         global _selected
  372.         _selected = None
  373.         
  374.         
  375.     # make some test dirs
  376.     names = ['wx-2.4-gtk-ansi',
  377.              'wx-2.5.2-gtk2-unicode',
  378.              'wx-2.5.3-gtk-ansi',
  379.              'wx-2.6-gtk2-unicode',
  380.              'wx-2.6-gtk2-ansi',
  381.              'wx-2.6-gtk-ansi',
  382.              'wx-2.7.1-gtk2-ansi',
  383.              ]
  384.     for name in names:
  385.         d = os.path.join('/tmp', name)
  386.         os.mkdir(d)
  387.         os.mkdir(os.path.join(d, 'wx'))

  388.     # setup sys.path to see those dirs
  389.     sys.path.append('/tmp')
  390.    

  391.     # now run some tests
  392.     pprint.pprint( getInstalled())
  393.     print checkInstalled("2.4")
  394.     print checkInstalled("2.5-unicode")
  395.     print checkInstalled("2.99-bogus")
  396.     print "Current sys.path:"
  397.     pprint.pprint(sys.path)
  398.     print
  399.    
  400.     test("2.4")
  401.     test("2.5")
  402.     test("2.5-gtk2")
  403.     test("2.5.2")
  404.     test("2.5-ansi")
  405.     test("2.5-unicode")
  406.     test("2.6")
  407.     test("2.6-ansi")
  408.     test(["2.6-unicode", "2.7-unicode"])
  409.     test(["2.6", "2.7"])
  410.     test(["2.6-unicode", "2.7-unicode"], optionsRequired=True)
  411.    
  412.    
  413.    
  414.     # There isn't a unicode match for this one, but it will give the best
  415.     # available 2.4.  Should it give an error instead?  I don't think so...
  416.     test("2.4-unicode")

  417.     # Try asking for multiple versions
  418.     test(["2.5.2", "2.5.3", "2.6"])

  419.     try:
  420.         # expecting an error on this one
  421.         test("2.9")
  422.     except VersionError, e:
  423.         print "Asked for 2.9:\t got Exception:", e

  424.     # check for exception when incompatible versions are requested
  425.     try:
  426.         select("2.4")
  427.         select("2.5")
  428.     except VersionError, e:
  429.         print "Asked for incompatible versions, got Exception:", e

  430.     _EM_DEBUG=1
  431.     testEM("2.6")
  432.     testEM("2.6-unicode")
  433.     testEM("2.6-unicode", True)
  434.     try:
  435.         testEM("2.9")
  436.     except VersionError, e:
  437.         print "EM: Asked for 2.9:\t got Exception:", e

  438.     # cleanup
  439.     for name in names:
  440.         d = os.path.join('/tmp', name)
  441.         os.rmdir(os.path.join(d, 'wx'))
  442.         os.rmdir(d)

  443.         
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-17 11:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表