<commit_before>""" PyCintex compatibility module.
    This module allows transferring away from PyCintex from ROOT v5 to v6.
    It provides both the original PyCintex.py (most code here is copied over
    from PyCintex.py) as well as the newer cppyy (from PyPy) APIs. In ROOT6,
    these codes are consolidated.
"""

import sys, string

### PyPy has 'cppyy' builtin (if enabled, that is)
if 'cppyy' in sys.builtin_module_names:
   _builtin_cppyy = True

   import imp
   sys.modules[ __name__ ] = \
      imp.load_module( 'cppyy', *(None, 'cppyy', ('', '', imp.C_BUILTIN) ) )
   del imp

   _thismodule = sys.modules[ __name__ ]
   _backend = _thismodule.gbl

   # custom behavior that is not yet part of PyPy's cppyy
   def _MakeRootClass( self, name ):
      return getattr( self, name )
   type(_backend).MakeRootClass = _MakeRootClass

   def _LookupRootEntity( self, name ):
      return getattr( self, name )
   type(_backend).LookupRootEntity = _LookupRootEntity

   class _Double(float): pass
   type(_backend).Double = _Double

   def _AddressOf( self, obj ):
      import array
      return array.array('L', [_thismodule.addressof( obj )] )
   type(_backend).AddressOf = _AddressOf

   del _AddressOf, _Double, _LookupRootEntity, _MakeRootClass

else:
   _builtin_cppyy = False

   # load PyROOT C++ extension module, special case for linux and Sun
   needsGlobal =  ( 0 <= string.find( sys.platform, 'linux' ) ) or\
                  ( 0 <= string.find( sys.platform, 'sunos' ) )
   if needsGlobal:
      # change dl flags to load dictionaries from pre-linked .so's
      dlflags = sys.getdlopenflags()
      sys.setdlopenflags( 0x100 | 0x2 )    # RTLD_GLOBAL | RTLD_NOW

   import libPyROOT as _backend

   # reset dl flags if needed
   if needsGlobal:
      sys.setdlopenflags( dlflags )
   del needsGlobal

# PyCintex tests rely on this, but they should not:
sys.modules[ __name__ ].libPyROOT = _backend

if not _builtin_cppyy:
   _backend.SetMemoryPolicy( _backend.kMemoryStrict )
_backend.MakeRootClass( 'PyROOT::TPyROOTApplication' ).InitCINTMessageCallback()

#--- Enable Autoloading ignoring possible error for the time being
try:    _backend.gInterpreter.EnableAutoLoading()
except: pass

### template support ------------------------------------------------------------
if not _builtin_cppyy:
   class Template:
      def __init__( self, name ):
         self.__name__ = name

      def __call__( self, *args ):
         newargs = [ self.__name__[ 0 <= self.__name__.find( 'std::' ) and 5 or 0:] ]
         for arg in args:
            if type(arg) == str:
               arg = ','.join( map( lambda x: x.strip(), arg.split(',') ) )
            newargs.append( arg )
         result = _backend.MakeRootTemplateClass( *newargs )

       # special case pythonization (builtin_map is not available from the C-API)
         if hasattr( result, 'push_back' ):
            def iadd( self, ll ):
               [ self.push_back(x) for x in ll ]
               return self

            result.__iadd__ = iadd

         return result

   _backend.Template = Template

#--- LoadDictionary function and aliases -----------------------------
def loadDictionary(name) :
   # prepend "lib"
   if sys.platform != 'win32' and name[:3] != 'lib' :
       name = 'lib' + name
   sc = _backend.gSystem.Load(name)
   if sc == -1 : raise RuntimeError("Error Loading dictionary")
loadDict = loadDictionary

#--- Load Cintex module and enable conversions Reflex->CINT-----------
# TSystem::Load() already knows that cintex depends on reflex.
# _backend.gSystem.Load('libReflex')
_backend.gSystem.Load( 'libCintex' )

Cintex = _backend.MakeRootClass( 'Cintex' )
Cintex.SetDebug(0)
Cintex.Enable()

#--- Other functions needed -------------------------------------------
if not _builtin_cppyy:
   class _stdmeta( type ):
      def __getattr__( cls, attr ):   # for non-templated classes in std
         klass = _backend.MakeRootClass( attr, cls )
         setattr( cls, attr, klass )
         return klass

   class _global_cpp:
      class std( object ):
         __metaclass__ = _stdmeta

         stlclasses = ( 'complex', 'pair', \
            'deque', 'list', 'queue', 'stack', 'vector', 'map', 'multimap', 'set', 'multiset' )

         for name in stlclasses:
            locals()[ name ] = Template( 'std::%s' % name )

         _backend.gROOT.ProcessLine( "#include <iostream>" )
         string = _backend.MakeRootClass( 'string' )

   _backend.SetRootLazyLookup( _global_cpp.__dict__ )
else:
   _global_cpp = _backend

def Namespace( name ) :
   if name == '' : return _global_cpp
   else :          return _backend.LookupRootEntity( name )
makeNamespace = Namespace

def makeClass( name ) :
   return _backend.MakeRootClass( name )

def addressOf( obj ) :
   return _backend.AddressOf( obj )[0]

def getAllClasses() :
   TClassTable = makeClass( 'TClassTable' )
   TClassTable.Init()
   classes = []
   while True :
      c = TClassTable.Next()
      if c : classes.append( c )
      else : break
   return classes

#--- Global namespace and global objects -------------------------------
gbl  = _global_cpp
NULL = 0 # _backend.GetRootGlobal returns a descriptor, which needs a class
class double(float): pass
class short(int): pass
class long_int(int): pass
class unsigned_short(int): pass
class unsigned_int(int): pass
class unsigned_long(long): pass

#--- Copy over locally defined names ------------------------------------
if _builtin_cppyy:
   for name in dir():
      if name[0] != '_': setattr( _thismodule, name, eval(name) )

#--- For test purposes --------------------------------------------------
if __name__ == '__main__' :
   loadDict( 'test_CintexDict' )
<commit_msg>do not touch TPyROOTApplication (and so do not load libPyROOT) for builtin cppyy<commit_after>""" PyCintex compatibility module.
    This module allows transferring away from PyCintex from ROOT v5 to v6.
    It provides both the original PyCintex.py (most code here is copied over
    from PyCintex.py) as well as the newer cppyy (from PyPy) APIs. In ROOT6,
    these codes are consolidated.
"""

import sys, string

### PyPy has 'cppyy' builtin (if enabled, that is)
if 'cppyy' in sys.builtin_module_names:
   _builtin_cppyy = True

   import imp
   sys.modules[ __name__ ] = \
      imp.load_module( 'cppyy', *(None, 'cppyy', ('', '', imp.C_BUILTIN) ) )
   del imp

   _thismodule = sys.modules[ __name__ ]
   _backend = _thismodule.gbl

   # custom behavior that is not yet part of PyPy's cppyy
   def _MakeRootClass( self, name ):
      return getattr( self, name )
   type(_backend).MakeRootClass = _MakeRootClass

   def _LookupRootEntity( self, name ):
      return getattr( self, name )
   type(_backend).LookupRootEntity = _LookupRootEntity

   class _Double(float): pass
   type(_backend).Double = _Double

   def _AddressOf( self, obj ):
      import array
      return array.array('L', [_thismodule.addressof( obj )] )
   type(_backend).AddressOf = _AddressOf

   del _AddressOf, _Double, _LookupRootEntity, _MakeRootClass

else:
   _builtin_cppyy = False

   # load PyROOT C++ extension module, special case for linux and Sun
   needsGlobal =  ( 0 <= string.find( sys.platform, 'linux' ) ) or\
                  ( 0 <= string.find( sys.platform, 'sunos' ) )
   if needsGlobal:
      # change dl flags to load dictionaries from pre-linked .so's
      dlflags = sys.getdlopenflags()
      sys.setdlopenflags( 0x100 | 0x2 )    # RTLD_GLOBAL | RTLD_NOW

   import libPyROOT as _backend

   # reset dl flags if needed
   if needsGlobal:
      sys.setdlopenflags( dlflags )
   del needsGlobal

# PyCintex tests rely on this, but they should not:
sys.modules[ __name__ ].libPyROOT = _backend

if not _builtin_cppyy:
   _backend.SetMemoryPolicy( _backend.kMemoryStrict )
   _backend.MakeRootClass( 'PyROOT::TPyROOTApplication' ).InitCINTMessageCallback()

#--- Enable Autoloading ignoring possible error for the time being
try:    _backend.gInterpreter.EnableAutoLoading()
except: pass

### template support ------------------------------------------------------------
if not _builtin_cppyy:
   class Template:
      def __init__( self, name ):
         self.__name__ = name

      def __call__( self, *args ):
         newargs = [ self.__name__[ 0 <= self.__name__.find( 'std::' ) and 5 or 0:] ]
         for arg in args:
            if type(arg) == str:
               arg = ','.join( map( lambda x: x.strip(), arg.split(',') ) )
            newargs.append( arg )
         result = _backend.MakeRootTemplateClass( *newargs )

       # special case pythonization (builtin_map is not available from the C-API)
         if hasattr( result, 'push_back' ):
            def iadd( self, ll ):
               [ self.push_back(x) for x in ll ]
               return self

            result.__iadd__ = iadd

         return result

   _backend.Template = Template

#--- LoadDictionary function and aliases -----------------------------
def loadDictionary(name) :
   # prepend "lib"
   if sys.platform != 'win32' and name[:3] != 'lib' :
       name = 'lib' + name
   sc = _backend.gSystem.Load(name)
   if sc == -1 : raise RuntimeError("Error Loading dictionary")
loadDict = loadDictionary

#--- Load Cintex module and enable conversions Reflex->CINT-----------
# TSystem::Load() already knows that cintex depends on reflex.
# _backend.gSystem.Load('libReflex')
_backend.gSystem.Load( 'libCintex' )

Cintex = _backend.MakeRootClass( 'Cintex' )
Cintex.SetDebug(0)
Cintex.Enable()

