<commit_before>import os
import re
import sys
import string
import subprocess
import textwrap
import time
from os.path import basename, getmtime, isdir, isfile, join

import egginst
from egginst.utils import bin_dir_name, rel_site_packages, pprint_fn_action

import config
from utils import canonical, cname_fn, get_info
from indexed_repo import (filename_dist, Chain, Req, add_Reqs_to_spec,
                          spec_as_req, parse_data)

# global options variables
prefix = None
dry_run = None
noapp = None
verbose = None

def print_path():
    prefixes = [sys.prefix]
    if prefix != sys.prefix:
        prefixes.insert(0, prefix)
    print "Prefixes:"
    for p in prefixes:
        print '    %s%s' % (p, ['', ' (sys)'][p == sys.prefix])
    print

    if sys.platform == 'win32':
        cmd = 'set'
    else:
        cmd = 'export'

    print "%s PATH=%s" % (cmd, os.pathsep.join(
                                 join(p, bin_dir_name) for p in prefixes))
    if prefix != sys.prefix:
        print "%s PYTHONPATH=%s" % (cmd, join(prefix, rel_site_packages))

    if sys.platform != 'win32':
        if sys.platform == 'darwin':
            name = 'DYLD_LIBRARY_PATH'
        else:
            name = 'LD_LIBRARY_PATH'
        print "%s %s=%s" % (cmd, name, os.pathsep.join(
                                 join(p, 'lib') for p in prefixes))

def list_option(pat):
    print "sys.prefix:", sys.prefix
    egginst.print_installed(sys.prefix, pat)
    if prefix == sys.prefix:
        return
    print
    print "prefix:", prefix
    egginst.print_installed(prefix, pat)

def egginst_subprocess(pkg_path, remove):
    # only used on Windows
    path = join(sys.prefix, bin_dir_name, 'egginst-script.py')
    args = [sys.executable, path, '--prefix', prefix]
    if dry_run:
        args.append('--dry-run')
    if remove:
        args.append('--remove')
    if noapp:
        args.append('--noapp')
    args.append(pkg_path)
    if verbose:
        print 'CALL: %r' % args
    subprocess.call(args)

def call_egginst(pkg_path, remove=False):
    fn = basename(pkg_path)
    if sys.platform == 'win32' and fn.startswith(('AppInst-', 'pywin32-')):
        print "Starting subprocess:"
        egginst_subprocess(pkg_path, remove)
        return

    pprint_fn_action(fn, 'removing' if remove else 'installing')
    if dry_run:
        return

    ei = egginst.EggInst(pkg_path, prefix, noapp=noapp)
    if remove:
        ei.remove()
    else:
        ei.install()

def check_write():
    if not isdir(prefix):
        os.makedirs(prefix)
    path = join(prefix, 'hello.txt')
    try:
        open(path, 'w').write('Hello World!\n')
    except:
        print "ERROR: Could not write simple file into:", prefix
        sys.exit(1)
    finally:
        if isfile(path):
            os.unlink(path)

def get_installed_version(prefix, cname):
    egg_info_dir = join(prefix, 'EGG-INFO')
    if not isdir(egg_info_dir):
        return
    for fn in os.listdir(egg_info_dir):
        if canonical(fn) != cname:
            continue
        meta_txt = join(egg_info_dir, fn, '__egginst__.txt')
        if not isfile(meta_txt):
            continue
        d = {}
        execfile(meta_txt, d)
        if cname_fn(d['egg_name']) == cname and '-' in d['egg_name']:
            return d['egg_name'][:-4].split('-', 1)[1]

def info_option(url, c, cname):
    print "Canonic.:", cname
    if url:
        info = get_info(url)
        if cname in info:
            spec = info[cname]
            print "Name    :", spec['name']
            print "License :", spec['license']
            for line in textwrap.wrap(' '.join(spec['description'].split()), 77):
                print line
        else:
            print "No information about %r in %r" % (cname, url)
    else:
        print "No 'info_url' in .enstaller4rc"
    print
    print "In repositories:"
    req = Req(cname)
    for repo in c.repos:
        if c.get_matches_repo(req, repo):
            print '    %s' % repo
    print

    dist = c.get_dist(Req(cname))
    if dist:
        reqs = set(r.name for r in c.reqs_dist(dist))
        print "Requirements: %s" % ', '.join(reqs)

    print "Available versions: %s" % ', '.join(c.list_versions(cname))
    print "sys.prefix = %r" % sys.prefix
    print "Installed: %s" % get_installed_version(sys.prefix, cname)
    if prefix == sys.prefix:
        return
    print "prefix = %r" % prefix
    print "Installed (prefix): %s" % get_installed_version(prefix, cname)

def search(c, pat=None):
    """
    Print the distributions available in a repo, i.e. a "virtual" repo made
    of a chain of (indexed) repos.
    """
    fmt = "%-20s %s"
    print fmt % ('Project name', 'Versions')
    print 40 * '-'

    names = set(spec['name'] for spec in c.index.itervalues())
    for name in sorted(names, key=string.lower):
        if pat and not pat.search(name):
            continue
        versions = c.list_versions(name)
        if versions:
            print fmt % (name, ', '.join(versions))

def read_depend_files():
    """
    Returns a dictionary mapping canonical project names to the spec
    dictionaries of the installed packages.
    """
    egg_info_dir = join(prefix, 'EGG-INFO')
    if not isdir(egg_info_dir):
        return {}
    res = {}
    for name in os.listdir(egg_info_dir):
        path = join(egg_info_dir, name, 'spec', 'depend')
        if isfile(path):
            spec = parse_data(open(path).read())
            add_Reqs_to_spec(spec)
            res[spec['cname']] = spec
    return res

def depend_warn(pkgs, ignore_version=False):
    """
    Warns the user about packages to be changed (i.e. removed or updated),
    if other packages depend on the package.

    Warnings are printed when the required name of the package matches.
    The ignore_version option determines if a version comparison is also
    desired as well, which it is not for the --remove option, since when
    a package is removed it does not matter which version is required.
    Hence, in remove_req() this function is called with ignore_version=True.
    """
    names = {}
    for pkg in pkgs:
        names[cname_fn(pkg)] = pkg
    index = read_depend_files()
    for spec in index.itervalues():
        if spec['cname'] in names:
            continue
        for req in spec["Reqs"]:
            if req.name not in names:
                continue
            if (ignore_version or
                     (req.version and
                      req.version != names[req.name].split('-')[1])):
                print "Warning: %s depends on %s" % (spec_as_req(spec), req)

def remove_req(req):
    """
    Tries remove a package from prefix given a requirement object.
    This function is only used for the --remove option.
    """
    for fn in egginst.get_installed(prefix):
        if req.name != cname_fn(fn):
            continue
        pkg = fn[:-4]
        if req.version:
            v_a, b_a = pkg.split('-')[1:3]
            if req.version != v_a or (req.build and req.build != int(b_a)):
                print("Version mismatch: %s is installed cannot remove %s." %
                      (pkg, req))
                return
        break
    else:
        print "Package %r does not seem to be installed." % req.name
        return
    depend_warn([pkg], ignore_version=True)
    call_egginst(pkg, remove=True)

def get_mtime_req(req):
    egg_info_dirs = [join(prefix, 'EGG-INFO')]
    if prefix != sys.prefix:
        egg_info_dirs.append(join(sys.prefix, 'EGG-INFO'))

    for egg_info_dir in egg_info_dirs:
        if isdir(egg_info_dir):
            for fn in os.listdir(egg_info_dir):
                if canonical(fn) == req.name:
                    return getmtime(join(egg_info_dir, fn))

def print_uptodate_req(req):
    """
    Prints the "up-to-date message" for the required package.
    """
    print "No update necessary, %s is up-to-date." % req
    mtime = get_mtime_req(req)
    if mtime is None:
        print "Hmm, could not determine mtime of %r" % req
    else:
        print "%s was installed/updated on: %s" % (req, time.ctime(mtime))

def get_dists(c, req, recur):
    """
    Resolves the requirement
    """
    dists = c.install_order(req, recur=recur)
    if dists is None:
        print "No distribution found for requirement '%s'." % req
        versions = c.list_versions(req.name)
        if versions:
            print "Versions for package %r are: %s" % (req.name,
                                                       ', '.join(versions))
        else:
            print
            print "You may want to run: easy_install %s" % req.name
        sys.exit(1)

    if verbose:
        print "Distributions in install order:"
        for d in dists:
            print '    ', d
    return dists

def iter_dists_excl(dists, exclude_fn):
    """
    Iterates over all dists, excluding the ones whose filename is an element
    of exclude_fn.  Yields both the distribution and filename.
    """
    for dist in dists:
        fn = filename_dist(dist)
        if fn in exclude_fn:
            continue
        yield dist, fn

