<commit_before>#!/usr/bin/env python

# Copyright 2012-2013 Tetsuo Kiso. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

"""
A simple CoNLL-X to tikz-dependency converter.

This converter aims to provide a funtion to visualize a simple
dependency tree through converting from the CoNLL-X data format to the tikz-dependency.

Usage:
  $ ./conllx_to_tikz_dep.py [options] conllx_data

or
  $ cat conllx_data | ./conllx_to_tikz_dep.py

For the details of the input data format, see the following link:

CoNLL-X Shared Task: Multi-lingual Dependency Parsing
http://ilk.uvt.nl/conll/#dataformat
"""

import optparse

matrix_separator = '\^'
special_chars = ['{', '}', '$', '&', '%']
correct_edge_color = 'red'
wrong_edge_color = 'blue!70!black'

class Token(object):

    def __init__(self):
        self.id = None
        self.form = None
        self.lemma = None
        self.cpos = None
        self.pos = None
        self.feat = None
        self.head = None
        self.deprel = None
        self.phead = None
        self.pdeprel = None

    def is_root(self):
        return self.head == 0 or self.head == -1

class Sentence(object):

    def __init__(self):
        self.tokens = []
        self.length = 0

    def __getitem__(self, i):
        return self.tokens[i]

    def __setitem__(self, i, t):
        self.tokens[i] = t

    def add(self, t):
        self.tokens.append(t)
        self.length += 1

    def length(self):
        return self.length

    def __str__(self):
        return ' '.join([v.form for v in self.tokens])

    def to_deptext(self):
      base = ' %s ' % matrix_separator
      s = base.join([v.form for v in self.tokens]) + ' \\\\'
      return s

    # returns a tuple of (head, dependent)
    def iterate_edges(self):
        for t in self.tokens:
            if t.is_root():
                continue
            yield (t.id, t.head)

    def iterate_labeled_edges(self):
        for t in self.tokens:
            if t.is_root():
                continue
            yield (t.id, t.head, t.deprel)

    def zip(self, other):
      for tup in zip(self.tokens, other.tokens):
        if len(tup) != 2:
          print 'Error: invalid input:', tup
          sys.exit(1)
        else:
          if tup[0].is_root() and tup[1].is_root:
            continue
          yield ((tup[0].id, tup[0].head), (tup[1].id, tup[1].head))

def replace_special(s):
  for c in special_chars:
    s = s.replace(c, '\\' + c)
  return s

def init_token(lis, is_conllx=True):
    t = Token()
    t.id = int(lis[0])
    t.form = replace_special(lis[1])

    t.lemma = lis[2]
    t.cpos = lis[3]
    t.pos = lis[4]
    t.feat = lis[5]
    t.head = int(lis[6])

    if lis[7] == '_':
      t.deprel = ''
    else:
      t.deprel = lis[7]

    if is_conllx:
      t.phead = lis[8]
      t.pdeprel = lis[9]
    return t

def open_conll(filename):
    with open(filename) as f:
        return read(f)

def read(f):
    sents = []
    s = Sentence()
    for l in f:
        if l.startswith('\n'):
            sents.append(s)
            s = Sentence()
            continue

        lis = l.rstrip().split('\t')
        if len(lis) == 1:
          lis = l.rstrip().split(' ')
        if len(lis) == 0:
            continue
        elif len(lis) == 8:
          s.add(init_token(lis, False))
        elif len(lis) == 10:
          s.add(init_token(lis))
        else:
          print 'Data format is broken!'
          sys.exit(1)
    return sents

# h: head, dependent.
def wrap_depedge(dep, h, opt=None):
  if opt == None:
    return '\depedge{%d}{%d}{}' % (h, dep)
  else:
    return '\depedge[%s]{%d}{%d}{}' % (opt, h, dep)

def wrap_depedge_with_label(dep, h, label, opt=None):
  if opt == None:
    return '\depedge{%d}{%d}{%s}' % (h, dep, label)
  else:
    return '\depedge[%s]{%d}{%d}{%s}' % (opt, h, dep, label)

def wrap_depedges(sent):
    return '\n'.join([wrap_depedge(dep, h) for dep, h in sent.iterate_edges()])

def wrap_depedges_with_label(sent):
    return '\n'.join([wrap_depedge_with_label(dep, h, l) for dep, h, l in sent.iterate_labeled_edges()])

class LaTeXFormatter(object):

    def __init__(self, doc_opt, tikz_dep_opt, tikz_deptxt_opt, with_label=False):
        self.doc_opt = doc_opt
        self.tikz_dep_opt = tikz_dep_opt
        self.tikz_deptxt_opt = tikz_deptxt_opt
        self.with_label = with_label

        self.dep_template = '''\\begin{dependency}[%s]
\\begin{deptext}[%s]
%s
\end{deptext}
%s
\end{dependency}'''

    def latex_header(self):
        return '''\documentclass{%s}
\usepackage{tikz-dependency}
\\begin{document}''' % self.doc_opt

    def latex_footer(self):
        return '''\end{document}'''

    def print_tikz_dep(self, sent):
      if self.with_label:
        print self.dep_template % (self.tikz_dep_opt, self.tikz_deptxt_opt,
                                   sent.to_deptext(), wrap_depedges_with_label(sent))
      else:
        print self.dep_template % (self.tikz_dep_opt, self.tikz_deptxt_opt,
                                   sent.to_deptext(), wrap_depedges(sent))

    def diff_depedges(self, gold, predict):
      res = []
      for correct, pre in gold.zip(predict):
        if correct == pre:
          res.append(wrap_depedge(*pre))
        else:
          res.append(wrap_depedge(*correct, opt='edge style={%s}' % correct_edge_color))
          res.append(wrap_depedge(*pre, opt='edge style={%s}' % wrong_edge_color))
      return '\n'.join(res)

    def print_diff_dep(self, gold, predict):
      print '''\\begin{dependency}[%s]
\\begin{deptext}[%s]
%s
\end{deptext}
%s
\end{dependency}''' % (self.tikz_dep_opt, self.tikz_deptxt_opt,
                       gold.to_deptext(), self.diff_depedges(gold, predict))

def parse_options():
    parser = optparse.OptionParser(usage='%prog [options] data')
    parser.add_option('--doc-option', dest='doc_opt', default='standalone',
                      help='the options of documentclass')
    parser.add_option('--dep-option', dest='dep_opt', default='theme = simple',
                      help='the option of the dependency environment')
    parser.add_option('--deptxt-option', dest='deptxt_opt',
                      default='column sep=.7em,ampersand replacement=%s' % matrix_separator,
                      help='the option of the deptext environment')
    parser.add_option('--reverse-edge', dest='reverse_edge', action="store_true", default=False,
                      help='Flag to reverse the direction of edges [default: %default]')
    parser.add_option('--with-label', dest='with_label', action="store_true", default=False,
                      help='Flag to enable label [default: %default]')
    parser.add_option('--diff', dest='gold', default=None,
                      help='Diff mode. You need to specify a gold file annotated by human.')
    (options, unused_args) = parser.parse_args()

    if options.reverse_edge:
      options.dep_opt += ',edge style={<-}'
    return (options, unused_args)

def diff(opts, args, tex_formatter):
  gold = open_conll(opts.gold)
  predict = open_conll(args[0])
  for g, p in zip(gold, predict):
    print tex_formatter.latex_header()
    tex_formatter.print_diff_dep(g, p)
    print tex_formatter.latex_footer()
    print

def main():
    import sys
    opts, unused_args = parse_options()

    tex_formatter = LaTeXFormatter(opts.doc_opt, opts.dep_opt, opts.deptxt_opt, opts.with_label)

    if opts.gold:
      diff(opts, unused_args, tex_formatter)
    else:
      if len(unused_args) == 0:
        sents = read(sys.stdin)
      if len(unused_args) >= 1:
        sents = open_conll(unused_args[0])

      for i, s in enumerate(sents):
        if i > 0: print
        print tex_formatter.latex_header()
        tex_formatter.print_tikz_dep(s)
        print tex_formatter.latex_footer()

if __name__ == '__main__':
    main()
<commit_msg>Bug fix.<commit_after>#!/usr/bin/env python

# Copyright 2012-2013 Tetsuo Kiso. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

"""
A simple CoNLL-X to tikz-dependency converter.

This converter aims to provide a funtion to visualize a simple
dependency tree through converting from the CoNLL-X data format to the tikz-dependency.

Usage:
  $ ./conllx_to_tikz_dep.py [options] conllx_data

or
  $ cat conllx_data | ./conllx_to_tikz_dep.py

For the details of the input data format, see the following link:

CoNLL-X Shared Task: Multi-lingual Dependency Parsing
http://ilk.uvt.nl/conll/#dataformat
"""

import optparse
import sys

matrix_separator = '\^'
special_chars = ['{', '}', '$', '&', '%']
correct_edge_color = 'red'
wrong_edge_color = 'blue!70!black'

class Token(object):

    def __init__(self):
        self.id = None
        self.form = None
        self.lemma = None
        self.cpos = None
        self.pos = None
        self.feat = None
        self.head = None
        self.deprel = None
        self.phead = None
        self.pdeprel = None

    def is_root(self):
        return self.head == 0 or self.head == -1

class Sentence(object):

    def __init__(self):
        self.tokens = []
        self.length = 0

    def __getitem__(self, i):
        return self.tokens[i]

    def __setitem__(self, i, t):
        self.tokens[i] = t

    def add(self, t):
        self.tokens.append(t)
        self.length += 1

    def length(self):
        return self.length

    def __str__(self):
        return ' '.join([v.form for v in self.tokens])

    def to_deptext(self):
      base = ' %s ' % matrix_separator
      s = base.join([v.form for v in self.tokens]) + ' \\\\'
      return s

    # returns a tuple of (head, dependent)
    def iterate_edges(self):
        for t in self.tokens:
            if t.is_root():
                continue
            yield (t.id, t.head)

    def iterate_labeled_edges(self):
        for t in self.tokens:
            if t.is_root():
                continue
            yield (t.id, t.head, t.deprel)

    def zip(self, other):
      for tup in zip(self.tokens, other.tokens):
        if len(tup) != 2:
          print 'Error: invalid input:', tup
          sys.exit(1)
        else:
          if tup[0].is_root() and tup[1].is_root:
            continue
          yield ((tup[0].id, tup[0].head), (tup[1].id, tup[1].head))

def replace_special(s):
  for c in special_chars:
    s = s.replace(c, '\\' + c)
  return s

def init_token(lis, is_conllx=True):
    t = Token()
    t.id = int(lis[0])
    t.form = replace_special(lis[1])

    t.lemma = lis[2]
    t.cpos = lis[3]
    t.pos = lis[4]
    t.feat = lis[5]
    t.head = int(lis[6])

    if lis[7] == '_':
      t.deprel = ''
    else:
      t.deprel = lis[7]

    if is_conllx:
      t.phead = lis[8]
      t.pdeprel = lis[9]
    return t

def open_conll(filename):
    with open(filename) as f:
        return read(f)

def read(f):
    sents = []
    s = Sentence()
    for l in f:
        if l.startswith('\n'):
            sents.append(s)
            s = Sentence()
            continue

        lis = l.rstrip().split('\t')
        if len(lis) == 1:
          lis = l.rstrip().split(' ')
        if len(lis) == 0:
            continue
        elif len(lis) == 8:
          s.add(init_token(lis, False))
        elif len(lis) == 10:
          s.add(init_token(lis))
        else:
          print 'Data format is broken!'
          sys.exit(1)
    return sents