#--- Other functions needed -------------------------------------------
if not _builtin_cppyy:
   class _stdmeta( type ):
      def __getattr__( cls, attr ):   # for non-templated classes in std
         klass = _backend.MakeRootClass( attr, cls )
         setattr( cls, attr, klass )
         return klass

   class _global_cpp:
      class std( object ):
         __metaclass__ = _stdmeta

         stlclasses = ( 'complex', 'pair', \
            'deque', 'list', 'queue', 'stack', 'vector', 'map', 'multimap', 'set', 'multiset' )

         for name in stlclasses:
            locals()[ name ] = Template( 'std::%s' % name )

         _backend.gROOT.ProcessLine( "#include <iostream>" )
         string = _backend.MakeRootClass( 'string' )

   _backend.SetRootLazyLookup( _global_cpp.__dict__ )
else:
   _global_cpp = _backend

def Namespace( name ) :
   if name == '' : return _global_cpp
   else :          return _backend.LookupRootEntity( name )
makeNamespace = Namespace

def makeClass( name ) :
   return _backend.MakeRootClass( name )

def addressOf( obj ) :
   return _backend.AddressOf( obj )[0]

def getAllClasses() :
   TClassTable = makeClass( 'TClassTable' )
   TClassTable.Init()
   classes = []
   while True :
      c = TClassTable.Next()
      if c : classes.append( c )
      else : break
   return classes

#--- Global namespace and global objects -------------------------------
gbl  = _global_cpp
NULL = 0 # _backend.GetRootGlobal returns a descriptor, which needs a class
class double(float): pass
class short(int): pass
class long_int(int): pass
class unsigned_short(int): pass
class unsigned_int(int): pass
class unsigned_long(long): pass

#--- Copy over locally defined names ------------------------------------
if _builtin_cppyy:
   for name in dir():
      if name[0] != '_': setattr( _thismodule, name, eval(name) )

#--- For test purposes --------------------------------------------------
if __name__ == '__main__' :
   loadDict( 'test_CintexDict' )
<|endoftext|>


<commit_before>from setuptools import setup, Extension
import os
import platform

root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
src_dir = os.path.join(root_dir, "src")
include_dir = os.path.join(root_dir, "include")

# Setup compilation arguments for native code
compile_args = []
link_args = []
if os.name == 'posix':
  compile_args = ["-O3", "-ffunction-sections", "-fdata-sections", "-fvisibility-inlines-hidden", "-std=c++11"]
  if platform.system() == 'Darwin':
    link_args = ["-Wl,-dead_strip"]
  else:
    link_args = ["-Wl,-z,noexecstack", "-Wl,-z,now", "-Wl,-z,relro", "-Wl,--gc-sections"]
elif os.name == 'nt':
  compile_args = ["/Ox", "/EHsc"]
  link_args = []

lib = Extension('lemmagen.libLemmagen',
                ["lemmagen/libLemmagen.pyx", os.path.join(src_dir, "lemmagen.cpp"), os.path.join(src_dir, "RdrLemmatizer.cpp")],
                extra_compile_args=compile_args,
                extra_link_args=link_args,
                include_dirs=[include_dir])

setup(name="Lemmagen",
      version="1.3.1",
      description="LemmaGen lemmatizer for Python supporing Slovene, Serbian, Romanian, Estonian, Bulgarian and other languages",
      package_data={'lemmagen':["dictionaries/*"]},
      license="GPLv2+",
      author="Jernej Virag",
      author_email="jernej@virag.si",
      setup_requires = ["setuptools>=18.0","cython>=0.28.4"],
      classifiers=[
        "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
        "Operating System :: OS Independent",
        "Intended Audience :: Developers",
        "Development Status :: 5 - Production/Stable",
        "Topic :: Software Development :: Libraries :: Python Modules",
        "Programming Language :: Python",
        "Programming Language :: Python :: 2",
        "Programming Language :: Python :: 3",
        "Topic :: Text Processing :: Linguistic",
      ],
      ext_modules=[lib],
      test_suite="tests",
      packages=["lemmagen"])
<commit_msg>Fix macOS build error<commit_after>from setuptools import setup, Extension
import os
import platform

root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
src_dir = os.path.join(root_dir, "src")
include_dir = os.path.join(root_dir, "include")

# Setup compilation arguments for native code
compile_args = []
link_args = []
if os.name == 'posix':
  compile_args = ["-O3", "-ffunction-sections", "-fdata-sections", "-fvisibility-inlines-hidden"]
  if platform.system() == 'Darwin':
    link_args = ["-Wl,-dead_strip"]
  else:
    compile_args.append("-std=c++11")
    link_args = ["-Wl,-z,noexecstack", "-Wl,-z,now", "-Wl,-z,relro", "-Wl,--gc-sections"]
elif os.name == 'nt':
  compile_args = ["/Ox", "/EHsc"]
  link_args = []

lib = Extension('lemmagen.libLemmagen',
                ["lemmagen/libLemmagen.pyx", os.path.join(src_dir, "lemmagen.cpp"), os.path.join(src_dir, "RdrLemmatizer.cpp")],
                extra_compile_args=compile_args,
                extra_link_args=link_args,
                include_dirs=[include_dir])

setup(name="Lemmagen",
      version="1.3.1",
      description="LemmaGen lemmatizer for Python supporing Slovene, Serbian, Romanian, Estonian, Bulgarian and other languages",
      package_data={'lemmagen':["dictionaries/*"]},
      license="GPLv2+",
      author="Jernej Virag",
      author_email="jernej@virag.si",
      setup_requires = ["setuptools>=18.0","cython>=0.28.4"],
      classifiers=[
        "License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)",
        "Operating System :: OS Independent",
        "Intended Audience :: Developers",
        "Development Status :: 5 - Production/Stable",
        "Topic :: Software Development :: Libraries :: Python Modules",
        "Programming Language :: Python",
        "Programming Language :: Python :: 2",
        "Programming Language :: Python :: 3",
        "Topic :: Text Processing :: Linguistic",
      ],
      ext_modules=[lib],
      test_suite="tests",
      packages=["lemmagen"])
<|endoftext|>


<commit_before>from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize

extensions = [
    Extension("*", ["*.pyx"],
              include_dirs = ["../../src"],
              language='c',
              extra_objects = ["../../src/libfreesasa.a"],
              extra_compile_args = ["-w"]
              )
]

setup(
    ext_modules = cythonize(extensions)
)
<commit_msg>added some installation info to the python bindings<commit_after>from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize

extensions = [
    Extension("*", ["*.pyx"],
              include_dirs = ["../../src"],
              language='c',
              extra_objects = ["../../src/libfreesasa.a"],
              extra_compile_args = ["-w"]
              )
]

setup(
    name='FreeSASA',
    description='Calculate solvent accessible surface areas of proteins',
    version='0.5.0', # how to make this use the version of the rest of the library
    author='Simon Mitternacht',
    url='http://mittinatten.github.io/freesasa/',
    license='GPL-v3',
    ext_modules = cythonize(extensions)
)
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

#
# Copyright © 2012-2013 by its contributors. See AUTHORS for details.
#
# Distributed under the MIT/X11 software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
#

import numbers
import six

from struct import unpack

from .base58 import VersionedPayload
from .errors import InvalidSecretError
from .serialize import serialize_beint, deserialize_beint
from .tools import StringIO

from .ecdsa__common import *

# Import as a different name so as to clearly distinguish from our ecdsa* modules
import ecdsa as pyecdsa

# Certicom secp256-k1, the ECDSA curve used by Bitcoin. This curve has recently
# been added to the python-ecdsa repository, but is still missing from the latest
# version on PyPI.
try:
    pyecdsa.curves.find_curve((1, 3, 132, 0, 10))
except pyecdsa.curves.UnknownCurveError:
    _a  = 0x0000000000000000000000000000000000000000000000000000000000000000L
    _b  = 0x0000000000000000000000000000000000000000000000000000000000000007L
    _p  = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
    _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
    _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
    _r  = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
    curve_secp256k1 = pyecdsa.ellipticcurve.CurveFp(_p, _a, _b)
    generator_secp256k1 = pyecdsa.ellipticcurve.Point(curve_secp256k1, _Gx, _Gy, _r)
    SECP256k1 = pyecdsa.curves.Curve('SECP256k1',
                                     curve_secp256k1,
                                     generator_secp256k1,
                                     (1, 3, 132, 0, 10))
    pyecdsa.curves.curves.append(SECP256k1)

# The Point class is only used in the creation of public keys and in the
# implementation of various ECDSA operations. Since all operations relevant to
# bitcoin are contained within this file, the Point class is not a properly
# specified API, and so for convenience we simply reuse the python-ecdsa Point
# class. Our only tweak is to use the SECP256k1 curve by default. INFINITY is
# a special-cased Point object.
from ecdsa.ellipticcurve import INFINITY
class Point(pyecdsa.ellipticcurve.Point):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('order', SECP256k1.order)
        super(Point, self).__init__(SECP256k1.curve, *args, **kwargs)

