summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Th?nault <sylvain.thenault@logilab.fr>2009-08-07 10:54:45 +0200
committerSylvain Th?nault <sylvain.thenault@logilab.fr>2009-08-07 10:54:45 +0200
commit29fbb301a61d85214a0de76b7308ffb7d9c9fd96 (patch)
tree4016396e39749c537439473b648eb39e5908dbb9
parenta37b556013111e0593f2600acc3dab71bff2968b (diff)
downloadlogilab-common-29fbb301a61d85214a0de76b7308ffb7d9c9fd96.tar.gz
remove modules deprecated for a while
-rw-r--r--bind.py263
-rwxr-xr-xdebian.intrepid/rules2
-rw-r--r--html.py42
-rw-r--r--logger.py150
-rw-r--r--patricia.py178
-rw-r--r--test/unittest_logger.py53
-rw-r--r--twisted_distutils.py213
7 files changed, 1 insertions, 900 deletions
diff --git a/bind.py b/bind.py
deleted file mode 100644
index 2838972..0000000
--- a/bind.py
+++ /dev/null
@@ -1,263 +0,0 @@
-"""Optimize globals in certain functions by binding their names to values
-provided in a dictionnary.
-
-:copyright: 2002-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: General Public License version 2 - http://www.gnu.org/licenses
-"""
-__docformat__ = "restructuredtext en"
-
-from warnings import warn
-warn('logilab.common.bind module is deprecated and will disappear in a near release',
- DeprecationWarning, stacklevel=2)
-
-# TODO: unit tests
-# * this module provide a function bind(func,vars) which replaces every
-# global variable 'm' by the value vars['m'] if such value exists in dict
-
-from dis import HAVE_ARGUMENT
-from new import code as make_code, function as make_function
-import inspect
-
-LOAD_GLOBAL = 116
-LOAD_CONST = 100
-EXTENDED_ARG = 143
-STORE_GLOBAL = 97
-
-def bind_code(co, globals):
- """
- Take a code object and a dictionnary and returns a new code object where
- the opcodes LOAD_GLOBAL are replaced by LOAD_CONST whenever the global's
- name appear in the dictionnary
- """
- consts = list(co.co_consts)
- assigned = {}
-
- code = co.co_code
- new_code = ""
- n = len(code)
- i = 0
- while i < n:
- c = code[i]
- op = ord(c)
- i += 1
- if op >= HAVE_ARGUMENT:
- oparg = ord(code[i]) + ord(code[i+1]) * 256
- i += 2
- else:
- oparg = None
- if op == LOAD_GLOBAL:
- name = co.co_names[oparg]
- if name in globals:
- k = assigned.get(name, None)
- if k == None:
- k = len(consts)
- assigned[name] = len(consts)
- consts.append(globals[name])
- op = LOAD_CONST
- oparg = k
- new_code += chr(op)
- if oparg is not None:
- new_code += chr(oparg & 255)
- new_code += chr( (oparg>>8) & 255 )
-
- return make_code(co.co_argcount,
- co.co_nlocals,
- co.co_stacksize,
- co.co_flags,
- new_code,
- tuple(consts),
- co.co_names,
- co.co_varnames,
- co.co_filename,
- co.co_name,
- co.co_firstlineno,
- co.co_lnotab )
-
-
-def bind(f, globals):
- """Returns a new function whose code object has been
- bound by bind_code()"""
- newcode = bind_code(f.func_code, globals)
- defaults = f.func_defaults or ()
- return make_function(newcode, f.func_globals, f.func_name, defaults)
-
-if type(__builtins__) == dict:
- builtins = __builtins__
-else:
- builtins = __builtins__.__dict__
-
-bind_code_opt = bind(bind_code, builtins )
-bind_code_opt = bind(bind_code_opt, globals() )
-
-
-def optimize_module(m, global_consts):
- if not inspect.ismodule(m):
- raise TypeError
- d = {}
- for i in global_consts:
- v = m.__dict__.get(i)
- d[i] = v
- builtins = m.__builtins__
- for name, f in m.__dict__.items():
- if inspect.isfunction(f):
- f = bind(f, builtins)
- if d:
- f = bind(f, d)
- m.__dict__[name] = f
-
-
-
-
-def analyze_code(co, globals, consts_dict, consts_list):
- """Take a code object and a dictionnary and returns a
- new code object where the opcodes LOAD_GLOBAL are replaced
- by LOAD_CONST whenever the global's name appear in the
- dictionnary"""
- modified_globals = []
- for c in co.co_consts:
- if c not in consts_list:
- consts_list.append(c)
- modified = []
- code = co.co_code
- new_code = ""
- n = len(code)
- i = 0
- extended_arg = 0
- while i < n:
- c = code[i]
- op = ord(c)
- i += 1
- if op >= HAVE_ARGUMENT:
- oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg
- extended_arg = 0
- i += 2
- else:
- oparg = None
- if op == EXTENDED_ARG:
- extended_arg = oparg*65536L
-
- if op == LOAD_GLOBAL:
- name = co.co_names[oparg]
- if name in globals:
- k = consts_dict.get(name, None)
- if k == None:
- k = len(consts_list)
- consts_dict[name] = k
- consts_list.append(globals[name])
- if op == STORE_GLOBAL:
- name = co.co_names[oparg]
- if name in globals:
- modified_globals.append(name)
- return modified_globals
-
-def rewrite_code(co, consts_dict, consts_tuple):
- """Take a code object and a dictionnary and returns a
- new code object where the opcodes LOAD_GLOBAL are replaced
- by LOAD_CONST whenever the global's name appear in the
- dictionnary"""
- code = co.co_code
- new_code = ""
- n = len(code)
- i = 0
- consts_list = list(consts_tuple)
- while i < n:
- c = code[i]
- op = ord(c)
- i += 1
- extended_arg = 0
- if op >= HAVE_ARGUMENT:
- oparg = ord(code[i]) + ord(code[i+1])*256+extended_arg
- extended_arg = 0
- i += 2
- else:
- oparg = None
- if op == EXTENDED_ARG:
- extended_arg = oparg*65536L
- elif op == LOAD_GLOBAL:
- name = co.co_names[oparg]
- k = consts_dict.get(name)
- if k is not None:
- op = LOAD_CONST
- oparg = k
- elif op == LOAD_CONST:
- val = co.co_consts[oparg]
- oparg = consts_list.index(val)
- new_code += chr(op)
- if oparg is not None:
- new_code += chr(oparg & 255)
- new_code += chr( (oparg>>8) & 255 )
-
- return make_code(co.co_argcount,
- co.co_nlocals,
- co.co_stacksize,
- co.co_flags,
- new_code,
- consts_tuple,
- co.co_names,
- co.co_varnames,
- co.co_filename,
- co.co_name,
- co.co_firstlineno,
- co.co_lnotab )
-
-def optimize_module_2(m, globals_consts, bind_builtins=1):
- if not inspect.ismodule(m):
- raise TypeError
- consts_dict = {}
- consts_list = []
- if type(globals_consts) == list or type(globals_consts) == tuple:
- globals = {}
- for i in globals_consts:
- v = m.__dict__.get(i)
- globals[i] = v
- else:
- globals = globals_consts
- if bind_builtins:
- for builtin_name, builtin_value in m.__builtins__.items():
- # this way it is possible to redefine a builtin in globals_consts
- globals.setdefault(builtin_name, builtin_value)
- functions = {}
- for name, f in m.__dict__.items():
- if inspect.isfunction(f):
- functions[name] = f
- analyze_code(f.func_code, globals, consts_dict, consts_list)
- consts_list = tuple(consts_list)
- for name, f in functions.items():
- newcode = rewrite_code(f.func_code, consts_dict, consts_list)
- defaults = f.func_defaults or ()
- m.__dict__[name] = make_function(newcode, f.func_globals, f.func_name,
- defaults)
-
-
-def run_bench(n):
- from time import time
- t = time()
- g = globals()
- for i in range(n):
- test = bind(bind_code, g)
- t1 = time()-t
- bind2 = bind(bind, {'bind_code':bind_code_opt})
- t = time()
- for i in range(n):
- test=bind2(bind_code, g)
- t2 = time()-t
- print "1 regular version", t1
- print "2 optimized version", t2
- print "ratio (1-2)/1 : %f %%" % (100.*(t1-t2)/t1)
-
-
-def test_pystone():
- from test import pystone
- for _ in range(5):
- pystone.main()
- optimize_module(pystone, ('TRUE','FALSE','Proc0','Proc1','Proc2','Proc3',
- 'Proc4','Proc5','Proc6','Proc7','Proc8','Func1',
- ' Func2','Func3'))
- optimize_module(pystone, builtins.keys())
- for _ in range(5):
- pystone.main()
-
-
-if __name__ == "__main__":
- run_bench(1000)
diff --git a/debian.intrepid/rules b/debian.intrepid/rules
index 937f9df..80739ef 100755
--- a/debian.intrepid/rules
+++ b/debian.intrepid/rules
@@ -23,7 +23,7 @@ ifeq (,$(findstring nocheck,$(DEB_BUILD_OPTIONS)))
# we need this hack because we have to import "logilab.common.pytest"
# but since it's a namespace package, we need to "simulate" it
touch $(CURDIR)/build/lib/logilab/__init__.py
- -PYTHONPATH=$(CURDIR)/build/lib/ $(CURDIR)/build/scripts-2.5/pytest
+ PYTHONPATH=$(CURDIR)/build/lib/ $(CURDIR)/build/scripts-2.5/pytest
rm -f $(CURDIR)/build/lib/logilab/__init__.py
endif
diff --git a/html.py b/html.py
deleted file mode 100644
index 8097ec0..0000000
--- a/html.py
+++ /dev/null
@@ -1,42 +0,0 @@
-"""Print traceback in HTML.
-
-:copyright: 2000-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: General Public License version 2 - http://www.gnu.org/licenses
-"""
-__docformat__ = "restructuredtext en"
-
-from warnings import warn
-warn('html module is deprecated and will disappear in a near release',
- DeprecationWarning, stacklevel=2)
-
-import traceback
-from xml.sax.saxutils import escape
-
-# mk html traceback error #####################################################
-
-def html_traceback(info, exception,
- title='', encoding='ISO-8859-1', body=''):
- """Return an html formatted traceback from python exception infos.
- """
- #typ, value, tbck = info
- stacktb = traceback.extract_tb(info[2]) #tbck)
- strings = []
- if body:
- strings.append('<div class="error_body">')
- strings.append(body)
- strings.append('</div>')
- if title:
- strings.append('<h1 class="error">%s</h1>'% escape(title))
- strings.append('<p class="error">%s</p>' % escape(str(exception)))
- strings.append('<div class="error_traceback">')
- for stackentry in stacktb :
- strings.append('<b>File</b> <b class="file">%s</b>, <b>line</b> '
- '<b class="line">%s</b>, <b>function</b> '
- '<b class="function">%s</b>:<br/>'%(
- escape(stackentry[0]), stackentry[1], stackentry[2]))
- if stackentry[3]:
- string = escape(repr(stackentry[3])[1:-1])#.encode(encoding)
- strings.append('&nbsp;&nbsp;%s<br/>\n' % string)
- strings.append('</div>')
- return '\n'.join(strings)
diff --git a/logger.py b/logger.py
deleted file mode 100644
index 2af5963..0000000
--- a/logger.py
+++ /dev/null
@@ -1,150 +0,0 @@
-"""Define a logger interface and two concrete loggers: one which prints
-everything on stdout, the other using syslog.
-
-:copyright: 2000-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: General Public License version 2 - http://www.gnu.org/licenses
-
-# FIXME use logging from stdlib instead.
-"""
-__docformat__ = "restructuredtext en"
-
-from warnings import warn
-warn('logilab.common.logger module is deprecated and will disappear in a future release. \
-use logging module instead.',
- DeprecationWarning, stacklevel=2)
-
-import sys
-import traceback
-import time
-
-
-LOG_EMERG = 0
-LOG_ALERT = 1
-LOG_CRIT = 2
-LOG_ERR = 3
-LOG_WARN = 4
-LOG_NOTICE = 5
-LOG_INFO = 6
-LOG_DEBUG = 7
-
-INDICATORS = ['emergency', 'alert', 'critical', 'error',
- 'warning', 'notice', 'info', 'debug']
-
-
-def make_logger(method='print', threshold=LOG_DEBUG, sid=None, output=None):
- """return a logger for the given method
-
- known methods are 'print', 'eprint' and syslog'
- """
- if method == 'print':
- if output is None:
- output = sys.stdout
- return PrintLogger(threshold, output, sid=sid)
- elif method == 'eprint':
- return PrintLogger(threshold, sys.stderr, sid=sid)
- elif method == 'syslog':
- return SysLogger(threshold, sid)
- elif method == 'file':
- if not output:
- raise ValueError('No logfile specified')
- else:
- logfile = open(output, 'a')
- return PrintLogger(threshold, logfile, sid=sid)
- else:
- raise ValueError('Unknown logger method: %r' % method)
-
-
-class AbstractLogger:
- """logger interface.
- Priorities allow to filter on the importance of events
- An event gets logged if it's priority is lower than the threshold"""
-
- def __init__(self, threshold=LOG_DEBUG, priority_indicator=1):
- self.threshold = threshold
- self.priority_indicator = priority_indicator
-
- def log(self, priority=LOG_DEBUG, message='', substs=None):
- """log a message with priority <priority>
- substs are optional substrings
- """
- #print 'LOG', self, priority, self.threshold, message
- if priority <= self.threshold :
- if substs is not None:
- message = message % substs
- if self.priority_indicator:
- message = '[%s] %s' % (INDICATORS[priority], message)
- self._writelog(priority, message)
-
- def _writelog(self, priority, message):
- """Override this method in concrete class """
- raise NotImplementedError()
-
- def log_traceback(self, priority=LOG_ERR, tb_info=None):
- """log traceback information with priority <priority>
- """
- assert tb_info is not None
- e_type, value, tbck = tb_info
- stacktb = traceback.extract_tb(tbck)
- l = ['Traceback (most recent call last):']
- for stackentry in stacktb :
- if stackentry[3]:
- plus = '\n %s' % stackentry[3]
- else:
- plus = ''
- l.append('filename="%s" line_number="%s" function_name="%s"%s' %
- (stackentry[0], stackentry[1], stackentry[2], plus))
- try:
- l.append(str(e_type) + ': ' + value.__str__())
- except UnicodeError:
- l.append(str(e_type) + ' (message can\'t be displayed)')
-
- self.log(priority, '\n'.join(l))
-
-
-class PrintLogger(AbstractLogger):
- """logger implementation
-
- log everything to a file, using the standard output by default
- """
-
- def __init__(self, threshold, output=sys.stdout, sid=None,
- encoding='UTF-8'):
- AbstractLogger.__init__(self, threshold)
- self.output = output
- self.sid = sid
- self.encoding = encoding
-
- def _writelog(self, priority, message):
- """overridden from AbstractLogger"""
- if isinstance(message, unicode):
- message = message.encode(self.encoding, 'replace')
- if self.sid is not None:
- self.output.write('[%s] [%s] %s\n' % (time.asctime(), self.sid,
- message))
- else:
- self.output.write('[%s] %s\n' % (time.asctime(), message))
- self.output.flush()
-
-class SysLogger(AbstractLogger):
- """ logger implementation
-
- log everything to syslog daemon
- use the LOCAL_7 facility
- """
-
- def __init__(self, threshold, sid=None, encoding='UTF-8'):
- import syslog
- AbstractLogger.__init__(self, threshold)
- if sid is None:
- sid = 'syslog'
- self.encoding = encoding
- syslog.openlog(sid, syslog.LOG_PID)
-
- def _writelog(self, priority, message):
- """overridden from AbstractLogger"""
- import syslog
- if isinstance(message, unicode):
- message = message.encode(self.encoding, 'replace')
- syslog.syslog(priority | syslog.LOG_LOCAL7, message)
-
diff --git a/patricia.py b/patricia.py
deleted file mode 100644
index 65805f9..0000000
--- a/patricia.py
+++ /dev/null
@@ -1,178 +0,0 @@
-"""A Python implementation of PATRICIA tree.
-
-PATRICIA - Practical Algorithm to Retrieve Information Coded in Alphanumeric
- D.R.Morrison (1968).
-See http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/PATRICIA.html if you
-want to know what's a PATRICIA tree...
-
-TODO: _ advanced search
- _ profile code
- _ use mxTextTools ?
-
-:copyright: 2000-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: General Public License version 2 - http://www.gnu.org/licenses
-"""
-__docformat__ = "restructuredtext en"
-
-from warnings import warn
-warn('logilab.common.patricia module is deprecated and will disappear in a near release',
- DeprecationWarning, stacklevel=2)
-
-def prefix(prfx, string):
- """return the index of the first character from string which differs from
- prefix
- """
- i = 0
- while i < len(prfx):
- if i == len(string) or prfx[i] != string[i]:
- break
- i += 1
- return i
-
-def split(index, string):
- """split a string on index, returning a 3-uple :
- (string before index, character at index, string after index)
- """
- return string[:index], string[index], string[index+1:]
-
-
-class PatriciaNode:
- """a PATRICIA trie node
- """
-
- def __init__(self, value='', leaf=0, data=None):
- self.value = value
- self.edges = {}
- if leaf:
- self.datas = [data]
- else:
- self.datas = []
-
- def insert(self, string, data):
- """ insert the string in the trie and associate data to it
- if the string exists is the trie, data is added to the existing datas
- """
- # are we arrived ?
- if self.value == string:
- self.datas.append(data)
- # not yet !
- else:
- # check we don't break compression (value don't match)
- ind = prefix(self.value, string)
- if ind < len(self.value):
- # split this node
- pfx, e, self.value = split(ind, self.value)
- if ind < len(string):
- n = PatriciaNode(pfx)
- n.edges[string[ind]] = PatriciaNode(string[ind+1:], 1, data)
- else:
- n = PatriciaNode(pfx, 1, data)
- n.edges[e] = self
- return n
- n_pfx, n_e, n_sfx = split(len(self.value), string)
- if n_e in self.edges:
- self.edges[n_e] = self.edges[n_e].insert(n_sfx, data)
- else:
- self.edges[n_e] = PatriciaNode(n_sfx, 1, data)
- return self
-
- def remove(self, string):
- """ return datas associated with string and remove string from the trie
- raise KeyError if the key isn't found
- FIXME: we should change the trie structure
- """
- if string == self.value and self.datas:
- datas = self.datas
- self.datas = []
- return datas
- else:
- pfx, e, sfx = split(len(self.value), string)
- if self.value == pfx:
- return self.edges[e].remove(sfx)
- raise KeyError(string)
-
- def lookup(self, string):
- """ return datas associated with string
- raise KeyError if the key isn't found
- """
- if string == self.value:
- if self.datas:
- return self.datas
- raise KeyError(string)
- else: # len(self.value) < len(string):
- pfx, e, sfx = split(len(self.value), string)
- if self.value == pfx:
- return self.edges[e].lookup(sfx)
- raise KeyError(string)
-
- def pfx_search(self, pfx, depth=-1):
- """ return all string with prefix pfx """
- sfxs = []
- if pfx and self.value[:len(pfx)] != pfx:
- pfx, e, sfx = split(len(self.value), pfx)
- if self.value == pfx and e in self.edges:
- sfxs = ['%s%s%s' % (self.value, e, sfx)
- for sfx in self.edges[e].pfx_search(sfx, depth)]
- else:
- if depth != 0:
- for e, child in self.edges.items():
- search = child.pfx_search('', depth-1-len(self.value))
- sfxs += ['%s%s%s' % (self.value, e, sfx)
- for sfx in search]
- if (depth < 0 or len(self.value) <= depth):
- if self.datas:
- sfxs.append(self.value)
- return sfxs
-
- def __str__(self, indent=''):
- node_str = ''.join([' %s%s:\n%s' % (indent, key,
- a.__str__(' %s' % indent))
- for key, a in self.edges.items()])
- return '%s%s, %s\n%s' % (indent, self.value, self.datas, node_str)
-
- def __repr__(self):
- return '<PatriciaNode id=%s value=%s childs=%s datas=%s>' % (
- id(self), self.value, self.edges.keys(), self.datas)
-
-
-class PatriciaTrie:
- """ wrapper class for a patricia tree
- delegates to the root of the tree (PatriciaNode)
- """
-
- def __init__(self):
- self._trie = None
- self.words = 0
-
- def insert(self, string, data=None):
- """ insert a string into the tree """
- self.words += 1
- if self._trie is None:
- self._trie = PatriciaNode(string, 1, data)
- else:
- self._trie = self._trie.insert(string, data)
-
- def remove(self, string):
- """ remove a string from the tree """
- if self._trie is not None:
- return self._trie.remove(string)
- raise KeyError(string)
-
- def lookup(self, string):
- """ look for a string into the tree """
- if self._trie is not None:
- return self._trie.lookup(string)
- raise KeyError(string)
-
- def pfx_search(self, string, depth=-1):
- """ search all words begining by <string> """
- if self._trie is not None:
- return self._trie.pfx_search(string, depth)
- raise KeyError(string)
-
- def __str__(self):
- return self._trie.__str__()
-
- def __repr__(self):
- return '<PatriciaTrie id=%s words=%s>' % (id(self), self.words)
diff --git a/test/unittest_logger.py b/test/unittest_logger.py
deleted file mode 100644
index 071893f..0000000
--- a/test/unittest_logger.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""unittests for logilab.common.logger"""
-
-from tempfile import mktemp
-import os
-import sys
-from cStringIO import StringIO
-
-from logilab.common.testlib import TestCase, unittest_main
-from logilab.common.logger import *
-
-
-def get_logged_messages(output):
- """strip timestamps and extract effective logged text
- (log lines look like: [timestamp] message)
- """
- return [line.split(']')[-1].strip() for line in output.splitlines()]
-
-
-class LoggerTC(TestCase):
-
- def test_defaultlogging(self):
- # redirect stdout so that we can test
- stdout_backup = sys.stdout
- sys.stdout = StringIO()
- # make default logger
- logger = make_logger()
- logger.log(message='hello')
- logger.log(message='world')
- output = sys.stdout.getvalue()
- msg = get_logged_messages(output)
- # restore stdout
- sys.stdout = stdout_backup
- self.assertEquals(msg, ['hello', 'world'])
-
- def test_filelogging(self):
- filename = mktemp(dir='/tmp')
- # make file logger
- logger = make_logger(method='file', output=filename)
- logger.log(message='hello')
- logger.log(message='world')
- # make sure everything gets flushed (testing purpose)
- logger.output.flush()
- output = open(filename).read() #os.read(descr, 300)
- # close everything correcly
- #os.close(descr)
- logger.output.close()
- # remove file
- os.remove(filename)
- self.assertEquals(get_logged_messages(output), ['hello', 'world'])
-
-if __name__ == '__main__':
- unittest_main()
-
diff --git a/twisted_distutils.py b/twisted_distutils.py
deleted file mode 100644
index 0d8a455..0000000
--- a/twisted_distutils.py
+++ /dev/null
@@ -1,213 +0,0 @@
-"""Distutils extensions for twisted framework.
-
-This module enables the installation of plugins.tml files using standard
-distutils syntax. It adds the following commands to the standard
-setup.py commands:
- - build_twisted_plugins: build (i.e. copy) plugins
- - install_twisted_plugins: install plugins
-
-Additionally, the following commands have been modified to deal with
-plugins files:
- - sdist
- - build
- - install
-
-To use these extenstion, you should import the setup fonction from this
-module, and use it normally. To list the plugins.tml files, use the
-twisted_plugins keyword argument to the setup function::
-
- from twisted_distutils import setup # you can also import Extension if needed
-
- if __name__ == '__main__':
- setup(name='my_twisted_app',
- version='1.0',
- author='me',
- packages=['my_package'],
- twisted_plugins = ['my_package/plugins.tml'])
-
-Note that you can use this to install files that are not twisted plugins in any
-package directory of your application.
-
-:copyright: 2000-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
-:license: General Public License version 2 - http://www.gnu.org/licenses
-"""
-__docformat__ = "restructuredtext en"
-
-# (c) 2002 Alexandre Fayolle <alexandre.fayolle@free.fr>
-# This module is heavily based on code copied from the python distutils
-# framework, especially distutils.command.build_script,
-# distutils.command.install_script. Many thanks to the authors of these
-# modules.
-# This module is provided as is, I'm not responsible if anything bad
-# happens to you or your python library while using this module. You may
-# freely copy it, distribute it and use it in your library or to distribute
-# your applications. I'd appreciate if you could drop me an email if you plan
-# to do so <wink>.
-#
-# Happy twisting!
-
-from warnings import warn
-warn('this module is deprecated and will disappear in a near release',
- DeprecationWarning, stacklevel=1)
-
-from distutils.core import Distribution, Command
-from distutils.command.install import install
-from distutils.command.build import build
-from distutils.command.sdist import sdist
-from distutils.dep_util import newer
-from distutils.util import convert_path
-import os
-
-class twisted_sdist(sdist):
- def add_defaults(self):
- sdist.add_defaults(self)
- if self.distribution.has_twisted_plugins():
- plugins = self.get_finalized_command('build_twisted_plugins')
- self.filelist.extend(plugins.get_source_files())
-
-class twisted_install(install):
- def initialize_options (self):
- install.initialize_options(self)
- self.twisted_plugins = None
-
- def has_twisted_plugins(self):
- return self.distribution.has_twisted_plugins()
-
- sub_commands = []
- sub_commands.extend(install.sub_commands)
- sub_commands.append(('install_twisted_plugins', has_twisted_plugins))
-
-
-class twisted_build(build):
- def initialize_options (self):
- build.initialize_options(self)
- self.twisted_plugins = None
-
- def has_twisted_plugins(self):
- return self.distribution.has_twisted_plugins()
-
- sub_commands = []
- sub_commands.extend(build.sub_commands)
- sub_commands.append(('build_twisted_plugins', has_twisted_plugins))
-
-class build_twisted_plugins (Command):
-
- description = "\"build\" twisted plugins (copy)"
-
- user_options = [
- ('build-dir=', 'd', "directory to \"build\" (copy) to"),
- ('force', 'f', "forcibly build everything (ignore file timestamps"),
- ]
-
- boolean_options = ['force']
-
-
- def initialize_options (self):
- self.build_dir = None
- self.twisted_plugins = None
- self.force = None
- self.outfiles = None
-
- def get_source_files(self):
- return self.twisted_plugins
-
- def finalize_options (self):
- self.set_undefined_options('build',
- ('build_lib', 'build_dir'),
- ('force', 'force'))
- self.twisted_plugins = self.distribution.twisted_plugins
-
-
- def run (self):
- if not self.twisted_plugins:
- return
- self.copy_twisted_plugins()
-
-
- def copy_twisted_plugins (self):
- """Copy each plugin listed in 'self.twisted_plugins'.
- """
- self.mkpath(self.build_dir)
- for plugin in self.twisted_plugins:
- adjust = 0
- plugin = convert_path(plugin)
- outfile = os.path.join(self.build_dir, plugin)
- if not self.force and not newer(plugin, outfile):
- self.announce("not copying %s (up-to-date)" % plugin)
- continue
-
- # Always open the file, but ignore failures in dry-run mode --
- # that way, we'll get accurate feedback if we can read the
- # plugin.
- try:
- f = open(plugin, "r")
- except IOError:
- if not self.dry_run:
- raise
- f = None
- else:
- f.close()
- self.copy_file(plugin, outfile)
-
-
-class install_twisted_plugins(Command):
-
- description = "install twisted plugins"
-
- user_options = [
- ('install-dir=', 'd', "directory to install scripts to"),
- ('build-dir=','b', "build directory (where to install from)"),
- ('force', 'f', "force installation (overwrite existing files)"),
- ('skip-build', None, "skip the build steps"),
- ]
-
- boolean_options = ['force', 'skip-build']
-
-
- def initialize_options (self):
- self.install_dir = None
- self.force = 0
- self.build_dir = None
- self.skip_build = None
-
- def finalize_options (self):
- self.set_undefined_options('build', ('build_lib', 'build_dir'))
- self.set_undefined_options('install',
- ('install_lib', 'install_dir'),
- ('force', 'force'),
- ('skip_build', 'skip_build'),
- )
-
- def run (self):
- if not self.skip_build:
- self.run_command('build_twisted_plugins')
- self.outfiles = self.copy_tree(self.build_dir, self.install_dir)
-
- def get_inputs (self):
- return self.distribution.twisted_plugins or []
-
- def get_outputs(self):
- return self.outfiles or []
-
-
-
-class TwistedDistribution(Distribution):
- def __init__(self,attrs=None):
- self.twisted_plugins = None
- Distribution.__init__(self, attrs)
- self.cmdclass = {'install':twisted_install,
- 'install_twisted_plugins':install_twisted_plugins,
- 'build':twisted_build,
- 'build_twisted_plugins':build_twisted_plugins,
- 'sdist':twisted_sdist,
- }
-
- def has_twisted_plugins(self):
- return self.twisted_plugins and len(self.twisted_plugins) > 0
-
-
-def setup(**attrs):
- from distutils import core
- attrs['distclass'] = TwistedDistribution
- core.setup(**attrs)