# h: head, dependent.
def wrap_depedge(dep, h, opt=None):
  if opt == None:
    return '\depedge{%d}{%d}{}' % (h, dep)
  else:
    return '\depedge[%s]{%d}{%d}{}' % (opt, h, dep)

def wrap_depedge_with_label(dep, h, label, opt=None):
  if opt == None:
    return '\depedge{%d}{%d}{%s}' % (h, dep, label)
  else:
    return '\depedge[%s]{%d}{%d}{%s}' % (opt, h, dep, label)

def wrap_depedges(sent):
    return '\n'.join([wrap_depedge(dep, h) for dep, h in sent.iterate_edges()])

def wrap_depedges_with_label(sent):
    return '\n'.join([wrap_depedge_with_label(dep, h, l) for dep, h, l in sent.iterate_labeled_edges()])

class LaTeXFormatter(object):

    def __init__(self, doc_opt, tikz_dep_opt, tikz_deptxt_opt, with_label=False):
        self.doc_opt = doc_opt
        self.tikz_dep_opt = tikz_dep_opt
        self.tikz_deptxt_opt = tikz_deptxt_opt
        self.with_label = with_label

        self.dep_template = '''\\begin{dependency}[%s]
\\begin{deptext}[%s]
%s
\end{deptext}
%s
\end{dependency}'''

    def latex_header(self):
        return '''\documentclass{%s}
\usepackage{tikz-dependency}
\\begin{document}''' % self.doc_opt

    def latex_footer(self):
        return '''\end{document}'''

    def print_tikz_dep(self, sent):
      if self.with_label:
        print self.dep_template % (self.tikz_dep_opt, self.tikz_deptxt_opt,
                                   sent.to_deptext(), wrap_depedges_with_label(sent))
      else:
        print self.dep_template % (self.tikz_dep_opt, self.tikz_deptxt_opt,
                                   sent.to_deptext(), wrap_depedges(sent))

    def diff_depedges(self, gold, predict):
      res = []
      for correct, pre in gold.zip(predict):
        if correct == pre:
          res.append(wrap_depedge(*pre))
        else:
          res.append(wrap_depedge(*correct, opt='edge style={%s}' % correct_edge_color))
          res.append(wrap_depedge(*pre, opt='edge style={%s}' % wrong_edge_color))
      return '\n'.join(res)

    def print_diff_dep(self, gold, predict):
      print '''\\begin{dependency}[%s]
\\begin{deptext}[%s]
%s
\end{deptext}
%s
\end{dependency}''' % (self.tikz_dep_opt, self.tikz_deptxt_opt,
                       gold.to_deptext(), self.diff_depedges(gold, predict))

def parse_options():
    parser = optparse.OptionParser(usage='%prog [options] data')
    parser.add_option('--doc-option', dest='doc_opt', default='standalone',
                      help='the options of documentclass')
    parser.add_option('--dep-option', dest='dep_opt', default='theme = simple',
                      help='the option of the dependency environment')
    parser.add_option('--deptxt-option', dest='deptxt_opt',
                      default='column sep=.7em,ampersand replacement=%s' % matrix_separator,
                      help='the option of the deptext environment')
    parser.add_option('--reverse-edge', dest='reverse_edge', action="store_true", default=False,
                      help='Flag to reverse the direction of edges [default: %default]')
    parser.add_option('--with-label', dest='with_label', action="store_true", default=False,
                      help='Flag to enable label [default: %default]')
    parser.add_option('--diff', dest='gold', default=None,
                      help='Diff mode. You need to specify a gold file annotated by human.')
    (options, unused_args) = parser.parse_args()

    if options.reverse_edge:
      options.dep_opt += ',edge style={<-}'
    return (options, unused_args)

def diff(opts, args, tex_formatter):
  gold = open_conll(opts.gold)
  predict = open_conll(args[0])
  for g, p in zip(gold, predict):
    print tex_formatter.latex_header()
    tex_formatter.print_diff_dep(g, p)
    print tex_formatter.latex_footer()
    print