class Secret(VersionedPayload):
    # The only understood secret version has a prefix byte of 0x80 (128)
    SECP256K1_EXPONENT = 0x80

    def __new__(cls, exponent=None, compressed=None, *args, **kwargs):
        if isinstance(exponent, numbers.Integral):
            # The exponent is a random number within range(1, curve.order).
            # Using an exponent of zero would result in trivial-to-break
            # encryption, and as stupid as it sounds, it is a mistake that
            # can happen, so we check for it.
            exponent = exponent % SECP256k1.order
            if not exponent:
                raise InvalidSecretError(u"the secret exponent must be an integer x such "
                    u"that 1 <= x < 0x%x (received 0x%x)" % (SECP256k1.order, exponent))

            # The exponent is always stored as 32 bytes, even if some of the
            # leading bits are zero.
            exponent = serialize_beint(exponent, 32)

            # As a rather hackish extension of the Bitcoin secret format, a compressed
            # key is indicated by suffixing a '\x01' byte to the secret exponent. Note
            # that compression is a property of public keys, not private keys.
            if compressed is None or compressed:
                exponent += six.int2byte(1)

            kwargs.setdefault('version', cls.SECP256K1_EXPONENT)

            # Reuse VersionPayload's constructor:
            return super(Secret, cls).__new__(cls, exponent, *args, **kwargs)

        # At the time of this writing the only serialized secret format is what
        # we call SECP256K1_EXPONENT, a serialized exponent of the SECP256k1
        # curve, with an optional suffix indicating compression.
        if 'payload' in kwargs:
            kwargs.setdefault('version', cls.SECP256K1_EXPONENT)

        # The VersionedPayload superclass takes care of the details of
        # extracting (and validating) the version, payload, and checksum.
        # Other than the checksum, it is our responsibilty to make sure
        # that the internal fields make sense:
        if compressed is not None:
            raise InvalidSecretError(u"cannot specify compression when "
                u"constructing from an existing serialized secret")

        # The 'payload' parameter of VersionedPayload may be specified as
        # either a positional or keyword argument, or not at all. Since we
        # don't know, we run the risk of sending multiple values if we
        # blindly pass on exponent. If it's passed as a keyword, exponent
        # should be None (the default value for VersionedPayload as well),
        # so we use that fact to distinguish the two cases:
        if exponent is None:
            secret = super(Secret, cls).__new__(cls, *args, **kwargs)
        else:
            secret = super(Secret, cls).__new__(cls, exponent, *args, **kwargs)

        # Do some basic checks to make sure that what we received was actually
        # a valid serialized Secret.
        if len(secret) not in (37, 38):
            raise InvalidSecretError(u"serialized secret must be either 37 "
                u"(uncompressed) or 38 (compressed) bytes in length, not "
                u"%d" % len(secret))
        if secret[:1] != six.int2byte(128):
            raise InvalidSecretError(u"incorrect version for serialized secret; "
                u"expected 0x80 (128), not 0x%x (%d)" % ((ord(secret[:1]),)*2))
        if len(secret) == 38 and secret[33:34] != six.int2byte(1):
            raise InvalidSecretError(u"compression flag must be 0x01 (1), "
                u"not 0x%x (%d)" % ((ord(secret[33:34]),)*2))
        assert 1 <= secret.exponent < SECP256k1.order, (u"encoded exponent "
            u"must be an integer x such that 1 <= x < 0x%x" % SECP256k1.order)

        # Return the newly generated Secret
        return secret

    # The exponent is stored as a 256-bit big endian integer, the first field
    # of the payload:
    exponent = property(lambda self:deserialize_beint(StringIO(self.payload[:32]), 32))
    # A compressed key is requested by suffixing 0x01 to the payload field. Note
    # that the following comparison only returns true if payload is exactly 33
    # bytes in length and the final byte is '\x01'.
    compressed = property(lambda self:self.payload[32:] == six.int2byte(1))

class Signature(tuple):
    def __new__(cls, r, s=None, *args, **kwargs):
        if s is None:
            r, s = r.r, r.s
        return super(Signature, cls).__new__(cls, (r, s), *args, **kwargs)

    r = property(lambda self:self[0])
    s = property(lambda self:self[1])

    def serialize(self):
        def _serialize_sint(n):
            n_str = serialize_beint(n)
            if not n_str or n_str[:1] > six.int2byte(0x7f):
                n_str = six.int2byte(0) + n_str
            return n_str
        def _serialize_derint(n):
            n_str = _serialize_sint(n)
            return b''.join([
                six.int2byte(0x02),
                six.int2byte(len(n_str)),
                n_str,
            ])
        r_str = _serialize_derint(self.r)
        s_str = _serialize_derint(self.s)
        return b''.join([
            six.int2byte(0x30),
            six.int2byte(len(r_str + s_str)),
            r_str,
            s_str,
        ])
    @classmethod
    def deserialize(cls, file_):
        id_ = unpack('>B', file_.read(1))[0]
        assert id_ == 0x30, id_
        seq_len = unpack('>B', file_.read(1))[0]
        seq = file_.read(seq_len)
        id_, seq = unpack('>B', seq[:1])[0], seq[1:]
        assert id_ == 0x02, id_
        r_len, seq = unpack('>B', seq[:1])[0], seq[1:]
        r_str, seq = seq[:r_len], seq[r_len:]
        id_, seq = unpack('>B', seq[:1])[0], seq[1:]
        assert id_ == 0x02, id_
        s_len, seq = unpack('>B', seq[:1])[0], seq[1:]
        s_str = seq[:s_len]
        assert 2+r_len+2+s_len == seq_len, (2+r_len+2+s_len, seq_len)
        return cls(deserialize_beint(StringIO(r_str), len(r_str)),
                   deserialize_beint(StringIO(s_str), len(s_str)))

class CompactSignature(Signature):
    def __init__(self, v, r, s, *args, **kwargs):
        super(CompactSignature, self).__init__(r, s, *args, **kwargs)
        self.v = v

    def serialize(self):
        return b''.join([
            six.int2byte(self.v),
            serialize_beint(self.r, 32),
            serialize_beint(self.s, 32),
        ])
    @classmethod
    def deserialize(cls, file_):
        v = unpack('>B', file_.read(1))[0]
        r = deserialize_beint(file_, 32)
        s = deserialize_beint(file_, 32)
        return cls(v, r, s)

class SigningKey(object):
    def __init__(self, secret, *args, **kwargs):
        super(SigningKey, self).__init__(*args, **kwargs)
        self._ecdsa_signing_key = pyecdsa.SigningKey.from_secret_exponent(
            secret.exponent, curve=SECP256k1, hashfunc=hash256)
        self.compressed = secret.compressed

    @property
    def secret(self):
        cls = getattr(self, 'get_secret_class', lambda:
              getattr(self, 'secret_class', Secret))()
        return cls(self._ecdsa_signing_key.privkey.secret_multiplier,
                   compressed=self.compressed)

    # Private / signing keys can be serialized in two ways: using the industry standard DER/ASN.1 notation, or by recording the
    def serialize(self):
        return self._ecdsa_signing_key.to_der()
    @classmethod
    def deserialize(cls, file_):
        id_ = unpack('>B', file_.read(1))[0]
        assert id_ == 0x30, id_
        seq_len = unpack('>B', file_.read(1))[0]
        seq = file_.read(seq_len)
        ecdsa_signing_key = pyecdsa.SigningKey.from_der(b''.join([
            six.int2byte(id_),
            six.int2byte(seq_len),
            seq]))
        obj = cls.__new__(cls)
        obj._ecdsa_signing_key = ecdsa_signing_key
        return obj

    def get_verifying_key(self):
        cls = getattr(self, 'get_verifying_key_class', lambda:
              getattr(self, 'verifying_key_class', VerifyingKey))()
        obj = cls.__new__(cls)
        obj._ecdsa_verifying_key = self._ecdsa_signing_key.verifying_key
        obj.compressed = self.compressed
        return obj

    def sign(self, digest, entropy=None):
        return Signature(*self._ecdsa_signing_key.sign_number(digest))

class VerifyingKey(object):
    def __init__(self, point, compressed=True, *args, **kwargs):
        super(VerifyingKey, self).__init__(*args, **kwargs)
        self._ecdsa_verifying_key = pyecdsa.VerifyingKey.from_public_point(
            point, curve=SECP256k1, hashfunc=hash256)
        self.compressed = compressed

    @property
    def point(self):
        return self._ecdsa_verifying_key.pubkey.point

    def serialize(self):
        point = self.point
        order = self._ecdsa_verifying_key.curve.generator.order()
        x_str = pyecdsa.util.number_to_string(point.x(), order)
        y_str = pyecdsa.util.number_to_string(point.y(), order)
        if self.compressed:
            return b''.join([six.int2byte(2 + (point.y() & 1)), x_str])
        else:
            return b''.join([six.int2byte(4), x_str, y_str])
    @classmethod
    def deserialize(cls, file_):
        id_ = unpack('>B', file_.read(1))[0]
        assert id_ in (0x02, 0x03, 0x04), id_
        x = pyecdsa.util.string_to_number(file_.read(SECP256k1.baselen))
        if id_ in (0x02, 0x03):
            compressed = True
            a = SECP256k1.curve.a()
            b = SECP256k1.curve.b()
            p = SECP256k1.curve.p()
            y = x * (x**2 + a) + b
            y = pyecdsa.numbertheory.square_root_mod_prime(y%p, p)
            if y&0x01 != id_&0x01:
                y = p - y
        else:
            compressed = False
            y = pyecdsa.util.string_to_number(file_.read(SECP256k1.baselen))
        return cls(Point(x,y), compressed=compressed)

    def verifies(self, signature, digest):
        return self._ecdsa_verifying_key.pubkey.verifies(digest, signature)

# ===----------------------------------------------------------------------===

from .crypto import hash256

#
# End of File
#
<commit_msg>Use a recordtype for signatures instead of deriving from tuple directly. This is both cleaner, and more expressive.<commit_after># -*- coding: utf-8 -*-

#
# Copyright © 2012-2013 by its contributors. See AUTHORS for details.
#
# Distributed under the MIT/X11 software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
#

import numbers
import six

from struct import unpack

from .base58 import VersionedPayload
from .errors import InvalidSecretError
from .mixins import SerializableMixin
from .serialize import serialize_beint, deserialize_beint
from .tools import StringIO

from .ecdsa__common import *

# Import as a different name so as to clearly distinguish from our ecdsa* modules
import ecdsa as pyecdsa

# Certicom secp256-k1, the ECDSA curve used by Bitcoin. This curve has recently
# been added to the python-ecdsa repository, but is still missing from the latest
# version on PyPI.
try:
    pyecdsa.curves.find_curve((1, 3, 132, 0, 10))