def main():
    from optparse import OptionParser

    p = OptionParser(
        usage="usage: %prog [options] [name] [version]",
        description=("download and install eggs ..."))

    p.add_option("--config",
                 action="store_true",
                 help="display the configuration and exit")

    p.add_option('-f', "--force",
                 action="store_true",
                 help="force install the main package "
                      "(not it's dependencies, see --forceall)")

    p.add_option("--forceall",
                 action="store_true",
                 help="force install of all packages "
                      "(i.e. including dependencies)")

    p.add_option('-i', "--info",
                 action="store_true",
                 help="show information about package(s)")

    p.add_option('-l', "--list",
                 action="store_true",
                 help="list the packages currently installed on the system")

    p.add_option('-n', "--dry-run",
                 action="store_true",
                 help="show what would have been downloaded/removed/installed")

    p.add_option('-N', "--no-deps",
                 action="store_true",
                 help="neither download nor install dependencies")

    p.add_option("--path",
                 action="store_true",
                 help="based on the configuration, display how to set the "
                      "PATH and PYTHONPATH environment variables")

    p.add_option("--prefix",
                 action="store",
                 help="install prefix (disregarding of any settings in "
                      "the config file)",
                 metavar='PATH')

    p.add_option("--proxy",
                 action="store",
                 help="use a proxy for downloads",
                 metavar='URL')

    p.add_option("--remove",
                 action="store_true",
                 help="remove a package")

    p.add_option('-s', "--search",
                 action="store_true",
                 help="search the index in the repo (chain) of packages "
                      "and display versions available.")

    p.add_option("--sys-prefix",
                 action="store_true",
                 help="use sys.prefix as the install prefix")

    p.add_option('-v', "--verbose", action="store_true")

    p.add_option('--version', action="store_true")

    opts, args = p.parse_args()

    if len(args) > 0 and (opts.config or opts.path):
        p.error("Option takes no arguments")

    if opts.prefix and opts.sys_prefix:
        p.error("Options --prefix and --sys-prefix exclude each ohter")

    if opts.force and opts.forceall:
        p.error("Options --force and --forceall exclude each ohter")

    pat = None
    if (opts.list or opts.search) and args:
        pat = re.compile(args[0], re.I)

    if opts.version:                              #  --version
        from enstaller import __version__
        print "Enstaller version:", __version__
        return

    if opts.config:                               #  --config
        config.print_config()
        return

    if opts.proxy:                                #  --proxy
        from proxy.api import setup_proxy
        setup_proxy(opts.proxy)

    if config.get_path() is None:
        # create config file if it dosn't exist
        config.write(opts.proxy)

    conf = config.read()                          #  conf

    if (not opts.proxy) and conf['proxy']:
        from proxy.api import setup_proxy
        setup_proxy(conf['proxy'])

    global prefix, dry_run, noapp, version        #  set globals
    if opts.sys_prefix:
        prefix = sys.prefix
    elif opts.prefix:
        prefix = opts.prefix
    else:
        prefix = conf['prefix']
    dry_run = opts.dry_run
    noapp = conf['noapp']
    version = opts.version

    if opts.path:                                 #  --path
        print_path()
        return

    if opts.list:                                 #  --list
        list_option(pat)
        return

    c = Chain(conf['IndexedRepos'], verbose)      #  init chain

    if opts.search:                               #  --search
        search(c, pat)
        return

    if opts.info:                                 #  --info
        if len(args) != 1:
            p.error("Option requires one argument (the name)")
        info_option(conf['info_url'], c, canonical(args[0]))
        return

    if len(args) == 0:
        p.error("Requirement (name and optional version) missing")
    if len(args) > 2:
        p.error("A requirement is a name and an optional version")
    req = Req(' '.join(args))

    print "prefix:", prefix
    check_write()
    if opts.remove:                               #  --remove
        remove_req(req)
        return

    dists = get_dists(c, req,                     #  dists
                      recur=not opts.no_deps)

    # Warn the user about packages which depend on what will be updated
    depend_warn([filename_dist(d) for d in dists])

    # Packages which are installed currently
    sys_inst = set(egginst.get_installed(sys.prefix))
    if prefix == sys.prefix:
        prefix_inst = sys_inst
    else:
        prefix_inst = set(egginst.get_installed(prefix))
    all_inst = sys_inst | prefix_inst

    # These are the packahes which are being excluded from being installed
    if opts.forceall:
        exclude = set()
    else:
        exclude = all_inst
        if opts.force:
            exclude.discard(filename_dist(dists[-1]))

    # Fetch distributions
    if not isdir(conf['local']):
        os.makedirs(conf['local'])
    for dist, fn in iter_dists_excl(dists, exclude):
        c.fetch_dist(dist, conf['local'],
                     check_md5=opts.force or opts.forceall,
                     dry_run=dry_run)

    # Remove packages (in reverse install order)
    for dist in dists[::-1]:
        fn = filename_dist(dist)
        if fn in all_inst:
            # if the distribution (which needs to be installed) is already
            # installed don't remove it
            continue
        cname = cname_fn(fn)
        # Only remove packages installed in prefix
        for fn_inst in prefix_inst:
            if cname == cname_fn(fn_inst):
                call_egginst(fn_inst, remove=True)

    # Install packages
    installed_something = False
    for dist, fn in iter_dists_excl(dists, exclude):
        installed_something = True
        call_egginst(join(conf['local'], fn))

    if not installed_something:
        print_uptodate_req(req)

if __name__ == '__main__':
    main()
<commit_msg>simplified how information about installed package is optained<commit_after>import os
import re
import sys
import string
import subprocess
import textwrap
import time
from os.path import basename, getmtime, isdir, isfile, join

import egginst
from egginst.utils import bin_dir_name, rel_site_packages, pprint_fn_action

import config
from utils import canonical, cname_fn, get_info
from indexed_repo import (filename_dist, Chain, Req, add_Reqs_to_spec,
                          spec_as_req, parse_data)

# global options variables
prefix = None
dry_run = None
noapp = None
verbose = None

def print_path():
    prefixes = [sys.prefix]
    if prefix != sys.prefix:
        prefixes.insert(0, prefix)
    print "Prefixes:"
    for p in prefixes:
        print '    %s%s' % (p, ['', ' (sys)'][p == sys.prefix])
    print

    if sys.platform == 'win32':
        cmd = 'set'
    else:
        cmd = 'export'

    print "%s PATH=%s" % (cmd, os.pathsep.join(
                                 join(p, bin_dir_name) for p in prefixes))
    if prefix != sys.prefix:
        print "%s PYTHONPATH=%s" % (cmd, join(prefix, rel_site_packages))

    if sys.platform != 'win32':
        if sys.platform == 'darwin':
            name = 'DYLD_LIBRARY_PATH'
        else:
            name = 'LD_LIBRARY_PATH'
        print "%s %s=%s" % (cmd, name, os.pathsep.join(
                                 join(p, 'lib') for p in prefixes))

def list_option(pat):
    print "sys.prefix:", sys.prefix
    egginst.print_installed(sys.prefix, pat)
    if prefix == sys.prefix:
        return
    print
    print "prefix:", prefix
    egginst.print_installed(prefix, pat)

def egginst_subprocess(pkg_path, remove):
    # only used on Windows
    path = join(sys.prefix, bin_dir_name, 'egginst-script.py')
    args = [sys.executable, path, '--prefix', prefix]
    if dry_run:
        args.append('--dry-run')
    if remove:
        args.append('--remove')
    if noapp:
        args.append('--noapp')
    args.append(pkg_path)
    if verbose:
        print 'CALL: %r' % args
    subprocess.call(args)

def call_egginst(pkg_path, remove=False):
    fn = basename(pkg_path)
    if sys.platform == 'win32' and fn.startswith(('AppInst-', 'pywin32-')):
        print "Starting subprocess:"
        egginst_subprocess(pkg_path, remove)
        return

    pprint_fn_action(fn, 'removing' if remove else 'installing')
    if dry_run:
        return

    ei = egginst.EggInst(pkg_path, prefix, noapp=noapp)
    if remove:
        ei.remove()
    else:
        ei.install()

def check_write():
    if not isdir(prefix):
        os.makedirs(prefix)
    path = join(prefix, 'hello.txt')
    try:
        open(path, 'w').write('Hello World!\n')
    except:
        print "ERROR: Could not write simple file into:", prefix
        sys.exit(1)
    finally:
        if isfile(path):
            os.unlink(path)

def get_installed_info(prefix, cname):
    """
    Returns a tuple(eggname, mtime) of the package specified by the
    canonical name found in prefix, or None if the package is not found.
    """
    egg_info_dir = join(prefix, 'EGG-INFO')
    if not isdir(egg_info_dir):
        return None
    for fn in os.listdir(egg_info_dir):
        if canonical(fn) != cname:
            continue
        meta_txt = join(egg_info_dir, fn, '__egginst__.txt')
        if not isfile(meta_txt):
            continue
        d = {}
        execfile(meta_txt, d)
        if cname_fn(d['egg_name']) == cname:
            return d['egg_name'], getmtime(meta_txt)
    return None

def print_installed_info(cname):
    info = get_installed_info(prefix, cname)
    if info is None:
        print "%s is not installed" % cname
    else:
        eggname, mtime = info
        print "%s was installed on: %s" % (eggname, time.ctime(mtime))

    if prefix == sys.prefix:
        return

    info = get_installed_info(sys.prefix, cname)
    if info is None:
        print "%s is not installed in sys.prefix" % cname
    else:
        eggname, mtime = info
        print "%s was installed in sys.prefix on: %s" % (eggname,
                                                         time.ctime(mtime))