def main():
    opts, unused_args = parse_options()

    tex_formatter = LaTeXFormatter(opts.doc_opt, opts.dep_opt, opts.deptxt_opt, opts.with_label)

    if opts.gold:
      diff(opts, unused_args, tex_formatter)
    else:
      if len(unused_args) == 0:
        sents = read(sys.stdin)
      if len(unused_args) >= 1:
        sents = open_conll(unused_args[0])

      for i, s in enumerate(sents):
        if i > 0: print
        print tex_formatter.latex_header()
        tex_formatter.print_tikz_dep(s)
        print tex_formatter.latex_footer()

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""Admin module for wastd.observations."""
from __future__ import absolute_import, unicode_literals

# from django import forms as django_forms
# import floppyforms as ff
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline
from django.forms import Textarea
from django.db import models

# from django.utils.translation import ugettext_lazy as _
from easy_select2 import select2_modelform as s2form
# from easy_select2.widgets import Select2
from fsm_admin.mixins import FSMTransitionMixin
from django_fsm_log.admin import StateLogInline
# from django_fsm_log.models import StateLog
from reversion.admin import VersionAdmin

from conservation.models import (
    FileAttachment,
    ConservationList,
    ConservationCategory,
    ConservationCriterion,
    # Gazettal,
    TaxonGazettal,
    CommunityGazettal
)

S2ATTRS = {'width': 'auto'}
ConservationCategoryForm = s2form(ConservationCategory, attrs=S2ATTRS)
ConservationCriterionForm = s2form(ConservationCriterion, attrs=S2ATTRS)
ConservationListForm = s2form(ConservationList, attrs=S2ATTRS)
TaxonGazettalForm = s2form(TaxonGazettal, attrs=S2ATTRS)
CommunityGazettalForm = s2form(CommunityGazettal, attrs=S2ATTRS)
FileAttachmentForm = s2form(FileAttachment, attrs=S2ATTRS)

FORMFIELD_OVERRIDES = {
    models.TextField: {'widget': Textarea(attrs={'rows': 20, 'cols': 80})},
}

class CustomStateLogInline(StateLogInline):
    """Custom StateLogInline."""

    classes = ('grp-collapse grp-closed wide extrapretty',)

class FileAttachmentInline(GenericTabularInline):
    """Inline for FileAttachment."""

    model = FileAttachment
    form = FileAttachmentForm
    extra = 1
    classes = ('grp-collapse grp-closed wide extrapretty',)

class ConservationCategoryInline(admin.TabularInline):
    """Inline admin for ConservationCategory."""

    extra = 1
    model = ConservationCategory
    classes = ('grp-collapse grp-closed wide extrapretty',)
    form = ConservationCategoryForm
    # formfield_overrides = FORMFIELD_OVERRIDES

class ConservationCriterionInline(admin.TabularInline):
    """Inline admin for ConservationCriterion."""

    extra = 1
    model = ConservationCriterion
    classes = ('grp-collapse grp-closed wide extrapretty',)
    form = ConservationCriterionForm
    # formfield_overrides = FORMFIELD_OVERRIDES

@admin.register(ConservationList)
class ConservationListAdmin(VersionAdmin):
    """Admin for ConservationList."""

    save_on_top = True
    date_hierarchy = 'active_to'

    # List View
    list_display = (
        "code",
        "label",
        "description",
        "active_from",
        "active_to",
        "scope_wa",
        "scope_cmw",
        "scope_intl",
        "scope_species",
        "scope_communities",
    )
    list_filter = ("scope_wa",
                   "scope_cmw",
                   "scope_intl",
                   "scope_species",
                   "scope_communities",)
    search_fields = ("code", "label", "description", )
    fieldsets = (
        ('Details', {'fields': ("code", "label", "description",)}),
        ('Scope', {
            'classes': ('grp-collapse', 'grp-closed', 'wide'),
            'fields': ("active_from", "active_to",
                       "scope_wa", "scope_cmw", "scope_intl",
                       "scope_species", "scope_communities")

        }),
    )
    formfield_overrides = FORMFIELD_OVERRIDES
    inlines = [ConservationCategoryInline,
               ConservationCriterionInline,
               FileAttachmentInline]

@admin.register(TaxonGazettal)
class TaxonGazettalAdmin(FSMTransitionMixin, VersionAdmin):
    """Admin for TaxonGazettal."""

    save_on_top = True
    date_hierarchy = 'gazetted_on'

    # FSM Transitions
    fsm_field = ['status', ]

    # List View
    list_display = (
        "taxon",
        "scope",
        "status",
        "category_cache",
        "criteria_cache",
        "proposed_on",
        "gazetted_on",
        "deactivated_on",
        "review_due",
        "comments",
    )
    list_filter = (
        "category",
        "scope",
        "status",
        ('proposed_on', admin.DateFieldListFilter),
        ('gazetted_on', admin.DateFieldListFilter),
        ('deactivated_on', admin.DateFieldListFilter),
        ('review_due', admin.DateFieldListFilter),
    )

    search_fields = ("comments", )

    # Detail View layout and widgets
    filter_horizontal = ('category', 'criteria',)
    raw_id_fields = ('taxon', )
    autocomplete_lookup_fields = {'fk': ['taxon', ]}
    form = TaxonGazettalForm
    formfield_overrides = FORMFIELD_OVERRIDES
    inlines = [CustomStateLogInline, FileAttachmentInline]

    fieldsets = (
        ('Conservation Status', {
            'classes': ('grp-collapse', 'grp-open', 'wide', 'extrapretty'),
            'fields': ("taxon", "scope", "category", "criteria",)}
         ),
        ('Approval process', {
            'classes': ('grp-collapse', 'grp-closed', 'wide', 'extrapretty'),
            'fields': ("proposed_on", "gazetted_on", "deactivated_on", "review_due", "comments",)}
         ),
        ('Data lineage', {
            'classes': ('grp-collapse', 'grp-closed', 'wide', 'extrapretty'),
            'fields': ("source", "source_id", )}
         ),
    )

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        """Restrict available cat and crit to lists relevant to species."""
        if db_field.name == "category":
            kwargs["queryset"] = ConservationCategory.objects.filter(
                conservation_list__scope_species=True).order_by('rank')

        if db_field.name == "criteria":
            kwargs["queryset"] = ConservationCriterion.objects.filter(
                conservation_list__scope_species=True).order_by('rank')
        return super(TaxonGazettalAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

@admin.register(CommunityGazettal)
class CommunityGazettalAdmin(FSMTransitionMixin, VersionAdmin):
    """Admin for CommunityGazettal."""

    save_on_top = True
    date_hierarchy = 'gazetted_on'

    # FSM Transitions
    fsm_field = ['status', ]

    # List View
    list_display = (
        "community",
        "scope",
        "status",
        "category_cache",
        "criteria_cache",
        "proposed_on",
        "gazetted_on",
        "deactivated_on",
        "review_due",
        "comments",
    )
    list_filter = (
        "category",
        "scope",
        "status",
        ('proposed_on', admin.DateFieldListFilter),
        ('gazetted_on', admin.DateFieldListFilter),
        ('deactivated_on', admin.DateFieldListFilter),
        ('review_due', admin.DateFieldListFilter),
    )
    search_fields = ("comments", )

    # Detail View
    filter_horizontal = ('category', 'criteria',)
    raw_id_fields = ('community', )
    autocomplete_lookup_fields = {'fk': ['community', ]}
    form = CommunityGazettalForm
    formfield_overrides = FORMFIELD_OVERRIDES
    inlines = [CustomStateLogInline, FileAttachmentInline]

    fieldsets = (
        ('Conservation Status', {
            'classes': ('grp-collapse', 'grp-open', 'wide', 'extrapretty'),
            'fields': ("community", "scope", "category", "criteria",)}
         ),
        ('Approval process', {
            'classes': ('grp-collapse', 'grp-closed', 'wide', 'extrapretty'),
            'fields': ("proposed_on", "gazetted_on", "deactivated_on", "review_due", "comments",)}
         ),
        ('Data lineage', {
            'classes': ('grp-collapse', 'grp-closed', 'wide', 'extrapretty'),
            'fields': ("source", "source_id", )}
         ),
    )

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        """Restrict available cat and crit to lists relevant to species."""
        if db_field.name == "category":
            kwargs["queryset"] = ConservationCategory.objects.filter(
                conservation_list__scope_communities=True).order_by('rank')

        if db_field.name == "criteria":
            kwargs["queryset"] = ConservationCriterion.objects.filter(
                conservation_list__scope_communities=True).order_by('rank')
        return super(CommunityGazettalAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
<commit_msg>gazettal admin: order car and crit by listcode then rank<commit_after># -*- coding: utf-8 -*-
"""Admin module for wastd.observations."""
from __future__ import absolute_import, unicode_literals

# from django import forms as django_forms
# import floppyforms as ff
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline
from django.forms import Textarea
from django.db import models

# from django.utils.translation import ugettext_lazy as _
from easy_select2 import select2_modelform as s2form
# from easy_select2.widgets import Select2
from fsm_admin.mixins import FSMTransitionMixin
from django_fsm_log.admin import StateLogInline
# from django_fsm_log.models import StateLog
from reversion.admin import VersionAdmin

from conservation.models import (
    FileAttachment,
    ConservationList,
    ConservationCategory,
    ConservationCriterion,
    # Gazettal,
    TaxonGazettal,
    CommunityGazettal
)

S2ATTRS = {'width': 'auto'}
ConservationCategoryForm = s2form(ConservationCategory, attrs=S2ATTRS)
ConservationCriterionForm = s2form(ConservationCriterion, attrs=S2ATTRS)
ConservationListForm = s2form(ConservationList, attrs=S2ATTRS)
TaxonGazettalForm = s2form(TaxonGazettal, attrs=S2ATTRS)
CommunityGazettalForm = s2form(CommunityGazettal, attrs=S2ATTRS)
FileAttachmentForm = s2form(FileAttachment, attrs=S2ATTRS)

FORMFIELD_OVERRIDES = {
    models.TextField: {'widget': Textarea(attrs={'rows': 20, 'cols': 80})},
}

class CustomStateLogInline(StateLogInline):
    """Custom StateLogInline."""

    classes = ('grp-collapse grp-closed wide extrapretty',)

class FileAttachmentInline(GenericTabularInline):
    """Inline for FileAttachment."""

    model = FileAttachment
    form = FileAttachmentForm
    extra = 1
    classes = ('grp-collapse grp-closed wide extrapretty',)

class ConservationCategoryInline(admin.TabularInline):
    """Inline admin for ConservationCategory."""

    extra = 1
    model = ConservationCategory
    classes = ('grp-collapse grp-closed wide extrapretty',)
    form = ConservationCategoryForm
    # formfield_overrides = FORMFIELD_OVERRIDES

class ConservationCriterionInline(admin.TabularInline):
    """Inline admin for ConservationCriterion."""

    extra = 1
    model = ConservationCriterion
    classes = ('grp-collapse grp-closed wide extrapretty',)
    form = ConservationCriterionForm
    # formfield_overrides = FORMFIELD_OVERRIDES

@admin.register(ConservationList)
class ConservationListAdmin(VersionAdmin):
    """Admin for ConservationList."""

    save_on_top = True
    date_hierarchy = 'active_to'

    # List View
    list_display = (
        "code",
        "label",
        "description",
        "active_from",
        "active_to",
        "scope_wa",
        "scope_cmw",
        "scope_intl",
        "scope_species",
        "scope_communities",
    )
    list_filter = ("scope_wa",
                   "scope_cmw",
                   "scope_intl",
                   "scope_species",
                   "scope_communities",)
    search_fields = ("code", "label", "description", )
    fieldsets = (
        ('Details', {'fields': ("code", "label", "description",)}),
        ('Scope', {
            'classes': ('grp-collapse', 'grp-closed', 'wide'),
            'fields': ("active_from", "active_to",
                       "scope_wa", "scope_cmw", "scope_intl",
                       "scope_species", "scope_communities")

        }),
    )
    formfield_overrides = FORMFIELD_OVERRIDES
    inlines = [ConservationCategoryInline,
               ConservationCriterionInline,
               FileAttachmentInline]

@admin.register(TaxonGazettal)
class TaxonGazettalAdmin(FSMTransitionMixin, VersionAdmin):
    """Admin for TaxonGazettal."""

    save_on_top = True
    date_hierarchy = 'gazetted_on'

    # FSM Transitions
    fsm_field = ['status', ]

    # List View
    list_display = (
        "taxon",
        "scope",
        "status",
        "category_cache",
        "criteria_cache",
        "proposed_on",
        "gazetted_on",
        "deactivated_on",
        "review_due",
        "comments",
    )
    list_filter = (
        "category",
        "scope",
        "status",
        ('proposed_on', admin.DateFieldListFilter),
        ('gazetted_on', admin.DateFieldListFilter),
        ('deactivated_on', admin.DateFieldListFilter),
        ('review_due', admin.DateFieldListFilter),
    )

    search_fields = ("comments", )

    # Detail View layout and widgets
    filter_horizontal = ('category', 'criteria',)
    raw_id_fields = ('taxon', )
    autocomplete_lookup_fields = {'fk': ['taxon', ]}
    form = TaxonGazettalForm
    formfield_overrides = FORMFIELD_OVERRIDES
    inlines = [CustomStateLogInline, FileAttachmentInline]

    fieldsets = (
        ('Conservation Status', {
            'classes': ('grp-collapse', 'grp-open', 'wide', 'extrapretty'),
            'fields': ("taxon", "scope", "category", "criteria",)}
         ),
        ('Approval process', {
            'classes': ('grp-collapse', 'grp-closed', 'wide', 'extrapretty'),
            'fields': ("proposed_on", "gazetted_on", "deactivated_on", "review_due", "comments",)}
         ),
        ('Data lineage', {
            'classes': ('grp-collapse', 'grp-closed', 'wide', 'extrapretty'),
            'fields': ("source", "source_id", )}
         ),
    )

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        """Restrict available cat and crit to lists relevant to species."""
        if db_field.name == "category":
            kwargs["queryset"] = ConservationCategory.objects.filter(
                conservation_list__scope_species=True).order_by('conservation_list__code', 'rank')

        if db_field.name == "criteria":
            kwargs["queryset"] = ConservationCriterion.objects.filter(
                conservation_list__scope_species=True).order_by('conservation_list__code', 'rank')
        return super(TaxonGazettalAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)

@admin.register(CommunityGazettal)
class CommunityGazettalAdmin(FSMTransitionMixin, VersionAdmin):
    """Admin for CommunityGazettal."""

    save_on_top = True
    date_hierarchy = 'gazetted_on'

    # FSM Transitions
    fsm_field = ['status', ]

    # List View
    list_display = (
        "community",
        "scope",
        "status",
        "category_cache",
        "criteria_cache",
        "proposed_on",
        "gazetted_on",
        "deactivated_on",
        "review_due",
        "comments",
    )
    list_filter = (
        "category",
        "scope",
        "status",
        ('proposed_on', admin.DateFieldListFilter),
        ('gazetted_on', admin.DateFieldListFilter),
        ('deactivated_on', admin.DateFieldListFilter),
        ('review_due', admin.DateFieldListFilter),
    )
    search_fields = ("comments", )

    # Detail View
    filter_horizontal = ('category', 'criteria',)
    raw_id_fields = ('community', )
    autocomplete_lookup_fields = {'fk': ['community', ]}
    form = CommunityGazettalForm
    formfield_overrides = FORMFIELD_OVERRIDES
    inlines = [CustomStateLogInline, FileAttachmentInline]

    fieldsets = (
        ('Conservation Status', {
            'classes': ('grp-collapse', 'grp-open', 'wide', 'extrapretty'),
            'fields': ("community", "scope", "category", "criteria",)}
         ),
        ('Approval process', {
            'classes': ('grp-collapse', 'grp-closed', 'wide', 'extrapretty'),
            'fields': ("proposed_on", "gazetted_on", "deactivated_on", "review_due", "comments",)}
         ),
        ('Data lineage', {
            'classes': ('grp-collapse', 'grp-closed', 'wide', 'extrapretty'),
            'fields': ("source", "source_id", )}
         ),
    )

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        """Restrict available cat and crit to lists relevant to species."""
        if db_field.name == "category":
            kwargs["queryset"] = ConservationCategory.objects.filter(
                conservation_list__scope_communities=True).order_by('conservation_list__code', 'rank')

        if db_field.name == "criteria":
            kwargs["queryset"] = ConservationCriterion.objects.filter(
                conservation_list__scope_communities=True).order_by('conservation_list__code', 'rank')
        return super(CommunityGazettalAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
<|endoftext|>


<commit_before>from uuid import UUID

import colander
from twisted.internet.defer import inlineCallbacks, returnValue
from werkzeug.exceptions import NotFound

from unicore.comments.service import db, app
from unicore.comments.service.views.base import (
    make_json_response, deserialize_or_raise)
from unicore.comments.service.views import pagination
from unicore.comments.service.models import StreamMetadata
from unicore.comments.service.schema import (
    StreamMetadata as StreamMetadataSchema)
from unicore.comments.service.views.filtering import FilterSchema, ALL

schema = StreamMetadataSchema()

'''
Stream Metadata resource
'''

@app.route('/streammetadata/<app_uuid>/<content_uuid>/', methods=['GET'])
@inlineCallbacks
def view_streammetadata(request, app_uuid, content_uuid):
    try:
        app_uuid = UUID(app_uuid)
        content_uuid = UUID(content_uuid)
    except ValueError:
        raise NotFound

    try:
        connection = yield app.db_engine.connect()
        metadata = yield StreamMetadata.get_by_pk(
            connection, app_uuid=app_uuid, content_uuid=content_uuid)
    finally:
        yield connection.close()

    if metadata is None:
        data = {
            'app_uuid': app_uuid,
            'content_uuid': content_uuid}
    else:
        data = metadata.to_dict()

    returnValue(make_json_response(request, data, schema=schema))

@app.route('/streammetadata/<app_uuid>/<content_uuid>/', methods=['PUT'])
@db.in_transaction
@inlineCallbacks
def update_streammetadata(request, app_uuid, content_uuid, connection):
    ''' There is only an update endpoint for stream metadata because,
    conceptually, metadata always exists for a stream, even if empty.
    '''
    data = deserialize_or_raise(
        schema.bind(app_uuid=app_uuid, content_uuid=content_uuid), request)
    metadata = yield StreamMetadata.get_by_pk(
        connection, app_uuid=app_uuid, content_uuid=content_uuid)

    if metadata is None:
        metadata = StreamMetadata(connection, data)
        yield metadata.insert()
    else:
        metadata.set('metadata', data['metadata'])
        yield metadata.update()

    returnValue(make_json_response(request, metadata.to_dict(), schema=schema))

'''
Stream Metadata collection resource
'''
<commit_msg>stream metadata list view<commit_after>from uuid import UUID
from itertools import chain

from twisted.internet.defer import inlineCallbacks, returnValue
from werkzeug.exceptions import NotFound
from sqlalchemy.sql import or_

from unicore.comments.service import db, app
from unicore.comments.service.views.base import (
    make_json_response, deserialize_or_raise)
from unicore.comments.service.views import pagination
from unicore.comments.service.models import StreamMetadata
from unicore.comments.service.schema import (
    StreamMetadata as StreamMetadataSchema)
from unicore.comments.service.views.filtering import FilterSchema, ALL

schema = StreamMetadataSchema()
schema_no_uuids = schema.clone()
del schema_no_uuids['app_uuid']
del schema_no_uuids['content_uuid']
streammetadata_filters = FilterSchema.from_schema(schema, {
    'app_uuid': ALL,
    'content_uuid': ALL
})

'''
Stream Metadata resource
'''

@app.route('/streammetadata/<app_uuid>/<content_uuid>/', methods=['GET'])
@inlineCallbacks
def view_streammetadata(request, app_uuid, content_uuid):
    ''' Returns empty metadata if the stream is not in the database.
    '''

    try:
        app_uuid = UUID(app_uuid)
        content_uuid = UUID(content_uuid)
    except ValueError:
        raise NotFound

    try:
        connection = yield app.db_engine.connect()
        metadata = yield StreamMetadata.get_by_pk(
            connection, app_uuid=app_uuid, content_uuid=content_uuid)
    finally:
        yield connection.close()

    if metadata is None:
        data = {
            'app_uuid': app_uuid,
            'content_uuid': content_uuid}
    else:
        data = metadata.to_dict()

    returnValue(make_json_response(request, data, schema=schema))

@app.route('/streammetadata/<app_uuid>/<content_uuid>/', methods=['PUT'])
@db.in_transaction
@inlineCallbacks
def update_streammetadata(request, app_uuid, content_uuid, connection):
    ''' There is only an update endpoint for stream metadata because,
    conceptually, metadata always exists for a stream, even if empty.
    '''

    data = deserialize_or_raise(
        schema.bind(app_uuid=app_uuid, content_uuid=content_uuid), request)
    metadata = yield StreamMetadata.get_by_pk(
        connection, app_uuid=app_uuid, content_uuid=content_uuid)

    if metadata is None:
        metadata = StreamMetadata(connection, data)
        yield metadata.insert()
    else:
        metadata.set('metadata', data['metadata'])
        yield metadata.update()

    returnValue(make_json_response(request, metadata.to_dict(), schema=schema))

'''
Stream Metadata collection resource
'''

def get_stream_primary_keys(request):
    filter_data = streammetadata_filters.convert_lists(request.args)
    filter_data = streammetadata_filters.deserialize(filter_data)

    app_uuids = set(filter_data.get('app_uuid_in', []))
    if 'app_uuid' in filter_data:
        app_uuids.add(filter_data['app_uuid'])
    content_uuids = set(filter_data.get('content_uuid_in', []))
    if 'content_uuid' in filter_data:
        content_uuids.add(filter_data['content_uuid'])

    # unbounded set
    if not app_uuids or not content_uuids:
        return None

    # bounded set
    pks = [{'app_uuid': a, 'content_uuid': c}
           for a in app_uuids for c in content_uuids]
    return pks

@inlineCallbacks
def unbounded_list_streammetadata(request):
    columns = StreamMetadata.__table__.c
    filter_expr = streammetadata_filters.get_filter_expression(
        request.args, columns)

    query = StreamMetadata.__table__ \
        .select() \
        .where(filter_expr)
    query, limit, offset = pagination.paginate(request.args, query)

    try:
        connection = yield app.db_engine.connect()
        result = yield connection.execute(query)
        result = yield result.fetchall()
    finally:
        yield connection.close()

    data = {
        'offset': offset,
        'limit': limit,
        'count': len(result),
        'objects': [schema.serialize(row) for row in result]
    }
    returnValue(make_json_response(request, data))

@inlineCallbacks
def bounded_list_streammetadata(request, primary_keys):
    filter_expr = [StreamMetadata._pk_expression(pk) for pk in primary_keys]
    filter_expr = or_(*filter_expr)

    query = StreamMetadata.__table__ \
        .select() \
        .where(filter_expr)

    try:
        connection = yield app.db_engine.connect()
        result = yield connection.execute(query)
        result = yield result.fetchall()
    finally:
        connection.close()

    all_pks_set = set(
        [(pk['app_uuid'], pk['content_uuid']) for pk in primary_keys])
    existing_pks_set = set(
        [(d['app_uuid'], d['content_uuid']) for d in result])
    non_db_objects = []
    for pk in all_pks_set - existing_pks_set:
        non_db_objects.append({
            'app_uuid': pk[0],
            'content_uuid': pk[1]})

    data = {
        'count': len(all_pks_set),
        'objects': [schema.serialize(row)
                    for row in chain(result, non_db_objects)]
    }
    returnValue(make_json_response(request, data))

@app.route('/streammetadata/', methods=['GET'])
@inlineCallbacks
def list_streammetadata(request):
    primary_keys = get_stream_primary_keys(request)
    if primary_keys is None:
        resp = yield unbounded_list_streammetadata(request)
    else:
        resp = yield bounded_list_streammetadata(request, primary_keys)
    returnValue(resp)

'''@app.route('/streammetadata/', methods=['PUT'])
@db.in_transaction
@inlineCallbacks
def update_list_streammetadata(request, connection):
    data = deserialize_or_raise(schema_no_uuids.bind(), request)
    columns = StreamMetadata.__table__.c
    filter_expr = streammetadata_filters.get_filter_expression(
        request.args, columns)

    query = StreamMetadata.__table__ \
        .update() \
        .where(filter_expr) \
        .values(**data)

    result = yield connection.execute(query)
    if result.rowcount > 0:
        pass'''
<|endoftext|>


<commit_before>import pytest

from stellar_sdk.__version__ import __version__
from stellar_sdk.call_builder import BaseCallBuilder
from stellar_sdk.client.aiohttp_client import AiohttpClient
from stellar_sdk.client.requests_client import RequestsClient
from stellar_sdk.exceptions import BadRequestError, NotFoundError, NotPageableError

class TestBaseCallBuilder:
    @pytest.mark.asyncio
    async def test_get_data_async(self):
        url = "https://httpbin.org/get"
        client = AiohttpClient()
        resp = (
            await BaseCallBuilder(url, client)
            .cursor(89777)
            .order(desc=False)
            .limit(25)
            .call()
        )

        assert resp["args"] == {"cursor": "89777", "limit": "25", "order": "asc"}
        assert resp["headers"] == {
            "Accept": "*/*",
            "Accept-Encoding": "gzip, deflate",
            "Content-Type": "application/x-www-form-urlencoded",
            "Host": "httpbin.org",
            "User-Agent": "py-stellar-sdk/{}/AiohttpClient".format(__version__),
            "X-Client-Name": "py-stellar-sdk",
            "X-Client-Version": __version__,
        }
        assert resp["url"] == "https://httpbin.org/get?cursor=89777&order=asc&limit=25"

    def test_get_data_sync(self):
        url = "https://httpbin.org/get"
        client = RequestsClient()
        resp = (
            BaseCallBuilder(url, client).limit(10).cursor(10086).order(desc=True).call()
        )
        assert resp["args"] == {"cursor": "10086", "limit": "10", "order": "desc"}
        assert resp["headers"] == {
            "Accept": "*/*",
            "Accept-Encoding": "gzip, deflate",
            "Host": "httpbin.org",
            "User-Agent": "py-stellar-sdk/{}/RequestsClient".format(__version__),
            "X-Client-Name": "py-stellar-sdk",
            "X-Client-Version": __version__,
        }
        assert resp["url"] == "https://httpbin.org/get?limit=10&cursor=10086&order=desc"

    @pytest.mark.slow
    @pytest.mark.asyncio
    @pytest.mark.timeout(30)
    async def test_get_stream_data_async(self):
        url = "https://horizon.stellar.org/ledgers"
        client = AiohttpClient()
        resp = BaseCallBuilder(url, client).cursor("now").stream()
        messages = []
        async for msg in resp:
            assert isinstance(msg, dict)
            messages.append(msg)
            if len(messages) == 2:
                break

    @pytest.mark.slow
    @pytest.mark.timeout(30)
    def test_stream_data_sync(self):
        url = "https://horizon.stellar.org/ledgers"
        client = RequestsClient()
        resp = BaseCallBuilder(url, client).cursor("now").stream()
        messages = []
        for msg in resp:
            assert isinstance(msg, dict)
            messages.append(msg)
            if len(messages) == 2:
                break

    def test_status_400_raise_sync(self):
        url = "https://horizon.stellar.org/accounts/BADACCOUNTID"
        client = RequestsClient()
        with pytest.raises(BadRequestError) as err:
            BaseCallBuilder(url, client).call()

        exception = err.value
        assert exception.status == 400
        assert exception.type == "https://stellar.org/horizon-errors/bad_request"
        assert exception.title == "Bad Request"
        assert exception.detail == "The request you sent was invalid in some way."
        assert exception.extras == {
            "invalid_field": "account_id",
            "reason": "invalid address",
        }

    def test_status_404_raise_sync(self):
        url = "https://horizon.stellar.org/not_found"
        client = RequestsClient()
        with pytest.raises(NotFoundError) as err:
            BaseCallBuilder(url, client).call()

        exception = err.value
        assert exception.status == 404
        assert exception.type == "https://stellar.org/horizon-errors/not_found"
        assert exception.title == "Resource Missing"
        assert (
            exception.detail
            == "The resource at the url requested was not found.  This "
            "usually occurs for one of two reasons:  The url requested is not valid, "
            "or no data in our database could be found with the parameters provided."
        )
        assert exception.extras is None

    @pytest.mark.asyncio
    async def test_status_400_raise_async(self):
        url = "https://horizon.stellar.org/accounts/BADACCOUNTID"
        client = AiohttpClient()
        with pytest.raises(BadRequestError) as err:
            await BaseCallBuilder(url, client).call()

        exception = err.value
        assert exception.status == 400
        assert exception.type == "https://stellar.org/horizon-errors/bad_request"
        assert exception.title == "Bad Request"
        assert exception.detail == "The request you sent was invalid in some way."
        assert exception.extras == {
            "invalid_field": "account_id",
            "reason": "invalid address",
        }

    @pytest.mark.asyncio
    async def test_status_404_raise_async(self):
        url = "https://horizon.stellar.org/not_found"
        client = AiohttpClient()
        with pytest.raises(NotFoundError) as err:
            await BaseCallBuilder(url, client).call()

        exception = err.value
        assert exception.status == 404
        assert exception.type == "https://stellar.org/horizon-errors/not_found"
        assert exception.title == "Resource Missing"
        assert (
            exception.detail
            == "The resource at the url requested was not found.  This "
            "usually occurs for one of two reasons:  The url requested is not valid, "
            "or no data in our database could be found with the parameters provided."
        )
        assert exception.extras is None

    @pytest.mark.asyncio
    async def test_get_data_async(self):
        url = "https://httpbin.org/get"
        client = AiohttpClient()
        resp = (
            await BaseCallBuilder(url, client)
            .cursor(89777)
            .order(desc=False)
            .limit(25)
            .call()
        )

        assert resp["args"] == {"cursor": "89777", "limit": "25", "order": "asc"}
        assert resp["headers"] == {
            "Accept": "*/*",
            "Accept-Encoding": "gzip, deflate",
            "Content-Type": "application/x-www-form-urlencoded",
            "Host": "httpbin.org",
            "User-Agent": "py-stellar-sdk/{}/AiohttpClient".format(__version__),
            "X-Client-Name": "py-stellar-sdk",
            "X-Client-Version": __version__,
        }
        assert resp["url"] == "https://httpbin.org/get?cursor=89777&order=asc&limit=25"

    def test_get_data_no_link(self):
        url = "https://httpbin.org/get"
        client = RequestsClient()
        call_builder = (
            BaseCallBuilder(url, client).limit(10).cursor(10086).order(desc=True)
        )
        call_builder.call()
        assert call_builder.next_href is None
        assert call_builder.prev_href is None

    def test_get_data_not_pageable_raise(self):
        url = "https://httpbin.org/get"
        client = RequestsClient()
        call_builder = (
            BaseCallBuilder(url, client).limit(10).cursor(10086).order(desc=True)
        )
        call_builder.call()
        with pytest.raises(NotPageableError, match="The next page does not exist."):
            call_builder.next()

        with pytest.raises(NotPageableError, match="The prev page does not exist."):
            call_builder.prev()

    def test_get_data_page(self):
        url = "https://horizon.stellar.org/transactions"
        client = RequestsClient()
        call_builder = (
            BaseCallBuilder(url, client)
            .cursor(81058917781504)
            .limit(10)
            .order(desc=True)
        )
        first_resp = call_builder.call()
        assert first_resp["_links"] == {
            "self": {
                "href": "https://horizon.stellar.org/transactions?cursor=81058917781504&limit=10&order=desc"
            },
            "next": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=desc"
            },
            "prev": {
                "href": "https://horizon.stellar.org/transactions?cursor=80607946215424&limit=10&order=asc"
            },
        }
        next_resp = call_builder.next()
        assert next_resp["_links"] == {
            "self": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=desc"
            },
            "next": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=desc"
            },
            "prev": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=asc"
            },
        }
        prev_page = call_builder.prev()
        assert prev_page["_links"] == {
            "self": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=asc"
            },
            "next": {
                "href": "https://horizon.stellar.org/transactions?cursor=81827716927488&limit=10&order=asc"
            },
            "prev": {
                "href": "https://horizon.stellar.org/transactions?cursor=33676838572032&limit=10&order=desc"
            },
        }
<commit_msg>fix: fix base call builder test cases.<commit_after>import pytest

from stellar_sdk.__version__ import __version__
from stellar_sdk.call_builder import BaseCallBuilder
from stellar_sdk.client.aiohttp_client import AiohttpClient
from stellar_sdk.client.requests_client import RequestsClient
from stellar_sdk.exceptions import BadRequestError, NotFoundError, NotPageableError

class TestBaseCallBuilder:
    @pytest.mark.asyncio
    async def test_get_data_async(self):
        url = "https://httpbin.org/get"
        client = AiohttpClient()
        resp = (
            await BaseCallBuilder(url, client)
            .cursor(89777)
            .order(desc=False)
            .limit(25)
            .call()
        )

        assert resp["args"] == {"cursor": "89777", "limit": "25", "order": "asc"}
        assert resp["headers"][
            "User-Agent"
        ] == "py-stellar-sdk/{}/AiohttpClient".format(__version__)
        assert resp["headers"]["X-Client-Name"] == "py-stellar-sdk"
        assert resp["headers"]["X-Client-Version"] == __version__
        assert resp["url"] == "https://httpbin.org/get?cursor=89777&order=asc&limit=25"

    def test_get_data_sync(self):
        url = "https://httpbin.org/get"
        client = RequestsClient()
        resp = (
            BaseCallBuilder(url, client).limit(10).cursor(10086).order(desc=True).call()
        )
        assert resp["args"] == {"cursor": "10086", "limit": "10", "order": "desc"}
        assert resp["headers"][
            "User-Agent"
        ] == "py-stellar-sdk/{}/RequestsClient".format(__version__)
        assert resp["headers"]["X-Client-Name"] == "py-stellar-sdk"
        assert resp["headers"]["X-Client-Version"] == __version__
        assert resp["url"] == "https://httpbin.org/get?limit=10&cursor=10086&order=desc"

    @pytest.mark.slow
    @pytest.mark.asyncio
    @pytest.mark.timeout(30)
    async def test_get_stream_data_async(self):
        url = "https://horizon.stellar.org/ledgers"
        client = AiohttpClient()
        resp = BaseCallBuilder(url, client).cursor("now").stream()
        messages = []
        async for msg in resp:
            assert isinstance(msg, dict)
            messages.append(msg)
            if len(messages) == 2:
                break

    @pytest.mark.slow
    @pytest.mark.timeout(30)
    def test_stream_data_sync(self):
        url = "https://horizon.stellar.org/ledgers"
        client = RequestsClient()
        resp = BaseCallBuilder(url, client).cursor("now").stream()
        messages = []
        for msg in resp:
            assert isinstance(msg, dict)
            messages.append(msg)
            if len(messages) == 2:
                break

    def test_status_400_raise_sync(self):
        url = "https://horizon.stellar.org/accounts/BADACCOUNTID"
        client = RequestsClient()
        with pytest.raises(BadRequestError) as err:
            BaseCallBuilder(url, client).call()

        exception = err.value
        assert exception.status == 400
        assert exception.type == "https://stellar.org/horizon-errors/bad_request"
        assert exception.title == "Bad Request"
        assert exception.detail == "The request you sent was invalid in some way."
        assert exception.extras == {
            "invalid_field": "account_id",
            "reason": "invalid address",
        }

    def test_status_404_raise_sync(self):
        url = "https://horizon.stellar.org/not_found"
        client = RequestsClient()
        with pytest.raises(NotFoundError) as err:
            BaseCallBuilder(url, client).call()

        exception = err.value
        assert exception.status == 404
        assert exception.type == "https://stellar.org/horizon-errors/not_found"
        assert exception.title == "Resource Missing"
        assert (
            exception.detail
            == "The resource at the url requested was not found.  This "
            "usually occurs for one of two reasons:  The url requested is not valid, "
            "or no data in our database could be found with the parameters provided."
        )
        assert exception.extras is None

    @pytest.mark.asyncio
    async def test_status_400_raise_async(self):
        url = "https://horizon.stellar.org/accounts/BADACCOUNTID"
        client = AiohttpClient()
        with pytest.raises(BadRequestError) as err:
            await BaseCallBuilder(url, client).call()

        exception = err.value
        assert exception.status == 400
        assert exception.type == "https://stellar.org/horizon-errors/bad_request"
        assert exception.title == "Bad Request"
        assert exception.detail == "The request you sent was invalid in some way."
        assert exception.extras == {
            "invalid_field": "account_id",
            "reason": "invalid address",
        }

    @pytest.mark.asyncio
    async def test_status_404_raise_async(self):
        url = "https://horizon.stellar.org/not_found"
        client = AiohttpClient()
        with pytest.raises(NotFoundError) as err:
            await BaseCallBuilder(url, client).call()

        exception = err.value
        assert exception.status == 404
        assert exception.type == "https://stellar.org/horizon-errors/not_found"
        assert exception.title == "Resource Missing"
        assert (
            exception.detail
            == "The resource at the url requested was not found.  This "
            "usually occurs for one of two reasons:  The url requested is not valid, "
            "or no data in our database could be found with the parameters provided."
        )
        assert exception.extras is None

    @pytest.mark.asyncio
    async def test_get_data_async(self):
        url = "https://httpbin.org/get"
        client = AiohttpClient()
        resp = (
            await BaseCallBuilder(url, client)
            .cursor(89777)
            .order(desc=False)
            .limit(25)
            .call()
        )

        assert resp["args"] == {"cursor": "89777", "limit": "25", "order": "asc"}
        assert resp["headers"][
            "User-Agent"
        ] == "py-stellar-sdk/{}/AiohttpClient".format(__version__)
        assert resp["headers"]["X-Client-Name"] == "py-stellar-sdk"
        assert resp["headers"]["X-Client-Version"] == __version__
        assert resp["url"] == "https://httpbin.org/get?cursor=89777&order=asc&limit=25"

    def test_get_data_no_link(self):
        url = "https://httpbin.org/get"
        client = RequestsClient()
        call_builder = (
            BaseCallBuilder(url, client).limit(10).cursor(10086).order(desc=True)
        )
        call_builder.call()
        assert call_builder.next_href is None
        assert call_builder.prev_href is None

    def test_get_data_not_pageable_raise(self):
        url = "https://httpbin.org/get"
        client = RequestsClient()
        call_builder = (
            BaseCallBuilder(url, client).limit(10).cursor(10086).order(desc=True)
        )
        call_builder.call()
        with pytest.raises(NotPageableError, match="The next page does not exist."):
            call_builder.next()

        with pytest.raises(NotPageableError, match="The prev page does not exist."):
            call_builder.prev()

    def test_get_data_page(self):
        url = "https://horizon.stellar.org/transactions"
        client = RequestsClient()
        call_builder = (
            BaseCallBuilder(url, client)
            .cursor(81058917781504)
            .limit(10)
            .order(desc=True)
        )
        first_resp = call_builder.call()
        assert first_resp["_links"] == {
            "self": {
                "href": "https://horizon.stellar.org/transactions?cursor=81058917781504&limit=10&order=desc"
            },
            "next": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=desc"
            },
            "prev": {
                "href": "https://horizon.stellar.org/transactions?cursor=80607946215424&limit=10&order=asc"
            },
        }
        next_resp = call_builder.next()
        assert next_resp["_links"] == {
            "self": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=desc"
            },
            "next": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=desc"
            },
            "prev": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=asc"
            },
        }
        prev_page = call_builder.prev()
        assert prev_page["_links"] == {
            "self": {
                "href": "https://horizon.stellar.org/transactions?cursor=12884905984&limit=10&order=asc"
            },
            "next": {
                "href": "https://horizon.stellar.org/transactions?cursor=81827716927488&limit=10&order=asc"
            },
            "prev": {
                "href": "https://horizon.stellar.org/transactions?cursor=33676838572032&limit=10&order=desc"
            },
        }
<|endoftext|>


<commit_before># Copyright 2014 ETH Zurich
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
:mod:`lib_packet_scion_test` --- lib.packet.scion unit tests
============================================================
"""
# Stdlib
import unittest

