Module compat
[hide private]
[frames] | no frames]

Source Code for Module compat

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2012 Edward d'Auvergne                                        # 
  4  #                                                                             # 
  5  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  6  #                                                                             # 
  7  # This program is free software: you can redistribute it and/or modify        # 
  8  # it under the terms of the GNU General Public License as published by        # 
  9  # the Free Software Foundation, either version 3 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # This program is distributed in the hope that it will be useful,             # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 15  # GNU General Public License for more details.                                # 
 16  #                                                                             # 
 17  # You should have received a copy of the GNU General Public License           # 
 18  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 19  #                                                                             # 
 20  ############################################################################### 
 21   
 22  # Module docstring. 
 23  """Temporary module for allowing relax to support both Python 2 and 3.""" 
 24   
 25  # Python module imports. 
 26  import sys 
 27  from copy import deepcopy 
 28  import os 
 29  import platform 
 30  if sys.version_info[0] == 2: 
 31      from Queue import Queue as Queue2 
 32  else: 
 33      from queue import Queue as Queue3 
 34      Queue2 = Queue3 
 35  import threading 
 36   
 37   
 38  # The operating system. 
 39  SYSTEM = platform.uname()[0] 
 40   
 41   
42 -def sorted(data):
43 """Python 2.3 and earlier replacement function for the builtin sorted() function.""" 44 45 # Make a copy of the data. 46 new_data = deepcopy(data) 47 48 # Sort. 49 new_data.sort() 50 51 # Return the new data. 52 return new_data
53 54 55
56 -class TaskQueue(Queue2):
57 """Python 2.4 and earlier Queuing class replacement. 58 59 This code comes from http://code.activestate.com/recipes/475160/ and is part of the Python sources from 2.5 onwards. 60 """ 61
62 - def __init__(self):
63 Queue2.__init__(self) 64 self.all_tasks_done = threading.Condition(self.mutex) 65 self.unfinished_tasks = 0
66
67 - def _put(self, item):
68 Queue2._put(self, item) 69 self.unfinished_tasks += 1
70
71 - def task_done(self):
72 """Indicate that a formerly enqueued task is complete. 73 74 Used by Queue consumer threads. For each get() used to fetch a task, 75 a subsequent call to task_done() tells the queue that the processing 76 on the task is complete. 77 78 If a join() is currently blocking, it will resume when all items 79 have been processed (meaning that a task_done() call was received 80 for every item that had been put() into the queue). 81 82 Raises a ValueError if called more times than there were items 83 placed in the queue. 84 """ 85 self.all_tasks_done.acquire() 86 try: 87 unfinished = self.unfinished_tasks - 1 88 if unfinished <= 0: 89 if unfinished < 0: 90 raise ValueError('task_done() called too many times') 91 self.all_tasks_done.notifyAll() 92 self.unfinished_tasks = unfinished 93 finally: 94 self.all_tasks_done.release()
95
96 - def join(self):
97 """Blocks until all items in the Queue have been gotten and processed. 98 99 The count of unfinished tasks goes up whenever an item is added to the 100 queue. The count goes down whenever a consumer thread calls task_done() 101 to indicate the item was retrieved and all work on it is complete. 102 103 When the count of unfinished tasks drops to zero, join() unblocks. 104 """ 105 self.all_tasks_done.acquire() 106 try: 107 while self.unfinished_tasks: 108 self.all_tasks_done.wait() 109 finally: 110 self.all_tasks_done.release()
111 112 113 # Alias the correct Queue. 114 if sys.version_info[0] == 2 and sys.version_info[1] <= 4: 115 Queue = TaskQueue # Alias the TaskQueue for Python 2.4 and earlier. 116 elif sys.version_info[0] == 2: 117 Queue = Queue2 118 else: 119 Queue = Queue3 120 121 122 # The Python version. 123 py_version = sys.version_info[0] 124 125 # Python 2 hacks. 126 if py_version == 2: 127 # Python 2 only imports. 128 import __builtin__ 129 130 # Switch all range() calls to xrange() for increased speed and memory reduction. 131 # This should work as all range() usage for Python 3 in relax must match the old xrange() usage. 132 __builtin__.range = __builtin__.xrange 133 134 # The sorted() builtin function for Python 2.3 and earlier. 135 if sys.version_info[1] <= 3: 136 setattr(__builtin__, 'sorted', sorted) 137 138 # The os.devnull object for Python 2.3 and earlier. 139 if sys.version_info[1] <= 3: 140 if SYSTEM == 'Linux': 141 os.devnull = '/dev/null' 142 elif SYSTEM == 'Windows' or SYSTEM == 'Microsoft': 143 os.devnull = 'nul' 144 elif SYSTEM == 'Darwin': 145 os.devnull = 'Dev:Null' 146 else: 147 os.devnull = None 148 149 150 # Python 3 work-arounds. 151 if py_version == 3: 152 # Python 3 only imports. 153 import builtins 154 155 # The unicode conversion function - essential for the GUI in Python 2. 156 builtins.unicode = builtins.str 157