def info_option(url, c, cname):
    print "Canonic.:", cname
    if url:
        info = get_info(url)
        if cname in info:
            spec = info[cname]
            print "Name    :", spec['name']
            print "License :", spec['license']
            for line in textwrap.wrap(' '.join(spec['description'].split()),
                                      77):
                print line
        else:
            print "No information about %r in %r" % (cname, url)
    else:
        print "No 'info_url' in .enstaller4rc"
    print
    print "In repositories:"
    req = Req(cname)
    for repo in c.repos:
        if c.get_matches_repo(req, repo):
            print '    %s' % repo
    print

    dist = c.get_dist(Req(cname))
    if dist:
        reqs = set(r.name for r in c.reqs_dist(dist))
        print "Requirements: %s" % ', '.join(reqs)

    print "Available versions: %s" % ', '.join(c.list_versions(cname))
    print_installed_info(cname)

def search(c, pat=None):
    """
    Print the distributions available in a repo, i.e. a "virtual" repo made
    of a chain of (indexed) repos.
    """
    fmt = "%-20s %s"
    print fmt % ('Project name', 'Versions')
    print 40 * '-'

    names = set(spec['name'] for spec in c.index.itervalues())
    for name in sorted(names, key=string.lower):
        if pat and not pat.search(name):
            continue
        versions = c.list_versions(name)
        if versions:
            print fmt % (name, ', '.join(versions))

def read_depend_files():
    """
    Returns a dictionary mapping canonical project names to the spec
    dictionaries of the installed packages.
    """
    egg_info_dir = join(prefix, 'EGG-INFO')
    if not isdir(egg_info_dir):
        return {}
    res = {}
    for name in os.listdir(egg_info_dir):
        path = join(egg_info_dir, name, 'spec', 'depend')
        if isfile(path):
            spec = parse_data(open(path).read())
            add_Reqs_to_spec(spec)
            res[spec['cname']] = spec
    return res

def depend_warn(pkgs, ignore_version=False):
    """
    Warns the user about packages to be changed (i.e. removed or updated),
    if other packages depend on the package.

    Warnings are printed when the required name of the package matches.
    The ignore_version option determines if a version comparison is also
    desired as well, which it is not for the --remove option, since when
    a package is removed it does not matter which version is required.
    Hence, in remove_req() this function is called with ignore_version=True.
    """
    names = {}
    for pkg in pkgs:
        names[cname_fn(pkg)] = pkg
    index = read_depend_files()
    for spec in index.itervalues():
        if spec['cname'] in names:
            continue
        for req in spec["Reqs"]:
            if req.name not in names:
                continue
            if (ignore_version or
                     (req.version and
                      req.version != names[req.name].split('-')[1])):
                print "Warning: %s depends on %s" % (spec_as_req(spec), req)

def remove_req(req):
    """
    Tries remove a package from prefix given a requirement object.
    This function is only used for the --remove option.
    """
    for fn in egginst.get_installed(prefix):
        if req.name != cname_fn(fn):
            continue
        pkg = fn[:-4]
        if req.version:
            v_a, b_a = pkg.split('-')[1:3]
            if req.version != v_a or (req.build and req.build != int(b_a)):
                print("Version mismatch: %s is installed cannot remove %s." %
                      (pkg, req))
                return
        break
    else:
        print "Package %r does not seem to be installed." % req.name
        return
    depend_warn([pkg], ignore_version=True)
    call_egginst(pkg, remove=True)

def get_dists(c, req, recur):
    """
    Resolves the requirement
    """
    dists = c.install_order(req, recur=recur)
    if dists is None:
        print "No distribution found for requirement '%s'." % req
        versions = c.list_versions(req.name)
        if versions:
            print "Versions for package %r are: %s" % (req.name,
                                                       ', '.join(versions))
        else:
            print
            print "You may want to run: easy_install %s" % req.name
        sys.exit(1)

    if verbose:
        print "Distributions in install order:"
        for d in dists:
            print '    ', d
    return dists

def iter_dists_excl(dists, exclude_fn):
    """
    Iterates over all dists, excluding the ones whose filename is an element
    of exclude_fn.  Yields both the distribution and filename.
    """
    for dist in dists:
        fn = filename_dist(dist)
        if fn in exclude_fn:
            continue
        yield dist, fn

def main():
    from optparse import OptionParser

    p = OptionParser(
        usage="usage: %prog [options] [name] [version]",
        description=("download and install eggs ..."))

    p.add_option("--config",
                 action="store_true",
                 help="display the configuration and exit")

    p.add_option('-f', "--force",
                 action="store_true",
                 help="force install the main package "
                      "(not it's dependencies, see --forceall)")

    p.add_option("--forceall",
                 action="store_true",
                 help="force install of all packages "
                      "(i.e. including dependencies)")

    p.add_option('-i', "--info",
                 action="store_true",
                 help="show information about package(s)")

    p.add_option('-l', "--list",
                 action="store_true",
                 help="list the packages currently installed on the system")

    p.add_option('-n', "--dry-run",
                 action="store_true",
                 help="show what would have been downloaded/removed/installed")

    p.add_option('-N', "--no-deps",
                 action="store_true",
                 help="neither download nor install dependencies")

    p.add_option("--path",
                 action="store_true",
                 help="based on the configuration, display how to set the "
                      "PATH and PYTHONPATH environment variables")

    p.add_option("--prefix",
                 action="store",
                 help="install prefix (disregarding of any settings in "
                      "the config file)",
                 metavar='PATH')

    p.add_option("--proxy",
                 action="store",
                 help="use a proxy for downloads",
                 metavar='URL')

    p.add_option("--remove",
                 action="store_true",
                 help="remove a package")

    p.add_option('-s', "--search",
                 action="store_true",
                 help="search the index in the repo (chain) of packages "
                      "and display versions available.")

    p.add_option("--sys-prefix",
                 action="store_true",
                 help="use sys.prefix as the install prefix")

    p.add_option('-v', "--verbose", action="store_true")

    p.add_option('--version', action="store_true")

    opts, args = p.parse_args()

    if len(args) > 0 and (opts.config or opts.path):
        p.error("Option takes no arguments")

    if opts.prefix and opts.sys_prefix:
        p.error("Options --prefix and --sys-prefix exclude each ohter")

    if opts.force and opts.forceall:
        p.error("Options --force and --forceall exclude each ohter")

    pat = None
    if (opts.list or opts.search) and args:
        pat = re.compile(args[0], re.I)

    if opts.version:                              #  --version
        from enstaller import __version__
        print "Enstaller version:", __version__
        return

    if opts.config:                               #  --config
        config.print_config()
        return

    if opts.proxy:                                #  --proxy
        from proxy.api import setup_proxy
        setup_proxy(opts.proxy)

    if config.get_path() is None:
        # create config file if it dosn't exist
        config.write(opts.proxy)

    conf = config.read()                          #  conf

    if (not opts.proxy) and conf['proxy']:
        from proxy.api import setup_proxy
        setup_proxy(conf['proxy'])

    global prefix, dry_run, noapp, version        #  set globals
    if opts.sys_prefix:
        prefix = sys.prefix
    elif opts.prefix:
        prefix = opts.prefix
    else:
        prefix = conf['prefix']
    dry_run = opts.dry_run
    noapp = conf['noapp']
    version = opts.version

    if opts.path:                                 #  --path
        print_path()
        return

    if opts.list:                                 #  --list
        list_option(pat)
        return

    c = Chain(conf['IndexedRepos'], verbose)      #  init chain

    if opts.search:                               #  --search
        search(c, pat)
        return

    if len(args) == 0:
        p.error("Requirement (name and optional version) missing")
    if len(args) > 2:
        p.error("A requirement is a name and an optional version")
    req = Req(' '.join(args))

    if opts.info:                                 #  --info
        if len(args) != 1:
            p.error("Option requires one argument (the name)")
        info_option(conf['info_url'], c, req.name)
        return

    print "prefix:", prefix
    check_write()
    if opts.remove:                               #  --remove
        remove_req(req)
        return

    dists = get_dists(c, req,                     #  dists
                      recur=not opts.no_deps)

    # Warn the user about packages which depend on what will be updated
    depend_warn([filename_dist(d) for d in dists])

    # Packages which are installed currently
    sys_inst = set(egginst.get_installed(sys.prefix))
    if prefix == sys.prefix:
        prefix_inst = sys_inst
    else:
        prefix_inst = set(egginst.get_installed(prefix))
    all_inst = sys_inst | prefix_inst

    # These are the packahes which are being excluded from being installed
    if opts.forceall:
        exclude = set()
    else:
        exclude = all_inst
        if opts.force:
            exclude.discard(filename_dist(dists[-1]))

    # Fetch distributions
    if not isdir(conf['local']):
        os.makedirs(conf['local'])
    for dist, fn in iter_dists_excl(dists, exclude):
        c.fetch_dist(dist, conf['local'],
                     check_md5=opts.force or opts.forceall,
                     dry_run=dry_run)

    # Remove packages (in reverse install order)
    for dist in dists[::-1]:
        fn = filename_dist(dist)
        if fn in all_inst:
            # if the distribution (which needs to be installed) is already
            # installed don't remove it
            continue
        cname = cname_fn(fn)
        # Only remove packages installed in prefix
        for fn_inst in prefix_inst:
            if cname == cname_fn(fn_inst):
                call_egginst(fn_inst, remove=True)

    # Install packages
    installed_something = False
    for dist, fn in iter_dists_excl(dists, exclude):
        installed_something = True
        call_egginst(join(conf['local'], fn))

    if not installed_something:
        print "No update necessary, %s is up-to-date." % req
        print_installed_info(req.name)

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


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

from __future__ import division

from ...base import *  # noqa analysis:ignore