# Has to be imported before anything else so that any relevant decorators are
# patched.
from test.testcommon import SCIONCommonTest

# SCION
from lib.packet.scion import SCIONCommonHdr

class TestSCIONCommonHdr(SCIONCommonTest):
    """
    Unit tests for lib.packet.scion.SCIONCommonHdr
    """

    def test_opaque_field(self):
        """

        """
        sch = SCIONCommonHdr()
        self.assertTrue(sch.version == 0)

    def test_equality(self):
        """

        """
        sch1 = SCIONCommonHdr()
        sch2 = SCIONCommonHdr()
        self.assertTrue(sch1.version == sch2.version)

    def test_pack_and_parse(self):
        """

        """
        sch = SCIONCommonHdr.from_values(4, 4, 0)
        schCopy = SCIONCommonHdr()
        schCopy.parse(sch.pack())
        self.assertTrue(sch.version == schCopy.version)
        self.assertTrue(sch.src_addr_len == schCopy.src_addr_len)
        self.assertTrue(sch.dst_addr_len == schCopy.dst_addr_len)
        self.assertTrue(sch.total_len == schCopy.total_len)
        self.assertTrue(sch.curr_iof_p == schCopy.curr_iof_p)
        self.assertTrue(sch.curr_of_p == schCopy.curr_of_p)
        self.assertTrue(sch.next_hdr == schCopy.next_hdr)
        self.assertTrue(sch.hdr_len == schCopy.hdr_len)