except pyecdsa.curves.UnknownCurveError:
    _a  = 0x0000000000000000000000000000000000000000000000000000000000000000L
    _b  = 0x0000000000000000000000000000000000000000000000000000000000000007L
    _p  = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
    _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
    _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
    _r  = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
    curve_secp256k1 = pyecdsa.ellipticcurve.CurveFp(_p, _a, _b)
    generator_secp256k1 = pyecdsa.ellipticcurve.Point(curve_secp256k1, _Gx, _Gy, _r)
    SECP256k1 = pyecdsa.curves.Curve('SECP256k1',
                                     curve_secp256k1,
                                     generator_secp256k1,
                                     (1, 3, 132, 0, 10))
    pyecdsa.curves.curves.append(SECP256k1)

# The Point class is only used in the creation of public keys and in the
# implementation of various ECDSA operations. Since all operations relevant to
# bitcoin are contained within this file, the Point class is not a properly
# specified API, and so for convenience we simply reuse the python-ecdsa Point
# class. Our only tweak is to use the SECP256k1 curve by default. INFINITY is
# a special-cased Point object.
from ecdsa.ellipticcurve import INFINITY
class Point(pyecdsa.ellipticcurve.Point):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('order', SECP256k1.order)
        super(Point, self).__init__(SECP256k1.curve, *args, **kwargs)

class Secret(VersionedPayload):
    # The only understood secret version has a prefix byte of 0x80 (128)
    SECP256K1_EXPONENT = 0x80

    def __new__(cls, exponent=None, compressed=None, *args, **kwargs):
        if isinstance(exponent, numbers.Integral):
            # The exponent is a random number within range(1, curve.order).
            # Using an exponent of zero would result in trivial-to-break
            # encryption, and as stupid as it sounds, it is a mistake that
            # can happen, so we check for it.
            exponent = exponent % SECP256k1.order
            if not exponent:
                raise InvalidSecretError(u"the secret exponent must be an integer x such "
                    u"that 1 <= x < 0x%x (received 0x%x)" % (SECP256k1.order, exponent))

            # The exponent is always stored as 32 bytes, even if some of the
            # leading bits are zero.
            exponent = serialize_beint(exponent, 32)

            # As a rather hackish extension of the Bitcoin secret format, a compressed
            # key is indicated by suffixing a '\x01' byte to the secret exponent. Note
            # that compression is a property of public keys, not private keys.
            if compressed is None or compressed:
                exponent += six.int2byte(1)

            kwargs.setdefault('version', cls.SECP256K1_EXPONENT)

            # Reuse VersionPayload's constructor:
            return super(Secret, cls).__new__(cls, exponent, *args, **kwargs)

        # At the time of this writing the only serialized secret format is what
        # we call SECP256K1_EXPONENT, a serialized exponent of the SECP256k1
        # curve, with an optional suffix indicating compression.
        if 'payload' in kwargs:
            kwargs.setdefault('version', cls.SECP256K1_EXPONENT)

        # The VersionedPayload superclass takes care of the details of
        # extracting (and validating) the version, payload, and checksum.
        # Other than the checksum, it is our responsibilty to make sure
        # that the internal fields make sense:
        if compressed is not None:
            raise InvalidSecretError(u"cannot specify compression when "
                u"constructing from an existing serialized secret")

        # The 'payload' parameter of VersionedPayload may be specified as
        # either a positional or keyword argument, or not at all. Since we
        # don't know, we run the risk of sending multiple values if we
        # blindly pass on exponent. If it's passed as a keyword, exponent
        # should be None (the default value for VersionedPayload as well),
        # so we use that fact to distinguish the two cases:
        if exponent is None:
            secret = super(Secret, cls).__new__(cls, *args, **kwargs)
        else:
            secret = super(Secret, cls).__new__(cls, exponent, *args, **kwargs)

        # Do some basic checks to make sure that what we received was actually
        # a valid serialized Secret.
        if len(secret) not in (37, 38):
            raise InvalidSecretError(u"serialized secret must be either 37 "
                u"(uncompressed) or 38 (compressed) bytes in length, not "
                u"%d" % len(secret))
        if secret[:1] != six.int2byte(128):
            raise InvalidSecretError(u"incorrect version for serialized secret; "
                u"expected 0x80 (128), not 0x%x (%d)" % ((ord(secret[:1]),)*2))
        if len(secret) == 38 and secret[33:34] != six.int2byte(1):
            raise InvalidSecretError(u"compression flag must be 0x01 (1), "
                u"not 0x%x (%d)" % ((ord(secret[33:34]),)*2))
        assert 1 <= secret.exponent < SECP256k1.order, (u"encoded exponent "
            u"must be an integer x such that 1 <= x < 0x%x" % SECP256k1.order)

        # Return the newly generated Secret
        return secret

    # The exponent is stored as a 256-bit big endian integer, the first field
    # of the payload:
    exponent = property(lambda self:deserialize_beint(StringIO(self.payload[:32]), 32))
    # A compressed key is requested by suffixing 0x01 to the payload field. Note
    # that the following comparison only returns true if payload is exactly 33
    # bytes in length and the final byte is '\x01'.
    compressed = property(lambda self:self.payload[32:] == six.int2byte(1))

from recordtype import recordtype
BaseSignature = recordtype('BaseSignature', 'r s'.split())

class Signature(SerializableMixin, BaseSignature):
    def serialize(self):
        def _serialize_sint(n):
            n_str = serialize_beint(n)
            if not n_str or n_str[:1] > six.int2byte(0x7f):
                n_str = six.int2byte(0) + n_str
            return n_str
        def _serialize_derint(n):
            n_str = _serialize_sint(n)
            return b''.join([
                six.int2byte(0x02),
                six.int2byte(len(n_str)),
                n_str,
            ])
        r_str = _serialize_derint(self.r)
        s_str = _serialize_derint(self.s)
        return b''.join([
            six.int2byte(0x30),
            six.int2byte(len(r_str + s_str)),
            r_str,
            s_str,
        ])
    @classmethod
    def deserialize(cls, file_):
        id_ = unpack('>B', file_.read(1))[0]
        assert id_ == 0x30, id_
        seq_len = unpack('>B', file_.read(1))[0]
        seq = file_.read(seq_len)
        id_, seq = unpack('>B', seq[:1])[0], seq[1:]
        assert id_ == 0x02, id_
        r_len, seq = unpack('>B', seq[:1])[0], seq[1:]
        r_str, seq = seq[:r_len], seq[r_len:]
        id_, seq = unpack('>B', seq[:1])[0], seq[1:]
        assert id_ == 0x02, id_
        s_len, seq = unpack('>B', seq[:1])[0], seq[1:]
        s_str = seq[:s_len]
        assert 2+r_len+2+s_len == seq_len, (2+r_len+2+s_len, seq_len)
        return cls(deserialize_beint(StringIO(r_str), len(r_str)),
                   deserialize_beint(StringIO(s_str), len(s_str)))

class CompactSignature(Signature):
    def __init__(self, v, r, s, *args, **kwargs):
        super(CompactSignature, self).__init__(r, s, *args, **kwargs)
        self.v = v

    def serialize(self):
        return b''.join([
            six.int2byte(self.v),
            serialize_beint(self.r, 32),
            serialize_beint(self.s, 32),
        ])
    @classmethod
    def deserialize(cls, file_):
        v = unpack('>B', file_.read(1))[0]
        r = deserialize_beint(file_, 32)
        s = deserialize_beint(file_, 32)
        return cls(v, r, s)

class SigningKey(object):
    def __init__(self, secret, *args, **kwargs):
        super(SigningKey, self).__init__(*args, **kwargs)
        self._ecdsa_signing_key = pyecdsa.SigningKey.from_secret_exponent(
            secret.exponent, curve=SECP256k1, hashfunc=hash256)
        self.compressed = secret.compressed

    @property
    def secret(self):
        cls = getattr(self, 'get_secret_class', lambda:
              getattr(self, 'secret_class', Secret))()
        return cls(self._ecdsa_signing_key.privkey.secret_multiplier,
                   compressed=self.compressed)

    # Private / signing keys can be serialized in two ways: using the industry standard DER/ASN.1 notation, or by recording the
    def serialize(self):
        return self._ecdsa_signing_key.to_der()
    @classmethod
    def deserialize(cls, file_):
        id_ = unpack('>B', file_.read(1))[0]
        assert id_ == 0x30, id_
        seq_len = unpack('>B', file_.read(1))[0]
        seq = file_.read(seq_len)
        ecdsa_signing_key = pyecdsa.SigningKey.from_der(b''.join([
            six.int2byte(id_),
            six.int2byte(seq_len),
            seq]))
        obj = cls.__new__(cls)
        obj._ecdsa_signing_key = ecdsa_signing_key
        return obj

    def get_verifying_key(self):
        cls = getattr(self, 'get_verifying_key_class', lambda:
              getattr(self, 'verifying_key_class', VerifyingKey))()
        obj = cls.__new__(cls)
        obj._ecdsa_verifying_key = self._ecdsa_signing_key.verifying_key
        obj.compressed = self.compressed
        return obj

    def sign(self, digest, entropy=None):
        return Signature(*self._ecdsa_signing_key.sign_number(digest))

class VerifyingKey(object):
    def __init__(self, point, compressed=True, *args, **kwargs):
        super(VerifyingKey, self).__init__(*args, **kwargs)
        self._ecdsa_verifying_key = pyecdsa.VerifyingKey.from_public_point(
            point, curve=SECP256k1, hashfunc=hash256)
        self.compressed = compressed

    @property
    def point(self):
        return self._ecdsa_verifying_key.pubkey.point

    def serialize(self):
        point = self.point
        order = self._ecdsa_verifying_key.curve.generator.order()
        x_str = pyecdsa.util.number_to_string(point.x(), order)
        y_str = pyecdsa.util.number_to_string(point.y(), order)
        if self.compressed:
            return b''.join([six.int2byte(2 + (point.y() & 1)), x_str])
        else:
            return b''.join([six.int2byte(4), x_str, y_str])
    @classmethod
    def deserialize(cls, file_):
        id_ = unpack('>B', file_.read(1))[0]
        assert id_ in (0x02, 0x03, 0x04), id_
        x = pyecdsa.util.string_to_number(file_.read(SECP256k1.baselen))
        if id_ in (0x02, 0x03):
            compressed = True
            a = SECP256k1.curve.a()
            b = SECP256k1.curve.b()
            p = SECP256k1.curve.p()
            y = x * (x**2 + a) + b
            y = pyecdsa.numbertheory.square_root_mod_prime(y%p, p)
            if y&0x01 != id_&0x01:
                y = p - y
        else:
            compressed = False
            y = pyecdsa.util.string_to_number(file_.read(SECP256k1.baselen))
        return cls(Point(x,y), compressed=compressed)

    def verifies(self, signature, digest):
        return self._ecdsa_verifying_key.pubkey.verifies(digest, signature)

