Ejemplo n.º 1
0
 def test_deprecated_func(self):
     any_func = deprecation.deprecated()(self.mk_func())
     any_func()
     any_func = deprecation.deprecated('message')(self.mk_func())
     any_func()
     self.assertEqual(self.messages,
                      ['The function "any_func" is deprecated', 'message'])
Ejemplo n.º 2
0
    ['a']
    >>>

    :type string: str or unicode
    :param string: a csv line

    :type sep: str or unicode
    :param sep: field separator, default to the comma (',')

    :rtype: str or unicode
    :return: the unquoted string (or the input string if it wasn't quoted)
    """
    return [word.strip() for word in string.split(sep) if word.strip()]


get_csv = deprecated('get_csv is deprecated, use splitstrip')(splitstrip)


def split_url_or_path(url_or_path):
    """return the latest component of a string containing either an url of the
    form <scheme>://<path> or a local file system path
    """
    if '://' in url_or_path:
        return url_or_path.rstrip('/').rsplit('/', 1)
    return osp.split(url_or_path.rstrip(osp.sep))


def text_to_dict(text):
    """parse multilines text containing simple 'key=value' lines and return a
    dict of {'key': 'value'}. When the same key is encountered multiple time,
    value is turned into a list containing all values.
Ejemplo n.º 3
0
    ['a']
    >>>

    :type string: str or unicode
    :param string: a csv line

    :type sep: str or unicode
    :param sep: field separator, default to the comma (',')

    :rtype: str or unicode
    :return: the unquoted string (or the input string if it wasn't quoted)
    """
    return [word.strip() for word in string.split(sep) if word.strip()]


get_csv = deprecated("get_csv is deprecated, use splitstrip")(splitstrip)


def split_url_or_path(url_or_path):
    """return the latest component of a string containing either an url of the
    form <scheme>://<path> or a local file system path
    """
    if "://" in url_or_path:
        return url_or_path.rstrip("/").rsplit("/", 1)
    return osp.split(url_or_path.rstrip(osp.sep))


def text_to_dict(text):
    """parse multilines text containing simple 'key=value' lines and return a
    dict of {'key': 'value'}. When the same key is encountered multiple time,
    value is turned into a list containing all values.
Ejemplo n.º 4
0
    def str_encode(string, encoding):
        return str(string)


# See also http://bugs.python.org/issue11776
if sys.version_info[0] == 3:

    def method_type(callable, instance, klass):
        # api change. klass is no more considered
        return types.MethodType(callable, instance)
else:
    # alias types otherwise
    method_type = types.MethodType

# Pythons 2 and 3 differ on where to get StringIO
if sys.version_info < (3, 0):
    from cStringIO import StringIO
    FileIO = file
    BytesIO = StringIO
    reload = reload
else:
    from io import FileIO, BytesIO, StringIO
    from imp import reload

from logilab.common.deprecation import deprecated

# Other projects import these from here, keep providing them for
# backwards compat
any = deprecated('use builtin "any"')(any)
all = deprecated('use builtin "all"')(all)
Ejemplo n.º 5
0
class Select(Statement, nodes.EditableMixIn, ScopeNode):
    """the select node is the base statement of the syntax tree for selection
    statement, always child of a UNION root.
    """
    vargraph = None
    parent = None
    distinct = False
    # limit / offset
    limit = None
    offset = 0
    # select clauses
    groupby = ()
    orderby = ()
    with_ = ()
    # set by the annotator
    has_aggregat = False

    def __init__(self):
        Statement.__init__(self)
        ScopeNode.__init__(self)
        self.selection = []
        # subqueries alias
        self.aliases = {}
        # syntax tree meta-information
        self.stinfo = {'rewritten': {}}

    @property
    def root(self):
        """return the root node of the tree"""
        return self.parent

    def get_description(self, mainindex, tr):
        """return the list of types or relations (if not found) associated to
        selected variables.
        mainindex is an optional selection index which should be considered has
        'pivot' entity.
        """
        descr = []
        for term in self.selection:
            # don't translate Any
            try:
                descr.append(term.get_description(mainindex, tr) or 'Any')
            except CoercionError:
                descr.append('Any')
        return descr

    @property
    def children(self):
        children = self.selection[:]
        if self.groupby:
            children += self.groupby
        if self.orderby:
            children += self.orderby
        if self.where:
            children.append(self.where)
        if self.having:
            children += self.having
        if self.with_:
            children += self.with_
        return children

    # repr / as_string / copy #################################################

    def __repr__(self):
        return self.as_string(userepr=True)

    def as_string(self, kwargs=None, userepr=False):
        """return the tree as an encoded rql string"""
        if userepr:
            as_string = repr
        else:

            def as_string(x):
                return x.as_string(kwargs=kwargs)

        s = [','.join(as_string(term) for term in self.selection)]
        if self.groupby:
            s.append('GROUPBY ' +
                     ','.join(as_string(term) for term in self.groupby))
        if self.orderby:
            s.append('ORDERBY ' +
                     ','.join(as_string(term) for term in self.orderby))
        if self.limit is not None:
            s.append('LIMIT %s' % self.limit)
        if self.offset:
            s.append('OFFSET %s' % self.offset)
        if self.where is not None:
            s.append('WHERE ' + as_string(self.where))
        if self.having:
            s.append('HAVING ' +
                     ','.join(as_string(term) for term in self.having))
        if self.with_:
            s.append('WITH ' +
                     ','.join(as_string(term) for term in self.with_))
        if self.distinct:
            return 'DISTINCT Any ' + ' '.join(s)
        return 'Any ' + ' '.join(s)

    def copy(self, copy_solutions=True, solutions=None):
        new = ScopeNode.copy(self, copy_solutions, solutions)
        if self.with_:
            new.set_with([sq.copy(new) for sq in self.with_], check=False)
        for child in self.selection:
            new.append_selected(child.copy(new))
        if self.groupby:
            new.set_groupby([sq.copy(new) for sq in self.groupby])
        if self.orderby:
            new.set_orderby([sq.copy(new) for sq in self.orderby])
        if self.where:
            new.set_where(self.where.copy(new))
        if self.having:
            new.set_having([sq.copy(new) for sq in self.having])
        new.distinct = self.distinct
        new.limit = self.limit
        new.offset = self.offset
        new.vargraph = self.vargraph
        return new

    # select specific methods #################################################

    def set_possible_types(self,
                           solutions,
                           kwargs=_MARKER,
                           key='possibletypes'):
        super(Select, self).set_possible_types(solutions, kwargs, key)
        for ca in self.aliases.values():
            ca.stinfo[key] = capt = set()
            for solution in solutions:
                capt.add(solution[ca.name])
            if kwargs is _MARKER:
                continue
            # propagage to subqueries in case we're introducing additional
            # type constraints
            for stmt in ca.query.children[:]:
                term = stmt.selection[ca.colnum]
                sols = [
                    sol for sol in stmt.solutions
                    if term.get_type(sol, kwargs) in capt
                ]
                if not sols:
                    ca.query.remove_select(stmt)
                else:
                    stmt.set_possible_types(sols)

    def set_statement_type(self, etype):
        """set the statement type for this selection
        this method must be called last (i.e. once selected variables has been
        added)
        """
        assert self.selection
        # Person P  ->  Any P where P is Person
        if etype != 'Any':
            variables = list(self.get_selected_variables())
            if not variables:
                raise BadRQLQuery('Setting type in selection is only allowed '
                                  'when some variable is selected')
            for var in variables:
                self.add_type_restriction(var.variable, etype)

    def set_distinct(self, value):
        """mark DISTINCT query"""
        if self.should_register_op and value != self.distinct:
            from rql.undo import SetDistinctOperation
            self.undo_manager.add_operation(
                SetDistinctOperation(self.distinct, self))
        self.distinct = value

    def set_limit(self, limit):
        if limit is not None and (not isinstance(limit, integer_types)
                                  or limit <= 0):
            raise BadRQLQuery('bad limit %s' % limit)
        if self.should_register_op and limit != self.limit:
            from rql.undo import SetLimitOperation
            self.undo_manager.add_operation(SetLimitOperation(
                self.limit, self))
        self.limit = limit

    def set_offset(self, offset):
        if offset is not None and (not isinstance(offset, integer_types)
                                   or offset < 0):
            raise BadRQLQuery('bad offset %s' % offset)
        if self.should_register_op and offset != self.offset:
            from rql.undo import SetOffsetOperation
            self.undo_manager.add_operation(
                SetOffsetOperation(self.offset, self))
        self.offset = offset

    def set_orderby(self, terms):
        self.orderby = terms
        for node in terms:
            node.parent = self

    def set_groupby(self, terms):
        self.groupby = terms
        for node in terms:
            node.parent = self

    def set_with(self, terms, check=True):
        self.with_ = []
        for node in terms:
            self.add_subquery(node, check)

    def add_subquery(self, node, check=True):
        assert node.query
        if not isinstance(self.with_, list):
            self.with_ = []
        node.parent = self
        self.with_.append(node)
        if check and len(node.aliases) != len(
                node.query.children[0].selection):
            raise BadRQLQuery('Should have the same number of aliases than '
                              'selected terms in sub-query')
        for i, alias in enumerate(node.aliases):
            alias = alias.name
            if check and alias in self.aliases:
                raise BadRQLQuery('Duplicated alias %s' % alias)
            ca = self.get_variable(alias, i)
            ca.query = node.query

    def remove_subquery(self, node):
        self.with_.remove(node)
        node.parent = None
        for i, alias in enumerate(node.aliases):
            del self.aliases[alias.name]

    def get_variable(self, name, colnum=None):
        """get a variable instance from its name

        the variable is created if it doesn't exist yet
        """
        if name in self.aliases:
            return self.aliases[name]
        if colnum is not None:  # take care, may be 0
            self.aliases[name] = calias = nodes.ColumnAlias(name, colnum)
            calias.stmt = self
            # alias may already have been used as a regular variable, replace it
            if name in self.defined_vars:
                var = self.defined_vars.pop(name)
                calias.stinfo['references'] = var.stinfo['references']
                for vref in var.references():
                    vref.variable = calias
            return self.aliases[name]
        return super(Select, self).get_variable(name)

    def clean_solutions(self, solutions=None):
        """when a rqlst has been extracted from another, this method returns
        solutions which make sense for this sub syntax tree
        """
        if solutions is None:
            solutions = self.solutions
        # this may occurs with rql optimization, for instance on
        # 'Any X WHERE X eid 12' query
        if not (self.defined_vars or self.aliases):
            self.solutions = [{}]
        else:
            newsolutions = []
            for origsol in solutions:
                asol = {}
                for var in self.defined_vars:
                    asol[var] = origsol[var]
                for var in self.aliases:
                    asol[var] = origsol[var]
                if asol not in newsolutions:
                    newsolutions.append(asol)
            self.solutions = newsolutions

    def get_selection_solutions(self):
        """return the set of variable names which take different type according
        to the solutions
        """
        descriptions = set()
        for solution in self.solutions:
            descr = []
            for term in self.selection:
                try:
                    descr.append(term.get_type(solution=solution))
                except CoercionError:
                    pass
            descriptions.add(tuple(descr))
        return descriptions

    # quick accessors #########################################################

    def get_selected_variables(self):
        """returns all selected variables, including those used in aggregate
        functions
        """
        for term in self.selection:
            for node in term.iget_nodes(nodes.VariableRef):
                yield node

    # construction helper methods #############################################

    def save_state(self):
        """save the current tree"""
        self.parent.save_state()

    def recover(self):
        """reverts the tree as it was when save_state() was last called"""
        self.parent.recover()

    def append_selected(self, term):
        if isinstance(term, nodes.Constant) and term.type == 'etype':
            raise BadRQLQuery('Entity type are not allowed in selection')
        term.parent = self
        self.selection.append(term)

    # XXX proprify edition, we should specify if we want:
    # * undo support
    # * references handling
    def replace(self, oldnode, newnode):
        if oldnode is self.where:
            self.where = newnode
        elif any(oldnode.is_equivalent(s) for s in self.selection):
            index = next(i for i, s in enumerate(self.selection)
                         if oldnode.is_equivalent(s))
            self.selection[index] = newnode
        elif any(oldnode.is_equivalent(o) for o in self.orderby):
            index = next(i for i, o in enumerate(self.orderby)
                         if oldnode.is_equivalent(o))
            self.orderby[index] = newnode
        elif any(oldnode.is_equivalent(g) for g in self.groupby):
            index = next(i for i, g in enumerate(self.groupby)
                         if oldnode.is_equivalent(g))
            self.groupby[index] = newnode
        elif any(oldnode.is_equivalent(h) for h in self.having):
            index = next(i for i, h in enumerate(self.having)
                         if oldnode.is_equivalent(h))
            self.having[index] = newnode
        else:
            raise Exception('duh XXX %s' % oldnode)
        # XXX no undo/reference support 'by design' (i.e. breaks things if you add
        # it...)
        oldnode.parent = None
        newnode.parent = self
        return oldnode, self, None

    def remove(self, node):
        if node is self.where:
            self.where = None
        elif any(node.is_equivalent(o) for o in self.orderby):
            self.remove_sort_term(node)
        elif any(node.is_equivalent(g) for g in self.groupby):
            self.remove_group_term(node)
        elif any(node.is_equivalent(h) for h in self.having):
            self.having.remove(node)
        # XXX selection
        else:
            raise Exception('duh XXX')
        node.parent = None
        return node, self, None

    def undefine_variable(self, var):
        """undefine the given variable and remove all relations where it appears"""
        if hasattr(var, 'variable'):
            var = var.variable
        # remove relations where this variable is referenced
        for vref in var.references():
            rel = vref.relation()
            if rel is not None:
                self.remove_node(rel)
            # XXX may have other nodes between vref and the sort term
            elif isinstance(vref.parent, nodes.SortTerm):
                self.remove_sort_term(vref.parent)
            elif vref in self.groupby:
                self.remove_group_term(vref)
            else:  # selected variable
                self.remove_selected(vref)
        # effective undefine operation
        if self.should_register_op:
            from rql.undo import UndefineVarOperation
            solutions = [d.copy() for d in self.solutions]
            self.undo_manager.add_operation(
                UndefineVarOperation(var, self, solutions))
        for sol in self.solutions:
            sol.pop(var.name, None)
        del self.defined_vars[var.name]

    def _var_index(self, var):
        """get variable index in the list using identity (Variable and VariableRef
        define __cmp__
        """
        for i, term in enumerate(self.selection):
            if term is var:
                return i
        raise IndexError()

    def remove_selected(self, var):
        """deletes var from selection variable"""
        # assert isinstance(var, VariableRef)
        index = self._var_index(var)
        if self.should_register_op:
            from rql.undo import UnselectVarOperation
            self.undo_manager.add_operation(UnselectVarOperation(var, index))
        for vref in self.selection.pop(index).iget_nodes(nodes.VariableRef):
            vref.unregister_reference()

    def add_selected(self, term, index=None):
        """override Select.add_selected to memoize modification when needed"""
        if isinstance(term, nodes.Variable):
            term = nodes.VariableRef(term, noautoref=1)
            term.register_reference()
        else:
            for var in term.iget_nodes(nodes.VariableRef):
                var = nodes.variable_ref(var)
                var.register_reference()
        if index is not None:
            self.selection.insert(index, term)
            term.parent = self
        else:
            self.append_selected(term)
        if self.should_register_op:
            from rql.undo import SelectVarOperation
            self.undo_manager.add_operation(SelectVarOperation(term))

    def add_group_var(self, var, index=None):
        """add var in 'orderby' constraints
        asc is a boolean indicating the group order (ascendent or descendent)
        """
        if not self.groupby:
            self.groupby = []
        vref = nodes.variable_ref(var)
        vref.register_reference()
        if index is None:
            self.groupby.append(vref)
        else:
            self.groupby.insert(index, vref)
        vref.parent = self
        if self.should_register_op:
            from rql.undo import AddGroupOperation
            self.undo_manager.add_operation(AddGroupOperation(vref))

    def remove_group_term(self, term):
        """remove the group variable and the group node if necessary"""
        if self.should_register_op:
            from rql.undo import RemoveGroupOperation
            self.undo_manager.add_operation(RemoveGroupOperation(term))
        for vref in term.iget_nodes(nodes.VariableRef):
            vref.unregister_reference()
        index = next(i for i, g in enumerate(self.groupby)
                     if term.is_equivalent(g))
        del self.groupby[index]

    remove_group_var = deprecated('[rql 0.29] use remove_group_term instead')(
        remove_group_term)

    def remove_groups(self):
        for vref in self.groupby[:]:
            self.remove_group_term(vref)

    def add_sort_var(self, var, asc=True):
        """add var in 'orderby' constraints
        asc is a boolean indicating the sort order (ascendent or descendent)
        """
        vref = nodes.variable_ref(var)
        vref.register_reference()
        term = nodes.SortTerm(vref, asc)
        self.add_sort_term(term)

    def add_sort_term(self, term, index=None):
        if not self.orderby:
            self.orderby = []
        if index is None:
            self.orderby.append(term)
        else:
            self.orderby.insert(index, term)
        term.parent = self
        for vref in term.iget_nodes(nodes.VariableRef):
            try:
                vref.register_reference()
            except AssertionError:
                pass  # already referenced
        if self.should_register_op:
            from rql.undo import AddSortOperation
            self.undo_manager.add_operation(AddSortOperation(term))

    def remove_sort_terms(self):
        if self.orderby:
            for term in self.orderby[:]:
                self.remove_sort_term(term)

    def remove_sort_term(self, term):
        """remove a sort term and the sort node if necessary"""
        if self.should_register_op:
            from rql.undo import RemoveSortOperation
            self.undo_manager.add_operation(RemoveSortOperation(term))
        for vref in term.iget_nodes(nodes.VariableRef):
            vref.unregister_reference()
        self.orderby.remove(term)

    def select_only_variables(self):
        selection = []
        for term in self.selection:
            for vref in term.iget_nodes(nodes.VariableRef):
                if not any(vref.is_equivalent(s) for s in selection):
                    vref.parent = self
                    selection.append(vref)
        self.selection = selection
Ejemplo n.º 6
0
import sys
import re
from os.path import exists, expanduser
from copy import copy
from ConfigParser import ConfigParser, NoOptionError, NoSectionError, \
     DuplicateSectionError
from warnings import warn

from logilab.common.compat import set, reversed
from logilab.common.textutils import normalize_text, unquote
from logilab.common.deprecation import deprecated
from logilab.common import optik_ext as optparse

REQUIRED = []

check_csv = deprecated('use lgc.optik_ext.check_csv')(optparse.check_csv)


class UnsupportedAction(Exception):
    """raised by set_option when it doesn't know what to do for an action"""


def _get_encoding(encoding, stream):
    encoding = encoding or getattr(stream, 'encoding', None)
    if not encoding:
        import locale
        encoding = locale.getpreferredencoding()
    return encoding


def _encode(string, encoding):
Ejemplo n.º 7
0
        value = self.NO_DEFAULT_VALUE
    return option.help.replace(self.default_tag, str(value))


def _validate(value, optdict, name=''):
    """return a validated value for an option according to its type

    optional argument name is only used for error message formatting
    """
    try:
        _type = optdict['type']
    except KeyError:
        # FIXME
        return value
    return _call_validator(_type, optdict, name, value)
convert = deprecated('[0.60] convert() was renamed _validate()')(_validate)

# format and output functions ##################################################

def comment(string):
    """return string as a comment"""
    lines = [line.strip() for line in string.splitlines()]
    return '# ' + ('%s# ' % os.linesep).join(lines)

def format_time(value):
    if not value:
        return '0'
    if value != int(value):
        return '%.2fs' % value
    value = int(value)
    nbmin, nbsec = divmod(value, 60)
Ejemplo n.º 8
0
    return sep.join(result)


def norm_read(path):
    """Return the content of the file with normalized line feeds.

    :type path: str
    :param path: path to the file to read

    :rtype: str
    :return: the content of the file with normalized line feeds
    """
    return open(path, 'U').read()


norm_read = deprecated("use \"open(path, 'U').read()\"")(norm_read)


def norm_open(path):
    """Return a stream for a file with content with normalized line feeds.

    :type path: str
    :param path: path to the file to open

    :rtype: file or StringIO
    :return: the opened file with normalized line feeds
    """
    return open(path, 'U')


norm_open = deprecated("use \"open(path, 'U')\"")(norm_open)
Ejemplo n.º 9
0
else:
    from io import FileIO, BytesIO, StringIO
    from imp import reload

# Where do pickles come from?
try:
    import cPickle as pickle
except ImportError:
    import pickle

from logilab.common.deprecation import deprecated

from itertools import izip, chain, imap

if sys.version_info < (3, 0):  # 2to3 will remove the imports
    izip = deprecated("izip exists in itertools since py2.3")(izip)
    imap = deprecated("imap exists in itertools since py2.3")(imap)
chain = deprecated("chain exists in itertools since py2.3")(chain)

sum = deprecated("sum exists in builtins since py2.3")(sum)
enumerate = deprecated("enumerate exists in builtins since py2.3")(enumerate)
frozenset = deprecated("frozenset exists in builtins since py2.4")(frozenset)
reversed = deprecated("reversed exists in builtins since py2.4")(reversed)
sorted = deprecated("sorted exists in builtins since py2.4")(sorted)
max = deprecated("max exists in builtins since py2.4")(max)


# Python2.5 builtins
try:
    any = any
    all = all
Ejemplo n.º 10
0
    >>> splitstrip('a')
    ['a']
    >>>

    :type string: str or unicode
    :param string: a csv line

    :type sep: str or unicode
    :param sep: field separator, default to the comma (',')

    :rtype: str or unicode
    :return: the unquoted string (or the input string if it wasn't quoted)
    """
    return [word.strip() for word in string.split(sep) if word.strip()]

get_csv = deprecated('get_csv is deprecated, use splitstrip')(splitstrip)


def split_url_or_path(url_or_path):
    """return the latest component of a string containing either an url of the
    form <scheme>://<path> or a local file system path
    """
    if '://' in url_or_path:
        return url_or_path.rstrip('/').rsplit('/', 1)
    return osp.split(url_or_path.rstrip(osp.sep))


def text_to_dict(text):
    """parse multilines text containing simple 'key=value' lines and return a
    dict of {'key': 'value'}. When the same key is encountered multiple time,
    value is turned into a list containing all values.
Ejemplo n.º 11
0
# See also http://bugs.python.org/issue11776
if sys.version_info[0] == 3:

    def method_type(callable, instance, klass):
        # api change. klass is no more considered
        return types.MethodType(callable, instance)


else:
    # alias types otherwise
    method_type = types.MethodType

# Pythons 2 and 3 differ on where to get StringIO
if sys.version_info < (3, 0):
    from cStringIO import StringIO

    FileIO = file
    BytesIO = StringIO
    reload = reload
else:
    from io import FileIO, BytesIO, StringIO
    from imp import reload

from logilab.common.deprecation import deprecated

# Other projects import these from here, keep providing them for
# backwards compat
any = deprecated('use builtin "any"')(any)
all = deprecated('use builtin "all"')(all)
Ejemplo n.º 12
0
            result.append('..')
    result += to_parts
    return sep.join(result)


def norm_read(path):
    """Return the content of the file with normalized line feeds.

    :type path: str
    :param path: path to the file to read

    :rtype: str
    :return: the content of the file with normalized line feeds
    """
    return open(path, 'U').read()
norm_read = deprecated("use \"open(path, 'U').read()\"")(norm_read)

def norm_open(path):
    """Return a stream for a file with content with normalized line feeds.

    :type path: str
    :param path: path to the file to open

    :rtype: file or StringIO
    :return: the opened file with normalized line feeds
    """
    return open(path, 'U')
norm_open = deprecated("use \"open(path, 'U')\"")(norm_open)

def lines(path, comments=None):
    """Return a list of non empty lines in the file located at `path`.
Ejemplo n.º 13
0
    reload = reload
else:
    from io import FileIO, BytesIO, StringIO
    from imp import reload

# Where do pickles come from?
try:
    import cPickle as pickle
except ImportError:
    import pickle

from logilab.common.deprecation import deprecated

from itertools import izip, chain, imap
if sys.version_info < (3, 0):# 2to3 will remove the imports
    izip = deprecated('izip exists in itertools since py2.3')(izip)
    imap = deprecated('imap exists in itertools since py2.3')(imap)
chain = deprecated('chain exists in itertools since py2.3')(chain)

sum = deprecated('sum exists in builtins since py2.3')(sum)
enumerate = deprecated('enumerate exists in builtins since py2.3')(enumerate)
frozenset = deprecated('frozenset exists in builtins since py2.4')(frozenset)
reversed = deprecated('reversed exists in builtins since py2.4')(reversed)
sorted = deprecated('sorted exists in builtins since py2.4')(sorted)
max = deprecated('max exists in builtins since py2.4')(max)


# Python2.5 builtins
try:
    any = any
    all = all
Ejemplo n.º 14
0
else:
    import unittest as unittest
    from unittest import SkipTest

from functools import wraps

from logilab.common.debugger import Debugger
from logilab.common.decorators import cached, classproperty
from logilab.common import textutils

__all__ = ['unittest_main', 'find_tests', 'nocoverage', 'pause_trace']

DEFAULT_PREFIXES = ('test', 'regrtest', 'smoketest', 'unittest', 'func',
                    'validation')

is_generator = deprecated('[lgc 0.63] use inspect.isgeneratorfunction')(
    isgeneratorfunction)

# used by unittest to count the number of relevant levels in the traceback
__unittest = 1


@deprecated('with_tempdir is deprecated, use {0}.TemporaryDirectory.'.format(
    'tempfile' if not PY2 else 'backports.tempfile'))
def with_tempdir(callable):
    """A decorator ensuring no temporary file left when the function return
    Work only for temporary file created with the tempfile module"""
    if isgeneratorfunction(callable):

        def proxy(*args, **kwargs):
            old_tmpdir = tempfile.gettempdir()
            new_tmpdir = tempfile.mkdtemp(prefix="temp-lgc-")
Ejemplo n.º 15
0
class OptionsProviderMixIn(object):
    """Mixin to provide options to an OptionsManager"""

    # those attributes should be overridden
    priority = -1
    name = 'default'
    options = ()
    level = 0

    def __init__(self):
        self.config = optik_ext.Values()
        for option in self.options:
            try:
                option, optdict = option
            except ValueError:
                raise Exception('Bad option: %r' % option)
            if isinstance(optdict.get('default'), Method):
                optdict['default'].bind(self)
            elif isinstance(optdict.get('callback'), Method):
                optdict['callback'].bind(self)
        self.load_defaults()

    def load_defaults(self):
        """initialize the provider using default values"""
        for opt, optdict in self.options:
            action = optdict.get('action')
            if action != 'callback':
                # callback action have no default
                default = self.option_default(opt, optdict)
                if default is REQUIRED:
                    continue
                self.set_option(opt, default, action, optdict)

    def option_default(self, opt, optdict=None):
        """return the default value for an option"""
        if optdict is None:
            optdict = self.get_option_def(opt)
        default = optdict.get('default')
        if callable(default):
            default = default()
        return default

    def option_attrname(self, opt, optdict=None):
        """get the config attribute corresponding to opt
        """
        if optdict is None:
            optdict = self.get_option_def(opt)
        return optdict.get('dest', opt.replace('-', '_'))
    option_name = deprecated('[0.60] OptionsProviderMixIn.option_name() was renamed to option_attrname()')(option_attrname)

    def option_value(self, opt):
        """get the current value for the given option"""
        return getattr(self.config, self.option_attrname(opt), None)

    def set_option(self, opt, value, action=None, optdict=None):
        """method called to set an option (registered in the options list)
        """
        if optdict is None:
            optdict = self.get_option_def(opt)
        if value is not None:
            value = _validate(value, optdict, opt)
        if action is None:
            action = optdict.get('action', 'store')
        if optdict.get('type') == 'named': # XXX need specific handling
            optname = self.option_attrname(opt, optdict)
            currentvalue = getattr(self.config, optname, None)
            if currentvalue:
                currentvalue.update(value)
                value = currentvalue
        if action == 'store':
            setattr(self.config, self.option_attrname(opt, optdict), value)
        elif action in ('store_true', 'count'):
            setattr(self.config, self.option_attrname(opt, optdict), 0)
        elif action == 'store_false':
            setattr(self.config, self.option_attrname(opt, optdict), 1)
        elif action == 'append':
            opt = self.option_attrname(opt, optdict)
            _list = getattr(self.config, opt, None)
            if _list is None:
                if isinstance(value, (list, tuple)):
                    _list = value
                elif value is not None:
                    _list = []
                    _list.append(value)
                setattr(self.config, opt, _list)
            elif isinstance(_list, tuple):
                setattr(self.config, opt, _list + (value,))
            else:
                _list.append(value)
        elif action == 'callback':
            optdict['callback'](None, opt, value, None)
        else:
            raise UnsupportedAction(action)

    def input_option(self, option, optdict, inputlevel=99):
        default = self.option_default(option, optdict)
        if default is REQUIRED:
            defaultstr = '(required): '
        elif optdict.get('level', 0) > inputlevel:
            return
        elif optdict['type'] == 'password' or default is None:
            defaultstr = ': '
        else:
            defaultstr = '(default: %s): ' % format_option_value(optdict, default)
        print ':%s:' % option
        print optdict.get('help') or option
        inputfunc = INPUT_FUNCTIONS[optdict['type']]
        value = inputfunc(optdict, defaultstr)
        while default is REQUIRED and not value:
            print 'please specify a value'
            value = inputfunc(optdict, '%s: ' % option)
        if value is None and default is not None:
            value = default
        self.set_option(option, value, optdict=optdict)

    def get_option_def(self, opt):
        """return the dictionary defining an option given it's name"""
        assert self.options
        for option in self.options:
            if option[0] == opt:
                return option[1]
        raise OptionError('no such option %s in section %r'
                          % (opt, self.name), opt)


    def all_options(self):
        """return an iterator on available options for this provider
        option are actually described by a 3-uple:
        (section, option name, option dictionary)
        """
        for section, options in self.options_by_section():
            if section is None:
                if self.name is None:
                    continue
                section = self.name.upper()
            for option, optiondict, value in options:
                yield section, option, optiondict

    def options_by_section(self):
        """return an iterator on options grouped by section

        (section, [list of (optname, optdict, optvalue)])
        """
        sections = {}
        for optname, optdict in self.options:
            sections.setdefault(optdict.get('group'), []).append(
                (optname, optdict, self.option_value(optname)))
        if None in sections:
            yield None, sections.pop(None)
        for section, options in sections.items():
            yield section.upper(), options

    def options_and_values(self, options=None):
        if options is None:
            options = self.options
        for optname, optdict in options:
            yield (optname, optdict, self.option_value(optname))
Ejemplo n.º 16
0
        value = self.NO_DEFAULT_VALUE
    return option.help.replace(self.default_tag, str(value))


def _validate(value, optdict, name=''):
    """return a validated value for an option according to its type

    optional argument name is only used for error message formatting
    """
    try:
        _type = optdict['type']
    except KeyError:
        # FIXME
        return value
    return _call_validator(_type, optdict, name, value)
convert = deprecated('[0.60] convert() was renamed _validate()')(_validate)

# format and output functions ##################################################

def comment(string):
    """return string as a comment"""
    lines = [line.strip() for line in string.splitlines()]
    return '# ' + ('%s# ' % os.linesep).join(lines)

def format_time(value):
    if not value:
        return '0'
    if value != int(value):
        return '%.2fs' % value
    value = int(value)
    nbmin, nbsec = divmod(value, 60)
Ejemplo n.º 17
0
    ['a']
    >>>

    :type string: str or unicode
    :param string: a csv line

    :type sep: str or unicode
    :param sep: field separator, default to the comma (',')

    :rtype: str or unicode
    :return: the unquoted string (or the input string if it wasn't quoted)
    """
    return [word.strip() for word in string.split(sep) if word.strip()]


get_csv = deprecated()(splitstrip)


def split_url_or_path(url_or_path):
    """return the latest component of a string containing either an url of the
    form <scheme>://<path> or a local file system path
    """
    if '://' in url_or_path:
        return url_or_path.rstrip('/').rsplit('/', 1)
    return osp.split(url_or_path.rstrip(osp.sep))


def text_to_dict(text):
    """parse multilines text containing simple 'key=value' lines and return a
    dict of {'key': 'value'}. When the same key is encountered multiple time,
    value is turned into a list containing all values.
Ejemplo n.º 18
0
            outfile = open(join(destdir, name), 'wb')
            outfile.write(zfobj.read(name))
            outfile.close()


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):
        cmd = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        self.out, self.err = cmd.communicate()
        self.status = os.WEXITSTATUS(cmd.returncode)

Execute = deprecated('Use subprocess.Popen instead')(Execute)


class ProgressBar(object):
    """A simple text progression bar."""

    def __init__(self, nbops, size=20, stream=sys.stdout, title=''):
        if title:
            self._fstr = '\r%s [%%-%ss]' % (title, int(size))
        else:
            self._fstr = '\r[%%-%ss]' % int(size)
        self._stream = stream
        self._total = nbops
        self._size = size
        self._current = 0
        self._progress = 0
Ejemplo n.º 19
0

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):
        cmd = subprocess.Popen(command,
                               shell=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
        self.out, self.err = cmd.communicate()
        self.status = os.WEXITSTATUS(cmd.returncode)


Execute = deprecated('Use subprocess.Popen instead')(Execute)


def acquire_lock(lock_file, max_try=10, delay=10, max_delay=3600):
    """Acquire a lock represented by a file on the file system

    If the process written in lock file doesn't exist anymore, we remove the
    lock file immediately
    If age of the lock_file is greater than max_delay, then we raise a UserWarning
    """
    count = abs(max_try)
    while count:
        try:
            fd = os.open(lock_file, os.O_EXCL | os.O_RDWR | os.O_CREAT)
            os.write(fd, str_to_bytes(str(os.getpid())))
            os.close(fd)
Ejemplo n.º 20
0
import sys
import re
from os.path import exists, expanduser
from copy import copy
from ConfigParser import ConfigParser, NoOptionError, NoSectionError, \
     DuplicateSectionError
from warnings import warn

from logilab.common.compat import set, reversed
from logilab.common.textutils import normalize_text, unquote
from logilab.common.deprecation import deprecated
from logilab.common import optik_ext as optparse

REQUIRED = []

check_csv = deprecated('use lgc.optik_ext.check_csv')(optparse.check_csv)

class UnsupportedAction(Exception):
    """raised by set_option when it doesn't know what to do for an action"""


def _get_encoding(encoding, stream):
    encoding = encoding or getattr(stream, 'encoding', None)
    if not encoding:
        import locale
        encoding = locale.getpreferredencoding()
    return encoding

def _encode(string, encoding):
    if isinstance(string, unicode):
        return string.encode(encoding)
Ejemplo n.º 21
0
    import unittest
    from unittest import SkipTest

from functools import wraps

from logilab.common.debugger import Debugger, colorize_source
from logilab.common.decorators import cached, classproperty
from logilab.common import textutils


__all__ = ['main', 'unittest_main', 'find_tests', 'run_test', 'spawn']

DEFAULT_PREFIXES = ('test', 'regrtest', 'smoketest', 'unittest',
                    'func', 'validation')

is_generator = deprecated('[lgc 0.63] use inspect.isgeneratorfunction')(isgeneratorfunction)

# used by unittest to count the number of relevant levels in the traceback
__unittest = 1


def with_tempdir(callable):
    """A decorator ensuring no temporary file left when the function return
    Work only for temporary file created with the tempfile module"""
    if isgeneratorfunction(callable):
        def proxy(*args, **kwargs):
            old_tmpdir = tempfile.gettempdir()
            new_tmpdir = tempfile.mkdtemp(prefix="temp-lgc-")
            tempfile.tempdir = new_tmpdir
            try:
                for x in callable(*args, **kwargs):
Ejemplo n.º 22
0
    ('remove_from_addmenu', uicfg.actionbox_appearsin_addmenu),
    ('set_fields_order', uicfg.autoform_field_kwargs),
    ('hide_field', uicfg.autoform_section),
    ('hide_fields', uicfg.autoform_section),
    ('set_field_kwargs', uicfg.autoform_field_kwargs),
    ('set_field', uicfg.autoform_field),
    ('edit_inline', uicfg.autoform_section),
    ('edit_as_attr', uicfg.autoform_section),
    ('set_muledit_editable', uicfg.autoform_section),
)

for funcname, tag in backward_compat_funcs:
    msg = ('[3.16] uihelper.%(name)s is deprecated, please use '
           'web.views.uicfg.%(rtagid)s.%(name)s' %
           dict(name=funcname, rtagid=tag.__regid__))
    globals()[funcname] = deprecated(msg)(getattr(tag, funcname))


class meta_formconfig(type):
    """metaclass of FormConfig classes, only for easier declaration purpose"""
    def __init__(cls, name, bases, classdict):
        if cls.etype is None:
            return
        uicfg_afs = cls.uicfg_afs or uicfg.autoform_section
        uicfg_aff = cls.uicfg_aff or uicfg.autoform_field
        uicfg_affk = cls.uicfg_affk or uicfg.autoform_field_kwargs
        for attr_role in cls.hidden:
            uicfg_afs.hide_field(cls.etype, attr_role, formtype=cls.formtype)
        for attr_role in cls.rels_as_attrs:
            uicfg_afs.edit_as_attr(cls.etype, attr_role, formtype=cls.formtype)
        for attr_role in cls.inlined:
Ejemplo n.º 23
0
    >>> splitstrip('a')
    ['a']
    >>>

    :type string: str or unicode
    :param string: a csv line

    :type sep: str or unicode
    :param sep: field separator, default to the comma (',')

    :rtype: str or unicode
    :return: the unquoted string (or the input string if it wasn't quoted)
    """
    return [word.strip() for word in string.split(sep) if word.strip()]

get_csv = deprecated()(splitstrip)


def split_url_or_path(url_or_path):
    """return the latest component of a string containing either an url of the
    form <scheme>://<path> or a local file system path
    """
    if '://' in url_or_path:
        return url_or_path.rstrip('/').rsplit('/', 1)
    return osp.split(url_or_path.rstrip(osp.sep))


def text_to_dict(text):
    """parse multilines text containing simple 'key=value' lines and return a
    dict of {'key': 'value'}. When the same key is encountered multiple time,
    value is turned into a list containing all values.
 def test_deprecated_func(self):
     any_func = deprecation.deprecated()(self.mk_func())
     any_func()
     any_func = deprecation.deprecated('message')(self.mk_func())
     any_func()
Ejemplo n.º 25
0
 def test_deprecated_func(self):
     any_func = deprecation.deprecated()(self.mk_func())
     any_func()
     any_func = deprecation.deprecated('message')(self.mk_func())
     any_func()
Ejemplo n.º 26
0
    reload = reload
else:
    from io import FileIO, BytesIO, StringIO
    from imp import reload

# Where do pickles come from?
try:
    import cPickle as pickle
except ImportError:
    import pickle

from logilab.common.deprecation import deprecated

from itertools import izip, chain, imap
if sys.version_info < (3, 0):# 2to3 will remove the imports
    izip = deprecated('izip exists in itertools since py2.3')(izip)
    imap = deprecated('imap exists in itertools since py2.3')(imap)
chain = deprecated('chain exists in itertools since py2.3')(chain)

sum = deprecated('sum exists in builtins since py2.3')(sum)
enumerate = deprecated('enumerate exists in builtins since py2.3')(enumerate)
frozenset = deprecated('frozenset exists in builtins since py2.4')(frozenset)
reversed = deprecated('reversed exists in builtins since py2.4')(reversed)
sorted = deprecated('sorted exists in builtins since py2.4')(sorted)
max = deprecated('max exists in builtins since py2.4')(max)


# Python2.5 builtins
try:
    any = any
    all = all
Ejemplo n.º 27
0
# Where do pickles come from?
try:
    import cPickle as pickle
except ImportError:
    import pickle

try:
    set = set
    frozenset = frozenset
except NameError:# Python 2.3 doesn't have `set`
    from sets import Set as set, ImmutableSet as frozenset

from logilab.common.deprecation import deprecated

from itertools import izip, chain, imap
izip = deprecated('izip exists in itertools since py2.3')(izip)
imap = deprecated('imap exists in itertools since py2.3')(imap)
chain = deprecated('chain exists in itertools since py2.3')(chain)

sum = deprecated('sum exists in builtins since py2.3')(sum)
enumerate = deprecated('enumerate exists in builtins since py2.3')(enumerate)

try:
    sorted = sorted
    reversed = reversed
except NameError: # py2.3

    def sorted(iterable, cmp=None, key=None, reverse=False):
        original = list(iterable)
        if key:
            l2 = [(key(elt), index) for index, elt in builtins.enumerate(original)]