summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--__init__.py205
-rw-r--r--astutils.py5
-rw-r--r--bind.py4
-rw-r--r--compat.py4
-rw-r--r--decorators.py102
-rw-r--r--deprecation.py83
-rw-r--r--html.py4
-rw-r--r--interface.py2
-rw-r--r--logger.py5
-rw-r--r--logservice.py5
-rw-r--r--modutils.py12
-rw-r--r--monclient.py5
-rw-r--r--monserver.py4
-rw-r--r--patricia.py4
-rw-r--r--shellutils.py59
-rw-r--r--test/unittest_compat.py2
-rw-r--r--test/unittest_graph.py2
-rw-r--r--test/unittest_textutils.py8
-rw-r--r--testlib.py2
-rw-r--r--textutils.py21
-rw-r--r--tree.py8
-rw-r--r--twisted_distutils.py6
23 files changed, 334 insertions, 235 deletions
diff --git a/ChangeLog b/ChangeLog
index b555adc..0433597 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,23 @@ ChangeLog for logilab.common
- new optional keepownership argument to backup|restore_database methods
- only register mxDatetime converters on psycopg2 adapter if
mx.DateTime is available
+ * moved some stuff which was in common __init__ file into specific
+ module. At this occasion new "decorators" and "deprecation" modules
+ has been add
+ * mark the following modules for deprecation, they will be removed in a
+ near version:
+ * astutils: moved to astng
+ * bind (never been used)
+ * html: deprecated
+ * logger/logservice: use logging module
+ * monclient/monserver (not used anymore)
+ * patricia (never been used)
+ * twisted_distutils (not used anymore)
+ * removed the following functions/methods which have been deprecated for a
+ while now:
+ * modutils.load_module_from_parts
+ * textutils.searchall
+ * tree.Node.leafs
2006-11-03 -- 0.20.2
* fileutils: new remove_dead_links function
diff --git a/__init__.py b/__init__.py
index 71a1f1c..f8f2e17 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,3 +1,6 @@
+# Copyright (c) 2004-2006 LOGILAB S.A. (Paris, FRANCE).
+# http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
@@ -10,21 +13,26 @@
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-""" Copyright (c) 2002-2006 LOGILAB S.A. (Paris, FRANCE).
- http://www.logilab.fr/ -- mailto:contact@logilab.fr
-
-Logilab common libraries
-"""
+"""Logilab common libraries:
-from __future__ import nested_scopes
+a set of common functionnalities shared among logilab projects
+"""
-# bw compat
-from logilab.common.graph import get_cycles
+from logilab.common.deprecation import moved
-# FIXME: move all those functions in a separated module
+get_cycles = moved('logilab.common.graph', 'get_cycles')
+cached = moved('logilab.common.decorators', 'cached')
+ProgressBar = moved('logilab.common.shellutils', 'ProgressBar')
+Execute = moved('logilab.common.shellutils', 'Execute')
+acquire_lock = moved('logilab.common.shellutils', 'acquire_lock')
+release_lock = moved('logilab.common.shellutils', 'release_lock')
+deprecated_function = moved('logilab.common.deprecation', 'deprecated_function')
+class_renamed = moved('logilab.common.deprecation', 'class_renamed')
def intersection(list1, list2):
"""return the intersection of list1 and list2"""
+ warn('this function is deprecated, use a set instead', DeprecationWarning,
+ stacklevel=2)
intersect_dict, result = {}, []
for item in list1:
intersect_dict[item] = 1
@@ -35,6 +43,8 @@ def intersection(list1, list2):
def difference(list1, list2):
"""return elements of list1 not in list2"""
+ warn('this function is deprecated, use a set instead', DeprecationWarning,
+ stacklevel=2)
tmp, result = {}, []
for i in list2:
tmp[i] = 1
@@ -45,6 +55,8 @@ def difference(list1, list2):
def union(list1, list2):
"""return list1 union list2"""
+ warn('this function is deprecated, use a set instead', DeprecationWarning,
+ stacklevel=2)
tmp = {}
for i in list1:
tmp[i] = 1
@@ -52,6 +64,9 @@ def union(list1, list2):
tmp[i] = 1
return tmp.keys()
+
+# XXX are functions below still used ?
+
def make_domains(lists):
"""
given a list of lists, return a list of domain for each list to produce all
@@ -88,7 +103,7 @@ def flatten(iterable, tr_func=None, results=None):
if results is None:
results = []
for val in iterable:
- if type(val) in (type(()), type([])):
+ if isinstance(val, (list, tuple)):
flatten(val, tr_func, results)
elif tr_func is None:
results.append(val)
@@ -97,174 +112,4 @@ def flatten(iterable, tr_func=None, results=None):
return results
-def cached(callableobj, keyarg=None):
- """simple decorator to cache result of method call"""
- #print callableobj, keyarg, callableobj.func_code.co_argcount
- if callableobj.func_code.co_argcount == 1 or keyarg == 0:
-
- def cache_wrapper1(self, *args):
- cache = '_%s_cache_' % callableobj.__name__
- #print 'cache1?', cache
- try:
- return getattr(self, cache)
- except AttributeError:
- #print 'miss'
- value = callableobj(self, *args)
- setattr(self, cache, value)
- return value
- return cache_wrapper1
-
- elif keyarg:
-
- def cache_wrapper2(self, *args, **kwargs):
- cache = '_%s_cache_' % callableobj.__name__
- key = args[keyarg-1]
- #print 'cache2?', cache, self, key
- try:
- _cache = getattr(self, cache)
- except AttributeError:
- #print 'init'
- _cache = {}
- setattr(self, cache, _cache)
- try:
- return _cache[key]
- except KeyError:
- #print 'miss', self, cache, key
- _cache[key] = callableobj(self, *args, **kwargs)
- return _cache[key]
- return cache_wrapper2
- def cache_wrapper3(self, *args):
- cache = '_%s_cache_' % callableobj.__name__
- #print 'cache3?', cache, self, args
- try:
- _cache = getattr(self, cache)
- except AttributeError:
- #print 'init'
- _cache = {}
- setattr(self, cache, _cache)
- try:
- return _cache[args]
- except KeyError:
- #print 'miss'
- _cache[args] = callableobj(self, *args)
- return _cache[args]
- return cache_wrapper3
-
-import sys
-
-class ProgressBar(object):
- """a simple text progression bar"""
-
- def __init__(self, nbops, size=20., stream=sys.stdout):
- self._dotevery = max(nbops / size, 1)
- self._fstr = '\r[%-20s]'
- self._dotcount, self._dots = 1, []
- self._stream = stream
-
- def update(self):
- """update the progression bar"""
- self._dotcount += 1
- if self._dotcount >= self._dotevery:
- self._dotcount = 1
- self._dots.append('.')
- self._stream.write(self._fstr % ''.join(self._dots))
- self._stream.flush()
-
-
-import tempfile
-import os
-import time
-from os.path import exists
-
-class Execute:
- """This is a deadlock save version of popen2 (no stdin), that returns
- an object with errorlevel, out and err
- """
-
- def __init__(self, command):
- outfile = tempfile.mktemp()
- errfile = tempfile.mktemp()
- self.status = os.system("( %s ) >%s 2>%s" %
- (command, outfile, errfile)) >> 8
- self.out = open(outfile,"r").read()
- self.err = open(errfile,"r").read()
- os.remove(outfile)
- os.remove(errfile)
-def acquire_lock(lock_file, max_try=10, delay=10):
- """acquire a lock represented by a file on the file system"""
- count = 0
- while max_try <= 0 or count < max_try:
- if not exists(lock_file):
- break
- count += 1
- time.sleep(delay)
- else:
- raise Exception('Unable to acquire %s' % lock_file)
- stream = open(lock_file, 'w')
- stream.write(str(os.getpid()))
- stream.close()
-
-def release_lock(lock_file):
- """release a lock represented by a file on the file system"""
- os.remove(lock_file)
-
-
-## Deprecation utilities #########################
-
-from warnings import warn
-
-class deprecated(type):
- """metaclass to print a warning on instantiation of a deprecated class"""
-
- def __call__(cls, *args, **kwargs):
- msg = getattr(cls, "__deprecation_warning__",
- "%s is deprecated" % cls.__name__)
- warn(msg, DeprecationWarning, stacklevel=2)
- return type.__call__(cls, *args, **kwargs)
-
-
-def class_renamed(old_name, new_class, message=None):
- """automatically creates a class which fires a DeprecationWarning
- when instantiated.
-
- >>> Set = class_renamed('Set', set, 'Set is now replaced by set')
- >>> s = Set()
- sample.py:57: DeprecationWarning: Set is now replaced by set
- s = Set()
- >>>
- """
- clsdict = {}
- if message is not None:
- clsdict['__deprecation_warning__'] = message
- try:
- # new-style class
- return deprecated(old_name, (new_class,), clsdict)
- except (NameError, TypeError):
- # old-style class
- class DeprecatedClass(new_class):
- """FIXME: There might be a better way to handle old/new-style class
- """
- def __init__(self, *args, **kwargs):
- warn(message, DeprecationWarning, stacklevel=2)
- new_class.__init__(self, *args, **kwargs)
- return DeprecatedClass
-
-
-def deprecated_function(new_func, message=None):
- """creates a function which fires a DeprecationWarning when used
-
- For example, if <bar> is deprecated in favour of <foo> :
- >>> bar = deprecated_function(foo, 'bar is deprecated')
- >>> bar()
- sample.py:57: DeprecationWarning: bar is deprecated
- bar()
- >>>
- """
- if message is None:
- message = "this function is deprecated, use %s instead" % (
- new_func.func_name)
- def deprecated(*args, **kwargs):
- warn(message, DeprecationWarning, stacklevel=2)
- return new_func(*args, **kwargs)
- return deprecated
diff --git a/astutils.py b/astutils.py
index 9d4fe36..1a14106 100644
--- a/astutils.py
+++ b/astutils.py
@@ -16,6 +16,11 @@
"""Some usefull functions to manipulate ast tuples
"""
+from warnings import warn
+warn('this module has been moved into logilab.astng and will disappear from \
+logilab.common in a near release',
+ DeprecationWarning, stacklevel=1)
+
__author__ = u"Sylvain Thenault"
import symbol
diff --git a/bind.py b/bind.py
index 9f2b40f..277af73 100644
--- a/bind.py
+++ b/bind.py
@@ -18,6 +18,10 @@
their names to values provided in a dictionnary
"""
+from warnings import warn
+warn('this module is deprecated and will disappear in a near release',
+ DeprecationWarning, stacklevel=1)
+
__revision__ = '$Id: bind.py,v 1.8 2005-11-22 13:12:59 syt Exp $'
# TODO: unit tests
diff --git a/compat.py b/compat.py
index 26490df..d9a11f5 100644
--- a/compat.py
+++ b/compat.py
@@ -1,6 +1,6 @@
# pylint: disable-msg=E0601,W0622,W0611
#
-# Copyright (c) 2004-2005 LOGILAB S.A. (Paris, FRANCE).
+# Copyright (c) 2004-2006 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This program is free software; you can redistribute it and/or modify it under
@@ -22,7 +22,7 @@ from __future__ import generators
from warnings import warn
-from logilab.common import class_renamed
+from logilab.common.deprecation import class_renamed
try:
set = set
diff --git a/decorators.py b/decorators.py
new file mode 100644
index 0000000..34c9bb7
--- /dev/null
+++ b/decorators.py
@@ -0,0 +1,102 @@
+# Copyright (c) 2006 LOGILAB S.A. (Paris, FRANCE).
+# http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+"""this module contains some function/method decorators"""
+
+# XXX rewrite so we can use the decorator syntax when keyarg has to be specified
+
+def cached(callableobj, keyarg=None):
+ """simple decorator to cache result of method call"""
+ #print callableobj, keyarg, callableobj.func_code.co_argcount
+ if callableobj.func_code.co_argcount == 1 or keyarg == 0:
+
+ def cache_wrapper1(self, *args):
+ cache = '_%s_cache_' % callableobj.__name__
+ #print 'cache1?', cache
+ try:
+ return getattr(self, cache)
+ except AttributeError:
+ #print 'miss'
+ value = callableobj(self, *args)
+ setattr(self, cache, value)
+ return value
+ return cache_wrapper1
+
+ elif keyarg:
+
+ def cache_wrapper2(self, *args, **kwargs):
+ cache = '_%s_cache_' % callableobj.__name__
+ key = args[keyarg-1]
+ #print 'cache2?', cache, self, key
+ try:
+ _cache = getattr(self, cache)
+ except AttributeError:
+ #print 'init'
+ _cache = {}
+ setattr(self, cache, _cache)
+ try:
+ return _cache[key]
+ except KeyError:
+ #print 'miss', self, cache, key
+ _cache[key] = callableobj(self, *args, **kwargs)
+ return _cache[key]
+ return cache_wrapper2
+ def cache_wrapper3(self, *args):
+ cache = '_%s_cache_' % callableobj.__name__
+ #print 'cache3?', cache, self, args
+ try:
+ _cache = getattr(self, cache)
+ except AttributeError:
+ #print 'init'
+ _cache = {}
+ setattr(self, cache, _cache)
+ try:
+ return _cache[args]
+ except KeyError:
+ #print 'miss'
+ _cache[args] = callableobj(self, *args)
+ return _cache[args]
+ return cache_wrapper3
+
+def clear_cache(obj, funcname):
+ """function to clear a cache handled by the cached decorator"""
+ try:
+ delattr(obj, '_%s_cache_' % funcname)
+ except AttributeError:
+ pass
+
+def copy_cache(obj, funcname, cacheobj):
+ """copy cache for <funcname> from cacheobj to obj"""
+ cache = '_%s_cache_' % funcname
+ try:
+ setattr(obj, cache, getattr(cacheobj, cache))
+ except AttributeError:
+ pass
+
+
+class wproperty(object):
+ """simple descriptor expecting to take a modifier function as first argument
+ and looking for a _<function name> to retreive the attribute
+ """
+ def __init__(self, setfunc):
+ self.setfunc = setfunc
+ self.attrname = '_%s' % setfunc.__name__
+
+ def __set__(self, obj, value):
+ setfunc(obj, value)
+
+ def __get__(self, obj, cls):
+ assert obj is not None
+ return getattr(obj, self.attrname)
diff --git a/deprecation.py b/deprecation.py
new file mode 100644
index 0000000..eeb1c3b
--- /dev/null
+++ b/deprecation.py
@@ -0,0 +1,83 @@
+# Copyright (c) 2005-2006 LOGILAB S.A. (Paris, FRANCE).
+# http://www.logilab.fr/ -- mailto:contact@logilab.fr
+
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 2 of the License, or (at your option) any later
+# version.
+
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+"""Deprecation utilities"""
+
+from warnings import warn
+from logilab.common.modutils import load_module_from_name
+
+class deprecated(type):
+ """metaclass to print a warning on instantiation of a deprecated class"""
+
+ def __call__(cls, *args, **kwargs):
+ msg = getattr(cls, "__deprecation_warning__",
+ "%s is deprecated" % cls.__name__)
+ warn(msg, DeprecationWarning, stacklevel=2)
+ return type.__call__(cls, *args, **kwargs)
+
+
+def class_renamed(old_name, new_class, message=None):
+ """automatically creates a class which fires a DeprecationWarning
+ when instantiated.
+
+ >>> Set = class_renamed('Set', set, 'Set is now replaced by set')
+ >>> s = Set()
+ sample.py:57: DeprecationWarning: Set is now replaced by set
+ s = Set()
+ >>>
+ """
+ clsdict = {}
+ if message is not None:
+ clsdict['__deprecation_warning__'] = message
+ try:
+ # new-style class
+ return deprecated(old_name, (new_class,), clsdict)
+ except (NameError, TypeError):
+ # old-style class
+ class DeprecatedClass(new_class):
+ """FIXME: There might be a better way to handle old/new-style class
+ """
+ def __init__(self, *args, **kwargs):
+ warn(message, DeprecationWarning, stacklevel=2)
+ new_class.__init__(self, *args, **kwargs)
+ return DeprecatedClass
+
+
+def deprecated_function(new_func, message=None):
+ """creates a function which fires a DeprecationWarning when used
+
+ For example, if <bar> is deprecated in favour of <foo> :
+ >>> bar = deprecated_function(foo, 'bar is deprecated')
+ >>> bar()
+ sample.py:57: DeprecationWarning: bar is deprecated
+ bar()
+ >>>
+ """
+ if message is None:
+ message = "this function is deprecated, use %s instead" % (
+ new_func.func_name)
+ def deprecated(*args, **kwargs):
+ warn(message, DeprecationWarning, stacklevel=2)
+ return new_func(*args, **kwargs)
+ return deprecated
+
+def moved(modpath, objname):
+ def callnew(*args, **kwargs):
+ message = "this object has been moved, it's now %s.%s" % (
+ modpath, objname)
+ warn(message, DeprecationWarning, stacklevel=2)
+ m = load_module_from_name(modpath)
+ return getattr(m, objname)(*args, **kwargs)
+ return callnew
diff --git a/html.py b/html.py
index e9f081f..6348906 100644
--- a/html.py
+++ b/html.py
@@ -14,6 +14,10 @@
http://www.logilab.fr/ -- mailto:contact@logilab.fr
"""
+from warnings import warn
+warn('this module is deprecated and will disappear in a near release',
+ DeprecationWarning, stacklevel=1)
+
__revision__ = "$Id: html.py,v 1.5 2003-09-12 11:54:47 syt Exp $"
import traceback
diff --git a/interface.py b/interface.py
index f4800f0..e94df1b 100644
--- a/interface.py
+++ b/interface.py
@@ -24,8 +24,6 @@
This module requires at least python 2.2
"""
-__revision__ = "$Id: interface.py,v 1.6 2004-05-10 14:40:50 syt Exp $"
-
from types import ListType, TupleType
class Interface:
diff --git a/logger.py b/logger.py
index 9fa62a0..b823deb 100644
--- a/logger.py
+++ b/logger.py
@@ -17,6 +17,11 @@ Define a logger interface and two concrete loggers : one which prints
everything on stdout, the other using syslog.
"""
+from warnings import warn
+warn('this module is deprecated and will disappear in a near release. \
+use logging module instead.',
+ DeprecationWarning, stacklevel=1)
+
__revision__ = "$Id: logger.py,v 1.18 2006-02-03 14:17:42 adim Exp $"
diff --git a/logservice.py b/logservice.py
index dd90f7b..00af91e 100644
--- a/logservice.py
+++ b/logservice.py
@@ -4,6 +4,11 @@ Copyright (c) 2003-2004 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
http://www.logilab.fr/ -- mailto:contact@logilab.fr
"""
+from warnings import warn
+warn('this module is deprecated and will disappear in a near release. \
+use logging module instead.',
+ DeprecationWarning, stacklevel=1)
+
__revision__ = "$Id: logservice.py,v 1.5 2006-03-05 16:13:28 syt Exp $"
from logilab.common.logger import make_logger, LOG_ERR, LOG_WARN, LOG_NOTICE, \
diff --git a/modutils.py b/modutils.py
index 19606b2..fadba5b 100644
--- a/modutils.py
+++ b/modutils.py
@@ -1,5 +1,5 @@
# -*- coding: iso-8859-1 -*-
-# Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE).
+# Copyright (c) 2003-2006 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This program is free software; you can redistribute it and/or modify it under
@@ -16,9 +16,8 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Python modules manipulation utility functions.
-:version: $Revision: 1.53 $
:author: Logilab
-:copyright: 2003-2005 LOGILAB S.A. (Paris, FRANCE)
+:copyright: 2003-2006 LOGILAB S.A. (Paris, FRANCE)
:contact: http://www.logilab.fr/ -- mailto:python-projects@logilab.org
@@ -33,16 +32,12 @@
:var BUILTIN_MODULES: dictionary with builtin module names has key
"""
-from __future__ import nested_scopes
-
-__revision__ = "$Id: modutils.py,v 1.53 2006-03-06 08:05:11 syt Exp $"
__docformat__ = "restructuredtext en"
import sys
import os
from os.path import walk, splitext, join, abspath, isdir, dirname, exists
from imp import find_module, load_module, C_BUILTIN, PY_COMPILED, PKG_DIRECTORY
-from logilab.common import deprecated_function
if sys.platform.startswith('win'):
PY_SOURCE_EXTS = ('py', 'pyw')
@@ -132,9 +127,6 @@ def load_module_from_modpath(parts, path=None, use_sys=1):
prevmodule = module
return module
-load_module_from_parts = deprecated_function(load_module_from_modpath)
-
-
def modpath_from_file(filename):
"""given a file path return the corresponding splitted module's name
diff --git a/monclient.py b/monclient.py
index 243f06b..19528dd 100644
--- a/monclient.py
+++ b/monclient.py
@@ -1,6 +1,11 @@
"""Simple interpreter client for monserver
provides a simple readline interface.
"""
+
+from warnings import warn
+warn('this module is deprecated and will disappear in a near release',
+ DeprecationWarning, stacklevel=1)
+
from socket import socket, SOCK_STREAM, AF_INET
from select import select
import sys
diff --git a/monserver.py b/monserver.py
index bdf38d3..f3c22b3 100644
--- a/monserver.py
+++ b/monserver.py
@@ -4,6 +4,10 @@ allows *one* client to connect and provides a command line interpreter
allowing the remote client to explore the process on the fly
"""
+from warnings import warn
+warn('this module is deprecated and will disappear in a near release',
+ DeprecationWarning, stacklevel=1)
+
__revision__ = '$Id: monserver.py,v 1.2 2005-11-22 13:13:02 syt Exp $'
import threading
diff --git a/patricia.py b/patricia.py
index 0b10e8b..ee179dd 100644
--- a/patricia.py
+++ b/patricia.py
@@ -26,6 +26,10 @@ TODO: _ advanced search
_ use mxTextTools ?
"""
+from warnings import warn
+warn('this module is deprecated and will disappear in a near release',
+ DeprecationWarning, stacklevel=1)
+
__revision__ = "$Id: patricia.py,v 1.5 2003-10-31 14:18:32 syt Exp $"
def prefix(prfx, string):
diff --git a/shellutils.py b/shellutils.py
index 18bd75d..da4f355 100644
--- a/shellutils.py
+++ b/shellutils.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2003-2005 LOGILAB S.A. (Paris, FRANCE).
+# Copyright (c) 2003-2006 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
# This program is free software; you can redistribute it and/or modify it under
@@ -14,13 +14,16 @@
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""
-Some shell utilities, usefull to write some python scripts instead of shell
+Some shell/term utilities, useful to write some python scripts instead of shell
scripts
"""
import os
import glob
import shutil
+import sys
+import tempfile
+import time
from os.path import exists, isdir, basename, join
def mv(source, destination, _action=os.rename):
@@ -59,3 +62,55 @@ def cp(source, destination):
"""
mv(source, destination, _action=shutil.copy)
+
+class Execute:
+ """This is a deadlock safe version of popen2 (no stdin), that returns
+ an object with errorlevel, out and err
+ """
+
+ def __init__(self, command):
+ outfile = tempfile.mktemp()
+ errfile = tempfile.mktemp()
+ self.status = os.system("( %s ) >%s 2>%s" %
+ (command, outfile, errfile)) >> 8
+ self.out = open(outfile,"r").read()
+ self.err = open(errfile,"r").read()
+ os.remove(outfile)
+ os.remove(errfile)
+
+def acquire_lock(lock_file, max_try=10, delay=10):
+ """acquire a lock represented by a file on the file system"""
+ count = 0
+ while max_try <= 0 or count < max_try:
+ if not exists(lock_file):
+ break
+ count += 1
+ time.sleep(delay)
+ else:
+ raise Exception('Unable to acquire %s' % lock_file)
+ stream = open(lock_file, 'w')
+ stream.write(str(os.getpid()))
+ stream.close()
+
+def release_lock(lock_file):
+ """release a lock represented by a file on the file system"""
+ os.remove(lock_file)
+
+
+class ProgressBar(object):
+ """a simple text progression bar"""
+
+ def __init__(self, nbops, size=20., stream=sys.stdout):
+ self._dotevery = max(nbops / size, 1)
+ self._fstr = '\r[%-20s]'
+ self._dotcount, self._dots = 1, []
+ self._stream = stream
+
+ def update(self):
+ """update the progression bar"""
+ self._dotcount += 1
+ if self._dotcount >= self._dotevery:
+ self._dotcount = 1
+ self._dots.append('.')
+ self._stream.write(self._fstr % ''.join(self._dots))
+ self._stream.flush()
diff --git a/test/unittest_compat.py b/test/unittest_compat.py
index 1558ba8..5c39198 100644
--- a/test/unittest_compat.py
+++ b/test/unittest_compat.py
@@ -1,7 +1,5 @@
"""provides unit tests for compat module"""
-__revision__ = '$Id: unittest_compat.py,v 1.3 2005-08-08 10:44:10 adim Exp $'
-
from logilab.common.testlib import TestCase, unittest_main
import sys
import types
diff --git a/test/unittest_graph.py b/test/unittest_graph.py
index 9bbea95..07c519c 100644
--- a/test/unittest_graph.py
+++ b/test/unittest_graph.py
@@ -1,7 +1,7 @@
# unit tests for the cache module
from logilab.common.testlib import TestCase, unittest_main
-from logilab.common import get_cycles
+from logilab.common.graph import get_cycles
class getCycleTestCase(TestCase):
diff --git a/test/unittest_textutils.py b/test/unittest_textutils.py
index b053035..3098086 100644
--- a/test/unittest_textutils.py
+++ b/test/unittest_textutils.py
@@ -90,14 +90,6 @@ class PrettyMatchTC(TestCase):
-
-class SearchAllTC(TestCase):
-
- def test_known(self):
- string = 'hiuherabcdefabcd'
- self.assertEquals(len(tu.searchall(RGX, string)), 2)
-
-
class UnquoteTC(TestCase):
def test(self):
self.assertEquals(tu.unquote('"toto"'), 'toto')
diff --git a/testlib.py b/testlib.py
index e8fb579..b891244 100644
--- a/testlib.py
+++ b/testlib.py
@@ -44,7 +44,7 @@ except ImportError:
pass
test_support = TestSupport()
-from logilab.common import class_renamed, deprecated_function
+from logilab.common.deprecation import class_renamed, deprecated_function
from logilab.common.compat import set, enumerate
from logilab.common.modutils import load_module_from_name
diff --git a/textutils.py b/textutils.py
index 17ccbfe..c319d7f 100644
--- a/textutils.py
+++ b/textutils.py
@@ -15,9 +15,8 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
"""Some text manipulation utility functions.
-:version: $Revision: 1.25 $
:author: Logilab
-:copyright: 2003-2005 LOGILAB S.A. (Paris, FRANCE)
+:copyright: 2003-2006 LOGILAB S.A. (Paris, FRANCE)
:contact: http://www.logilab.fr/ -- mailto:python-projects@logilab.org
:group text formatting: normalize_text, normalize_paragraph, pretty_match,\
@@ -46,28 +45,10 @@ unquote, colorize_ansi
ANSI terminal code reseting format defined by a previous ANSI escape sequence
"""
-__revision__ = "$Id: textutils.py,v 1.25 2005-09-06 08:51:01 alf Exp $"
__docformat__ = "restructuredtext en"
import re
from os import linesep
-from warnings import warn
-
-
-def searchall(rgx, data):
- """apply a regexp using "search" until no more match is found
-
- This function is deprecated, use re.finditer() instead.
- """
- warn('logilab.common.textutils.searchall() is deprecated, use '
- 're.finditer() instead', DeprecationWarning)
- result = []
- match = rgx.search(data)
- while match is not None:
- result.append(match)
- match = rgx.search(data, match.end())
- return result
-
def unquote(string):
"""remove optional quotes (simple or double) from the string
diff --git a/tree.py b/tree.py
index 00be29a..f8c0828 100644
--- a/tree.py
+++ b/tree.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2000-2003 LOGILAB S.A. (Paris, FRANCE).
+# Copyright (c) 2003-2006 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This program is free software; you can redistribute it and/or modify it under
@@ -17,12 +17,8 @@
base class to represent tree structure
"""
-__revision__ = "$Id: tree.py,v 1.24 2006-02-24 10:40:21 nico Exp $"
-
import sys
-from warnings import warn
-from logilab.common import deprecated_function
from logilab.common.visitor import VisitedMixIn, FilteredIterator, no_filter
## Exceptions #################################################################
@@ -186,8 +182,6 @@ class Node :
else:
return [self]
- leafs = deprecated_function(leaves) # backward compatibility
-
def flatten(self, _list=None):
"""
return a list with all the nodes descendant from this node
diff --git a/twisted_distutils.py b/twisted_distutils.py
index 67dbd6b..7673eea 100644
--- a/twisted_distutils.py
+++ b/twisted_distutils.py
@@ -45,6 +45,12 @@ package directory of your application.
#
# Happy twisting!
#
+
+
+from warnings import warn
+warn('this module is deprecated and will disappear in a near release',
+ DeprecationWarning, stacklevel=1)
+
__revision__ = "$Id: twisted_distutils.py,v 1.4 2003-09-12 11:54:48 syt Exp $"
from distutils.core import Distribution, Command