# ===----------------------------------------------------------------------===

from .crypto import hash256

#
# End of File
#
<|endoftext|>


<commit_before>"""
Decorator utility for function decorators that works using ast.

This is intented to be a utility for signature preserving function
decorators.

"""
from __future__ import absolute_import

__all__ = [
    'ASTorator',
    'wraps',
    'decorator',
    'value',
    'flatorator',
]

import ast
from inspect import getsourcefile
from functools import update_wrapper
from types import FunctionType

from .compat import signature, ast_arg, exec_compat, is_identifier
from .common import Scope

class ASTorator(object):
    """
    Decorates wapper functions with a given function signature.

    Uses abstract syntax trees for dynamic code generation.

    """
    def __init__(self, signature, funcname=None, filename=None):
        self.signature = signature
        self.funcname = funcname
        self.filename = filename

    @classmethod
    def from_function(cls, function):
        try:
            filename = getsourcefile(function)
        except:
            filename = None
        if is_identifier(function.__name__):
            funcname = function.__name__
        else:
            funcname = None
        return cls(signature(function), funcname, filename)

    def decorate(self, callback):
        """
        Create wrapper that calls function with all its arguments.

        The callback may be a function, lambda or any ast.expr.

        """
        # TODO: check whether the callback has compatible signature

        scope = Scope(self.signature.parameters.keys())
        context = {'__builtins__': __builtins__}

        filename = '<wraps(%s:%s)>' % (self.filename or '?', self.funcname)
        callback_name = scope.reserve('_call')

        # Add a value to the context
        empty = self.signature.empty
        def hasattr(param, attr):
            return not getattr(param, attr, empty) is empty

        def attr(param, attr):
            if hasattr(param, attr):
                return ast.Attribute(
                    value=ast.Name(id=param.name, ctx=ast.Load()),
                    attr=attr,
                    ctx=ast.Load())
            else:
                return None

        params = list(self.signature.parameters.values())
        sig = ast.arguments(
            args=[],
            vararg=None,
            varargannotation=None,
            kwonlyargs=[],
            kwarg=None,
            kwargannotation=None,
            defaults=[],
            kw_defaults=[])
        call = ast.Call(
            func=ast.Name(id=callback_name, ctx=ast.Load()),
            args=[],
            keywords=[],
            starargs=None,
            kwargs=None)

        for param in self.signature.parameters.values():
            context[param.name] = param

            # positional parameters
            if param.kind == param.POSITIONAL_OR_KEYWORD:
                sig.args.append(ast_arg(
                    arg=param.name,
                    annotation=attr(param, 'annotation')))
                call.args.append(ast.Name(id=param.name, ctx=ast.Load()))
                if hasattr(param, 'default'):
                    sig.defaults.append(attr(param, 'default'))

            # keyword only
            elif param.kind == param.KEYWORD_ONLY:
                sig.kwonlyargs.append(ast_arg(
                    arg=param.name,
                    annotation=attr(param, 'annotation')))
                call.keywords.append(ast.keyword(
                    arg=param.name,
                    value=ast.Name(id=param.name, ctx=ast.Load())))
                sig.kw_defaults.append(attr(param, 'default'))

            # varargs
            elif param.kind == param.VAR_POSITIONAL:
                sig.vararg = param.name
                sig.varargannotation = attr(param, 'annotation')
                call.starargs = ast.Name(id=param.name, ctx=ast.Load())

            # kwargs
            elif param.kind == param.VAR_KEYWORD:
                sig.kwarg = param.name
                sig.kwargannotation = attr(param, 'annotation')
                call.kwargs = ast.Name(id=param.name, ctx=ast.Load())

            else:
                raise ValueError("Cannot handle parameter type: %s" % param)

        if hasattr(self.signature, 'return_annotation'):
            retannot_name = scope.reserve('_returns')
            context[retannot_name] = self.signature.return_annotation
            returns = ast.Name(id=retannot_name, ctx=ast.Load())
        else:
            returns = None

        # Functions just get called:
        if isinstance(callback, FunctionType):
            context[callback_name] = callback

        # THIS IS SOMEWHAT DANGEROUS, BUT ALSO REALLY COOL:
        elif isinstance(callback, ast.expr):
            call = callback

        # custom expression generator
        else:
            context[callback_name] = callback.value
            call = callback.ast(callback_name)

        # generate and evaluate the complete expression
        loc = {}
        if self.funcname is None:
            expr = ast.Expression(body=ast.Lambda(
                args=sig,
                body=call
            ))
            code = compile(ast.fix_missing_locations(expr), filename, 'eval')
            return eval(code, context, loc)

        else:
            expr = ast.Module(body=[
                ast.FunctionDef(
                    name=self.funcname,
                    args=sig,
                    body=[ast.Return(value=call)],
                    decorator_list=[],
                    returns=returns)
            ])
            code = compile(ast.fix_missing_locations(expr), filename, 'exec')
            exec_compat(code, context, loc)
            return loc[self.funcname]

    __call__ = decorate

    def decorate_with_boundargspec(self, function):
        """
        Create wrapper that calls function with a BoundArgSpec.
        """
        return NotImplemented

    def decorate_with_boundargs(self, function):
        """
        Create a wrapper that calls function with a BoundArgs.
        """
        return self.decorate(
            lambda *args, **kwargs:
                function(self.signature.bind(*args, **kwargs)))

def wraps(function=None, wrapper=None):
    """
    Wrap a function and copy its signature.

    >>> def real(a, b=1, *args, **kwargs):
    ...     return "%r %r %r %r" % (a, b, args, kwargs)

    >>> @wraps(real)
    ... def fake(*args, **kwargs):
    ...     return "Fake: " + real(*args, **kwargs)

    >>> assert signature(fake) == signature(real)

    >>> def check_fake(real, fake, *args, **kwargs):
    ...     rreal = real(*args, **kwargs)
    ...     rfake = fake(*args, **kwargs)
    ...     assert rfake == "Fake: " + rreal, '%r != %r' % (rreal, rfake)

    >>> check_fake(real, fake, 1, 2, 3, 4, kwonly=5, kwarg=6)

    >>> x = [3]
    >>> def real(first = x): return first
    >>> fake = wraps(real, lambda first: real(first))
    >>> assert fake() is real()

    """
    # defer creation of the actual function wrapper until called again
    # (this is for use as a decorator)
    if wrapper is None:
        return lambda wrapper: wraps(function, wrapper)
    if function is None:
        return lambda function: wraps(function, wrapper)

    return update_wrapper(
        ASTorator.from_function(function)(wrapper),
        function)

def decorator(decorator):
    """
    Decorator for signature preserving function decorators.

    >>> def mul(first, second = 1):
    ...     return first * second

    >>> @decorator
    ... def plus_one(fn):
    ...     return lambda *args, **kwargs: 1 + fn(*args, **kwargs)

    >>> fake = plus_one(mul)
    >>> assert fake(2, 3) == 7
    >>> assert fake(4) == 5

    """
    @wraps(decorator)
    def decorate(function):
        return wraps(function, decorator(function))
    return decorate

def flatorator(flatorator):
    """
    Decorator for flat signature preserving decorators.

    >>> @flatorator
    ... def fakeit(fn, *args, **kwargs):
    ...     return 1 + fn(*args, **kwargs)

    >>> @fakeit
    ... def real(a, b=0):
    ...     return a + b
    >>> real(1)
    2

    """
    def decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            return flatorator(fn, *args, **kwargs)
        return wrapper
    return decorator

class Value(object):
    def __init__(self, value):
        self.value = value

    def ast(self, value_name):
        return ast.Name(id=value_name, ctx=ast.Load())

def value(val):
    """
    Return a 'callback' value for use with decorate.

    Example:

    >>> def real(a, b = 1, *args, **kwargs):
    ...     return None
    >>> fake = wraps(real)(value(2.2))
    >>> fake(0) == 2.2
    True

    >>> fake = wraps(real)(value("Hello world!"))
    >>> fake(a=0)
    'Hello world!'

    >>> x = []
    >>> fake = wraps(real)(value(x))
    >>> assert fake(0) is x

    """
    t = type(val)
    if t is int or t is float:
        return ast.Num(n=val)
    elif t is str:
        return ast.Str(s=val)
    elif t is bytes:
        return ast.Bytes(s=val)
    else:
        return Value(val)

<commit_msg>Remove obsolet code remnant<commit_after>"""
Decorator utility for function decorators that works using ast.

This is intented to be a utility for signature preserving function
decorators.

"""
from __future__ import absolute_import

__all__ = [
    'ASTorator',
    'wraps',
    'decorator',
    'value',
    'flatorator',
]

import ast
from inspect import getsourcefile
from functools import update_wrapper
from types import FunctionType

from .compat import signature, ast_arg, exec_compat, is_identifier
from .common import Scope