if __name__ == "__main__":
    unittest.main()
<commit_msg>SCIONCommonHdr tests rewritten<commit_after># Copyright 2015 ETH Zurich
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
:mod:`lib_packet_scion_test` --- lib.packet.scion unit tests
============================================================
"""
# Stdlib
from unittest.mock import patch, MagicMock

# External packages
import nose
import nose.tools as ntools

# SCION
from lib.packet.scion import (
    get_type,
    SCIONCommonHdr)

class TestGetType(object):
    """
    Unit tests for lib.packet.scion.get_type
    """
    @patch("lib.packet.scion.PacketType", autospec=True)
    def test_in_src(self, packet_type):
        pkt = MagicMock(spec_set=['hdr'])
        pkt.hdr = MagicMock(spec_set=['src_addr'])
        pkt.hdr.src_addr = MagicMock(spec_set=['host_addr'])
        pkt.hdr.src_addr.host_addr = 'src_addr'
        packet_type.SRC = ['src_addr']
        ntools.eq_(get_type(pkt), 'src_addr')

    @patch("lib.packet.scion.PacketType", autospec=True)
    def test_in_dst(self, packet_type):
        pkt = MagicMock(spec_set=['hdr'])
        pkt.hdr = MagicMock(spec_set=['src_addr', 'dst_addr'])
        pkt.hdr.dst_addr = MagicMock(spec_set=['host_addr'])
        pkt.hdr.dst_addr.host_addr = 'dst_addr'
        packet_type.SRC = []
        packet_type.DST = ['dst_addr']
        ntools.eq_(get_type(pkt), 'dst_addr')

    @patch("lib.packet.scion.PacketType", autospec=True)
    def test_in_none(self, packet_type):
        pkt = MagicMock(spec_set=['hdr'])
        pkt.hdr = MagicMock(spec_set=['src_addr', 'dst_addr'])
        packet_type.SRC = []
        packet_type.DST = []
        ntools.eq_(get_type(pkt), packet_type.DATA)

class TestSCIONCommonHdrInit(object):
    """
    Unit tests for lib.packet.scion.SCIONCommonHdr.__init__
    """
    @patch("lib.packet.scion.HeaderBase.__init__", autospec=True)
    def test_basic(self, init):
        hdr = SCIONCommonHdr()
        init.assert_called_once_with(hdr)
        ntools.eq_(hdr.version, 0)
        ntools.eq_(hdr.src_addr_len, 0)
        ntools.eq_(hdr.dst_addr_len, 0)
        ntools.eq_(hdr.total_len, 0)
        ntools.eq_(hdr.curr_iof_p, 0)
        ntools.eq_(hdr.curr_of_p, 0)
        ntools.eq_(hdr.next_hdr, 0)
        ntools.eq_(hdr.hdr_len, 0)

    @patch("lib.packet.scion.SCIONCommonHdr.parse", autospec=True)
    def test_with_args(self, parse):
        hdr = SCIONCommonHdr('data')
        parse.assert_called_once_with(hdr, 'data')

class TestSCIONCommonHdrFromValues(object):
    """
    Unit tests for lib.packet.scion.SCIONCommonHdr.from_values
    """
    def test(self):
        # called with args (src_addr_len, dst_addr_len, next_hdr)
        hdr = SCIONCommonHdr.from_values(1, 2, 3)
        ntools.eq_(hdr.src_addr_len, 1)
        ntools.eq_(hdr.dst_addr_len, 2)
        ntools.eq_(hdr.next_hdr, 3)
        ntools.eq_(hdr.curr_of_p, 1 + 2)
        ntools.eq_(hdr.curr_iof_p, 1 + 2)
        ntools.eq_(hdr.hdr_len, SCIONCommonHdr.LEN + 1 + 2)
        ntools.eq_(hdr.total_len, SCIONCommonHdr.LEN + 1 + 2)

class TestSCIONCommonHdrParse(object):
    """
    Unit tests for lib.packet.scion.SCIONCommonHdr.parse
    """
    def test_wrong_type(self):
        hdr = SCIONCommonHdr()
        ntools.assert_raises(AssertionError, hdr.parse, 123)

    def test_bad_length(self):
        hdr = SCIONCommonHdr()
        dlen = SCIONCommonHdr.LEN - 1
        hdr.parse(b'\x00' * dlen)
        ntools.assert_false(hdr.parsed)

    def test_full(self):
        hdr = SCIONCommonHdr()
        data = bytes.fromhex('a102 0304 05 06 07 08')
        hdr.parse(data)
        ntools.eq_(hdr.total_len, 0x0304)
        ntools.eq_(hdr.curr_iof_p, 0x05)
        ntools.eq_(hdr.curr_of_p, 0x06)
        ntools.eq_(hdr.next_hdr, 0x07)
        ntools.eq_(hdr.hdr_len, 0x08)
        types = 0xa102
        ntools.eq_(hdr.version, (types & 0xf000) >> 12)
        ntools.eq_(hdr.src_addr_len, (types & 0x0fc0) >> 6)
        ntools.eq_(hdr.dst_addr_len, types & 0x003f)
        ntools.assert_true(hdr.parsed)

class TestSCIONCommonHdrPack(object):
    """
    Unit tests for lib.packet.scion.SCIONCommonHdr.pack
    """
    def test(self):
        hdr = SCIONCommonHdr()
        hdr.version = 0xa
        hdr.dst_addr_len = 0x2
        hdr.src_addr_len = 0x4
        hdr.total_len = 0x304
        hdr.curr_iof_p = 0x5
        hdr.curr_of_p = 0x6
        hdr.next_hdr = 0x7
        hdr.hdr_len = 0x8
        packed = bytes.fromhex('a102 0304 05 06 07 08')
        ntools.eq_(hdr.pack(), packed)

if __name__ == "__main__":
    nose.run(defaultTest=__name__)
<|endoftext|>


<commit_before>import unittest

import pytest

import cupy
from cupy import testing

@testing.gpu
class TestRational(unittest.TestCase):

    @testing.for_int_dtypes(no_bool=True)
    @testing.numpy_cupy_array_equal()
    def test_gcd_basic(self, xp, dtype):
        a = testing.shaped_random((6, 6), xp, dtype, seed=0)
        b = testing.shaped_random((6, 6), xp, dtype, seed=1)
        return xp.gcd(a, b)

    @testing.for_dtypes(['e', 'f', 'd', 'F', 'D'])
    def test_gcd_dtype_check(self, dtype):
        a = cupy.random.randint(-10, 10, size=(10, 10)).astype(dtype)
        b = cupy.random.randint(-10, 10, size=(10, 10)).astype(dtype)
        with pytest.raises(TypeError):
            cupy.gcd(a, b)

    @testing.for_int_dtypes(no_bool=True)
    @testing.numpy_cupy_array_equal()
    def test_lcm_basic(self, xp, dtype):
        a = testing.shaped_random((6, 6), xp, dtype, seed=2)
        b = testing.shaped_random((6, 6), xp, dtype, seed=3)
        return xp.lcm(a, b)

    @testing.for_dtypes(['e', 'f', 'd', 'F', 'D'])
    def test_lcm_dtype_check(self, dtype):
        a = cupy.random.randint(-10, 10, size=(10, 10)).astype(dtype)
        b = cupy.random.randint(-10, 10, size=(10, 10)).astype(dtype)
        with pytest.raises(TypeError):
            cupy.lcm(a, b)
<commit_msg>errortype tests<commit_after>import unittest

import pytest

import cupy
from cupy import testing

@testing.gpu
class TestRational(unittest.TestCase):

    @testing.for_int_dtypes(no_bool=True)
    @testing.numpy_cupy_array_equal()
    def test_gcd_basic(self, xp, dtype):
        a = testing.shaped_random((6, 6), xp, dtype, seed=0)
        b = testing.shaped_random((6, 6), xp, dtype, seed=1)
        return xp.gcd(a, b)

    @testing.for_dtypes(['e', 'f', 'd', 'F', 'D'])
    def test_gcd_dtype_check(self, dtype):
        a = cupy.random.randint(-10, 10, size=(10, 10)).astype(dtype)
        b = cupy.random.randint(-10, 10, size=(10, 10)).astype(dtype)
        with pytest.raises(TypeError):
            cupy.gcd(a, b)

    @testing.for_int_dtypes(no_bool=True)
    @testing.numpy_cupy_array_equal()
    def test_gcd_erroneous_cases(self, xp, dtype):
        a = xp.array([0, -10, -5, 10])
        b = xp.array([0, 5, -10, -5])
        return xp.gcd(a, b)

    @testing.for_int_dtypes(no_bool=True)
    @testing.numpy_cupy_array_equal()
    def test_lcm_basic(self, xp, dtype):
        a = testing.shaped_random((6, 6), xp, dtype, seed=2)
        b = testing.shaped_random((6, 6), xp, dtype, seed=3)
        return xp.lcm(a, b)

    @testing.for_dtypes(['e', 'f', 'd', 'F', 'D'])
    def test_lcm_dtype_check(self, dtype):
        a = cupy.random.randint(-10, 10, size=(10, 10)).astype(dtype)
        b = cupy.random.randint(-10, 10, size=(10, 10)).astype(dtype)
        with pytest.raises(TypeError):
            cupy.lcm(a, b)

    @testing.for_int_dtypes(no_bool=True)
    @testing.numpy_cupy_array_equal()
    def test_lcm_erroneous_cases(self, xp, dtype):
        a = xp.array([0, -10, -5, 10])
        b = xp.array([0, 5, -10, -5])
        return xp.lcm(a, b)
<|endoftext|>


<commit_before>import unittest

from cupy import testing

@testing.gpu
class TestSample(unittest.TestCase):

    _multiprocess_can_split_ = True
<commit_msg>Add unittest for rand and randn<commit_after>import mock
import unittest

import numpy

from cupy import random
from cupy import testing

@testing.gpu
class TestSample(unittest.TestCase):

    _multiprocess_can_split_ = True

    def setUp(self):
        random.random_sample = mock.Mock()

    def test_rand(self):
        random.rand(1, 2, 3, dtype=numpy.float32)
        random.random_sample.assert_call_once_with((1, 2, 3), numpy.float32)

    def test_rand_invalid_argument(self):
        with self.assertRaises(TypeError):
            random.rand(1, 2, 3, unnecessary='unnecessary_argument')

    def test_randn(self):
        random.randn(1, 2, 3, dtype=numpy.float32)
        random.random_sample.assert_call_once_with((1, 2, 3), numpy.float32)

    def test_randn_invalid_argument(self):
        with self.assertRaises(TypeError):
            random.randn(1, 2, 3, unnecessary='unnecessary_argument')
<|endoftext|>


<commit_before>import doctest
import unittest

from pympler.muppy import refbrowser

class TreeTest(unittest.TestCase):

    # sample tree used in output tests
    sample_tree = None

    def setUp(self):
        # set up a sample tree with three children, each having
        # five string leaves and some have references to other children
        TreeTest.sample_tree = refbrowser._Node('root')
        branch1 = refbrowser._Node('branch1')
        TreeTest.sample_tree.children.append(branch1)
        branch2 = refbrowser._Node('branch2')
        TreeTest.sample_tree.children.append(branch2)
        branch3 = refbrowser._Node('branch3')
        TreeTest.sample_tree.children.append(branch3)
        branch2.children.append(branch3)
        branch3.children.append(branch1)
        for i in ['a','b','c','d','e']:
            branch1.children.append(i)
            branch2.children.append(i)
            branch3.children.append(i)

    def test_node(self):
        """Test node functionality.

        _Nodes can be created, linked to each other, and the output function
        should return the expected result.

        """
        # default representation
        n = refbrowser._Node(1)
        expected = str(1)
        self.assert_(str(n) == expected)
        # custom representation
        expected = 'the quick brown fox'
        def foo(o): return expected
        n = refbrowser._Node(1, foo)
        self.assert_(str(n) == expected)
        # attach child
        n.children.append(2)

    def test_get_tree(self):
        """Test reference browser tree representation."""
        #root <- ref1 <- ref11
        #     <- ref11 (already included)
        #     <- ref2 <- ref22
        root = 'root id'
        ref1 = [root]
        ref11 = [ref1, root]
        ref2 = {1: root}
        ref22 = {1: ref2}

        res = refbrowser.RefBrowser(root, repeat=False).get_tree()
        # note that ref11 should not be included due to the repeat argument
        refs = [ref1, ref2]
        children = [c.o for c in res.children if isinstance(c, refbrowser._Node)]
        for r in refs:
            if r not in children:
                print r
            self.assert_(r in children)
        self.assert_(ref11 not in children)
        # now we test the repeat argument
        res = refbrowser.RefBrowser(root, repeat=True).get_tree()
        refs = [ref1, ref11, ref2]
        children = [c.o for c in res.children if isinstance(c, refbrowser._Node)]
        for r in refs:
            self.assert_(r in children)
        # test if maxdepth is working
        res = refbrowser.RefBrowser(root, maxdepth=0).get_tree()
        self.assert_(len(res.children) == 0)
        res = refbrowser.RefBrowser(root, maxdepth=1).get_tree()
        for c in res.children:
            if c == ref1:
                self.assert_(len(c.children) == 0)
        # test if the str_func is applied correctly
        expected = 'the quick brown fox'
        def foo(o): return expected
        res = refbrowser.RefBrowser(root, str_func=foo, maxdepth=2).get_tree()
        self.assert_(str(res) == expected)
        res = refbrowser.RefBrowser(root, str_func=foo, repeat=True,\
                                    maxdepth=2).get_tree()
        self.assert_(str(res) == expected)

test_print_tree = """