from numpy import maximum as max_, round as round_, minimum as min_, logical_not as not_, where, select

class ppa_eligibilite(Variable):
    column = BoolCol
    entity_class = Familles
    label = u"Eligibilité à la PPA pour un mois"

    def function(self, simulation, period):
        period = period.this_month
        P = simulation.legislation_at(period.start)
        age_min = P.minim.ppa.age_min
        condition_age_individus = simulation.calculate('age', period) >= age_min
        condition_age = self.any_by_roles(condition_age_individus)
        elig = condition_age

        return period, elig

class ppa_montant_forfaitaire_familial_non_majore(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Montant forfaitaire familial (sans majoration)"

    def function(self, simulation, period):
        period = period.this_month
        nb_parents = simulation.calculate('nb_par', period)
        nb_enfants = simulation.calculate('nb_enfant_rsa', period)
        ppa_majoree_eligibilite = simulation.calculate('rsa_majore_eligibilite', period)
        rmi = simulation.legislation_at(period.start).minim.rmi
        nb_personnes = nb_parents + nb_enfants

        taux_non_majore = (
            1 +
            (nb_personnes >= 2) * rmi.txp2 +
            (nb_personnes >= 3) * rmi.txp3 +
            (nb_personnes >= 4) * where(nb_parents == 1, rmi.txps, rmi.txp3) + # Si nb_par == 1, pas de conjoint, la 4e personne est un enfant, donc le taux est de 40%.
            max_(nb_personnes - 4, 0) * rmi.txps
            )

        return period, rmi.rmi * taux_non_majore

class ppa_montant_forfaitaire_familial_majore(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Montant forfaitaire familial (avec majoration)"

    def function(self, simulation, period):
        nb_enfants = simulation.calculate('nb_enfant_rsa', period)
        rmi = simulation.legislation_at(period.start).minim.rmi
        taux_majore = rmi.majo_rsa.pac0 + rmi.majo_rsa.pac_enf_sup * nb_enfants

        return period, rmi.rmi * taux_majore

class ppa_revenu_activite(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Revenu d'activité pris en compte pour la PPA"

    def function(self, simulation, period):
        period = period.this_month
        ppa_revenu_activite_individus = simulation.compute('ppa_revenu_activite_i', period)
        ppa_revenu_activite = self.sum_by_entity(ppa_revenu_activite_individus)

        return period, ppa_revenu_activite

class ppa_revenu_activite_i(Variable):
    column = FloatCol
    entity_class = Individus
    label = u"Revenu d'activité pris en compte pour la PPA (Individus) pour un mois"

    def function(self, simulation, period):
        period = period.this_month
        ressources = [
            'salaire_net',
            'revenus_stage_formation_pro',
            'bourse_recherche',
            'indemnites_chomage_partiel',
            'indemnites_journalieres',
            'tns_auto_entrepreneur_benefice',
            ]

        revenus_mensualises = sum(
            simulation.calculate(ressource, period) for ressource in ressources)

        def get_last_known(variable_name):
            valeur_n = simulation.calculate(variable_name, period.this_year)
            valeur_n_1 = simulation.calculate(variable_name, period.last_year)
            valeur_n_2 = simulation.calculate(variable_name, period.n_2)
            return select(
                [valeur_n > 0, valeur_n_1 > 0, valeur_n_2 > 0],
                [valeur_n, valeur_n_1, valeur_n_2]
                ) / 12
        revenus_annualises = get_last_known('tns_benefice_exploitant_agricole') + get_last_known('tns_autres_revenus') + get_last_known('tns_micro_entreprise_benefice')

        return period, revenus_mensualises + revenus_annualises

class ppa_ressources_hors_activite(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Revenu hors activité pris en compte pour la PPA"

    def function(self, simulation, period, reference_period):
        pf = simulation.calculate('ppa_base_ressources_prestations_familiales', period, extra_params = [reference_period])
        ressources_hors_activite_individus = simulation.compute('ppa_ressources_hors_activite_i', period)
        ressources_hors_activite = self.sum_by_entity(ressources_hors_activite_individus) + pf

        return period, ressources_hors_activite

class ppa_ressources_hors_activite_i(Variable):
    column = FloatCol
    entity_class = Individus
    label = u"Revenu hors activité pris en compte pour la PPA (Individus) pour un mois"

    def function(self, simulation, period):
        period = period.this_month

        ressources = [
            'aah',
            'chomage_net',
            'retraite_nette',
            'retraite_combattant',
            'pensions_alimentaires_percues',
            'prestation_compensatoire',
            'revenus_locatifs',
            ]

        ressources_hors_activite_i = sum(
            simulation.calculate(ressource, period) for ressource in ressources)

        return period, ressources_hors_activite_i

class ppa_base_ressources_prestations_familiales(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Prestations familiales prises en compte dans le calcul de la PPA"

    def function(self, simulation, period, reference_period):
        period = period.this_month

        prestations_calculees = [
            'af_base',
            'rsa_forfait_asf',
            'paje_base',
           ]
        prestations_autres = [
            'paje_clca',
            'paje_prepare',
            'paje_colca',
            ]

        result = sum(simulation.calculate(prestation, reference_period) for prestation in prestations_calculees)
        result += sum(simulation.calculate(prestation, period) for prestation in prestations_autres)
        cf_non_majore_avant_cumul = simulation.calculate('cf_non_majore_avant_cumul', reference_period)
        cf = simulation.calculate('cf', reference_period)
        # Seul le montant non majoré est pris en compte dans la base de ressources du RSA
        cf_non_majore = (cf > 0) * cf_non_majore_avant_cumul
        result = result + cf_non_majore

        return period, result

class ppa_base_ressources(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Bases ressource prise en compte pour la PPA"

    def function(self, simulation, period, reference_period):
        period = period.this_month
        ppa_revenu_activite = simulation.calculate('ppa_revenu_activite', period)
        ppa_ressources_hors_activite = simulation.calculate('ppa_ressources_hors_activite', period, extra_params = [reference_period])
        return period, ppa_revenu_activite + ppa_ressources_hors_activite

class ppa_bonification(Variable):
    column = FloatCol
    entity_class = Individus
    label = u"Bonification de la PPA pour un individu"

    def function(self, simulation, period):
        period = period.this_month
        P = simulation.legislation_at(period.start)
        smic_horaire = P.cotsoc.gen.smic_h_b
        rsa_base = P.minim.rmi.rmi
        revenu_activite = simulation.calculate('ppa_revenu_activite_i', period)
        seuil_1 = P.minim.ppa.bonification.seuil_1 * smic_horaire
        seuil_2 = P.minim.ppa.bonification.seuil_2 * smic_horaire
        bonification_max = round_(P.minim.ppa.bonification.montant_max * rsa_base)

        bonification = bonification_max * (revenu_activite - seuil_1) / (seuil_2 - seuil_1)
        bonification = max_(bonification, 0)
        bonification = min_(bonification, bonification_max)

        return period, bonification

<commit_msg>Introduce ppa_fictive<commit_after># -*- coding: utf-8 -*-

from __future__ import division

from ...base import *  # noqa analysis:ignore

from numpy import maximum as max_, round as round_, minimum as min_, logical_not as not_, where, select

class ppa_eligibilite(Variable):
    column = BoolCol
    entity_class = Familles
    label = u"Eligibilité à la PPA pour un mois"

    def function(self, simulation, period):
        period = period.this_month
        P = simulation.legislation_at(period.start)
        age_min = P.minim.ppa.age_min
        condition_age_individus = simulation.calculate('age', period) >= age_min
        condition_age = self.any_by_roles(condition_age_individus)
        elig = condition_age

        return period, elig

class ppa_montant_forfaitaire_familial_non_majore(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Montant forfaitaire familial (sans majoration)"

    def function(self, simulation, period):
        period = period.this_month
        nb_parents = simulation.calculate('nb_par', period)
        nb_enfants = simulation.calculate('nb_enfant_rsa', period)
        ppa_majoree_eligibilite = simulation.calculate('rsa_majore_eligibilite', period)
        rmi = simulation.legislation_at(period.start).minim.rmi
        nb_personnes = nb_parents + nb_enfants

        taux_non_majore = (
            1 +
            (nb_personnes >= 2) * rmi.txp2 +
            (nb_personnes >= 3) * rmi.txp3 +
            (nb_personnes >= 4) * where(nb_parents == 1, rmi.txps, rmi.txp3) + # Si nb_par == 1, pas de conjoint, la 4e personne est un enfant, donc le taux est de 40%.
            max_(nb_personnes - 4, 0) * rmi.txps
            )

        return period, rmi.rmi * taux_non_majore

class ppa_montant_forfaitaire_familial_majore(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Montant forfaitaire familial (avec majoration)"

    def function(self, simulation, period):
        nb_enfants = simulation.calculate('nb_enfant_rsa', period)
        rmi = simulation.legislation_at(period.start).minim.rmi
        taux_majore = rmi.majo_rsa.pac0 + rmi.majo_rsa.pac_enf_sup * nb_enfants

        return period, rmi.rmi * taux_majore

class ppa_revenu_activite(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Revenu d'activité pris en compte pour la PPA"

    def function(self, simulation, period):
        period = period.this_month
        ppa_revenu_activite_individus = simulation.compute('ppa_revenu_activite_i', period)
        ppa_revenu_activite = self.sum_by_entity(ppa_revenu_activite_individus)

        return period, ppa_revenu_activite

class ppa_revenu_activite_i(Variable):
    column = FloatCol
    entity_class = Individus
    label = u"Revenu d'activité pris en compte pour la PPA (Individus) pour un mois"

    def function(self, simulation, period):
        period = period.this_month
        ressources = [
            'salaire_net',
            'revenus_stage_formation_pro',
            'bourse_recherche',
            'indemnites_chomage_partiel',
            'indemnites_journalieres',
            'tns_auto_entrepreneur_benefice',
            ]

        revenus_mensualises = sum(
            simulation.calculate(ressource, period) for ressource in ressources)

        def get_last_known(variable_name):
            valeur_n = simulation.calculate(variable_name, period.this_year)
            valeur_n_1 = simulation.calculate(variable_name, period.last_year)
            valeur_n_2 = simulation.calculate(variable_name, period.n_2)
            return select(
                [valeur_n > 0, valeur_n_1 > 0, valeur_n_2 > 0],
                [valeur_n, valeur_n_1, valeur_n_2]
                ) / 12
        revenus_annualises = get_last_known('tns_benefice_exploitant_agricole') + get_last_known('tns_autres_revenus') + get_last_known('tns_micro_entreprise_benefice')

        return period, revenus_mensualises + revenus_annualises

class ppa_ressources_hors_activite(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Revenu hors activité pris en compte pour la PPA"

    def function(self, simulation, period, reference_period):
        pf = simulation.calculate('ppa_base_ressources_prestations_familiales', period, extra_params = [reference_period])
        ressources_hors_activite_individus = simulation.compute('ppa_ressources_hors_activite_i', period)
        ressources_hors_activite = self.sum_by_entity(ressources_hors_activite_individus) + pf

        return period, ressources_hors_activite

class ppa_ressources_hors_activite_i(Variable):
    column = FloatCol
    entity_class = Individus
    label = u"Revenu hors activité pris en compte pour la PPA (Individus) pour un mois"

    def function(self, simulation, period):
        period = period.this_month

        ressources = [
            'aah',
            'chomage_net',
            'retraite_nette',
            'retraite_combattant',
            'pensions_alimentaires_percues',
            'prestation_compensatoire',
            'revenus_locatifs',
            ]

        ressources_hors_activite_i = sum(
            simulation.calculate(ressource, period) for ressource in ressources)

        return period, ressources_hors_activite_i

class ppa_base_ressources_prestations_familiales(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Prestations familiales prises en compte dans le calcul de la PPA"

    def function(self, simulation, period, reference_period):
        period = period.this_month

        prestations_calculees = [
            'af_base',
            'rsa_forfait_asf',
            'paje_base',
           ]
        prestations_autres = [
            'paje_clca',
            'paje_prepare',
            'paje_colca',
            ]

        result = sum(simulation.calculate(prestation, reference_period) for prestation in prestations_calculees)
        result += sum(simulation.calculate(prestation, period) for prestation in prestations_autres)
        cf_non_majore_avant_cumul = simulation.calculate('cf_non_majore_avant_cumul', reference_period)
        cf = simulation.calculate('cf', reference_period)
        # Seul le montant non majoré est pris en compte dans la base de ressources du RSA
        cf_non_majore = (cf > 0) * cf_non_majore_avant_cumul
        result = result + cf_non_majore

        return period, result

class ppa_base_ressources(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Bases ressource prise en compte pour la PPA"

    def function(self, simulation, period, reference_period):
        period = period.this_month
        ppa_revenu_activite = simulation.calculate('ppa_revenu_activite', period)
        ppa_ressources_hors_activite = simulation.calculate('ppa_ressources_hors_activite', period, extra_params = [reference_period])
        return period, ppa_revenu_activite + ppa_ressources_hors_activite

class ppa_bonification(Variable):
    column = FloatCol
    entity_class = Individus
    label = u"Bonification de la PPA pour un individu"

    def function(self, simulation, period):
        period = period.this_month
        P = simulation.legislation_at(period.start)
        smic_horaire = P.cotsoc.gen.smic_h_b
        rsa_base = P.minim.rmi.rmi
        revenu_activite = simulation.calculate('ppa_revenu_activite_i', period)
        seuil_1 = P.minim.ppa.bonification.seuil_1 * smic_horaire
        seuil_2 = P.minim.ppa.bonification.seuil_2 * smic_horaire
        bonification_max = round_(P.minim.ppa.bonification.montant_max * rsa_base)

        bonification = bonification_max * (revenu_activite - seuil_1) / (seuil_2 - seuil_1)
        bonification = max_(bonification, 0)
        bonification = min_(bonification, bonification_max)

        return period, bonification

class ppa_fictive(Variable):
    column = FloatCol
    entity_class = Familles
    label = u"Prime pour l'activité fictive pour un mois"

    def function(self, simulation, period, reference_period):
        period = period.this_month
        forfait_logement = simulation.calculate('rsa_forfait_logement', reference_period)
        ppa_majoree_eligibilite = simulation.calculate('rsa_majore_eligibilite', reference_period)

        elig = simulation.calculate('ppa_eligibilite', period)
        pente = simulation.legislation_at(period.start).minim.rmi.pente
        mff_non_majore = simulation.calculate('ppa_montant_forfaitaire_familial_non_majore', period)
        mff_majore = simulation.calculate('ppa_montant_forfaitaire_familial_majore', period)
        montant_forfaitaire_familialise = where(ppa_majoree_eligibilite, mff_majore, mff_non_majore)
        ppa_base_ressources = simulation.calculate('ppa_base_ressources', period, extra_params = [reference_period])
        ppa_revenu_activite = simulation.calculate('ppa_revenu_activite', period)
        bonification_individus = simulation.compute('ppa_bonification', period)
        bonification = self.sum_by_entity(bonification_individus)

        ppa_montant_base = (
            montant_forfaitaire_familialise +
            bonification +
            pente * ppa_revenu_activite - ppa_base_ressources
            - forfait_logement
            )

        ppa_deduction = (
            montant_forfaitaire_familialise
            - ppa_base_ressources
            - forfait_logement
            )

        ppa_fictive = ppa_montant_base - max_(ppa_deduction,0)
        ppa_fictive = max_(ppa_fictive, 0)
        return period, elig * ppa_fictive

<|endoftext|>


<commit_before>#!/usr/bin/env python
#
# iuwandbox.py
#
# Copyright (C) 2014-2016, Takazumi Shirayanagi
# This software is released under the new BSD License,
# see LICENSE
#

import os
import sys
import re
import codecs

from argparse import ArgumentParser
from wandbox import Wandbox
from requests.exceptions import HTTPError

IUTEST_FUSED_SRC = os.path.join(os.path.dirname(__file__), '../../fused-src/iutest.min.hpp')
IUTEST_INCLUDE_REGEX = re.compile(r'^\s*#\s*include\s*".*iutest\.hpp"')
EXPAND_INCLUDE_REGEX = re.compile(r'^\s*#\s*include\s*"(.*?)"')

#
# command line option
def parse_command_line():
    parser = ArgumentParser()
    parser.add_argument(
        '-v',
        '--version',
        action='version',
        version=u'%(prog)s version 4.2'
    )
    parser.add_argument(
        '--list_compiler',
        action='store_true',
        help='listup compiler.'
    )
    parser.add_argument(
        '--list_options',
        metavar='COMPILER',
        help='listup compiler options.'
    )
    parser.add_argument(
        '-c',
        '--compiler',
        default='gcc-head',
        help='compiler select. default: %(default)s'
    )
    parser.add_argument(
        '-x',
        '--options',
        help='used options for a compiler.'
    )
    parser.add_argument(
        '--default',
        action='store_true',
        help='use default options.'
    )
    parser.add_argument(
        '--boost',
        metavar='VERSION',
        help='set boost options version X.XX or nothing.'
    )
    parser.add_argument(
        '--sprout',
        action='store_true',
        help='use sprout.'
    )
    parser.add_argument(
        '--msgpack',
        action='store_true',
        help='use msgpack.'
    )
    parser.add_argument(
        '--stdin',
        help='set stdin.'
    )
    parser.add_argument(
        '-f',
        '--compiler_option_raw',
        metavar='OPTIONS',
        action='append',
        default=['-D__WANDBOX__'],
        help='compile-time any additional options.'
    )
    parser.add_argument(
        '-r',
        '--runtime_option_raw',
        metavar='OPTIONS',
        action='append',
        help='runtime-time any additional options.'
    )
    parser.add_argument(
        '-s',
        '--save',
        action='store_true',
        help='generate permanent link.'
    )
    parser.add_argument(
        '--permlink',
        metavar='ID',
        help='get permanent link.'
    )
    parser.add_argument(
        '-o',
        '--output',
        metavar='FILE',
        help='output source code.'
    )
    parser.add_argument(
        '--xml',
        metavar='FILE',
        help='output result xml.'
    )
    parser.add_argument(
        '--junit',
        metavar='FILE',
        help='output result junit xml.'
    )
    parser.add_argument(
        '--stderr',
        action='store_true',
        help='output stderr.'
    )
    parser.add_argument(
        '--encoding',
        help='set encoding.'
    )
    parser.add_argument(
        '--expand_include',
        action='store_true',
        help='expand include file.'
    )
    parser.add_argument(
        '--check_config',
        action='store_true',
        help='check config.'
    )
    parser.add_argument(
        '--verbose',
        action='store_true',
        help='verbose.'
    )
    parser.add_argument(
        '--dryrun',
        action='store_true',
        help='dryrun.'
    )
    parser.add_argument(
        'code',
        metavar='CODE',
        nargs='?',
        help='source code file'
    )
    options = parser.parse_args()
    return options, parser

# file open
def file_open(path, mode, encoding):
    if encoding:
        file = codecs.open(path, mode, encoding)
    else:
        file = open(path, mode)
    return file

# make include filename
def make_include_filename(path, includes, included_files):
    if path in included_files:
        return included_files[path]
    else:
        include_dir, include_filename = os.path.split(path)
        while include_filename in includes:
            include_dir, dirname = os.path.split(include_dir)
            include_filename = dirname + '__' + include_filename
        included_files[path] = include_filename
        return include_filename

# make code
def make_code(path, encoding, expand, includes, included_files):
    code = ''
    file = file_open(path, 'r', encoding)
    for line in file:
        m = IUTEST_INCLUDE_REGEX.match(line)
        if m:
            code += '#include "iutest.hpp"\n'
            code += '//origin>> ' + line
            if 'iutest.hpp' not in includes:
                f = codecs.open(IUTEST_FUSED_SRC, 'r', 'utf-8-sig')
                includes['iutest.hpp'] = f.read()
        else:
            m = EXPAND_INCLUDE_REGEX.match(line)
            if m:
                include_path = os.path.join(os.path.dirname(path), m.group(1))
                if os.path.exists(include_path):
                    expand_include_file_code = make_code(include_path, encoding, expand, includes, included_files)
                    if expand:
                        code += expand_include_file_code
                        code += '//origin>> '
                    else:
                        include_abspath = os.path.abspath(include_path)
                        include_filename = make_include_filename(include_abspath, includes, included_files)
                        code += '#include "' + include_filename + '"\n'
                        code += '//origin>> '
                        if include_filename not in includes:
                            includes[include_filename] = expand_include_file_code
            code += line
    file.close()
    return code

# check config
def check_config(options):
    if not find_compiler(options.compiler):
        print('Wandbox is not supported compiler [' + options.compiler + ']')
        listup_compiler()
        sys.exit(1)

# setup includes
def setup_includes(w, includes):
    for filename,code in includes.items():
        w.add_file(filename, code)

# run wandbox
def run_wandbox(code, includes, options):
    w = Wandbox()
    w.compiler(options.compiler)
    opt = []
    if options.options:
        opt = options.options.split(',')
    elif options.default:
        opt = get_default_options(options.compiler)
    if options.boost:
        opt = list(filter(lambda s: s.find('boost') == -1, opt))
        opt.append('boost-' + str(options.boost))
    if options.sprout and 'sprout' not in opt:
        opt.append('sprout')
    if options.msgpack and 'msgpack' not in opt:
        opt.append('msgpack')
    w.options(','.join(opt))
    if options.stdin:
        w.stdin(options.stdin)
    if options.compiler_option_raw:
        co = '\n'.join(options.compiler_option_raw)
        co = co.replace('\\n', '\n')
        if options.compiler == "clang-3.5":
            co += "\n-DIUTEST_HAS_HDR_CXXABI=0"
        if options.compiler in ["clang-3.2", "clang-3.1", "clang-3.0"]:
            co += "\n-Qunused-arguments"
        w.compiler_options(co)
    if options.runtime_option_raw:
        ro = ''
        for opt in options.runtime_option_raw:
            ro += opt + '\n'
        ro = ro.replace('\\n', '\n')
        w.runtime_options(ro)
    if options.save:
        w.permanent_link(options.save)
    if options.verbose:
        w.dump()
    w.code(code)
    setup_includes(w, includes)
    if options.dryrun:
        sys.exit(0)
    def run(retries):
        try:
            return w.run()
        except HTTPError as e:
            if e.response.status_code == 504 and retries > 0:
                print(e.message)
                return run(retries-1)
            else:
                raise
        except:
            raise
    return run(3)

# show result
def show_result(r, options):
    if 'error' in r:
        print(r['error'])
        sys.exit(1)
    if options.stderr:
        if 'compiler_output' in r:
            print('compiler_output:')
            print(r['compiler_output'].encode('utf_8'))
        if 'compiler_error' in r:
            sys.stderr.write(r['compiler_error'].encode('utf_8'))
        if 'program_output' in r:
            print('program_output:')
            print(r['program_output'].encode('utf_8'))
        if options.xml is None and options.junit is None and 'program_error' in r:
            sys.stderr.write(r['program_error'].encode('utf_8'))
    else:
        if 'compiler_message' in r:
            print('compiler_message:')
            print(r['compiler_message'].encode('utf_8'))
        if 'program_message' in r:
            print('program_message:')
            print(r['program_message'].encode('utf_8'))
    if 'url' in r:
        print('permlink: ' + r['permlink'])
        print('url: ' + r['url'])
    if 'signal' in r:
        print('signal: ' + r['signal'])
    if 'status' in r:
        return int(r['status'])
    return 1

# show parameter
def show_parameter(r):
    if 'compiler' in r:
        print('compiler:' + r['compiler'])
    if 'options' in r:
        print('options:' + r['options'])
    if 'compiler-option-raw' in r:
        print('compiler-option-raw:' + r['compiler-option-raw'])
    if 'runtime-option-raw' in r:
        print('runtime-option-raw' + r['runtime-option-raw'])
    if 'created-at' in r:
        print(r['created-at'])

def set_output_xml(options, t, xml):
    options.stderr = True
    if options.runtime_option_raw:
        options.runtime_option_raw.append("--iutest_output=" + t + ":" + xml)
    else:
        options.runtime_option_raw = ["--iutest_output=" + t + ":" + xml]

def run(options):
    filepath = options.code
    if not os.path.exists(filepath):
        sys.exit(1)
    includes = {}
    included_files = {}
    code = make_code(filepath, options.encoding, options.expand_include, includes, included_files)
    if options.output:
        f = file_open(options.output, 'w', options.encoding)
        f.write(code)
        f.close()
    xml = None
    if options.xml:
        xml = options.xml
        set_output_xml(options, 'xml', xml)
    if options.junit:
        xml = options.junit
        set_output_xml(options, 'junit', xml)
    r = run_wandbox(code, includes, options)
    b = show_result(r, options)
    if xml and 'program_error' in r:
        f = file_open(xml, 'w', options.encoding)
        f.write(r['program_error'])
        f.close()
    sys.exit(b)

# listup compiler
def listup_compiler(verbose):
    w = Wandbox()
    r = w.get_compiler_list()
    for d in r:
        if d['language'] == 'C++':
            if verbose:
                print(d['name'] + ' (' + d['version'] + ')')
            else:
                print(d['name'])

# find compiler
def find_compiler(c):
    w = Wandbox()
    r = w.get_compiler_list()
    for d in r:
        if d['language'] == 'C++' and d['name'] == c:
            return True
    return False

# listup options
def listup_options(compiler):
    w = Wandbox()
    r = w.get_compiler_list()
    for d in r:
        if d['name'] == compiler:
            if 'switches' in d:
                switches = d['switches']
                for s in switches:
                    if 'name' in s:
                        if s['default']:
                            print(s['name'] + ' (default)')
                        else:
                            print(s['name'])
                    elif 'options' in s:
                        print(s['default'] + ' (default)')
                        for o in s['options']:
                            print('  ' + o['name'])

# get default options
def get_default_options(compiler):
    w = Wandbox()
    r = w.get_compiler_list()
    opt = []
    for d in r:
        if d['name'] == compiler:
            if 'switches' in d:
                switches = d['switches']
                for s in switches:
                    if 'name' in s:
                        if s['default']:
                            opt.append(s['name'])
                    elif 'options' in s:
                        opt.append(s['default'])
    return opt

# get permlink
def get_permlink(options):
    w = Wandbox()
    r = w.get_permlink(options.permlink)
    p = r['parameter']
    show_parameter(p)
    print('result:')
    b = show_result(r['result'], options)
    if options.output:
        f = open(options.output, 'w')
        f.write(p['code'])
        f.close()
    sys.exit(b)

def main():
    options, parser = parse_command_line()
    if options.list_compiler:
        listup_compiler(options.verbose)
    elif options.list_options:
        listup_options(options.list_options)
    elif options.permlink:
        get_permlink(options)
    else:
        if options.check_config:
            check_config(options)
        elif options.code is None:
            parser.print_help()
            sys.exit(1)
        run(options)

if __name__ == '__main__':
    main()
<commit_msg>fix flake8<commit_after>#!/usr/bin/env python
#
# iuwandbox.py
#
# Copyright (C) 2014-2016, Takazumi Shirayanagi
# This software is released under the new BSD License,
# see LICENSE
#

import os
import sys
import re
import codecs

from argparse import ArgumentParser
from wandbox import Wandbox
from requests.exceptions import HTTPError

IUTEST_FUSED_SRC = os.path.join(os.path.dirname(__file__), '../../fused-src/iutest.min.hpp')
IUTEST_INCLUDE_REGEX = re.compile(r'^\s*#\s*include\s*".*iutest\.hpp"')
EXPAND_INCLUDE_REGEX = re.compile(r'^\s*#\s*include\s*"(.*?)"')

#
# command line option
def parse_command_line():
    parser = ArgumentParser()
    parser.add_argument(
        '-v',
        '--version',
        action='version',
        version=u'%(prog)s version 4.2'
    )
    parser.add_argument(
        '--list_compiler',
        action='store_true',
        help='listup compiler.'
    )
    parser.add_argument(
        '--list_options',
        metavar='COMPILER',
        help='listup compiler options.'
    )
    parser.add_argument(
        '-c',
        '--compiler',
        default='gcc-head',
        help='compiler select. default: %(default)s'
    )
    parser.add_argument(
        '-x',
        '--options',
        help='used options for a compiler.'
    )
    parser.add_argument(
        '--default',
        action='store_true',
        help='use default options.'
    )
    parser.add_argument(
        '--boost',
        metavar='VERSION',
        help='set boost options version X.XX or nothing.'
    )
    parser.add_argument(
        '--sprout',
        action='store_true',
        help='use sprout.'
    )
    parser.add_argument(
        '--msgpack',
        action='store_true',
        help='use msgpack.'
    )
    parser.add_argument(
        '--stdin',
        help='set stdin.'
    )
    parser.add_argument(
        '-f',
        '--compiler_option_raw',
        metavar='OPTIONS',
        action='append',
        default=['-D__WANDBOX__'],
        help='compile-time any additional options.'
    )
    parser.add_argument(
        '-r',
        '--runtime_option_raw',
        metavar='OPTIONS',
        action='append',
        help='runtime-time any additional options.'
    )
    parser.add_argument(
        '-s',
        '--save',
        action='store_true',
        help='generate permanent link.'
    )
    parser.add_argument(
        '--permlink',
        metavar='ID',
        help='get permanent link.'
    )
    parser.add_argument(
        '-o',
        '--output',
        metavar='FILE',
        help='output source code.'
    )
    parser.add_argument(
        '--xml',
        metavar='FILE',
        help='output result xml.'
    )
    parser.add_argument(
        '--junit',
        metavar='FILE',
        help='output result junit xml.'
    )
    parser.add_argument(
        '--stderr',
        action='store_true',
        help='output stderr.'
    )
    parser.add_argument(
        '--encoding',
        help='set encoding.'
    )
    parser.add_argument(
        '--expand_include',
        action='store_true',
        help='expand include file.'
    )
    parser.add_argument(
        '--check_config',
        action='store_true',
        help='check config.'
    )
    parser.add_argument(
        '--verbose',
        action='store_true',
        help='verbose.'
    )
    parser.add_argument(
        '--dryrun',
        action='store_true',
        help='dryrun.'
    )
    parser.add_argument(
        'code',
        metavar='CODE',
        nargs='?',
        help='source code file'
    )
    options = parser.parse_args()
    return options, parser

# file open
def file_open(path, mode, encoding):
    if encoding:
        file = codecs.open(path, mode, encoding)
    else:
        file = open(path, mode)
    return file

# make include filename
def make_include_filename(path, includes, included_files):
    if path in included_files:
        return included_files[path]
    else:
        include_dir, include_filename = os.path.split(path)
        while include_filename in includes:
            include_dir, dirname = os.path.split(include_dir)
            include_filename = dirname + '__' + include_filename
        included_files[path] = include_filename
        return include_filename

# make code
def make_code(path, encoding, expand, includes, included_files):
    code = ''
    file = file_open(path, 'r', encoding)
    for line in file:
        m = IUTEST_INCLUDE_REGEX.match(line)
        if m:
            code += '#include "iutest.hpp"\n'
            code += '//origin>> ' + line
            if 'iutest.hpp' not in includes:
                f = codecs.open(IUTEST_FUSED_SRC, 'r', 'utf-8-sig')
                includes['iutest.hpp'] = f.read()
        else:
            m = EXPAND_INCLUDE_REGEX.match(line)
            if m:
                include_path = os.path.join(os.path.dirname(path), m.group(1))
                if os.path.exists(include_path):
                    expand_include_file_code = make_code(
                        include_path, encoding, expand, includes, included_files)
                    if expand:
                        code += expand_include_file_code
                        code += '//origin>> '
                    else:
                        include_abspath = os.path.abspath(include_path)
                        include_filename = make_include_filename(
                            include_abspath, includes, included_files)
                        code += '#include "' + include_filename + '"\n'
                        code += '//origin>> '
                        if include_filename not in includes:
                            includes[include_filename] = expand_include_file_code
            code += line
    file.close()
    return code

# check config
def check_config(options):
    if not find_compiler(options.compiler):
        print('Wandbox is not supported compiler [' + options.compiler + ']')
        listup_compiler()
        sys.exit(1)

# setup includes
def setup_includes(w, includes):
    for filename, code in includes.items():
        w.add_file(filename, code)

# run wandbox
def run_wandbox(code, includes, options):
    w = Wandbox()
    w.compiler(options.compiler)
    opt = []
    if options.options:
        opt = options.options.split(',')
    elif options.default:
        opt = get_default_options(options.compiler)
    if options.boost:
        opt = list(filter(lambda s: s.find('boost') == -1, opt))
        opt.append('boost-' + str(options.boost))
    if options.sprout and 'sprout' not in opt:
        opt.append('sprout')
    if options.msgpack and 'msgpack' not in opt:
        opt.append('msgpack')
    w.options(','.join(opt))
    if options.stdin:
        w.stdin(options.stdin)
    if options.compiler_option_raw:
        co = '\n'.join(options.compiler_option_raw)
        co = co.replace('\\n', '\n')
        if options.compiler == "clang-3.5":
            co += "\n-DIUTEST_HAS_HDR_CXXABI=0"
        if options.compiler in ["clang-3.2", "clang-3.1", "clang-3.0"]:
            co += "\n-Qunused-arguments"
        w.compiler_options(co)
    if options.runtime_option_raw:
        ro = ''
        for opt in options.runtime_option_raw:
            ro += opt + '\n'
        ro = ro.replace('\\n', '\n')
        w.runtime_options(ro)
    if options.save:
        w.permanent_link(options.save)
    if options.verbose:
        w.dump()
    w.code(code)
    setup_includes(w, includes)
    if options.dryrun:
        sys.exit(0)

    def run(retries):
        try:
            return w.run()
        except HTTPError as e:
            if e.response.status_code == 504 and retries > 0:
                print(e.message)
                return run(retries - 1)
            else:
                raise
        except:
            raise
    return run(3)

# show result
def show_result(r, options):
    if 'error' in r:
        print(r['error'])
        sys.exit(1)
    if options.stderr:
        if 'compiler_output' in r:
            print('compiler_output:')
            print(r['compiler_output'].encode('utf_8'))
        if 'compiler_error' in r:
            sys.stderr.write(r['compiler_error'].encode('utf_8'))
        if 'program_output' in r:
            print('program_output:')
            print(r['program_output'].encode('utf_8'))
        if options.xml is None and options.junit is None and 'program_error' in r:
            sys.stderr.write(r['program_error'].encode('utf_8'))
    else:
        if 'compiler_message' in r:
            print('compiler_message:')
            print(r['compiler_message'].encode('utf_8'))
        if 'program_message' in r:
            print('program_message:')
            print(r['program_message'].encode('utf_8'))
    if 'url' in r:
        print('permlink: ' + r['permlink'])
        print('url: ' + r['url'])
    if 'signal' in r:
        print('signal: ' + r['signal'])
    if 'status' in r:
        return int(r['status'])
    return 1

# show parameter
def show_parameter(r):
    if 'compiler' in r:
        print('compiler:' + r['compiler'])
    if 'options' in r:
        print('options:' + r['options'])
    if 'compiler-option-raw' in r:
        print('compiler-option-raw:' + r['compiler-option-raw'])
    if 'runtime-option-raw' in r:
        print('runtime-option-raw' + r['runtime-option-raw'])
    if 'created-at' in r:
        print(r['created-at'])

def set_output_xml(options, t, xml):
    options.stderr = True
    if options.runtime_option_raw:
        options.runtime_option_raw.append("--iutest_output=" + t + ":" + xml)
    else:
        options.runtime_option_raw = ["--iutest_output=" + t + ":" + xml]

def run(options):
    filepath = options.code
    if not os.path.exists(filepath):
        sys.exit(1)
    includes = {}
    included_files = {}
    code = make_code(filepath, options.encoding, options.expand_include, includes, included_files)
    if options.output:
        f = file_open(options.output, 'w', options.encoding)
        f.write(code)
        f.close()
    xml = None
    if options.xml:
        xml = options.xml
        set_output_xml(options, 'xml', xml)
    if options.junit:
        xml = options.junit
        set_output_xml(options, 'junit', xml)
    r = run_wandbox(code, includes, options)
    b = show_result(r, options)
    if xml and 'program_error' in r:
        f = file_open(xml, 'w', options.encoding)
        f.write(r['program_error'])
        f.close()
    sys.exit(b)

# listup compiler
def listup_compiler(verbose):
    w = Wandbox()
    r = w.get_compiler_list()
    for d in r:
        if d['language'] == 'C++':
            if verbose:
                print(d['name'] + ' (' + d['version'] + ')')
            else:
                print(d['name'])

# find compiler
def find_compiler(c):
    w = Wandbox()
    r = w.get_compiler_list()
    for d in r:
        if d['language'] == 'C++' and d['name'] == c:
            return True
    return False

# listup options
def listup_options(compiler):
    w = Wandbox()
    r = w.get_compiler_list()
    for d in r:
        if d['name'] == compiler:
            if 'switches' in d:
                switches = d['switches']
                for s in switches:
                    if 'name' in s:
                        if s['default']:
                            print(s['name'] + ' (default)')
                        else:
                            print(s['name'])
                    elif 'options' in s:
                        print(s['default'] + ' (default)')
                        for o in s['options']:
                            print('  ' + o['name'])

# get default options
def get_default_options(compiler):
    w = Wandbox()
    r = w.get_compiler_list()
    opt = []
    for d in r:
        if d['name'] == compiler:
            if 'switches' in d:
                switches = d['switches']
                for s in switches:
                    if 'name' in s:
                        if s['default']:
                            opt.append(s['name'])
                    elif 'options' in s:
                        opt.append(s['default'])
    return opt

# get permlink
def get_permlink(options):
    w = Wandbox()
    r = w.get_permlink(options.permlink)
    p = r['parameter']
    show_parameter(p)
    print('result:')
    b = show_result(r['result'], options)
    if options.output:
        f = open(options.output, 'w')
        f.write(p['code'])
        f.close()
    sys.exit(b)

def main():
    options, parser = parse_command_line()
    if options.list_compiler:
        listup_compiler(options.verbose)
    elif options.list_options:
        listup_options(options.list_options)
    elif options.permlink:
        get_permlink(options)
    else:
        if options.check_config:
            check_config(options)
        elif options.code is None:
            parser.print_help()
            sys.exit(1)
        run(options)

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


<commit_before># -*- coding: utf-8 -*-
from .selenium_base import SeleniumTestCase

class MapTest(SeleniumTestCase):
    # These tests run against a MockAPIServer started by the
    # custom_runner
    def test_map_slider(self):
        self.browser.get(
            self.live_server_url
            + "/analyse/#org=CCG&numIds=0212000AA&denomIds=2.12&selectedTab=map"
        )

        # Await map
        self.find_by_xpath("//*[@class='leaflet-zoom-animated' and name()='svg']")

        # In the default month (Sept) there is one "maximum" value
        self.assertEqual(
            len(
                self.browser.find_elements_by_xpath(
                    "//*[@fill='#67001f' and name()='path']"
                )
            ),
            1,
        )
        self.assertEqual(
            self.find_by_xpath("//p[@class='chart-sub-title']").text, "in Sep '16"
        )

        # Move the slider
        #
        # The firefox webdriver doesn't currently support mouse
        # events, so we have to inject them straight into the browser.
        js = """
        var slider = $('#chart-date-slider');
        slider.val(0);
        slider.trigger('change');
        """
        self.browser.execute_script(js)

        # Check the values for Gravesend have changed as expected
        self.assertEqual(
            len(
                self.browser.find_elements_by_xpath(
                    "//*[@fill='#67001f' and name()='path']"
                )
            ),
            2,
        )
        self.assertEqual(
            self.find_by_xpath("//p[@class='chart-sub-title']").text, "in Apr '13"
        )

class SmallListTest(SeleniumTestCase):
    # These tests run against a MockAPIServer started by the
    # custom_runner
    def test_nothing_hidden_by_default(self):
        self.browser.get(
            self.live_server_url
            + (
                "/analyse/#org=practice&orgIds=X&numIds=0212000AA"
                "&denom=total_list_size&selectedTab=summary"
            )
        )
        warning = self.find_by_xpath("//div[contains(@class, 'toggle')]/a")
        self.assertIn("Remove", warning.text)
        xlabels = self.find_by_xpath("//*[contains(@class, 'highcharts-xaxis-labels')]")
        self.assertIn("GREEN", xlabels.text)
        warning.click()
        warning = self.find_by_xpath("//div[contains(@class, 'toggle')]/a")
        self.assertIn("Show", warning.text)
        xlabels = self.find_by_xpath("//*[contains(@class, 'highcharts-xaxis-labels')]")
        self.assertNotIn("GREEN", xlabels.text)

class AnalyseSummaryTotalsTest(SeleniumTestCase):
    def test_summary_totals_on_analyse_page(self):
        self.browser.get(self.live_server_url + "/analyse/#org=CCG&numIds=0212000AA")
        expected = {
            "panel-heading": (
                "Total prescribing for Rosuvastatin Calcium across all "
                "CCGs in NHS England"
            ),
            "js-selected-month": "Sep '16",
            "js-financial-year-range": "Apr—Sep '16",
            "js-year-range": "Oct '15—Sep '16",
            "js-cost-month-total": "29,720",
            "js-cost-financial-year-total": "178,726",
            "js-cost-year-total": "379,182",
            "js-items-month-total": "1,669",
            "js-items-financial-year-total": "9,836",
            "js-items-year-total": "20,622",
        }
        for classname, value in expected.items():
            selector = (
                '//*[@id="{id}"]'
                '//*[contains(concat(" ", @class, " "), " {classname} ")]'.format(
                    id="js-summary-totals", classname=classname
                )
            )
            element = self.find_by_xpath(selector)
            self.assertTrue(
                element.is_displayed(), ".{} is not visible".format(classname)
            )
            self.assertEqual(element.text.strip(), value)
<commit_msg>Mark some tests as expected failures<commit_after># -*- coding: utf-8 -*-
# All the tests in this file fail in CI (BrowserStack running in Github
# Actions) but pass locally (though a different set of tests fail locally and
# pass in CI). Given that we were previously ignoring the functional test suite
# altogether when running under Travis/Saucelabs and that we have no time or
# funding to work on this, we've decided the least bad option is to mark these
# tests as expected failures for now.
#
# I've re-run the tests several times and they appear to at least be consistent
# failures, unlike the intermittent ones we had with Travis/Saucelabs.
import unittest

from .selenium_base import SeleniumTestCase

class MapTest(SeleniumTestCase):
    # These tests run against a MockAPIServer started by the
    # custom_runner
    @unittest.expectedFailure
    def test_map_slider(self):
        self.browser.get(
            self.live_server_url
            + "/analyse/#org=CCG&numIds=0212000AA&denomIds=2.12&selectedTab=map"
        )

        # Await map
        self.find_by_xpath("//*[@class='leaflet-zoom-animated' and name()='svg']")

        # In the default month (Sept) there is one "maximum" value
        self.assertEqual(
            len(
                self.browser.find_elements_by_xpath(
                    "//*[@fill='#67001f' and name()='path']"
                )
            ),
            1,
        )
        self.assertEqual(
            self.find_by_xpath("//p[@class='chart-sub-title']").text, "in Sep '16"
        )

        # Move the slider
        #
        # The firefox webdriver doesn't currently support mouse
        # events, so we have to inject them straight into the browser.
        js = """
        var slider = $('#chart-date-slider');
        slider.val(0);
        slider.trigger('change');
        """
        self.browser.execute_script(js)

        # Check the values for Gravesend have changed as expected
        self.assertEqual(
            len(
                self.browser.find_elements_by_xpath(
                    "//*[@fill='#67001f' and name()='path']"
                )
            ),
            2,
        )
        self.assertEqual(
            self.find_by_xpath("//p[@class='chart-sub-title']").text, "in Apr '13"
        )

class SmallListTest(SeleniumTestCase):
    # These tests run against a MockAPIServer started by the
    # custom_runner
    @unittest.expectedFailure
    def test_nothing_hidden_by_default(self):
        self.browser.get(
            self.live_server_url
            + (
                "/analyse/#org=practice&orgIds=X&numIds=0212000AA"
                "&denom=total_list_size&selectedTab=summary"
            )
        )
        warning = self.find_by_xpath("//div[contains(@class, 'toggle')]/a")
        self.assertIn("Remove", warning.text)
        xlabels = self.find_by_xpath("//*[contains(@class, 'highcharts-xaxis-labels')]")
        self.assertIn("GREEN", xlabels.text)
        warning.click()
        warning = self.find_by_xpath("//div[contains(@class, 'toggle')]/a")
        self.assertIn("Show", warning.text)
        xlabels = self.find_by_xpath("//*[contains(@class, 'highcharts-xaxis-labels')]")
        self.assertNotIn("GREEN", xlabels.text)

class AnalyseSummaryTotalsTest(SeleniumTestCase):
    @unittest.expectedFailure
    def test_summary_totals_on_analyse_page(self):
        self.browser.get(self.live_server_url + "/analyse/#org=CCG&numIds=0212000AA")
        expected = {
            "panel-heading": (
                "Total prescribing for Rosuvastatin Calcium across all "
                "CCGs in NHS England"
            ),
            "js-selected-month": "Sep '16",
            "js-financial-year-range": "Apr—Sep '16",
            "js-year-range": "Oct '15—Sep '16",
            "js-cost-month-total": "29,720",
            "js-cost-financial-year-total": "178,726",
            "js-cost-year-total": "379,182",
            "js-items-month-total": "1,669",
            "js-items-financial-year-total": "9,836",
            "js-items-year-total": "20,622",
        }
        for classname, value in expected.items():
            selector = (
                '//*[@id="{id}"]'
                '//*[contains(concat(" ", @class, " "), " {classname} ")]'.format(
                    id="js-summary-totals", classname=classname
                )
            )
            element = self.find_by_xpath(selector)
            self.assertTrue(
                element.is_displayed(), ".{} is not visible".format(classname)
            )
            self.assertEqual(element.text.strip(), value)
<|endoftext|>