class ASTorator(object):
    """
    Decorates wapper functions with a given function signature.

    Uses abstract syntax trees for dynamic code generation.

    """
    def __init__(self, signature, funcname=None, filename=None):
        self.signature = signature
        self.funcname = funcname
        self.filename = filename

    @classmethod
    def from_function(cls, function):
        try:
            filename = getsourcefile(function)
        except:
            filename = None
        if is_identifier(function.__name__):
            funcname = function.__name__
        else:
            funcname = None
        return cls(signature(function), funcname, filename)

    def decorate(self, callback):
        """
        Create wrapper that calls function with all its arguments.

        The callback may be a function, lambda or any ast.expr.

        """
        # TODO: check whether the callback has compatible signature

        scope = Scope(self.signature.parameters.keys())
        context = {'__builtins__': __builtins__}

        filename = '<wraps(%s:%s)>' % (self.filename or '?', self.funcname)
        callback_name = scope.reserve('_call')

        # Add a value to the context
        empty = self.signature.empty
        def hasattr(param, attr):
            return not getattr(param, attr, empty) is empty

        def attr(param, attr):
            if hasattr(param, attr):
                return ast.Attribute(
                    value=ast.Name(id=param.name, ctx=ast.Load()),
                    attr=attr,
                    ctx=ast.Load())
            else:
                return None

        sig = ast.arguments(
            args=[],
            vararg=None,
            varargannotation=None,
            kwonlyargs=[],
            kwarg=None,
            kwargannotation=None,
            defaults=[],
            kw_defaults=[])
        call = ast.Call(
            func=ast.Name(id=callback_name, ctx=ast.Load()),
            args=[],
            keywords=[],
            starargs=None,
            kwargs=None)

        for param in self.signature.parameters.values():
            context[param.name] = param

            # positional parameters
            if param.kind == param.POSITIONAL_OR_KEYWORD:
                sig.args.append(ast_arg(
                    arg=param.name,
                    annotation=attr(param, 'annotation')))
                call.args.append(ast.Name(id=param.name, ctx=ast.Load()))
                if hasattr(param, 'default'):
                    sig.defaults.append(attr(param, 'default'))

            # keyword only
            elif param.kind == param.KEYWORD_ONLY:
                sig.kwonlyargs.append(ast_arg(
                    arg=param.name,
                    annotation=attr(param, 'annotation')))
                call.keywords.append(ast.keyword(
                    arg=param.name,
                    value=ast.Name(id=param.name, ctx=ast.Load())))
                sig.kw_defaults.append(attr(param, 'default'))

            # varargs
            elif param.kind == param.VAR_POSITIONAL:
                sig.vararg = param.name
                sig.varargannotation = attr(param, 'annotation')
                call.starargs = ast.Name(id=param.name, ctx=ast.Load())

            # kwargs
            elif param.kind == param.VAR_KEYWORD:
                sig.kwarg = param.name
                sig.kwargannotation = attr(param, 'annotation')
                call.kwargs = ast.Name(id=param.name, ctx=ast.Load())

            else:
                raise ValueError("Cannot handle parameter type: %s" % param)

        if hasattr(self.signature, 'return_annotation'):
            retannot_name = scope.reserve('_returns')
            context[retannot_name] = self.signature.return_annotation
            returns = ast.Name(id=retannot_name, ctx=ast.Load())
        else:
            returns = None

        # Functions just get called:
        if isinstance(callback, FunctionType):
            context[callback_name] = callback

        # THIS IS SOMEWHAT DANGEROUS, BUT ALSO REALLY COOL:
        elif isinstance(callback, ast.expr):
            call = callback

        # custom expression generator
        else:
            context[callback_name] = callback.value
            call = callback.ast(callback_name)

        # generate and evaluate the complete expression
        loc = {}
        if self.funcname is None:
            expr = ast.Expression(body=ast.Lambda(
                args=sig,
                body=call
            ))
            code = compile(ast.fix_missing_locations(expr), filename, 'eval')
            return eval(code, context, loc)

        else:
            expr = ast.Module(body=[
                ast.FunctionDef(
                    name=self.funcname,
                    args=sig,
                    body=[ast.Return(value=call)],
                    decorator_list=[],
                    returns=returns)
            ])
            code = compile(ast.fix_missing_locations(expr), filename, 'exec')
            exec_compat(code, context, loc)
            return loc[self.funcname]

    __call__ = decorate

    def decorate_with_boundargspec(self, function):
        """
        Create wrapper that calls function with a BoundArgSpec.
        """
        return NotImplemented

    def decorate_with_boundargs(self, function):
        """
        Create a wrapper that calls function with a BoundArgs.
        """
        return self.decorate(
            lambda *args, **kwargs:
                function(self.signature.bind(*args, **kwargs)))

def wraps(function=None, wrapper=None):
    """
    Wrap a function and copy its signature.

    >>> def real(a, b=1, *args, **kwargs):
    ...     return "%r %r %r %r" % (a, b, args, kwargs)

    >>> @wraps(real)
    ... def fake(*args, **kwargs):
    ...     return "Fake: " + real(*args, **kwargs)

    >>> assert signature(fake) == signature(real)

    >>> def check_fake(real, fake, *args, **kwargs):
    ...     rreal = real(*args, **kwargs)
    ...     rfake = fake(*args, **kwargs)
    ...     assert rfake == "Fake: " + rreal, '%r != %r' % (rreal, rfake)

    >>> check_fake(real, fake, 1, 2, 3, 4, kwonly=5, kwarg=6)

    >>> x = [3]
    >>> def real(first = x): return first
    >>> fake = wraps(real, lambda first: real(first))
    >>> assert fake() is real()

    """
    # defer creation of the actual function wrapper until called again
    # (this is for use as a decorator)
    if wrapper is None:
        return lambda wrapper: wraps(function, wrapper)
    if function is None:
        return lambda function: wraps(function, wrapper)

    return update_wrapper(
        ASTorator.from_function(function)(wrapper),
        function)

def decorator(decorator):
    """
    Decorator for signature preserving function decorators.

    >>> def mul(first, second = 1):
    ...     return first * second

    >>> @decorator
    ... def plus_one(fn):
    ...     return lambda *args, **kwargs: 1 + fn(*args, **kwargs)

    >>> fake = plus_one(mul)
    >>> assert fake(2, 3) == 7
    >>> assert fake(4) == 5

    """
    @wraps(decorator)
    def decorate(function):
        return wraps(function, decorator(function))
    return decorate

def flatorator(flatorator):
    """
    Decorator for flat signature preserving decorators.

    >>> @flatorator
    ... def fakeit(fn, *args, **kwargs):
    ...     return 1 + fn(*args, **kwargs)

    >>> @fakeit
    ... def real(a, b=0):
    ...     return a + b
    >>> real(1)
    2

    """
    def decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            return flatorator(fn, *args, **kwargs)
        return wrapper
    return decorator

class Value(object):
    def __init__(self, value):
        self.value = value

    def ast(self, value_name):
        return ast.Name(id=value_name, ctx=ast.Load())

def value(val):
    """
    Return a 'callback' value for use with decorate.

    Example:

    >>> def real(a, b = 1, *args, **kwargs):
    ...     return None
    >>> fake = wraps(real)(value(2.2))
    >>> fake(0) == 2.2
    True

    >>> fake = wraps(real)(value("Hello world!"))
    >>> fake(a=0)
    'Hello world!'

    >>> x = []
    >>> fake = wraps(real)(value(x))
    >>> assert fake(0) is x

    """
    t = type(val)
    if t is int or t is float:
        return ast.Num(n=val)
    elif t is str:
        return ast.Str(s=val)
    elif t is bytes:
        return ast.Bytes(s=val)
    else:
        return Value(val)

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
#
# Copyright (C) 2003-2005 Edgewall Software
# Copyright (C) 2003-2005 Daniel Lundin <daniel@edgewall.com>
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://trac.edgewall.com/license.html.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://projects.edgewall.com/trac/.
#
# Author: Daniel Lundin <daniel@edgewall.com>

from trac.db import Table, Column, Index

# Database version identifier. Used for automatic upgrades.
db_version = 17

def __mkreports(reports):
    """Utility function used to create report data in same syntax as the
    default data. This extra step is done to simplify editing the default
    reports."""
    result = []
    for report in reports:
        result.append((None, report[0], report[2], report[1]))
    return result

##
## Database schema
##

schema = [
    # Common
    Table('system', key='name')[
        Column('name'),
        Column('value')],
    Table('permission', key=('username', 'action'))[
        Column('username'),
        Column('action')],
    Table('auth_cookie', key=('cookie', 'ipnr', 'name'))[
        Column('cookie'),
        Column('name'),
        Column('ipnr'),
        Column('time', type='int')],
    Table('session', key=('sid', 'authenticated', 'var_name'))[
        Column('sid'),
        Column('authenticated', type='int'),
        Column('var_name'),
        Column('var_value')],

    # Attachments
    Table('attachment', key=('type', 'id', 'filename'))[
        Column('type'),
        Column('id'),
        Column('filename'),
        Column('size', type='int'),
        Column('time', type='int'),
        Column('description'),
        Column('author'),
        Column('ipnr')],

    # Wiki system
    Table('wiki', key=('name', 'version'))[
        Column('name'),
        Column('version', type='int'),
        Column('time', type='int'),
        Column('author'),
        Column('ipnr'),
        Column('text'),
        Column('comment'),
        Column('readonly', type='int'),
        Index(['time'])],

    # Version control cache
    Table('revision', key='rev')[
        Column('rev'),
        Column('time', type='int'),
        Column('author'),
        Column('message'),
        Index(['time'])],
    Table('node_change', key=('rev', 'path', 'change_type'))[
        Column('rev'),
        Column('path'),
        Column('node_type', size=1),
        Column('change_type', size=1),
        Column('base_path'),
        Column('base_rev'),
        Index(['rev'])],

    # Ticket system
    Table('ticket', key='id')[
        Column('id', auto_increment=True),
        Column('type'),
        Column('time', type='int'),
        Column('changetime', type='int'),
        Column('component'),
        Column('severity'),
        Column('priority'),
        Column('owner'),
        Column('reporter'),
        Column('cc'),
        Column('version'),
        Column('milestone'),
        Column('status'),
        Column('resolution'),
        Column('summary'),
        Column('description'),
        Column('keywords'),
        Index(['time']),
        Index(['status'])],
    Table('ticket_change', key=('ticket', 'time', 'field'))[
        Column('ticket', type='int'),
        Column('time', type='int'),
        Column('author'),
        Column('field'),
        Column('oldvalue'),
        Column('newvalue'),
        Index(['ticket', 'time'])],
    Table('ticket_custom', key=('ticket', 'name'))[
        Column('ticket', type='int'),
        Column('name'),
        Column('value')],
    Table('enum', key=('type', 'name'))[
        Column('type'),
        Column('name'),
        Column('value')],
    Table('component', key='name')[
        Column('name'),
        Column('owner'),
        Column('description')],
    Table('milestone', key='name')[
        Column('name'),
        Column('due', type='int'),
        Column('completed', type='int'),
        Column('description')],
    Table('version', key='name')[
        Column('name'),
        Column('time', type='int'),
        Column('description')],

    # Report system
    Table('report', key='id')[
        Column('id', auto_increment=True),
        Column('author'),
        Column('title'),
        Column('sql'),
        Column('description')],
]