let's start with a small tree first
>>> crb = refbrowser.ConsoleBrowser(None, maxdepth=1)
>>> crb.print_tree(TreeTest.sample_tree)
root-+-branch1
     +-branch2
     +-branch3

okay, next level
>>> crb = refbrowser.ConsoleBrowser(None, maxdepth=2)
>>> crb.print_tree(TreeTest.sample_tree)
root-+-branch1-+-a
     |         +-b
     |         +-c
     |         +-d
     |         +-e
     |
     +-branch2-+-branch3
     |         +-a
     |         +-b
     |         +-c
     |         +-d
     |         +-e
     |
     +-branch3-+-branch1
               +-a
               +-b
               +-c
               +-d
               +-e

and now full size

>>> crb = refbrowser.ConsoleBrowser(None, maxdepth=4)
>>> crb.print_tree(TreeTest.sample_tree)
root-+-branch1-+-a
     |         +-b
     |         +-c
     |         +-d
     |         +-e
     |
     +-branch2-+-branch3-+-branch1-+-a
     |         |         |         +-b
     |         |         |         +-c
     |         |         |         +-d
     |         |         |         +-e
     |         |         |
     |         |         +-a
     |         |         +-b
     |         |         +-c
     |         |         +-d
     |         |         +-e
     |         |
     |         +-a
     |         +-b
     |         +-c
     |         +-d
     |         +-e
     |
     +-branch3-+-branch1-+-a
               |         +-b
               |         +-c
               |         +-d
               |         +-e
               |
               +-a
               +-b
               +-c
               +-d
               +-e
