Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(28)

Delta Between Two Patch Sets: translate/storage/base.py

Issue 81: Fix CPO memory leak SVN Base: https://translate.svn.sourceforge.net/svnroot/translate/src/trunk/
Left Patch Set: Added some tests workarounds Created 1 year, 4 months ago
Right Patch Set: Created 1 year, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: View regular side by side diff
Right: View regular side by side diff
LEFTRIGHT
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 # 3 #
4 # Copyright 2006-2008 Zuza Software Foundation 4 # Copyright 2006-2008 Zuza Software Foundation
5 # 5 #
6 # This file is part of translate. 6 # This file is part of translate.
7 # 7 #
8 # translate is free software; you can redistribute it and/or modify 8 # translate is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by 9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or 10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version. 11 # (at your option) any later version.
12 # 12 #
13 # translate is distributed in the hope that it will be useful, 13 # translate is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details. 16 # GNU General Public License for more details.
17 # 17 #
18 # You should have received a copy of the GNU General Public License 18 # You should have received a copy of the GNU General Public License
19 # along with translate; if not, write to the Free Software 19 # along with translate; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 21
22 """Base classes for storage interfaces. 22 """Base classes for storage interfaces.
23 23
24 @organization: Zuza Software Foundation 24 @organization: Zuza Software Foundation
25 @copyright: 2006-2007 Zuza Software Foundation 25 @copyright: 2006-2007 Zuza Software Foundation
26 @license: U{GPL <http://www.fsf.org/licensing/licenses/gpl.html>} 26 @license: U{GPL <http://www.fsf.org/licensing/licenses/gpl.html>}
27 """ 27 """
28 28
29 try: 29 try:
30 import cPickle as pickle 30 import cPickle as pickle
31 except: 31 except:
32 import pickle 32 import pickle
33 from exceptions import NotImplementedError 33 from exceptions import NotImplementedError
34 34
35 def force_override(method, baseclass): 35 def force_override(method, baseclass):
36 """Forces derived classes to override method.""" 36 """Forces derived classes to override method."""
37 37
38 if type(method.im_self) == type(baseclass): 38 if type(method.im_self) == type(baseclass):
39 # then this is a classmethod and im_self is the actual class 39 # then this is a classmethod and im_self is the actual class
40 actualclass = method.im_self 40 actualclass = method.im_self
41 else: 41 else:
42 actualclass = method.im_class 42 actualclass = method.im_class
43 if actualclass != baseclass: 43 if actualclass != baseclass:
44 raise NotImplementedError("%s does not reimplement %s as required by %s" % (actualclass.__name__, method.__name__, baseclass.__name__)) 44 raise NotImplementedError("%s does not reimplement %s as required by %s" % (actualclass.__name__, method.__name__, baseclass.__name__))
45 45
46 class ParseError(Exception): 46 class ParseError(Exception):
47 pass 47 pass
48 48
49 class TranslationUnit(object): 49 class TranslationUnit(object):
50 """Base class for translation units. 50 """Base class for translation units.
(...skipping 203 matching lines...) Show 10 above Show 10 below
254 def isheader(self): 254 def isheader(self):
255 """Indicates whether this unit is a header.""" 255 """Indicates whether this unit is a header."""
256 256
257 return False 257 return False
258 258
259 def isreview(self): 259 def isreview(self):
260 """Indicates whether this unit needs review.""" 260 """Indicates whether this unit needs review."""
261 return False 261 return False
262 262
263 263
264 def isblank(self): 264 def isblank(self):
265 """Used to see if this unit has no source or target string. 265 """Used to see if this unit has no source or target string.
266 266
267 @note: This is probably used more to find translatable units, 267 @note: This is probably used more to find translatable units,
268 and we might want to move in that direction rather and get rid of this. 268 and we might want to move in that direction rather and get rid of this.
269 269
270 """ 270 """
271 271
272 return not (self.source or self.target) 272 return not (self.source or self.target)
273 273
274 def hasplural(self): 274 def hasplural(self):
275 """Tells whether or not this specific unit has plural strings.""" 275 """Tells whether or not this specific unit has plural strings."""
276 276
277 #TODO: Reconsider 277 #TODO: Reconsider
278 return False 278 return False
279 279
280 def getsourcelanguage(self): 280 def getsourcelanguage(self):
281 return getattr(self._store, "sourcelanguage", "en") 281 return getattr(self._store, "sourcelanguage", "en")
282 282
283 def gettargetlanguage(self): 283 def gettargetlanguage(self):
284 return getattr(self._store, "targetlanguage", None) 284 return getattr(self._store, "targetlanguage", None)
285 285
286 def merge(self, otherunit, overwrite=False, comments=True): 286 def merge(self, otherunit, overwrite=False, comments=True):
287 """Do basic format agnostic merging.""" 287 """Do basic format agnostic merging."""
288 288
289 if self.target == "" or overwrite: 289 if self.target == "" or overwrite:
290 self.target = otherunit.target 290 self.target = otherunit.target
291 291
292 def unit_iter(self): 292 def unit_iter(self):
293 """Iterator that only returns this unit.""" 293 """Iterator that only returns this unit."""
294 yield self 294 yield self
295 295
296 def getunits(self): 296 def getunits(self):
297 """This unit in a list.""" 297 """This unit in a list."""
298 return [self] 298 return [self]
299 299
300 def buildfromunit(cls, unit): 300 def buildfromunit(cls, unit):
301 """Build a native unit from a foreign unit, preserving as much 301 """Build a native unit from a foreign unit, preserving as much
302 information as possible.""" 302 information as possible."""
303 303
304 if type(unit) == cls and hasattr(unit, "copy") and callable(unit.copy): 304 #if type(unit) == cls and hasattr(unit, "copy") and callable(unit.copy):
305 return unit.copy() 305 # return unit.copy()
306 newunit = cls(unit.source) 306 newunit = cls(unit.source)
307 newunit.target = unit.target 307 newunit.target = unit.target
308 newunit.markfuzzy(unit.isfuzzy()) 308 newunit.markfuzzy(unit.isfuzzy())
309 locations = unit.getlocations() 309 locations = unit.getlocations()
310 if locations: 310 if locations:
311 newunit.addlocations(locations) 311 newunit.addlocations(locations)
312 notes = unit.getnotes() 312 notes = unit.getnotes()
313 if notes: 313 if notes:
314 newunit.addnote(notes) 314 newunit.addnote(notes)
315 return newunit 315 return newunit
316 buildfromunit = classmethod(buildfromunit) 316 buildfromunit = classmethod(buildfromunit)
317 317
318 class TranslationStore(object): 318 class TranslationStore(object):
319 """Base class for stores for multiple translation units of type UnitClass."" " 319 """Base class for stores for multiple translation units of type UnitClass."" "
320 320
321 UnitClass = TranslationUnit 321 UnitClass = TranslationUnit
322 Mimetypes = None 322 Mimetypes = None
323 Extensions = None 323 Extensions = None
324 324
325 def __init__(self, unitclass=None): 325 def __init__(self, unitclass=None):
326 """Constructs a blank TranslationStore.""" 326 """Constructs a blank TranslationStore."""
327 327
328 self.units = [] 328 self.units = []
329 self.filepath = None 329 self.filepath = None
330 self.translator = "" 330 self.translator = ""
331 self.date = "" 331 self.date = ""
332 self.sourcelanguage = None 332 self.sourcelanguage = None
333 self.targetlanguage = None 333 self.targetlanguage = None
334 if unitclass: 334 if unitclass:
335 self.UnitClass = unitclass 335 self.UnitClass = unitclass
336 super(TranslationStore, self).__init__() 336 super(TranslationStore, self).__init__()
337 337
338 def setsourcelanguage(self, sourcelanguage): 338 def setsourcelanguage(self, sourcelanguage):
339 """Sets the source language for this store""" 339 """Sets the source language for this store"""
340 self.sourcelanguage = sourcelanguage 340 self.sourcelanguage = sourcelanguage
341 341
342 def settargetlanguage(self, targetlanguage): 342 def settargetlanguage(self, targetlanguage):
343 """Sets the target language for this store""" 343 """Sets the target language for this store"""
344 self.targetlanguage = targetlanguage 344 self.targetlanguage = targetlanguage
345 345
346 def unit_iter(self): 346 def unit_iter(self):
347 """Iterator over all the units in this store.""" 347 """Iterator over all the units in this store."""
348 for unit in self.units: 348 for unit in self.units:
349 yield unit 349 yield unit
350 350
351 def getunits(self): 351 def getunits(self):
352 """Return a list of all units in this store.""" 352 """Return a list of all units in this store."""
353 return [unit for unit in self.unit_iter()] 353 return [unit for unit in self.unit_iter()]
354 354
355 def addunit(self, unit): 355 def addunit(self, unit):
(...skipping 104 matching lines...) Show 10 above Show 10 below
460 return newstore 460 return newstore
461 parsestring = classmethod(parsestring) 461 parsestring = classmethod(parsestring)
462 462
463 def parse(self, data): 463 def parse(self, data):
464 """parser to process the given source string""" 464 """parser to process the given source string"""
465 self.units = pickle.loads(data).units 465 self.units = pickle.loads(data).units
466 466
467 def savefile(self, storefile): 467 def savefile(self, storefile):
468 """Writes the string representation to the given file (or filename).""" 468 """Writes the string representation to the given file (or filename)."""
469 if isinstance(storefile, basestring): 469 if isinstance(storefile, basestring):
470 storefile = open(storefile, "w") 470 storefile = open(storefile, "w")
471 self.fileobj = storefile 471 self.fileobj = storefile
472 self._assignname() 472 self._assignname()
473 storestring = str(self) 473 storestring = str(self)
474 storefile.write(storestring) 474 storefile.write(storestring)
475 storefile.close() 475 storefile.close()
476 476
477 def save(self): 477 def save(self):
478 """Save to the file that data was originally read from, if available.""" 478 """Save to the file that data was originally read from, if available."""
479 fileobj = getattr(self, "fileobj", None) 479 fileobj = getattr(self, "fileobj", None)
480 if not fileobj: 480 if not fileobj:
481 filename = getattr(self, "filename", None) 481 filename = getattr(self, "filename", None)
482 if filename: 482 if filename:
483 fileobj = file(filename, "w") 483 fileobj = file(filename, "w")
484 else: 484 else:
485 fileobj.close() 485 fileobj.close()
486 filename = getattr(fileobj, "name", getattr(fileobj, "filename", Non e)) 486 filename = getattr(fileobj, "name", getattr(fileobj, "filename", Non e))
487 if not filename: 487 if not filename:
488 raise ValueError("No file or filename to save to") 488 raise ValueError("No file or filename to save to")
489 fileobj = fileobj.__class__(filename, "w") 489 fileobj = fileobj.__class__(filename, "w")
490 self.savefile(fileobj) 490 self.savefile(fileobj)
491 491
492 def parsefile(cls, storefile): 492 def parsefile(cls, storefile):
493 """Reads the given file (or opens the given filename) and parses back to an object.""" 493 """Reads the given file (or opens the given filename) and parses back to an object."""
494 494
495 if isinstance(storefile, basestring): 495 if isinstance(storefile, basestring):
496 storefile = open(storefile, "r") 496 storefile = open(storefile, "r")
497 mode = getattr(storefile, "mode", "r") 497 mode = getattr(storefile, "mode", "r")
498 #For some reason GzipFile returns 1, so we have to test for that here 498 #For some reason GzipFile returns 1, so we have to test for that here
499 if mode == 1 or "r" in mode: 499 if mode == 1 or "r" in mode:
500 storestring = storefile.read() 500 storestring = storefile.read()
501 storefile.close() 501 storefile.close()
502 else: 502 else:
503 storestring = "" 503 storestring = ""
504 newstore = cls.parsestring(storestring) 504 newstore = cls.parsestring(storestring)
505 newstore.fileobj = storefile 505 newstore.fileobj = storefile
506 newstore._assignname() 506 newstore._assignname()
507 return newstore 507 return newstore
508 parsefile = classmethod(parsefile) 508 parsefile = classmethod(parsefile)
509 509
LEFTRIGHT

Powered by Google App Engine
This is Rietveld r159