##
## Default Reports
##

reports = (
('Active Tickets',
"""
 * List all active tickets by priority.
 * Color each row based on priority.
 * If a ticket has been accepted, a '*' is appended after the owner's name
""",
"""
SELECT p.value AS __color__,
   id AS ticket, summary, component, version, milestone, t.type AS type,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY p.value, milestone, t.type, time
"""),
#----------------------------------------------------------------------------
 ('Active Tickets by Version',
"""
This report shows how to color results by priority,
while grouping results by version.

Last modification time, description and reporter are included as hidden fields
for useful RSS export.
""",
"""
SELECT p.value AS __color__,
   version AS __group__,
   id AS ticket, summary, component, version, t.type AS type,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY (version IS NULL),version, p.value, t.type, time
"""),
#----------------------------------------------------------------------------
('All Tickets by Milestone',
"""
This report shows how to color results by priority,
while grouping results by milestone.

Last modification time, description and reporter are included as hidden fields
for useful RSS export.
""",
"""
SELECT p.value AS __color__,
   milestone||' Release' AS __group__,
   id AS ticket, summary, component, version, t.type AS type,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY (milestone IS NULL),milestone, p.value, t.type, time
"""),
#----------------------------------------------------------------------------
('Assigned, Active Tickets by Owner',
"""
List assigned tickets, group by ticket owner, sorted by priority.
""",
"""

SELECT p.value AS __color__,
   owner AS __group__,
   id AS ticket, summary, component, milestone, t.type AS type, time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t,enum p
  WHERE status = 'assigned'
AND p.name=t.priority AND p.type='priority'
  ORDER BY owner, p.value, t.type, time
"""),
#----------------------------------------------------------------------------
('Assigned, Active Tickets by Owner (Full Description)',
"""
List tickets assigned, group by ticket owner.
This report demonstrates the use of full-row display.
""",
"""
SELECT p.value AS __color__,
   owner AS __group__,
   id AS ticket, summary, component, milestone, t.type AS type, time AS created,
   description AS _description_,
   changetime AS _changetime, reporter AS _reporter
  FROM ticket t, enum p
  WHERE status = 'assigned'
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY owner, p.value, t.type, time
"""),
#----------------------------------------------------------------------------
('All Tickets By Milestone  (Including closed)',
"""
A more complex example to show how to make advanced reports.
""",
"""
SELECT p.value AS __color__,
   t.milestone AS __group__,
   (CASE status
      WHEN 'closed' THEN 'color: #777; background: #ddd; border-color: #ccc;'
      ELSE
        (CASE owner WHEN '$USER' THEN 'font-weight: bold' END)
    END) AS __style__,
   id AS ticket, summary, component, status,
   resolution,version, t.type AS type, priority, owner,
   changetime AS modified,
   time AS _time,reporter AS _reporter
  FROM ticket t,enum p
  WHERE p.name=t.priority AND p.type='priority'
  ORDER BY (milestone IS NULL), milestone DESC, (status = 'closed'),
        (CASE status WHEN 'closed' THEN modified ELSE (-1)*p.value END) DESC
"""),
#----------------------------------------------------------------------------
('My Tickets',
"""
This report demonstrates the use of the automatically set
$USER dynamic variable, replaced with the username of the
logged in user when executed.
""",
"""
SELECT p.value AS __color__,
   (CASE status WHEN 'assigned' THEN 'Assigned' ELSE 'Owned' END) AS __group__,
   id AS ticket, summary, component, version, milestone,
   t.type AS type, priority, time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE t.status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority' AND owner = '$USER'
  ORDER BY (status = 'assigned') DESC, p.value, milestone, t.type, time
"""),
#----------------------------------------------------------------------------
('Active Tickets, Mine first',
"""
 * List all active tickets by priority.
 * Show all tickets owned by the logged in user in a group first.
""",
"""
SELECT p.value AS __color__,
   (CASE owner
     WHEN '$USER' THEN 'My Tickets'
     ELSE 'Active Tickets'
    END) AS __group__,
   id AS ticket, summary, component, version, milestone, t.type AS type,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY (owner = '$USER') DESC, p.value, milestone, t.type, time
"""))

##
## Default database values
##

# (table, (column1, column2), ((row1col1, row1col2), (row2col1, row2col2)))
data = (('component',
             ('name', 'owner'),
               (('component1', 'somebody'),
                ('component2', 'somebody'))),
           ('milestone',
             ('name', 'due', 'completed'),
               (('milestone1', 0, 0),
                ('milestone2', 0, 0),
                ('milestone3', 0, 0),
                ('milestone4', 0, 0))),
           ('version',
             ('name', 'time'),
               (('1.0', 0),
                ('2.0', 0))),
           ('enum',
             ('type', 'name', 'value'),
               (('status', 'new', 1),
                ('status', 'assigned', 2),
                ('status', 'reopened', 3),
                ('status', 'closed', 4),
                ('resolution', 'fixed', 1),
                ('resolution', 'invalid', 2),
                ('resolution', 'wontfix', 3),
                ('resolution', 'duplicate', 4),
                ('resolution', 'worksforme', 5),
                ('priority', 'blocker', 1),
                ('priority', 'critical', 2),
                ('priority', 'major', 3),
                ('priority', 'minor', 4),
                ('priority', 'trivial', 5),
                ('ticket_type', 'defect', 1),
                ('ticket_type', 'enhancement', 2),
                ('ticket_type', 'task', 3))),
           ('permission',
             ('username', 'action'),
               (('anonymous', 'LOG_VIEW'),
                ('anonymous', 'FILE_VIEW'),
                ('anonymous', 'WIKI_VIEW'),
                ('anonymous', 'WIKI_CREATE'),
                ('anonymous', 'WIKI_MODIFY'),
                ('anonymous', 'SEARCH_VIEW'),
                ('anonymous', 'REPORT_VIEW'),
                ('anonymous', 'REPORT_SQL_VIEW'),
                ('anonymous', 'TICKET_VIEW'),
                ('anonymous', 'TICKET_CREATE'),
                ('anonymous', 'TICKET_MODIFY'),
                ('anonymous', 'BROWSER_VIEW'),
                ('anonymous', 'TIMELINE_VIEW'),
                ('anonymous', 'CHANGESET_VIEW'),
                ('anonymous', 'ROADMAP_VIEW'),
                ('anonymous', 'MILESTONE_VIEW'))),
           ('system',
             ('name', 'value'),
               (('database_version', str(db_version)),)),
           ('report',
             ('author', 'title', 'sql', 'description'),
               __mkreports(reports)))

default_components = ('trac.About', 'trac.attachment',
                      'trac.db.postgres_backend', 'trac.db.sqlite_backend',
                      'trac.mimeview.enscript', 'trac.mimeview.patch',
                      'trac.mimeview.php', 'trac.mimeview.rst',
                      'trac.mimeview.silvercity', 'trac.mimeview.txtl',
                      'trac.Search', 'trac.Settings',
                      'trac.ticket.query', 'trac.ticket.report',
                      'trac.ticket.roadmap', 'trac.ticket.web_ui',
                      'trac.Timeline',
                      'trac.versioncontrol.web_ui',
                      'trac.versioncontrol.svn_fs',
                      'trac.wiki.macros', 'trac.wiki.web_ui',
                      'trac.web.auth')
<commit_msg>Remove variable from report comment, which was causing #2894.<commit_after># -*- coding: utf-8 -*-
#
# Copyright (C) 2003-2005 Edgewall Software
# Copyright (C) 2003-2005 Daniel Lundin <daniel@edgewall.com>
# All rights reserved.
#
# This software is licensed as described in the file COPYING, which
# you should have received as part of this distribution. The terms
# are also available at http://trac.edgewall.com/license.html.
#
# This software consists of voluntary contributions made by many
# individuals. For the exact contribution history, see the revision
# history and logs, available at http://projects.edgewall.com/trac/.
#
# Author: Daniel Lundin <daniel@edgewall.com>

from trac.db import Table, Column, Index

# Database version identifier. Used for automatic upgrades.
db_version = 17

def __mkreports(reports):
    """Utility function used to create report data in same syntax as the
    default data. This extra step is done to simplify editing the default
    reports."""
    result = []
    for report in reports:
        result.append((None, report[0], report[2], report[1]))
    return result

##
## Database schema
##