"""

__test__ = {"test_print_tree": test_print_tree}

def suite():
    suite = unittest.makeSuite(TreeTest,'test')
    suite.addTest(doctest.DocTestSuite())
    return suite

if __name__ == '__main__':
    unittest.TextTestRunner(verbosity=2).run(suite())

<commit_msg>Adapted test to reflect changes in Python issue 4688 (http://bugs.python.org/issue4688).<commit_after>import doctest
import unittest

from pympler.muppy import refbrowser

class TreeTest(unittest.TestCase):

    # sample tree used in output tests
    sample_tree = None

    def setUp(self):
        # set up a sample tree with three children, each having
        # five string leaves and some have references to other children
        TreeTest.sample_tree = refbrowser._Node('root')
        branch1 = refbrowser._Node('branch1')
        TreeTest.sample_tree.children.append(branch1)
        branch2 = refbrowser._Node('branch2')
        TreeTest.sample_tree.children.append(branch2)
        branch3 = refbrowser._Node('branch3')
        TreeTest.sample_tree.children.append(branch3)
        branch2.children.append(branch3)
        branch3.children.append(branch1)
        for i in ['a','b','c','d','e']:
            branch1.children.append(i)
            branch2.children.append(i)
            branch3.children.append(i)

    def test_node(self):
        """Test node functionality.

        _Nodes can be created, linked to each other, and the output function
        should return the expected result.

        """
        # default representation
        n = refbrowser._Node(1)
        expected = str(1)
        self.assert_(str(n) == expected)
        # custom representation
        expected = 'the quick brown fox'
        def foo(o): return expected
        n = refbrowser._Node(1, foo)
        self.assert_(str(n) == expected)
        # attach child
        n.children.append(2)

    def test_get_tree(self):
        """Test reference browser tree representation."""
        #root <- ref1 <- ref11
        #     <- ref11 (already included)
        #     <- ref2 <- ref22
        root = 'root id'
        # the key-value pair is required since Python 2.7/3.1
        # see http://bugs.python.org/issue4688 for details
        ref1 = [root, []]
        ref11 = [ref1, root]
        ref2 = {1: root, 2:[]}
        ref22 = {1: ref2}

        res = refbrowser.RefBrowser(root, repeat=False).get_tree()
        # note that ref11 should not be included due to the repeat argument
        refs = [ref1, ref2]
        children = [c.o for c in res.children if isinstance(c, refbrowser._Node)]
        for r in refs:
            self.assert_(r in children, "%s not in children" % r)
        self.assert_(ref11 not in children)
        # now we test the repeat argument
        res = refbrowser.RefBrowser(root, repeat=True).get_tree()
        refs = [ref1, ref11, ref2]
        children = [c.o for c in res.children if isinstance(c, refbrowser._Node)]
        for r in refs:
            self.assert_(r in children)
        # test if maxdepth is working
        res = refbrowser.RefBrowser(root, maxdepth=0).get_tree()
        self.assert_(len(res.children) == 0)
        res = refbrowser.RefBrowser(root, maxdepth=1).get_tree()
        for c in res.children:
            if c == ref1:
                self.assert_(len(c.children) == 0)
        # test if the str_func is applied correctly
        expected = 'the quick brown fox'
        def foo(o): return expected
        res = refbrowser.RefBrowser(root, str_func=foo, maxdepth=2).get_tree()
        self.assert_(str(res) == expected)
        res = refbrowser.RefBrowser(root, str_func=foo, repeat=True,\
                                    maxdepth=2).get_tree()
        self.assert_(str(res) == expected)

test_print_tree = """

let's start with a small tree first
>>> crb = refbrowser.ConsoleBrowser(None, maxdepth=1)
>>> crb.print_tree(TreeTest.sample_tree)
root-+-branch1
     +-branch2
     +-branch3

okay, next level
>>> crb = refbrowser.ConsoleBrowser(None, maxdepth=2)
>>> crb.print_tree(TreeTest.sample_tree)
root-+-branch1-+-a
     |         +-b
     |         +-c
     |         +-d
     |         +-e
     |
     +-branch2-+-branch3
     |         +-a
     |         +-b
     |         +-c
     |         +-d
     |         +-e
     |
     +-branch3-+-branch1
               +-a
               +-b
               +-c
               +-d
               +-e

and now full size

>>> crb = refbrowser.ConsoleBrowser(None, maxdepth=4)
>>> crb.print_tree(TreeTest.sample_tree)
root-+-branch1-+-a
     |         +-b
     |         +-c
     |         +-d
     |         +-e
     |
     +-branch2-+-branch3-+-branch1-+-a
     |         |         |         +-b
     |         |         |         +-c
     |         |         |         +-d
     |         |         |         +-e
     |         |         |
     |         |         +-a
     |         |         +-b
     |         |         +-c
     |         |         +-d
     |         |         +-e
     |         |
     |         +-a
     |         +-b
     |         +-c
     |         +-d
     |         +-e
     |
     +-branch3-+-branch1-+-a
               |         +-b
               |         +-c
               |         +-d
               |         +-e
               |
               +-a
               +-b
               +-c
               +-d
               +-e
