<commit_before># coding: utf-8

RESOURCE_MAPPING = {
    # Accounts
    'who_am_i': {
        'resource': 'account/who_am_i',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Accounts.md'
    },

    # Client Contacts
    'contacts': {
        'resource': 'contacts',
        'docs': 'https://help.getharvest.com/api-v2/clients-api/clients/contacts/#list-all-contacts',
        'methods': ['POST', 'GET']
    },
    'contact': {
        'resource': 'contacts/{contact_id}',
        'docs': 'https://help.getharvest.com/api-v2/clients-api/clients/contacts/#retrieve-a-contact',
        'methods': ['PATCH', 'GET', 'DELETE']
    },

    # Clients
    'clients': {
        'resource': 'clients',
        'docs': 'https://help.getharvest.com/api-v2/clients-api/clients/clients/#list-all-clients',
        'methods': ['GET', 'POST']
    },
    'client': {
        'resource': 'clients/{client_id}',
        'docs': 'https://help.getharvest.com/api-v2/clients-api/clients/clients/#retrieve-a-client',
        'methods': ['GET', 'PATCH', 'DELETE']
    },

    # Company
    'company': {
        'resource': 'company',
        'docs': 'https://help.getharvest.com/api-v2/company-api/company/company/#retrieve-a-company',
        'methods': ['GET']
    },

    # Expense Categories
    'expense_categories': {
        'resource': 'expense_categories',
        'docs': 'https://help.getharvest.com/api-v2/expenses-api/expenses/expense-categories/#list-all-expense-categories',
        'methods': ['GET', 'POST']
    },
    'expense_category': {
        'resource': 'expense_categories/{expense_category_id}',
        'docs': 'https://help.getharvest.com/api-v2/expenses-api/expenses/expense-categories/#retrieve-an-expense-category',
        'methods': ['GET', 'PATCH', 'DELETE']
    },

    # Expense Tracking
    'expenses': {
        'resource': 'expenses',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Expense%20Tracking.md',
        'methods': ['POST']
    },
    'expense': {
        'resource': 'expenses/{expense_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Expense%20Tracking.md',
        'methods': ['PUT', 'GET', 'DELETE']
    },
    'expense_receipt': {
        'resource': 'expenses/{expense_id}/receipt',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Expense%20Tracking.md',
        'methods': ['POST', 'GET']
    },

    # Invoice Categories
    'invoice_item_categories': {
        'resource': 'invoice_item_categories',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Categories.md',
        'methods': ['POST', 'GET']
    },
    'invoice_item_category': {
        'resource': 'invoice_item_categories/{category_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Categories.md',
        'methods': ['PUT', 'DELETE']
    },

    # Invoice Messages
    'invoices_messages': {
        'resource': 'invoices/{invoice_id}/messages',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['GET', 'POST']
    },
    'invoices_message': {
        'resource': 'invoices/{invoice_id}/messages/{message_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['GET', 'DELETE']
    },
    'invoices_message_mark_as_sent': {
        'resource': 'invoices/{invoice_id}/messages/mark_as_sent',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['POST']
    },
    'invoices_message_mark_as_closed': {
        'resource': 'invoices/{invoice_id}/messages/mark_as_closed',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['POST']
    },
    'invoices_message_re_open': {
        'resource': 'invoices/{invoice_id}/messages/re_open',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['POST']
    },
    'invoices_message_mark_as_drafg': {
        'resource': 'invoices/{invoice_id}/messages/mark_as_draft',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['POST']
    },

    # Invoice Payments
    'invoices_payments': {
        'resource': 'invoices/{invoice_id}/payments',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Payments.md',
        'methods': ['GET', 'POST']
    },
    'invoices_payment': {
        'resource': 'invoices/{invoice_id}/payments/{payment_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Payments.md',
        'methods': ['GET', 'DELETE']
    },

    # Invoices
    'invoices': {
        'resource': 'invoices',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoices.md',
        'methods': ['GET', 'POST']
    },
    'invoice': {
        'resource': 'invoices/{invoice_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoices.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },

    # People
    'users': {
        'resource': 'people',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/People.md',
        'methods': ['GET', 'POST']
    },
    'user': {
        'resource': 'people/{user_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/People.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
    'user_toggle': {
        'resource': 'people/{user_id}/toggle',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/People.md',
        'methods': ['POST']
    },

    # Projects
    'projects': {
        'resource': 'projects',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Projects.md',
        'methods': ['GET', 'POST']
    },
    'project': {
        'resource': 'projects/{project_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Projects.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
    'de_activate_project': {
        'resource': 'projects/{project_id}/toggle',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Projects.md',
        'methods': ['PUT']
    },

    # Task Assignment
    'task_assignments': {
        'resource': 'projects/{project_id}/task_assignments',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Task%20Assignment.md',
        'methods': ['GET', 'POST']
    },
    'task_assignment': {
        'resource': 'projects/{project_id}/task_assignments/{task_assignment_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Task%20Assignment.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
    'task_assignment_add_with_create_new_task': {
        'resource': 'projects/{project_id}/task_assignments/add_with_create_new_task',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Task%20Assignment.md',
        'methods': ['POST']
    },

    # Tasks
    'tasks': {
        'resource': 'tasks',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Tasks.md',
        'methods': ['GET', 'POST']
    },
    'task': {
        'resource': 'tasks/{task_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Tasks.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
    'task_activate': {
        'resource': 'tasks/{task_id}/activate',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Tasks.md',
        'methods': ['POST']
    },

    # Time Tracking
    'tracking_daily': {
        'resource': 'daily',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'tracking_daily_day': {
        'resource': 'daily/{day_of_the_year}/{year}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'tracking_daily_day_user': {
        'resource': 'daily/{day_of_the_year}/{year}?of_user={user_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'tracking_entry': {
        'resource': 'daily/show/{day_entry_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'timer_toggle': {
        'resource': 'daily/timer/{day_entry_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'create_tracking_entry': {
        'resource': 'daily/add',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
        'methods': ['POST']
    },
    'delete_tracking_entry': {
        'resource': 'daily/delete/{day_entry_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
        'methods': ['DELETE']
    },
    'update_tracking_entry': {
        'resource': 'daily/update/{day_entry_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
        'methods': ['POST']
    },

    # Time and Expense Reporting
    'project_entries': {
        'resource': 'projects/{project_id}/entries',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20and%20Expense%20Reporting.md',
    },
    'user_entries': {
        'resource': 'people/{user_id}/entries',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20and%20Expense%20Reporting.md',
    },
    'user_expenses': {
        'resource': 'people/{user_id}/expenses',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20and%20Expense%20Reporting.md',
    },
    'project_expenses': {
        'resource': 'projects/{project_id}/expenses',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20and%20Expense%20Reporting.md',
    },

    # User Assignment
    'user_assignments': {
        'resource': 'projects/{project_id}/user_assignments',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/User%20Assignment.md',
        'methods': ['GET', 'POST']
    },
    'user_assignment': {
        'resource': 'projects/{project_id}/user_assignments/{user_assignment_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/User%20Assignment.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
}
<commit_msg>Update Expenses resource params to v2<commit_after># coding: utf-8

RESOURCE_MAPPING = {
    # Accounts
    'who_am_i': {
        'resource': 'account/who_am_i',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Accounts.md'
    },

    # Client Contacts
    'contacts': {
        'resource': 'contacts',
        'docs': 'https://help.getharvest.com/api-v2/clients-api/clients/contacts/#list-all-contacts',
        'methods': ['POST', 'GET']
    },
    'contact': {
        'resource': 'contacts/{contact_id}',
        'docs': 'https://help.getharvest.com/api-v2/clients-api/clients/contacts/#retrieve-a-contact',
        'methods': ['PATCH', 'GET', 'DELETE']
    },

    # Clients
    'clients': {
        'resource': 'clients',
        'docs': 'https://help.getharvest.com/api-v2/clients-api/clients/clients/#list-all-clients',
        'methods': ['GET', 'POST']
    },
    'client': {
        'resource': 'clients/{client_id}',
        'docs': 'https://help.getharvest.com/api-v2/clients-api/clients/clients/#retrieve-a-client',
        'methods': ['GET', 'PATCH', 'DELETE']
    },

    # Company
    'company': {
        'resource': 'company',
        'docs': 'https://help.getharvest.com/api-v2/company-api/company/company/#retrieve-a-company',
        'methods': ['GET']
    },

    # Expense Categories
    'expense_categories': {
        'resource': 'expense_categories',
        'docs': 'https://help.getharvest.com/api-v2/expenses-api/expenses/expense-categories/#list-all-expense-categories',
        'methods': ['GET', 'POST']
    },
    'expense_category': {
        'resource': 'expense_categories/{expense_category_id}',
        'docs': 'https://help.getharvest.com/api-v2/expenses-api/expenses/expense-categories/#retrieve-an-expense-category',
        'methods': ['GET', 'PATCH', 'DELETE']
    },

    # Expenses
    'expenses': {
        'resource': 'expenses',
        'docs': 'https://help.getharvest.com/api-v2/expenses-api/expenses/expenses/#list-all-expenses',
        'methods': ['GET', 'POST']
    },
    'expense': {
        'resource': 'expenses/{expense_id}',
        'docs': 'https://help.getharvest.com/api-v2/expenses-api/expenses/expenses/#retrieve-an-expense',
        'methods': ['PATCH', 'GET', 'DELETE']
    },

    # Invoice Categories
    'invoice_item_categories': {
        'resource': 'invoice_item_categories',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Categories.md',
        'methods': ['POST', 'GET']
    },
    'invoice_item_category': {
        'resource': 'invoice_item_categories/{category_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Categories.md',
        'methods': ['PUT', 'DELETE']
    },

    # Invoice Messages
    'invoices_messages': {
        'resource': 'invoices/{invoice_id}/messages',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['GET', 'POST']
    },
    'invoices_message': {
        'resource': 'invoices/{invoice_id}/messages/{message_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['GET', 'DELETE']
    },
    'invoices_message_mark_as_sent': {
        'resource': 'invoices/{invoice_id}/messages/mark_as_sent',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['POST']
    },
    'invoices_message_mark_as_closed': {
        'resource': 'invoices/{invoice_id}/messages/mark_as_closed',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['POST']
    },
    'invoices_message_re_open': {
        'resource': 'invoices/{invoice_id}/messages/re_open',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['POST']
    },
    'invoices_message_mark_as_drafg': {
        'resource': 'invoices/{invoice_id}/messages/mark_as_draft',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Messages.md',
        'methods': ['POST']
    },

    # Invoice Payments
    'invoices_payments': {
        'resource': 'invoices/{invoice_id}/payments',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Payments.md',
        'methods': ['GET', 'POST']
    },
    'invoices_payment': {
        'resource': 'invoices/{invoice_id}/payments/{payment_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoice%20Payments.md',
        'methods': ['GET', 'DELETE']
    },

    # Invoices
    'invoices': {
        'resource': 'invoices',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoices.md',
        'methods': ['GET', 'POST']
    },
    'invoice': {
        'resource': 'invoices/{invoice_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Invoices.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },

    # People
    'users': {
        'resource': 'people',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/People.md',
        'methods': ['GET', 'POST']
    },
    'user': {
        'resource': 'people/{user_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/People.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
    'user_toggle': {
        'resource': 'people/{user_id}/toggle',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/People.md',
        'methods': ['POST']
    },

    # Projects
    'projects': {
        'resource': 'projects',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Projects.md',
        'methods': ['GET', 'POST']
    },
    'project': {
        'resource': 'projects/{project_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Projects.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
    'de_activate_project': {
        'resource': 'projects/{project_id}/toggle',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Projects.md',
        'methods': ['PUT']
    },

    # Task Assignment
    'task_assignments': {
        'resource': 'projects/{project_id}/task_assignments',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Task%20Assignment.md',
        'methods': ['GET', 'POST']
    },
    'task_assignment': {
        'resource': 'projects/{project_id}/task_assignments/{task_assignment_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Task%20Assignment.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
    'task_assignment_add_with_create_new_task': {
        'resource': 'projects/{project_id}/task_assignments/add_with_create_new_task',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Task%20Assignment.md',
        'methods': ['POST']
    },

    # Tasks
    'tasks': {
        'resource': 'tasks',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Tasks.md',
        'methods': ['GET', 'POST']
    },
    'task': {
        'resource': 'tasks/{task_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Tasks.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
    'task_activate': {
        'resource': 'tasks/{task_id}/activate',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Tasks.md',
        'methods': ['POST']
    },

    # Time Tracking
    'tracking_daily': {
        'resource': 'daily',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'tracking_daily_day': {
        'resource': 'daily/{day_of_the_year}/{year}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'tracking_daily_day_user': {
        'resource': 'daily/{day_of_the_year}/{year}?of_user={user_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'tracking_entry': {
        'resource': 'daily/show/{day_entry_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'timer_toggle': {
        'resource': 'daily/timer/{day_entry_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
    },
    'create_tracking_entry': {
        'resource': 'daily/add',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
        'methods': ['POST']
    },
    'delete_tracking_entry': {
        'resource': 'daily/delete/{day_entry_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
        'methods': ['DELETE']
    },
    'update_tracking_entry': {
        'resource': 'daily/update/{day_entry_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20Tracking.md',
        'methods': ['POST']
    },

    # Time and Expense Reporting
    'project_entries': {
        'resource': 'projects/{project_id}/entries',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20and%20Expense%20Reporting.md',
    },
    'user_entries': {
        'resource': 'people/{user_id}/entries',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20and%20Expense%20Reporting.md',
    },
    'user_expenses': {
        'resource': 'people/{user_id}/expenses',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20and%20Expense%20Reporting.md',
    },
    'project_expenses': {
        'resource': 'projects/{project_id}/expenses',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/Time%20and%20Expense%20Reporting.md',
    },

    # User Assignment
    'user_assignments': {
        'resource': 'projects/{project_id}/user_assignments',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/User%20Assignment.md',
        'methods': ['GET', 'POST']
    },
    'user_assignment': {
        'resource': 'projects/{project_id}/user_assignments/{user_assignment_id}',
        'docs': 'https://github.com/harvesthq/api/blob/master/Sections/User%20Assignment.md',
        'methods': ['GET', 'PUT', 'DELETE']
    },
}
<|endoftext|>


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

import os, sys, subprocess, difflib, json

interpreter = None
requested = []

for arg in sys.argv[1:]:
  if arg.startswith('--interpreter='):
    interpreter = arg.split('=')[1]
    print '[ using wasm interpreter at "%s" ]' % interpreter
    assert os.path.exists(interpreter), 'interpreter not found'
  else:
    requested.append(arg)

def fail(actual, expected):
  raise Exception("incorrect output, diff:\n\n%s" % (
    ''.join([a.rstrip()+'\n' for a in difflib.unified_diff(expected.split('\n'), actual.split('\n'), fromfile='expected', tofile='actual')])
  ))

if not interpreter:
  print '[ no wasm interpreter provided, you should pass one as --interpreter=path/to/interpreter ]'

print '[ checking asm2wasm testcases... ]\n'

if len(requested) == 0:
  tests = sorted(os.listdir('test'))
else:
  tests = requested[:]

for asm in tests:
  if asm.endswith('.asm.js'):
    print '..', asm
    wasm = asm.replace('.asm.js', '.wast')
    actual, err = subprocess.Popen([os.path.join('bin', 'asm2wasm'), os.path.join('test', asm)], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
    assert err == '', 'bad err:' + err

    # verify output
    if not os.path.exists(os.path.join('test', wasm)):
      print actual
      raise Exception('output .wast file does not exist')
    expected = open(os.path.join('test', wasm)).read()
    if actual != expected:
      fail(actual, expected)

    # verify in wasm
    if interpreter:
      proc = subprocess.Popen([interpreter, os.path.join('test', wasm)], stderr=subprocess.PIPE)
      out, err = proc.communicate()
      if proc.returncode != 0:
        try: # to parse the error
          reported = err.split(':')[1]
          start, end = reported.split('-')
          start_line, start_col = map(int, start.split('.'))
          lines = expected.split('\n')
          print
          print '='*80
          print lines[start_line-1]
          print (' '*(start_col-1)) + '^'
          print (' '*(start_col-1)) + '|'
          print '='*80
          print err
        except Exception, e:
          raise Exception('wasm interpreter error: ' + err) # failed to pretty-print
        raise Exception('wasm interpreter error')

print '\n[ checking wasm-shell testcases... ]\n'

for t in tests:
  if t.endswith('.wast') and not t.startswith('spec'):
    print '..', t
    t = os.path.join('test', t)
    actual, err = subprocess.Popen([os.path.join('bin', 'wasm-shell'), t, 'print-wasm'], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
    assert err == '', 'bad err:' + err

    expected = open(t).read()
    if actual != expected:
      fail(actual, expected)

print '\n[ checking wasm-shell spec testcases... ]\n'

if len(requested) == 0:
  BLACKLIST = ['unreachable.wast', 'select.wast']
  spec_tests = [os.path.join('spec', t) for t in sorted(os.listdir(os.path.join('test', 'spec'))) if t not in BLACKLIST]
else:
  spec_tests = requested[:]

for t in spec_tests:
  if t.startswith('spec') and t.endswith('.wast'):
    print '..', t
    wast = os.path.join('test', t)
    proc = subprocess.Popen([os.path.join('bin', 'wasm-shell'), wast], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    actual, err = proc.communicate()
    assert proc.returncode == 0, err

    expected = os.path.join('test', 'spec', 'expected-output', os.path.basename(wast) + '.log')
    if os.path.exists(expected):
      expected = open(expected).read()
      # fix it up, our pretty (i32.const 83) must become compared to a homely 83 : i32
      def fix(x):
        x = x.strip()
        if not x: return x
        v, t = x.split(' : ')
        if v.endswith('.'): v = v[:-1] # remove trailing '.'
        return '(' + t + '.const ' + v + ')'
      expected = '\n'.join(map(fix, expected.split('\n')))
      print '       (using expected output)'
    else:
      continue
    actual = actual.strip()
    expected = expected.strip()
    if actual != expected:
      fail(actual, expected)

print '\n[ checking wasm.js polyfill testcases... (need both emcc and nodejs in your path) ]\n'

for c in tests:
  if c.endswith(('.c', '.cpp')):
    print '..', c
    base = c.replace('.cpp', '').replace('.c', '')
    post = base + '.post.js'
    try:
      post = open(os.path.join('test', post)).read()
    except:
      post = None
    expected = open(os.path.join('test', base + '.txt')).read()
    emcc = os.path.join('test', base + '.emcc')
    extra = []
    if os.path.exists(emcc):
      extra = json.loads(open(emcc).read())
    if os.path.exists('a.normal.js'): os.unlink('a.normal.js')
    for opts in [[], ['-O1'], ['-O2'], ['-O3'], ['-Oz']]:
      command = ['./emcc_to_wasm.js.sh', os.path.join('test', c)] + opts + extra
      subprocess.check_call(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      print '....' + ' '.join(command)
      if post:
        open('a.normal.js', 'a').write(post)
        open('a.wasm.js', 'a').write(post)
      else:
        print '     (no post)'
      for which in ['normal', 'wasm']:
        print '......', which
        try:
          args = json.loads(open(os.path.join('test', base + '.args')).read())
        except:
          args = []
          print '     (no args)'
        proc = subprocess.Popen(['nodejs', 'a.' + which + '.js'] + args, stdout=subprocess.PIPE)
        out, err = proc.communicate()
        assert proc.returncode == 0
        if out.strip() != expected.strip():
          fail(out, expected)

print '\n[ success! ]'

<commit_msg>update blacklist<commit_after>#!/usr/bin/env python

import os, sys, subprocess, difflib, json

interpreter = None
requested = []

for arg in sys.argv[1:]:
  if arg.startswith('--interpreter='):
    interpreter = arg.split('=')[1]
    print '[ using wasm interpreter at "%s" ]' % interpreter
    assert os.path.exists(interpreter), 'interpreter not found'
  else:
    requested.append(arg)

def fail(actual, expected):
  raise Exception("incorrect output, diff:\n\n%s" % (
    ''.join([a.rstrip()+'\n' for a in difflib.unified_diff(expected.split('\n'), actual.split('\n'), fromfile='expected', tofile='actual')])
  ))

if not interpreter:
  print '[ no wasm interpreter provided, you should pass one as --interpreter=path/to/interpreter ]'

print '[ checking asm2wasm testcases... ]\n'

if len(requested) == 0:
  tests = sorted(os.listdir('test'))
else:
  tests = requested[:]

for asm in tests:
  if asm.endswith('.asm.js'):
    print '..', asm
    wasm = asm.replace('.asm.js', '.wast')
    actual, err = subprocess.Popen([os.path.join('bin', 'asm2wasm'), os.path.join('test', asm)], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
    assert err == '', 'bad err:' + err

    # verify output
    if not os.path.exists(os.path.join('test', wasm)):
      print actual
      raise Exception('output .wast file does not exist')
    expected = open(os.path.join('test', wasm)).read()
    if actual != expected:
      fail(actual, expected)

    # verify in wasm
    if interpreter:
      proc = subprocess.Popen([interpreter, os.path.join('test', wasm)], stderr=subprocess.PIPE)
      out, err = proc.communicate()
      if proc.returncode != 0:
        try: # to parse the error
          reported = err.split(':')[1]
          start, end = reported.split('-')
          start_line, start_col = map(int, start.split('.'))
          lines = expected.split('\n')
          print
          print '='*80
          print lines[start_line-1]
          print (' '*(start_col-1)) + '^'
          print (' '*(start_col-1)) + '|'
          print '='*80
          print err
        except Exception, e:
          raise Exception('wasm interpreter error: ' + err) # failed to pretty-print
        raise Exception('wasm interpreter error')

print '\n[ checking wasm-shell testcases... ]\n'

for t in tests:
  if t.endswith('.wast') and not t.startswith('spec'):
    print '..', t
    t = os.path.join('test', t)
    actual, err = subprocess.Popen([os.path.join('bin', 'wasm-shell'), t, 'print-wasm'], stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
    assert err == '', 'bad err:' + err

    expected = open(t).read()
    if actual != expected:
      fail(actual, expected)

print '\n[ checking wasm-shell spec testcases... ]\n'

if len(requested) == 0:
  BLACKLIST = ['nan-propagation.wast']
  spec_tests = [os.path.join('spec', t) for t in sorted(os.listdir(os.path.join('test', 'spec'))) if t not in BLACKLIST]
else:
  spec_tests = requested[:]

for t in spec_tests:
  if t.startswith('spec') and t.endswith('.wast'):
    print '..', t
    wast = os.path.join('test', t)
    proc = subprocess.Popen([os.path.join('bin', 'wasm-shell'), wast], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    actual, err = proc.communicate()
    assert proc.returncode == 0, err

    expected = os.path.join('test', 'spec', 'expected-output', os.path.basename(wast) + '.log')
    if os.path.exists(expected):
      expected = open(expected).read()
      # fix it up, our pretty (i32.const 83) must become compared to a homely 83 : i32
      def fix(x):
        x = x.strip()
        if not x: return x
        v, t = x.split(' : ')
        if v.endswith('.'): v = v[:-1] # remove trailing '.'
        return '(' + t + '.const ' + v + ')'
      expected = '\n'.join(map(fix, expected.split('\n')))
      print '       (using expected output)'
    else:
      continue
    actual = actual.strip()
    expected = expected.strip()
    if actual != expected:
      fail(actual, expected)

print '\n[ checking wasm.js polyfill testcases... (need both emcc and nodejs in your path) ]\n'

for c in tests:
  if c.endswith(('.c', '.cpp')):
    print '..', c
    base = c.replace('.cpp', '').replace('.c', '')
    post = base + '.post.js'
    try:
      post = open(os.path.join('test', post)).read()
    except:
      post = None
    expected = open(os.path.join('test', base + '.txt')).read()
    emcc = os.path.join('test', base + '.emcc')
    extra = []
    if os.path.exists(emcc):
      extra = json.loads(open(emcc).read())
    if os.path.exists('a.normal.js'): os.unlink('a.normal.js')
    for opts in [[], ['-O1'], ['-O2'], ['-O3'], ['-Oz']]:
      command = ['./emcc_to_wasm.js.sh', os.path.join('test', c)] + opts + extra
      subprocess.check_call(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      print '....' + ' '.join(command)
      if post:
        open('a.normal.js', 'a').write(post)
        open('a.wasm.js', 'a').write(post)
      else:
        print '     (no post)'
      for which in ['normal', 'wasm']:
        print '......', which
        try:
          args = json.loads(open(os.path.join('test', base + '.args')).read())
        except:
          args = []
          print '     (no args)'
        proc = subprocess.Popen(['nodejs', 'a.' + which + '.js'] + args, stdout=subprocess.PIPE)
        out, err = proc.communicate()
        assert proc.returncode == 0
        if out.strip() != expected.strip():
          fail(out, expected)

print '\n[ success! ]'

<|endoftext|>


<commit_before>import numpy as np
import pylab
import pyfits
import sys
import glob
import os
from pyraf import iraf
import glob
from astropy.io import fits as fits

print '----------------------------------------------'
print 'Welcome to the Gemini data reduction pipeline!'
print '----------------------------------------------'
print ' '
print ' '

#find where user is working

mainpath = os.getcwd()

foldername=raw_input('What is the folder you are working in?    ')

# collect all fits files in the working directory

files = glob.glob('S*.fits')

sz = np.size(files)

wave     = np.chararray(sz,itemsize=10)
obj      = np.chararray(sz,itemsize=10)
grat     = np.chararray(sz,itemsize=10)
mask     = np.chararray(sz,itemsize=10)
obstype  = np.chararray(sz,itemsize=10)
obsclass = np.chararray(sz,itemsize=10)
date     = np.chararray(sz,itemsize=10)

for i in np.arange(0,sz):
    tmp         = pyfits.open(files[i])
    hdr         = tmp[0].header
    wave[i]     = (hdr['centwave'])
    obj[i]      = (hdr['object'])
    grat[i]     = (hdr['grating'])
    mask[i]     = (hdr['maskname'])
    obstype[i]  = (hdr['obstype'])
    obsclass[i] = (hdr['obsclass'])
    date[i]     = (hdr['date'])

if mask[0] == 'IFU-R': setup = 'blue'
if mask[0] == 'IFU-2': setup = 'red'

for i in np.arange(0,sz):
    print files[i],obj[i],grat[i],mask[i],obstype[i],obsclass[i],wave[i]

#select either the red or blue setups

if setup == 'blue':
    waves = np.array(['480.0', '490.0'])
    slit = 'red'
if setup == 'red':
    waves = np.array(['635.0', '640.0'])
    slit = 'both'

#pull out acquisition images

selacq = (obsclass == 'acq')
acqimages = np.extract(selacq, files)

#pull out science images

selsci1 = (obsclass == 'science') & (wave == waves[0])
sciimage1 = np.extract(selsci1,files)
n = np.size(sciimage1)
if n <= 1:
    sci11 = sciimage1[0]
else:
    sci11 = sciimage1[0]
    sci12 = sciimage1[1]
selsci2 = (obsclass == 'science') & (wave == waves[1])
sciimage2 = np.extract(selsci2,files)
if n <= 1:
    sci21 = sciimage2[0]
else:
    sci21 = sciimage2[0]
    sci22 = sciimage2[1]

#pull out arcs

selarc1 = (wave == waves[0]) & (obstype == 'ARC')
arc1 = np.extract(selarc1, files)
selarc2 = (wave == waves[1]) & (obstype == 'ARC')
arc2 = np.extract(selarc2, files)

#pull out flats

selflat1 = (wave == waves[0]) & (obstype == 'FLAT')
flat1 = np.extract(selflat1, files)[0]
flat1base = flat1.split('.')[0]
selflat2 = (wave == waves[1]) & (obstype == 'FLAT')
flat2 = np.extract(selflat2, files)[0]
flat2base = flat2.split('.')[0]

#pull out date

obsdate = date[0] #date should be same for all files

if obsdate == '2015-11-08': biasim='20151108bias.fits'

#pull out bias

#pull out standard star info

#if date = 2015 and setup = blue then standard star folder = ??

#pull out galaxy name

selname = (obsclass == 'science') & (wave == waves[0])
galname = np.extract(selname, obj)

#f = open('reduction.cl', 'w')

#defining all reduction tasks

def run_gfreduce(inimage,slit,cr,wt,ss,inter,os,tr,bi,):
    iraf.gemini.gmos.gfreduce(inimage, fl_gscrrej=cr, fl_wavtran=wt, fl_skysub=ss, fl_inter=inter, slits=slit, fl_over=yes, rawpath=foldername, logfile=galname[0]+'.log', bias=biasim)

def run_arcs(inimage,flatname):
    iraf.gemini.gmos.gfreduce(inimage, wavtran=no, fl_inter=no, ref='erg'+flatname, recenter=no, trace=no, fl_skysub=no, fl_gscrrej=no, fl_bias=no, fl_over=no, order=1, weights=none, slits=slit)

def plot_spaxels(inimage,verinfo):
    iraf.gemini.gmos.gfdisplay(inimage, ver=verinfo)

def wave_cal(inimage):
    iraf.gemini.gmos.gswavelength(inimage, fl_inter=yes, nlost=10)
#add coordlist!

def wave_trans(inimage,wavtranimage):
    iraf.gemini.gmos.gftransform('erg'+inimage, wavtran=wavtranimage)

def qe_corr(inimage,refimage):
    iraf.gemini.gmos.gqecorr(inimage, refimges=refimage, fl_keep=yes)

def extract(inimage

#   start reduction   #
#######################

if setup == "red":

    #load iraf packages
    iraf.load('gemini')
    iraf.load('gmos')

    #start reducing the first flat
    flat1done = False
    while (flat1done == False):
        run_flats(flat1)
        check1 = os.path.isfile('erg' + flat1base + '_1.fits')
        check2 = os.path.isfile('erg' + flat1base + '_2.fits')
        if (check1 == True) or (check2 == True):
            print('Looks like you did not get all the way through, would you like to start over?')
            print('1=yes')
            print('2=no')
            ans = raw_input('your choice:   ')
            if ans == 1:
                delete(foldername + 'database/' + 'aperg' + flat1base + '_1')
                delete(foldername + 'database/' + 'aperg' + flat1base + '_2')
                delete(foldername + 'erg' + flat1)
                delete(foldername + 'rg' + flat1)
                delete(foldername + 'g' + flat1)
            else: flat1done = True
        else: flat1done = True

    #start reducing the second flat
    flat2done = False
    while (flat2done == False):
        run_flats(flat2)
        check2 = os.path.isfile('erg' + flat2base + '_1.fits')
        if (check1 == True) or (check2 == True):
            print('Looks like you did not get all the way through, would you like to start over?')
            print('1=yes')
            print('2=no')
            ans = raw_input('your choice:   ')
            if ans == 1:
                delete(foldername + 'database/' + 'aperg' + flat2base + '_1')
                delete(foldername + 'database/' + 'aperg' + flat2base + '_2')
                delete(foldername + 'erg' + flat2)
                delete(foldername + 'rg' + flat2)
                delete(foldername + 'g' + flat2)
            else: flat2done = True
        else: flat2done = True

else:

    iraf.load('gemini')

    iraf.load('gmos')

    run_flats(flat1)
    run_flats(flat2)
<commit_msg>adding updates and corrections to iraf tasks<commit_after>import numpy as np
import pylab
import pyfits
import sys
import glob
import os
from pyraf import iraf
import glob
import time
from astropy.io import fits as fits

print '----------------------------------------------'
print 'Welcome to the Gemini data reduction pipeline!'
print '----------------------------------------------'
print ' '
print ' '

#find where user is working

mainpath = os.getcwd()

foldername=raw_input('What is the folder you are working in?    ')

#if mainpath =! foldername: break

# collect all fits files in the working directory

files = glob.glob('S*.fits')

sz = np.size(files)

wave     = np.chararray(sz,itemsize=10)
obj      = np.chararray(sz,itemsize=10)
grat     = np.chararray(sz,itemsize=10)
mask     = np.chararray(sz,itemsize=10)
obstype  = np.chararray(sz,itemsize=10)
obsclass = np.chararray(sz,itemsize=10)
date     = np.chararray(sz,itemsize=10)

for i in np.arange(0,sz):
    tmp         = pyfits.open(files[i])
    hdr         = tmp[0].header
    wave[i]     = (hdr['centwave'])
    obj[i]      = (hdr['object'])
    grat[i]     = (hdr['grating'])
    mask[i]     = (hdr['maskname'])
    obstype[i]  = (hdr['obstype'])
    obsclass[i] = (hdr['obsclass'])
    date[i]     = (hdr['date'])

if mask[0] == 'IFU-R': setup = 'blue'
if mask[0] == 'IFU-2': setup = 'red'

#for i in np.arange(0,sz):
#    print files[i],obj[i],grat[i],mask[i],obstype[i],obsclass[i],wave[i]

#select either the red or blue setups

if setup == 'blue':
    waves = np.array(['480.0', '490.0'])
    slit = 'red'
if setup == 'red':
    waves = np.array(['635.0', '640.0'])
    slit = 'both'

#pull out acquisition images

selacq = (obsclass == 'acq')
acqimages = np.extract(selacq, files)

#pull out science images

selsci1 = (obsclass == 'science') & (wave == waves[0])
sciimage1 = np.extract(selsci1,files)
n = np.size(sciimage1)
if n <= 1:
    sci11 = sciimage1[0]
    sci11base = sci11.split('.')[0]
else:
    sci11 = sciimage1[0]
    sci12 = sciimage1[1]
    sci11base = sci11.split('.')[0]
    sci12base = sci12.split('.')[0]

selsci2 = (obsclass == 'science') & (wave == waves[1])
sciimage2 = np.extract(selsci2,files)
if n <= 1:
    sci21 = sciimage2[0]
    sci21base = sci21.split('.')[0]
else:
    sci21 = sciimage2[0]
    sci22 = sciimage2[1]
    sci21base = sci21.split('.')[0]
    sci22base = sci22.split('.')[0]

#pull out arcs

selarc1 = (wave == waves[0]) & (obstype == 'ARC')
arc1 = np.extract(selarc1, files)
n = np.size(arc1)
if n <= 1:
    arc11 = arc1[0]
    arc11base = arc11.split('.')[0]
else:
    arc11 = arc1[0]
    arc12 = arc1[1]
    arc11base = arc11.split('.')[0]
    arc12base = arc12.split('.')[0]

selarc2 = (wave == waves[1]) & (obstype == 'ARC')
arc2 = np.extract(selarc2, files)
n = np.size(arc2)
if n <= 1:
    arc21 = arc2[0]
    arc21base = arc21.split('.')[0]
else:
    arc21 = arc2[0]
    arc22 = arc2[1]
    arc21base = arc21.split('.')[0]
    arc22base = arc22.split('.')[0]

#pull out flats

selflat1 = (wave == waves[0]) & (obstype == 'FLAT')
flat1 = np.extract(selflat1, files)[0]
flat1base = flat1.split('.')[0]
selflat2 = (wave == waves[1]) & (obstype == 'FLAT')
flat2 = np.extract(selflat2, files)[0]
flat2base = flat2.split('.')[0]

#pull out date

obsdate = date[0] #date should be same for all files

if obsdate == '2015-11-08': biasim='20151108bias.fits'

#pull out bias

bias1 = glob.glob('*bias*.fits')[0]
biasbase = bias1.split('.')[0]
#pull out standard star info

#if date = 2015 and setup = blue then standard star folder = ??

#pull out galaxy name

selname = (obsclass == 'science') & (wave == waves[0])
galname = np.extract(selname, obj)

#print out list
print('file name            file type    cent. wavelength')
print(flat1 + '  flat         ' + waves[0])
print(flat2 + '  flat         ' + waves[1])
print(arc11 + '  arc          ' + waves[0])
try:
    arc12
except NameError:
    pass
else:
    print(arc12 + '  arc       ' + waves[0])
print(arc21 + '  arc          ' + waves[1])
try:
    arc12
except NameError:
    pass
else:
    print(arc22 + ' arc         ' + waves[1])

print(sci11 + '  science      ' + waves[0])
try:
    sci12
except NameError:
    pass
else:
    print(sci12 + '  science      ' + waves[0])
print(sci21 + '  science      ' + waves[1])
try:
    sci22
except NameError:
    pass
else:
    print(sci22 + '  science      ' + waves[1])
print(bias1 + '    bias         ---')

print('')
print('')
print('Do these look correct to you?')
print('1=yes')
print('0=no')
ans = raw_input('your choice:   ')

if ans == '0':
    print('Whoa, a bug already?! Shoot Elaine an email.')
    sys.exit()
else:
    print('Alright, on to the reduction...')
    time.sleep(3)

def run_gfreduce(inimage,biasimage,refimage,slit,cr,wt,ss,inter,os,tr,bi,ex,fl,ap,weight):
    iraf.gemini.gmos.gfreduce(inimage, \
                              fl_inter=inter, \
                              fl_over=os, \
                              fl_trim=tr, \
                              fl_bias=bi, \
                              fl_flux=fl, \
                              fl_extract=ex, \
                              fl_gscrrej=cr, \
                              fl_wavtran=wt,
                              fl_gsappwave=ap, \
                              fl_skysub=ss, \
                              slits=slit, \
                              rawpath=foldername, \
                              weights=weight, \
                              logfile=galname[0]+'.log', \
                              bias=biasimage)

def plot_spaxels(inimage,verinfo):
    iraf.gemini.gmos.gfdisplay(inimage, ver=verinfo)

def wave_cal(inimage):
    iraf.gemini.gmos.gswavelength(inimage, fl_inter=yes, nlost=10)
#add coordlist!

def wave_trans(inimage,wavtranimage):
    iraf.gemini.gmos.gftransform('erg'+inimage, wavtran=wavtranimage)

def qe_corr(inimage,refimage):
    iraf.gemini.gmos.gqecorr(inimage, refimges=refimage, fl_keep=yes)

#######################
#   start reduction   #
#######################

if setup == "red":

    #load iraf packages
    iraf.load('gemini')
    time.sleep(3)
    iraf.load('gmos')
    time.sleep(3)

    #start reducing the first flat
    flat1done = False
    while (flat1done == False):
        run_gfreduce(flat1,bias1,'',slit,'no','no','no','yes','yes','no','yes','yes','no','no','none')
        check1 = os.path.isfile('erg' + flat1base + '_1.fits')
        check2 = os.path.isfile('erg' + flat1base + '_2.fits')
        if (check1 == True) or (check2 == True):
            print('Looks like you did not get all the way through, would you like to start over?')
            print('1=yes')
            print('0=no')
            ans = raw_input('your choice:   ')
            if ans == 1:
                delete(foldername + 'database/' + 'aperg' + flat1base + '_1')
                delete(foldername + 'database/' + 'aperg' + flat1base + '_2')
                delete(foldername + 'erg' + flat1base + '_1.fits')
                delete(foldername + 'erg' + flat1base + '_2.fits')
                delete(foldername + 'erg' + flat1)
                delete(foldername + 'rg' + flat1)
                delete(foldername + 'g' + flat1)
            else: flat1done = True
        else: flat1done = True

    #start reducing the second flat
    flat2done = False
    while (flat2done == False):
        run_gfreduce(flat1,bias1,'',slit,'no','no','no','yes','yes','no','yes','yes','no','no','none')
        check1 = os.path.isfile('erg' + flat2base + '_1.fits')
        check2 = os.path.isfile('erg' + flat2base + '_2.fits')
        if (check1 == True) or (check2 == True):
            print('Looks like you did not get all the way through, would you like to start over?')
            print('1=yes')
            print('0=no')
            ans = raw_input('your choice:   ')
            if ans == 1:
                delete(foldername + 'database/' + 'aperg' + flat2base + '_1')
                delete(foldername + 'database/' + 'aperg' + flat2base + '_2')
                delete(foldername + 'erg' + flat2base + '_1.fits')
                delete(foldername + 'erg' + flat2base + '_2.fits')
                delete(foldername + 'erg' + flat2)
                delete(foldername + 'rg' + flat2)
                delete(foldername + 'g' + flat2)
            else: flat2done = True
        else: flat2done = True

<|endoftext|>


<commit_before># These are experimental IPython magics, providing quick shortcuts for simple
# tasks. None of these save any data.

# To use, run this in an IPython shell:
# ip = get_ipython()
# ip.register_magics(BlueskyMagics)

import asyncio
import warnings
from bluesky.utils import ProgressBarManager
from bluesky import RunEngine, RunEngineInterrupted
from IPython.core.magic import Magics, magics_class, line_magic
from traitlets import MetaHasTraits
import numpy as np
import collections
from operator import attrgetter
from . import plans as bp
from . import plan_stubs as bps

try:
    # cytools is a drop-in replacement for toolz, implemented in Cython
    from cytools import partition
except ImportError:
    from toolz import partition

# This is temporarily here to allow for warnings to be printed
# we changed positioners to a property but since we never instantiate
# the class we need to add this
class MetaclassForClassProperties(MetaHasTraits, type):
    @property
    def positioners(self):
        if self._positioners:
            warnings.warn("BlueskyMagics.positioners is deprecated. "
                          "Please use the newer labels feature.")
        return self._positioners

    @positioners.setter
    def positioners(self, val):
        warnings.warn("BlueskyMagics.positioners is deprecated. "
                      "Please use the newer labels feature.")
        self._positioners = val

    @property
    def detectors(self):
        if self._detectors:
            warnings.warn("BlueskyMagics.detectors is deprecated. "
                          "Please use the newer labels feature.")
        return self._detectors

    @detectors.setter
    def detectors(self, val):
        warnings.warn("BlueskyMagics.detectors is deprecated. "
                      "Please use the newer labels feature.")
        self._detectors = val

    _positioners = []
    _detectors = []

@magics_class
class BlueskyMagics(Magics, metaclass=MetaclassForClassProperties):
    """
    IPython magics for bluesky.

    To install:

    >>> ip = get_ipython()
    >>> ip.register_magics(BlueskyMagics)

    Optionally configure default detectors and positioners by setting
    the class attributes:

    * ``BlueskyMagics.detectors``
    * ``BlueskyMagics.positioners``

    For more advanced configuration, access the magic's RunEngine instance and
    ProgressBarManager instance:

    * ``BlueskyMagics.RE``
    * ``BlueskyMagics.pbar_manager``
    """
    RE = RunEngine({}, loop=asyncio.new_event_loop())
    pbar_manager = ProgressBarManager()

    def _ensure_idle(self):
        if self.RE.state != 'idle':
            print('The RunEngine invoked by magics cannot be resumed.')
            print('Aborting...')
            self.RE.abort()

    @line_magic
    def mov(self, line):
        if len(line.split()) % 2 != 0:
            raise TypeError("Wrong parameters. Expected: "
                            "%mov motor position (or several pairs like that)")
        args = []
        for motor, pos in partition(2, line.split()):
            args.append(eval(motor, self.shell.user_ns))
            args.append(eval(pos, self.shell.user_ns))
        plan = bps.mv(*args)
        self.RE.waiting_hook = self.pbar_manager
        try:
            self.RE(plan)
        except RunEngineInterrupted:
            ...
        self.RE.waiting_hook = None
        self._ensure_idle()
        return None

    @line_magic
    def movr(self, line):
        if len(line.split()) % 2 != 0:
            raise TypeError("Wrong parameters. Expected: "
                            "%mov motor position (or several pairs like that)")
        args = []
        for motor, pos in partition(2, line.split()):
            args.append(eval(motor, self.shell.user_ns))
            args.append(eval(pos, self.shell.user_ns))
        plan = bps.mvr(*args)
        self.RE.waiting_hook = self.pbar_manager
        try:
            self.RE(plan)
        except RunEngineInterrupted:
            ...
        self.RE.waiting_hook = None
        self._ensure_idle()
        return None

    @line_magic
    def ct(self, line):
        # If the deprecated BlueskyMagics.detectors list is non-empty, it has
        # been configured by the user, and we must revert to the old behavior.
        if type(self).detectors:
            if line.strip():
                dets = eval(line, self.shell.user_ns)
            else:
                dets = type(self).detectors
        else:
            # new behaviour
            devices_dict = get_labeled_devices(user_ns=self.shell.user_ns)
            if line.strip():
                if '[' in line or ']' in line:
                    raise ValueError("It looks like you entered a list like "
                                     "`%ct [motors, detectors]` "
                                     "Magics work a bit differently than "
                                     "normal Python. Enter "
                                     "*space-separated* labels like "
                                     "`%ct motors detectors`.")
                # User has provided a white list of labels like
                # %ct label1 label2
                labels = line.strip().split()
            else:
                labels = ['detectors']
            dets = []
            for label in labels:
                dets.extend(obj for _, obj in devices_dict.get(label, []))
        plan = bp.count(dets)
        print("[This data will not be saved. "
              "Use the RunEngine to collect data.]")
        try:
            self.RE(plan, _ct_callback)
        except RunEngineInterrupted:
            ...
        self._ensure_idle()
        return None

    FMT_PREC = 6

    @line_magic
    def wa(self, line):
        "List positioner info. 'wa' stands for 'where all'."
        # If the deprecated BlueskyMagics.positioners list is non-empty, it has
        # been configured by the user, and we must revert to the old behavior.
        if type(self).positioners:
            if line.strip():
                positioners = eval(line, self.shell.user_ns)
            else:
                positioners = type(self).positioners
            if len(positioners) > 0:
                _print_positioners(positioners, precision=self.FMT_PREC)
        else:
            # new behaviour
            devices_dict = get_labeled_devices(user_ns=self.shell.user_ns)
            if line.strip():
                if '[' in line or ']' in line:
                    raise ValueError("It looks like you entered a list like "
                                     "`%wa [motors, detectors]` "
                                     "Magics work a bit differently than "
                                     "normal Python. Enter "
                                     "*space-separated* labels like "
                                     "`%wa motors detectors`.")
                # User has provided a white list of labels like
                # %wa label1 label2
                labels = line.strip().split()
            else:
                # Show all labels.
                labels = list(devices_dict.keys())
            for label in labels:
                print(label)
                try:
                    devices = devices_dict[label]
                except KeyError:
                    print('<no matches for this label>')
                    continue
                # ignore the first key
                if are_positioners(devices):
                    positioners = [positioner[1] for positioner in devices_dict[label]]
                    _print_positioners(positioners, precision=self.FMT_PREC,
                                       prefix=" "*8)
                else:
                    _print_devices(devices, prefix=" "*8)

def _print_devices(devices, prefix=""):
    cols = ["Python name", "Ophyd Name"]
    print(prefix + "{:20s} \t {:20s}".format(*cols))
    print(prefix + "="*40)
    for name, obj in devices:
        print(prefix + "{:20s} \t {:20s}".format(name, str(obj.name)))

def are_positioners(devs):
    # only true if all are positioners
    # takes ((name, dev),...) tuple
    return all(is_positioner(obj) for _, obj in devs)

def is_positioner(dev):
    return hasattr(dev, 'position')

def _print_positioners(positioners, sort=True, precision=6, prefix=""):
    '''
        This will take a list of positioners and try to print them.

        Parameters
        ----------
        positioners : list
            list of positioners

        sort : bool, optional
            whether or not to sort the list

        precision: int, optional
            The precision to use for numbers
    '''
    # sort first
    if sort:
        positioners = sorted(set(positioners), key=attrgetter('name'))

    values = []
    for p in positioners:
        try:
            values.append(p.position)
        except Exception as exc:
            values.append(exc)

    headers = ['Positioner', 'Value', 'Low Limit', 'High Limit', 'Offset']
    LINE_FMT = prefix + '{: <30} {: <11} {: <11} {: <11} {: <11}'
    lines = []
    lines.append(LINE_FMT.format(*headers))
    for p, v in zip(positioners, values):
        if not isinstance(v, Exception):
            try:
                prec = p.precision
            except Exception:
                prec = precision
            value = np.round(v, decimals=prec)
            try:
                low_limit, high_limit = p.limits
            except Exception as exc:
                low_limit = high_limit = exc.__class__.__name__
            else:
                low_limit = np.round(low_limit, decimals=prec)
                high_limit = np.round(high_limit, decimals=prec)
            try:
                offset = p.user_offset.get()
            except Exception as exc:
                offset = exc.__class__.__name__
            else:
                offset = np.round(offset, decimals=prec)
        else:
            value = v.__class__.__name__  # e.g. 'DisconnectedError'
            low_limit = high_limit = offset = ''

        lines.append(LINE_FMT.format(p.name, value, low_limit, high_limit,
                                     offset))
    print('\n'.join(lines))

def get_labeled_devices(user_ns=None, maxdepth=6):
    ''' Returns dict of labels mapped to devices with that label

        Parameters
        ----------
        user_ns : dict, optional
            The namespace to search on
            Default is to grab the namespace of the ipython shell.

        maxdepth: int, optional
            max recursion depth

        Returns
        -------
            A dictionary of (name, ophydobject) tuple indexed by device label.

        Examples
        --------
        Read devices labeled as motors:
            objs = get_labeled_devices()
            my_motors = objs['motors']
    '''
    # could be set but lists are more common for users
    obj_list = collections.defaultdict(list)

    if maxdepth <= 0:
        warnings.warn("Recursion limit exceeded")
        return obj_list

    if user_ns is None:
        user_ns = get_ipython().user_ns

    for key, obj in user_ns.items():
        # ignore objects beginning with "_"
        # (mainly for ipython stored objs from command line
        # return of commands)
        # also check its a subclass of desired classes
        if not key.startswith("_"):
            if is_parent(obj):
                labels = getattr(obj, '_ophyd_labels_', set())
                obj_list.update(get_labeled_devices(user_ns=obj.__dict__,
                                                    maxdepth=maxdepth-1,))
            else:
                if hasattr(obj, '_ophyd_labels_'):
                    # don't inherit parent labels
                    labels = obj._ophyd_labels_
                    for label in labels:
                        obj_list[label].append((key, obj))

    # Convert from defaultdict to normal dict before returning.
    return dict(obj_list)

def is_parent(dev):
    # return whether a node is a parent
    # should not have component_names, or if yes, should be empty
    # read_attrs needed to check it's an instance and not class itself
    return (isinstance(dev, type) and
            len(getattr(dev, 'component_names', [])) > 0)

def get_children(dev):
    children = list()
    if hasattr(dev, 'component_names') and len(dev.component_names) > 0:
        for comp_name in dev.component_names:
            children.append(getattr(dev, comp_name))
    return children

def _ct_callback(name, doc):
    if name != 'event':
        return
    for k, v in doc['data'].items():
        print('{: <30} {}'.format(k, v))
<commit_msg>FIX: correct labels processing<commit_after># These are experimental IPython magics, providing quick shortcuts for simple
# tasks. None of these save any data.

# To use, run this in an IPython shell:
# ip = get_ipython()
# ip.register_magics(BlueskyMagics)

import asyncio
import warnings
from bluesky.utils import ProgressBarManager
from bluesky import RunEngine, RunEngineInterrupted
from IPython.core.magic import Magics, magics_class, line_magic
from traitlets import MetaHasTraits
import numpy as np
import collections
from operator import attrgetter
from . import plans as bp
from . import plan_stubs as bps

try:
    # cytools is a drop-in replacement for toolz, implemented in Cython
    from cytools import partition
except ImportError:
    from toolz import partition

# This is temporarily here to allow for warnings to be printed
# we changed positioners to a property but since we never instantiate
# the class we need to add this
class MetaclassForClassProperties(MetaHasTraits, type):
    @property
    def positioners(self):
        if self._positioners:
            warnings.warn("BlueskyMagics.positioners is deprecated. "
                          "Please use the newer labels feature.")
        return self._positioners

    @positioners.setter
    def positioners(self, val):
        warnings.warn("BlueskyMagics.positioners is deprecated. "
                      "Please use the newer labels feature.")
        self._positioners = val

    @property
    def detectors(self):
        if self._detectors:
            warnings.warn("BlueskyMagics.detectors is deprecated. "
                          "Please use the newer labels feature.")
        return self._detectors

    @detectors.setter
    def detectors(self, val):
        warnings.warn("BlueskyMagics.detectors is deprecated. "
                      "Please use the newer labels feature.")
        self._detectors = val

    _positioners = []
    _detectors = []

@magics_class
class BlueskyMagics(Magics, metaclass=MetaclassForClassProperties):
    """
    IPython magics for bluesky.

    To install:

    >>> ip = get_ipython()
    >>> ip.register_magics(BlueskyMagics)

    Optionally configure default detectors and positioners by setting
    the class attributes:

    * ``BlueskyMagics.detectors``
    * ``BlueskyMagics.positioners``

    For more advanced configuration, access the magic's RunEngine instance and
    ProgressBarManager instance:

    * ``BlueskyMagics.RE``
    * ``BlueskyMagics.pbar_manager``
    """
    RE = RunEngine({}, loop=asyncio.new_event_loop())
    pbar_manager = ProgressBarManager()

    def _ensure_idle(self):
        if self.RE.state != 'idle':
            print('The RunEngine invoked by magics cannot be resumed.')
            print('Aborting...')
            self.RE.abort()

    @line_magic
    def mov(self, line):
        if len(line.split()) % 2 != 0:
            raise TypeError("Wrong parameters. Expected: "
                            "%mov motor position (or several pairs like that)")
        args = []
        for motor, pos in partition(2, line.split()):
            args.append(eval(motor, self.shell.user_ns))
            args.append(eval(pos, self.shell.user_ns))
        plan = bps.mv(*args)
        self.RE.waiting_hook = self.pbar_manager
        try:
            self.RE(plan)
        except RunEngineInterrupted:
            ...
        self.RE.waiting_hook = None
        self._ensure_idle()
        return None

    @line_magic
    def movr(self, line):
        if len(line.split()) % 2 != 0:
            raise TypeError("Wrong parameters. Expected: "
                            "%mov motor position (or several pairs like that)")
        args = []
        for motor, pos in partition(2, line.split()):
            args.append(eval(motor, self.shell.user_ns))
            args.append(eval(pos, self.shell.user_ns))
        plan = bps.mvr(*args)
        self.RE.waiting_hook = self.pbar_manager
        try:
            self.RE(plan)
        except RunEngineInterrupted:
            ...
        self.RE.waiting_hook = None
        self._ensure_idle()
        return None

    @line_magic
    def ct(self, line):
        # If the deprecated BlueskyMagics.detectors list is non-empty, it has
        # been configured by the user, and we must revert to the old behavior.
        if type(self).detectors:
            if line.strip():
                dets = eval(line, self.shell.user_ns)
            else:
                dets = type(self).detectors
        else:
            # new behaviour
            devices_dict = get_labeled_devices(user_ns=self.shell.user_ns)
            if line.strip():
                if '[' in line or ']' in line:
                    raise ValueError("It looks like you entered a list like "
                                     "`%ct [motors, detectors]` "
                                     "Magics work a bit differently than "
                                     "normal Python. Enter "
                                     "*space-separated* labels like "
                                     "`%ct motors detectors`.")
                # User has provided a white list of labels like
                # %ct label1 label2
                labels = line.strip().split()
            else:
                labels = ['detectors']
            dets = []
            for label in labels:
                dets.extend(obj for _, obj in devices_dict.get(label, []))
        plan = bp.count(dets)
        print("[This data will not be saved. "
              "Use the RunEngine to collect data.]")
        try:
            self.RE(plan, _ct_callback)
        except RunEngineInterrupted:
            ...
        self._ensure_idle()
        return None

    FMT_PREC = 6

    @line_magic
    def wa(self, line):
        "List positioner info. 'wa' stands for 'where all'."
        # If the deprecated BlueskyMagics.positioners list is non-empty, it has
        # been configured by the user, and we must revert to the old behavior.
        if type(self).positioners:
            if line.strip():
                positioners = eval(line, self.shell.user_ns)
            else:
                positioners = type(self).positioners
            if len(positioners) > 0:
                _print_positioners(positioners, precision=self.FMT_PREC)
        else:
            # new behaviour
            devices_dict = get_labeled_devices(user_ns=self.shell.user_ns)
            if line.strip():
                if '[' in line or ']' in line:
                    raise ValueError("It looks like you entered a list like "
                                     "`%wa [motors, detectors]` "
                                     "Magics work a bit differently than "
                                     "normal Python. Enter "
                                     "*space-separated* labels like "
                                     "`%wa motors detectors`.")
                # User has provided a white list of labels like
                # %wa label1 label2
                labels = line.strip().split()
            else:
                # Show all labels.
                labels = list(devices_dict.keys())
            for label in labels:
                print(label)
                try:
                    devices = devices_dict[label]
                except KeyError:
                    print('<no matches for this label>')
                    continue
                # ignore the first key
                if are_positioners(devices):
                    positioners = [positioner[1] for positioner in devices_dict[label]]
                    _print_positioners(positioners, precision=self.FMT_PREC,
                                       prefix=" "*8)
                else:
                    _print_devices(devices, prefix=" "*8)

def _print_devices(devices, prefix=""):
    cols = ["Python name", "Ophyd Name"]
    print(prefix + "{:20s} \t {:20s}".format(*cols))
    print(prefix + "="*40)
    for name, obj in devices:
        print(prefix + "{:20s} \t {:20s}".format(name, str(obj.name)))

def are_positioners(devs):
    # only true if all are positioners
    # takes ((name, dev),...) tuple
    return all(is_positioner(obj) for _, obj in devs)

def is_positioner(dev):
    return hasattr(dev, 'position')

def _print_positioners(positioners, sort=True, precision=6, prefix=""):
    '''
        This will take a list of positioners and try to print them.

        Parameters
        ----------
        positioners : list
            list of positioners

        sort : bool, optional
            whether or not to sort the list

        precision: int, optional
            The precision to use for numbers
    '''
    # sort first
    if sort:
        positioners = sorted(set(positioners), key=attrgetter('name'))

    values = []
    for p in positioners:
        try:
            values.append(p.position)
        except Exception as exc:
            values.append(exc)

    headers = ['Positioner', 'Value', 'Low Limit', 'High Limit', 'Offset']
    LINE_FMT = prefix + '{: <30} {: <11} {: <11} {: <11} {: <11}'
    lines = []
    lines.append(LINE_FMT.format(*headers))
    for p, v in zip(positioners, values):
        if not isinstance(v, Exception):
            try:
                prec = p.precision
            except Exception:
                prec = precision
            value = np.round(v, decimals=prec)
            try:
                low_limit, high_limit = p.limits
            except Exception as exc:
                low_limit = high_limit = exc.__class__.__name__
            else:
                low_limit = np.round(low_limit, decimals=prec)
                high_limit = np.round(high_limit, decimals=prec)
            try:
                offset = p.user_offset.get()
            except Exception as exc:
                offset = exc.__class__.__name__
            else:
                offset = np.round(offset, decimals=prec)
        else:
            value = v.__class__.__name__  # e.g. 'DisconnectedError'
            low_limit = high_limit = offset = ''

        lines.append(LINE_FMT.format(p.name, value, low_limit, high_limit,
                                     offset))
    print('\n'.join(lines))

def get_labeled_devices(user_ns=None, maxdepth=6):
    ''' Returns dict of labels mapped to devices with that label

        Parameters
        ----------
        user_ns : dict, optional
            The namespace to search on
            Default is to grab the namespace of the ipython shell.

        maxdepth: int, optional
            max recursion depth

        Returns
        -------
            A dictionary of (name, ophydobject) tuple indexed by device label.

        Examples
        --------
        Read devices labeled as motors:
            objs = get_labeled_devices()
            my_motors = objs['motors']
    '''
    # could be set but lists are more common for users
    obj_list = collections.defaultdict(list)

    if maxdepth <= 0:
        warnings.warn("Recursion limit exceeded")
        return obj_list

    if user_ns is None:
        user_ns = get_ipython().user_ns

    for key, obj in user_ns.items():
        # ignore objects beginning with "_"
        # (mainly for ipython stored objs from command line
        # return of commands)
        # also check its a subclass of desired classes
        if not key.startswith("_"):
            if hasattr(obj, '_ophyd_labels_'):
                # don't inherit parent labels
                labels = obj._ophyd_labels_
                for label in labels:
                    obj_list[label].append((key, obj))

                if is_parent(obj):
                    for c_key, v in get_labeled_devices(user_ns={k: getattr(obj, k)
                                                             for k in obj.read_attrs
                                                             if '.' not in k},
                                                        maxdepth=maxdepth-1,
                                                       ).items():
                        obj_list[c_key].extend([('.'.join([key, ot[0]]), ot[1]) for ot in v])

    # Convert from defaultdict to normal dict before returning.
    return dict(obj_list)

def is_parent(dev):
    # return whether a node is a parent
    # should not have component_names, or if yes, should be empty
    # read_attrs needed to check it's an instance and not class itself
    return (not isinstance(dev, type) and
            len(getattr(dev, 'component_names', [])) > 0)

def get_children(dev):
    children = list()
    if hasattr(dev, 'component_names') and len(dev.component_names) > 0:
        for comp_name in dev.component_names:
            children.append(getattr(dev, comp_name))
    return children

def _ct_callback(name, doc):
    if name != 'event':
        return
    for k, v in doc['data'].items():
        print('{: <30} {}'.format(k, v))
<|endoftext|>


<commit_before>from .effect import Effect, SnpEff, VEP, OldSnpEff, BCFT

__version__ = "0.3.1"
<commit_msg>bump version<commit_after>from .effect import Effect, SnpEff, VEP, OldSnpEff, BCFT

__version__ = "0.3.2"
<|endoftext|>


<commit_before>from StringIO import StringIO
from functools import partial
from unittest import TestCase, skip
import os

from bp.filepath import FilePath
from bp.memory import MemoryFS, MemoryPath

from mkenv import find
from mkenv.common import Locator

class TestFind(TestCase):
    def setUp(self):
        self.stdin = StringIO()
        self.stdout = StringIO()
        self.stderr = StringIO()

        self.fs = MemoryFS()
        self.locator = Locator(root=MemoryPath(fs=self.fs))

    def run_cli(self, argv=(), exit_status=os.EX_OK):
        find.run(
            argv=argv,
            stdin=self.stdin,
            stdout=self.stdout,
            stderr=self.stderr,
            exit=partial(self.assertEqual, exit_status),
            arguments={"locator" : self.locator},
        )
        return (
            self.stdin.getvalue(),
            self.stdout.getvalue(),
            self.stderr.getvalue(),
        )

    def test_find_without_args_finds_the_virtualenv_root(self):
        stdin, stdout, stderr = self.run_cli()
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.root.path + "\n", ""),
        )

    def test_find_d_finds_envs_by_directory(self):
        this_dir = FilePath(__file__).parent()
        stdin, stdout, stderr = self.run_cli(["-d", this_dir.path])
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.for_directory(this_dir).path + "\n", ""),
        )

    def test_find_d_defaults_to_cwd(self):
        stdin, stdout, stderr = self.run_cli(["-d"])
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.for_directory(FilePath(".")).path + "\n", ""),
        )

    def test_find_n_finds_envs_by_name(self):
        stdin, stdout, stderr = self.run_cli(["-n", "bla"])
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.for_name("bla").path + "\n", ""),
        )

    def test_find_existing_fails_for_non_existing_virtualenvs(self):
        stdin, stdout, stderr = self.run_cli(
            ["-n", "bla", "--existing-only"], exit_status=1,
        )
        self.assertEqual((stdin, stdout, stderr), ("", "", ""))

    @skip("Skipped until bp supports some more nice things in MemoryPath.")
    def test_find_existing_succeeds_for_existing_virtualenvs(self):
        # TODO: Should probably use make.
        MemoryPath(fs=self.fs, path="bla").createDirectory()
        stdin, stdout, stderr = self.run_cli(["-n", "bla", "--existing-only"])
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.for_directory("bla").path + "\n", ""),
        )
<commit_msg>Fix the test, now it works.<commit_after>from StringIO import StringIO
from functools import partial
from unittest import TestCase, skip
import os

from bp.filepath import FilePath
from bp.memory import MemoryFS, MemoryPath

from mkenv import find
from mkenv.common import Locator

class TestFind(TestCase):
    def setUp(self):
        self.stdin = StringIO()
        self.stdout = StringIO()
        self.stderr = StringIO()

        self.fs = MemoryFS()
        self.locator = Locator(root=MemoryPath(fs=self.fs))

    def run_cli(self, argv=(), exit_status=os.EX_OK):
        find.run(
            argv=argv,
            stdin=self.stdin,
            stdout=self.stdout,
            stderr=self.stderr,
            exit=partial(self.assertEqual, exit_status),
            arguments={"locator" : self.locator},
        )
        return (
            self.stdin.getvalue(),
            self.stdout.getvalue(),
            self.stderr.getvalue(),
        )

    def test_find_without_args_finds_the_virtualenv_root(self):
        stdin, stdout, stderr = self.run_cli()
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.root.path + "\n", ""),
        )

    def test_find_d_finds_envs_by_directory(self):
        this_dir = FilePath(__file__).parent()
        stdin, stdout, stderr = self.run_cli(["-d", this_dir.path])
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.for_directory(this_dir).path + "\n", ""),
        )

    def test_find_d_defaults_to_cwd(self):
        stdin, stdout, stderr = self.run_cli(["-d"])
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.for_directory(FilePath(".")).path + "\n", ""),
        )

    def test_find_n_finds_envs_by_name(self):
        stdin, stdout, stderr = self.run_cli(["-n", "bla"])
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.for_name("bla").path + "\n", ""),
        )

    def test_find_existing_fails_for_non_existing_virtualenvs(self):
        stdin, stdout, stderr = self.run_cli(
            ["-n", "bla", "--existing-only"], exit_status=1,
        )
        self.assertEqual((stdin, stdout, stderr), ("", "", ""))

    def test_find_existing_succeeds_for_existing_virtualenvs(self):
        MemoryPath(fs=self.fs, path=("bla",)).createDirectory()
        stdin, stdout, stderr = self.run_cli(["-n", "bla", "--existing-only"])
        self.assertEqual(
            (stdin, stdout, stderr),
            ("", self.locator.for_name("bla").path + "\n", ""),
        )
<|endoftext|>


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

class Dealer(object):
    """ It deals investors Generation kWh use rights to contracts according its
        availability and investors criteria.
    """

    def is_active(self,
            contract_id, start_date, end_date):
        """ Returns True if contract_id has generation kwh activated
            during the period"""
        return False

    def get_available_kwh(self, contract_id, start_date, end_date, fare, period):
        """ Returns generationkwh [kWh] available for contract_id during the
            date interval, fare and period"""
        return 40

    def use_kwh(self, contract_id, start_date, end_date, fare, period, kwh):
        """Marks the indicated kwh as used, if available, for the contract,
           date interval, fare and period and returns the ones efectively used.
        """
        return kwh

    def refund_kwh(self, contract_id, start_date, end_date, fare, period, kwh):
        """Refunds the indicated kwh, marking them as available again, for the
           contract, date interval, fare and period and returns the ones
           efectively used.
        """
        pass

# vim: ts=4 sw=4 et
<commit_msg>IMP Development mockup update<commit_after># -*- encoding: utf-8 -*-

class Dealer(object):
    """ It deals investors Generation kWh use rights to contracts according its
        availability and investors criteria.
    """

    def is_active(self,
            contract_id, start_date, end_date):
        """ Returns True if contract_id has generation kwh activated
            during the period"""
        if contract_id == 4:
            return True
        return False

    # Do not use for invoicing, ONLY statistics
    def get_available_kwh(self, contract_id, start_date, end_date, fare, period):
        """ Returns generationkwh [kWh] available for contract_id during the
            date interval, fare and period"""
        return 40

    def use_kwh(self, contract_id, start_date, end_date, fare, period, kwh):
        """Marks the indicated kwh as used, if available, for the contract,
           date interval, fare and period and returns the ones efectively used.
        """
        return [
            {'member_id': 13, 'kwh': int(round(kwh / 2))},
            {'member_id': 42, 'kwh': int(round(kwh / 4))}
        ]

    def refund_kwh(self, contract_id, start_date, end_date, fare, period, kwh,
                   partner_id):
        """Refunds the indicated kwh, marking them as available again, for the
           contract, date interval, fare and period and returns the ones
           efectively used.
        """
        pass

# vim: ts=4 sw=4 et
<|endoftext|>