schema = [
    # Common
    Table('system', key='name')[
        Column('name'),
        Column('value')],
    Table('permission', key=('username', 'action'))[
        Column('username'),
        Column('action')],
    Table('auth_cookie', key=('cookie', 'ipnr', 'name'))[
        Column('cookie'),
        Column('name'),
        Column('ipnr'),
        Column('time', type='int')],
    Table('session', key=('sid', 'authenticated', 'var_name'))[
        Column('sid'),
        Column('authenticated', type='int'),
        Column('var_name'),
        Column('var_value')],

    # Attachments
    Table('attachment', key=('type', 'id', 'filename'))[
        Column('type'),
        Column('id'),
        Column('filename'),
        Column('size', type='int'),
        Column('time', type='int'),
        Column('description'),
        Column('author'),
        Column('ipnr')],

    # Wiki system
    Table('wiki', key=('name', 'version'))[
        Column('name'),
        Column('version', type='int'),
        Column('time', type='int'),
        Column('author'),
        Column('ipnr'),
        Column('text'),
        Column('comment'),
        Column('readonly', type='int'),
        Index(['time'])],

    # Version control cache
    Table('revision', key='rev')[
        Column('rev'),
        Column('time', type='int'),
        Column('author'),
        Column('message'),
        Index(['time'])],
    Table('node_change', key=('rev', 'path', 'change_type'))[
        Column('rev'),
        Column('path'),
        Column('node_type', size=1),
        Column('change_type', size=1),
        Column('base_path'),
        Column('base_rev'),
        Index(['rev'])],

    # Ticket system
    Table('ticket', key='id')[
        Column('id', auto_increment=True),
        Column('type'),
        Column('time', type='int'),
        Column('changetime', type='int'),
        Column('component'),
        Column('severity'),
        Column('priority'),
        Column('owner'),
        Column('reporter'),
        Column('cc'),
        Column('version'),
        Column('milestone'),
        Column('status'),
        Column('resolution'),
        Column('summary'),
        Column('description'),
        Column('keywords'),
        Index(['time']),
        Index(['status'])],
    Table('ticket_change', key=('ticket', 'time', 'field'))[
        Column('ticket', type='int'),
        Column('time', type='int'),
        Column('author'),
        Column('field'),
        Column('oldvalue'),
        Column('newvalue'),
        Index(['ticket', 'time'])],
    Table('ticket_custom', key=('ticket', 'name'))[
        Column('ticket', type='int'),
        Column('name'),
        Column('value')],
    Table('enum', key=('type', 'name'))[
        Column('type'),
        Column('name'),
        Column('value')],
    Table('component', key='name')[
        Column('name'),
        Column('owner'),
        Column('description')],
    Table('milestone', key='name')[
        Column('name'),
        Column('due', type='int'),
        Column('completed', type='int'),
        Column('description')],
    Table('version', key='name')[
        Column('name'),
        Column('time', type='int'),
        Column('description')],

    # Report system
    Table('report', key='id')[
        Column('id', auto_increment=True),
        Column('author'),
        Column('title'),
        Column('sql'),
        Column('description')],
]

##
## Default Reports
##

reports = (
('Active Tickets',
"""
 * List all active tickets by priority.
 * Color each row based on priority.
 * If a ticket has been accepted, a '*' is appended after the owner's name
""",
"""
SELECT p.value AS __color__,
   id AS ticket, summary, component, version, milestone, t.type AS type,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY p.value, milestone, t.type, time
"""),
#----------------------------------------------------------------------------
 ('Active Tickets by Version',
"""
This report shows how to color results by priority,
while grouping results by version.

Last modification time, description and reporter are included as hidden fields
for useful RSS export.
""",
"""
SELECT p.value AS __color__,
   version AS __group__,
   id AS ticket, summary, component, version, t.type AS type,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY (version IS NULL),version, p.value, t.type, time
"""),
#----------------------------------------------------------------------------
('All Tickets by Milestone',
"""
This report shows how to color results by priority,
while grouping results by milestone.

Last modification time, description and reporter are included as hidden fields
for useful RSS export.
""",
"""
SELECT p.value AS __color__,
   milestone||' Release' AS __group__,
   id AS ticket, summary, component, version, t.type AS type,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY (milestone IS NULL),milestone, p.value, t.type, time
"""),
#----------------------------------------------------------------------------
('Assigned, Active Tickets by Owner',
"""
List assigned tickets, group by ticket owner, sorted by priority.
""",
"""

SELECT p.value AS __color__,
   owner AS __group__,
   id AS ticket, summary, component, milestone, t.type AS type, time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t,enum p
  WHERE status = 'assigned'
AND p.name=t.priority AND p.type='priority'
  ORDER BY owner, p.value, t.type, time
"""),
#----------------------------------------------------------------------------
('Assigned, Active Tickets by Owner (Full Description)',
"""
List tickets assigned, group by ticket owner.
This report demonstrates the use of full-row display.
""",
"""
SELECT p.value AS __color__,
   owner AS __group__,
   id AS ticket, summary, component, milestone, t.type AS type, time AS created,
   description AS _description_,
   changetime AS _changetime, reporter AS _reporter
  FROM ticket t, enum p
  WHERE status = 'assigned'
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY owner, p.value, t.type, time
"""),
#----------------------------------------------------------------------------
('All Tickets By Milestone  (Including closed)',
"""
A more complex example to show how to make advanced reports.
""",
"""
SELECT p.value AS __color__,
   t.milestone AS __group__,
   (CASE status
      WHEN 'closed' THEN 'color: #777; background: #ddd; border-color: #ccc;'
      ELSE
        (CASE owner WHEN '$USER' THEN 'font-weight: bold' END)
    END) AS __style__,
   id AS ticket, summary, component, status,
   resolution,version, t.type AS type, priority, owner,
   changetime AS modified,
   time AS _time,reporter AS _reporter
  FROM ticket t,enum p
  WHERE p.name=t.priority AND p.type='priority'
  ORDER BY (milestone IS NULL), milestone DESC, (status = 'closed'),
        (CASE status WHEN 'closed' THEN modified ELSE (-1)*p.value END) DESC
"""),
#----------------------------------------------------------------------------
('My Tickets',
"""
This report demonstrates the use of the automatically set
USER dynamic variable, replaced with the username of the
logged in user when executed.
""",
"""
SELECT p.value AS __color__,
   (CASE status WHEN 'assigned' THEN 'Assigned' ELSE 'Owned' END) AS __group__,
   id AS ticket, summary, component, version, milestone,
   t.type AS type, priority, time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE t.status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority' AND owner = '$USER'
  ORDER BY (status = 'assigned') DESC, p.value, milestone, t.type, time
"""),
#----------------------------------------------------------------------------
('Active Tickets, Mine first',
"""
 * List all active tickets by priority.
 * Show all tickets owned by the logged in user in a group first.
""",
"""
SELECT p.value AS __color__,
   (CASE owner
     WHEN '$USER' THEN 'My Tickets'
     ELSE 'Active Tickets'
    END) AS __group__,
   id AS ticket, summary, component, version, milestone, t.type AS type,
   (CASE status WHEN 'assigned' THEN owner||' *' ELSE owner END) AS owner,
   time AS created,
   changetime AS _changetime, description AS _description,
   reporter AS _reporter
  FROM ticket t, enum p
  WHERE status IN ('new', 'assigned', 'reopened')
AND p.name = t.priority AND p.type = 'priority'
  ORDER BY (owner = '$USER') DESC, p.value, milestone, t.type, time
"""))

##
## Default database values
##

# (table, (column1, column2), ((row1col1, row1col2), (row2col1, row2col2)))
data = (('component',
             ('name', 'owner'),
               (('component1', 'somebody'),
                ('component2', 'somebody'))),
           ('milestone',
             ('name', 'due', 'completed'),
               (('milestone1', 0, 0),
                ('milestone2', 0, 0),
                ('milestone3', 0, 0),
                ('milestone4', 0, 0))),
           ('version',
             ('name', 'time'),
               (('1.0', 0),
                ('2.0', 0))),
           ('enum',
             ('type', 'name', 'value'),
               (('status', 'new', 1),
                ('status', 'assigned', 2),
                ('status', 'reopened', 3),
                ('status', 'closed', 4),
                ('resolution', 'fixed', 1),
                ('resolution', 'invalid', 2),
                ('resolution', 'wontfix', 3),
                ('resolution', 'duplicate', 4),
                ('resolution', 'worksforme', 5),
                ('priority', 'blocker', 1),
                ('priority', 'critical', 2),
                ('priority', 'major', 3),
                ('priority', 'minor', 4),
                ('priority', 'trivial', 5),
                ('ticket_type', 'defect', 1),
                ('ticket_type', 'enhancement', 2),
                ('ticket_type', 'task', 3))),
           ('permission',
             ('username', 'action'),
               (('anonymous', 'LOG_VIEW'),
                ('anonymous', 'FILE_VIEW'),
                ('anonymous', 'WIKI_VIEW'),
                ('anonymous', 'WIKI_CREATE'),
                ('anonymous', 'WIKI_MODIFY'),
                ('anonymous', 'SEARCH_VIEW'),
                ('anonymous', 'REPORT_VIEW'),
                ('anonymous', 'REPORT_SQL_VIEW'),
                ('anonymous', 'TICKET_VIEW'),
                ('anonymous', 'TICKET_CREATE'),
                ('anonymous', 'TICKET_MODIFY'),
                ('anonymous', 'BROWSER_VIEW'),
                ('anonymous', 'TIMELINE_VIEW'),
                ('anonymous', 'CHANGESET_VIEW'),
                ('anonymous', 'ROADMAP_VIEW'),
                ('anonymous', 'MILESTONE_VIEW'))),
           ('system',
             ('name', 'value'),
               (('database_version', str(db_version)),)),
           ('report',
             ('author', 'title', 'sql', 'description'),
               __mkreports(reports)))

default_components = ('trac.About', 'trac.attachment',
                      'trac.db.postgres_backend', 'trac.db.sqlite_backend',
                      'trac.mimeview.enscript', 'trac.mimeview.patch',
                      'trac.mimeview.php', 'trac.mimeview.rst',
                      'trac.mimeview.silvercity', 'trac.mimeview.txtl',
                      'trac.Search', 'trac.Settings',
                      'trac.ticket.query', 'trac.ticket.report',
                      'trac.ticket.roadmap', 'trac.ticket.web_ui',
                      'trac.Timeline',
                      'trac.versioncontrol.web_ui',
                      'trac.versioncontrol.svn_fs',
                      'trac.wiki.macros', 'trac.wiki.web_ui',
                      'trac.web.auth')
<|endoftext|>