"""

__test__ = {"test_print_tree": test_print_tree}

def suite():
    suite = unittest.makeSuite(TreeTest,'test')
    suite.addTest(doctest.DocTestSuite())
    return suite

if __name__ == '__main__':
    unittest.TextTestRunner(verbosity=2).run(suite())

<|endoftext|>


<commit_before># Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Spla(CMakePackage):
    """Specialized Parallel Linear Algebra, providing distributed GEMM
    functionality for specific matrix distributions with optional GPU
    acceleration."""

    homepage = "https://github.com/eth-cscs/spla"
    url      = "https://github.com/eth-cscs/spla/archive/v1.0.0.tar.gz"
    git = 'https://github.com/eth-cscs/spla.git'

    version('1.2.1', sha256='4d7237f752dc6257778c84ee19c9635072b1cb8ce8d9ab6e34a047f63a736b29')
    version('1.2.0', sha256='96ddd13c155ef3d7e40f87a982cdb439cf9e720523e66b6d20125d346ffe8fca')
    version('1.1.1', sha256='907c374d9c53b21b9f67ce648e7b2b09c320db234a1013d3f05919cd93c95a4b')
    version('1.1.0', sha256='b0c4ebe4988abc2b3434e6c50e7eb0612f3f401bc1aa79ad58a6a92dc87fa65b')
    version('1.0.0', sha256='a0eb269b84d7525b223dc650de12170bba30fbb3ae4f93eb2b5cbdce335e4da1')
    version('develop', branch='develop')
    version('master', branch='master')

    variant('openmp', default=True, description="Build with OpenMP support")
    variant('static', default=False, description="Build as static library")
    variant('cuda', default=False, description="CUDA backend")
    variant('rocm', default=False, description="ROCm backend")

    conflicts("+cuda", when="+rocm", msg="+cuda and +rocm are mutually exclusive")

    depends_on('mpi')
    depends_on('blas')
    depends_on('cmake@3.10:', type='build')

    depends_on('cuda', when='+cuda')
    depends_on('rocblas', when='+rocm')
    depends_on('hip', when='+rocm')
    depends_on('hsakmt-roct', when='+rocm', type='link')
    depends_on('hsa-rocr-dev', when='+rocm', type='link')

    def cmake_args(self):
        args = [
            self.define_from_variant('SPLA_OMP', 'openmp'),
            self.define_from_variant('SPLA_STATIC', 'static')
        ]

        if '+cuda' in self.spec:
            args += ["-DSPLA_GPU_BACKEND=CUDA"]
        elif '+rocm' in self.spec:
            args += ["-DSPLA_GPU_BACKEND=ROCM"]
        else:
            args += ["-DSPLA_GPU_BACKEND=OFF"]

        if self.spec['blas'].name == 'openblas':
            args += ["-DSPLA_HOST_BLAS=OPENBLAS"]
        elif self.spec['blas'].name in ['amdblis', 'blis']:
            args += ["-DSPLA_HOST_BLAS=BLIS"]
        elif self.spec['blas'].name == 'atlas':
            args += ["-DSPLA_HOST_BLAS=ATLAS"]
        elif self.spec['blas'].name == 'intel-mkl':
            args += ["-DSPLA_HOST_BLAS=MKL"]
        elif self.spec['blas'].name == 'netlib-lapack':
            args += ["-DSPLA_HOST_BLAS=GENERIC"]
        elif self.spec['blas'].name == 'cray-libsci':
            args += ["-DSPLA_HOST_BLAS=CRAY_LIBSCI"]

        return args
<commit_msg>spla: added version 1.3.0 (#22013)<commit_after># Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Spla(CMakePackage):
    """Specialized Parallel Linear Algebra, providing distributed GEMM
    functionality for specific matrix distributions with optional GPU
    acceleration."""

    homepage = "https://github.com/eth-cscs/spla"
    url      = "https://github.com/eth-cscs/spla/archive/v1.0.0.tar.gz"
    git = 'https://github.com/eth-cscs/spla.git'

    version('1.3.0', sha256='ff05a22bd655607ff941f3228ac8605a813e1eec6eaa49fbcf7b58a3a4cf5f00')
    version('1.2.1', sha256='4d7237f752dc6257778c84ee19c9635072b1cb8ce8d9ab6e34a047f63a736b29')
    version('1.2.0', sha256='96ddd13c155ef3d7e40f87a982cdb439cf9e720523e66b6d20125d346ffe8fca')
    version('1.1.1', sha256='907c374d9c53b21b9f67ce648e7b2b09c320db234a1013d3f05919cd93c95a4b')
    version('1.1.0', sha256='b0c4ebe4988abc2b3434e6c50e7eb0612f3f401bc1aa79ad58a6a92dc87fa65b')
    version('1.0.0', sha256='a0eb269b84d7525b223dc650de12170bba30fbb3ae4f93eb2b5cbdce335e4da1')
    version('develop', branch='develop')
    version('master', branch='master')

    variant('openmp', default=True, description="Build with OpenMP support")
    variant('static', default=False, description="Build as static library")
    variant('cuda', default=False, description="CUDA backend")
    variant('rocm', default=False, description="ROCm backend")
    variant('fortran', default=False, description="Build fortran module")

    conflicts("+cuda", when="+rocm", msg="+cuda and +rocm are mutually exclusive")

    depends_on('mpi')
    depends_on('blas')
    depends_on('cmake@3.10:', type='build')

    depends_on('cuda', when='+cuda')
    depends_on('rocblas', when='+rocm')
    depends_on('hip', when='+rocm')
    depends_on('hsakmt-roct', when='+rocm', type='link')
    depends_on('hsa-rocr-dev', when='+rocm', type='link')

    def cmake_args(self):
        args = [
            self.define_from_variant('SPLA_OMP', 'openmp'),
            self.define_from_variant('SPLA_FORTRAN', 'fortran'),
            self.define_from_variant('SPLA_STATIC', 'static')
        ]

        if '+cuda' in self.spec:
            args += ["-DSPLA_GPU_BACKEND=CUDA"]
        elif '+rocm' in self.spec:
            args += ["-DSPLA_GPU_BACKEND=ROCM"]
        else:
            args += ["-DSPLA_GPU_BACKEND=OFF"]

        if self.spec['blas'].name == 'openblas':
            args += ["-DSPLA_HOST_BLAS=OPENBLAS"]
        elif self.spec['blas'].name in ['amdblis', 'blis']:
            args += ["-DSPLA_HOST_BLAS=BLIS"]
        elif self.spec['blas'].name == 'atlas':
            args += ["-DSPLA_HOST_BLAS=ATLAS"]
        elif self.spec['blas'].name == 'intel-mkl':
            args += ["-DSPLA_HOST_BLAS=MKL"]
        elif self.spec['blas'].name == 'netlib-lapack':
            args += ["-DSPLA_HOST_BLAS=GENERIC"]
        elif self.spec['blas'].name == 'cray-libsci':
            args += ["-DSPLA_HOST_BLAS=CRAY_LIBSCI"]

        return args
<|endoftext|>


<commit_before># Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Wget(AutotoolsPackage, GNUMirrorPackage):
    """GNU Wget is a free software package for retrieving files using
    HTTP, HTTPS and FTP, the most widely-used Internet protocols. It is a
    non-interactive commandline tool, so it may easily be called from scripts,
    cron jobs, terminals without X-Windows support, etc."""

    homepage = "http://www.gnu.org/software/wget/"
    gnu_mirror_path = "wget/wget-1.19.1.tar.gz"

    version('1.20.3', sha256='31cccfc6630528db1c8e3a06f6decf2a370060b982841cfab2b8677400a5092e')
    version('1.19.1', sha256='9e4f12da38cc6167d0752d934abe27c7b1599a9af294e73829be7ac7b5b4da40')
    version('1.17',   sha256='3e04ad027c5b6ebd67c616eec13e66fbedb3d4d8cbe19cc29dadde44b92bda55')
    version('1.16',   sha256='b977fc10ac7a72d987d48136251aeb332f2dced1aabd50d6d56bdf72e2b79101')

    variant('ssl', default='openssl', values=('gnutls', 'openssl'),
            description='Specify SSL backend')
    variant('zlib', default=True,
            description='Enable zlib support')
    variant('libpsl', default=False,
            description='Enable support for libpsl cookie checking')
    variant('pcre', default=False,
            description='Enable PCRE style regular expressions')
    variant('python', default=False,
            description='Enable Python support')

    depends_on('gnutls',  when='ssl=gnutls')
    depends_on('openssl', when='ssl=openssl')

    depends_on('gettext', type='build')
    depends_on('python@3:', type='build', when='+python')

    depends_on('zlib', when='+zlib')
    depends_on('libpsl', when='+libpsl')
    depends_on('pcre', when='+pcre')

    depends_on('perl@5.12.0:', type='build')
    depends_on('pkgconfig', type='build')
    depends_on('iconv')

    depends_on('valgrind', type='test')

    build_directory = 'spack-build'

    def configure_args(self):
        spec = self.spec

        args = [
            '--with-ssl={0}'.format(spec.variants['ssl'].value),
        ]

        if '+zlib' in spec:
            args.append('--with-zlib')
        else:
            args.append('--without-zlib')

        if '+libpsl' in spec:
            args.append('--with-libpsl')
        else:
            args.append('--without-libpsl')

        if '+pcre' in spec:
            args.append('--enable-pcre')
        else:
            args.append('--disable-pcre')

        if self.run_tests:
            args.append('--enable-valgrind-tests')
        else:
            args.append('--disable-valgrind-tests')

        return args
<commit_msg>wget: add 1.21 (#22675)<commit_after># Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

from spack import *

class Wget(AutotoolsPackage, GNUMirrorPackage):
    """GNU Wget is a free software package for retrieving files using
    HTTP, HTTPS and FTP, the most widely-used Internet protocols. It is a
    non-interactive commandline tool, so it may easily be called from scripts,
    cron jobs, terminals without X-Windows support, etc."""

    homepage = "http://www.gnu.org/software/wget/"
    gnu_mirror_path = "wget/wget-1.19.1.tar.gz"

    version('1.21',   sha256='b3bc1a9bd0c19836c9709c318d41c19c11215a07514f49f89b40b9d50ab49325')
    version('1.20.3', sha256='31cccfc6630528db1c8e3a06f6decf2a370060b982841cfab2b8677400a5092e')
    version('1.19.1', sha256='9e4f12da38cc6167d0752d934abe27c7b1599a9af294e73829be7ac7b5b4da40')
    version('1.17',   sha256='3e04ad027c5b6ebd67c616eec13e66fbedb3d4d8cbe19cc29dadde44b92bda55')
    version('1.16',   sha256='b977fc10ac7a72d987d48136251aeb332f2dced1aabd50d6d56bdf72e2b79101')

    variant('ssl', default='openssl', values=('gnutls', 'openssl'),
            description='Specify SSL backend')
    variant('zlib', default=True,
            description='Enable zlib support')
    variant('libpsl', default=False,
            description='Enable support for libpsl cookie checking')
    variant('pcre', default=False,
            description='Enable PCRE style regular expressions')
    variant('python', default=False,
            description='Enable Python support')

    depends_on('gnutls',  when='ssl=gnutls')
    depends_on('openssl', when='ssl=openssl')

    depends_on('gettext', type='build')
    depends_on('python@3:', type='build', when='+python')

    depends_on('zlib', when='+zlib')
    depends_on('libpsl', when='+libpsl')
    depends_on('pcre', when='+pcre')

    depends_on('perl@5.12.0:', type='build')
    depends_on('pkgconfig', type='build')
    depends_on('iconv')

    depends_on('valgrind', type='test')

    build_directory = 'spack-build'

    def configure_args(self):
        spec = self.spec

        args = [
            '--with-ssl={0}'.format(spec.variants['ssl'].value),
        ]

        if '+zlib' in spec:
            args.append('--with-zlib')
        else:
            args.append('--without-zlib')

        if '+libpsl' in spec:
            args.append('--with-libpsl')
        else:
            args.append('--without-libpsl')

        if '+pcre' in spec:
            args.append('--enable-pcre')
        else:
            args.append('--disable-pcre')

        if self.run_tests:
            args.append('--enable-valgrind-tests')
        else:
            args.append('--disable-valgrind-tests')

        return args
<|endoftext|>