<commit_before>import datetime
import logging
import re
import time
import urllib2
from urlparse import urljoin

from django.db import transaction

import lxml.html
import requests

from parliament.committees.models import (Committee, CommitteeMeeting,
    CommitteeActivity, CommitteeActivityInSession,
    CommitteeInSession)
from parliament.core.models import Session
from parliament.hansards.models import Document

logger = logging.getLogger(__name__)

COMMITTEE_LIST_URL = 'http://www.parl.gc.ca/Committees/en/List?parl=%d&session=%d'
@transaction.atomic
def import_committee_list(session=None):
    if session is None:
        session = Session.objects.current()

    def make_committee(name_en, acronym, parent=None):
        try:
            return Committee.objects.get_by_acronym(acronym, session)
        except Committee.DoesNotExist:
            committee, created = Committee.objects.get_or_create(name_en=name_en.strip(), parent=parent)
            if created:
                logger.warning(u"Creating committee: %s, %s" % (committee.name_en, committee.slug))
            CommitteeInSession.objects.get_or_create(
                committee=committee, session=session, acronym=acronym)
            return committee

    resp = requests.get(COMMITTEE_LIST_URL % (session.parliamentnum, session.sessnum))
    resp.raise_for_status()
    root = lxml.html.fromstring(resp.text)

    found = False
    for cmte_div in root.cssselect('.committees-list .accordion-item'):
        acronym = cmte_div.cssselect('.accordion-bar-title .committee-acronym-cell')
        assert len(acronym) == 1
        acronym = acronym[0].text_content()

        name = cmte_div.cssselect('.accordion-bar-title .committee-name')
        assert len(name) == 1
        name = name[0].text_content()
        com = make_committee(name, acronym)
        found = True

        for sub in cmte_div.cssselect('.subcommittee-item .subcommittee-name'):
            match = re.search(r'^(.+) \(([A-Z0-9]{3,5})\)$', sub.text_content())
            (name, acronym) = match.groups()
            make_committee(name, acronym, parent=com)

    if not found:
        logger.error("No committees in list")

    return True

def _docid_from_url(u):
    return int(re.search(r'(Doc|publication)Id=(\d+)&', u).group(2))

def _12hr(hour, ampm):
    hour = int(hour)
    hour += 12 * bool('p' in ampm.lower())
    if hour % 12 == 0:
        # noon, midnight
        hour -= 12
    return hour

def _parse_date(d):
    """datetime objects from e.g. March 11, 2011"""
    return datetime.date(
        *time.strptime(d, '%B %d, %Y')[:3]
    )

def import_committee_documents(session):
    for comm in Committee.objects.filter(sessions=session).order_by('-parent'):
        # subcommittees last
        import_committee_meetings(comm, session)
        #import_committee_reports(comm, session)
        #time.sleep(1)

COMMITTEE_MEETINGS_URL = 'http://www.parl.gc.ca/Committees/en/%(acronym)s/Meetings?parl=%(parliamentnum)d&session=%(sessnum)d'
@transaction.atomic
def import_committee_meetings(committee, session):

    acronym = committee.get_acronym(session)
    url = COMMITTEE_MEETINGS_URL % {'acronym': acronym,
        'parliamentnum': session.parliamentnum,
        'sessnum': session.sessnum}
    resp = urllib2.urlopen(url)
    tree = lxml.html.parse(resp)
    root = tree.getroot()
    for mtg_row in root.cssselect('#meeting-accordion .accordion-item'):
        source_id = mtg_row.get('id')
        assert source_id.startswith('meeting-item-')
        source_id = int(source_id.replace('meeting-item-', '').strip())

        number = int(re.sub(r'\D', '', mtg_row.cssselect('.meeting-title .meeting-number')[0].text))
        assert number > 0
        try:
            meeting = CommitteeMeeting.objects.select_related('evidence').get(
                committee=committee, session=session, number=number)
        except CommitteeMeeting.DoesNotExist:
            meeting = CommitteeMeeting(committee=committee,
                session=session, number=number)

        if meeting.source_id:
            if meeting.source_id != source_id:
                logger.error("Source ID mismatch for %s meeting %s %s" % (committee, number, source_id))
                continue
        else:
            meeting.source_id = source_id
            if meeting.id:
                meeting.save()

        date_string = mtg_row.cssselect('.meeting-title .date-label')[0].text
        if date_string == 'Today':
            meeting.date = datetime.date.today()
        elif date_string == 'Tomorrow':
            meeting.date = datetime.date.today() + datetime.timedelta(days=1)
        else:
            meeting.date = _parse_date(date_string.partition(', ')[2]) # partition is to split off day of week

        timestring = mtg_row.cssselect('.the-time')[0].text_content()
        match = re.search(r'(\d\d?):(\d\d) ([ap]m)(?: - (\d\d?):(\d\d) ([ap]m))?\s\(',
            timestring, re.UNICODE)
        meeting.start_time = datetime.time(_12hr(match.group(1), match.group(3)), int(match.group(2)))
        if match.group(4):
            meeting.end_time = datetime.time(_12hr(match.group(4), match.group(6)), int(match.group(5)))

        notice_link = mtg_row.cssselect('a.btn-meeting-notice')
        if notice_link:
            meeting.notice = _docid_from_url(notice_link[0].get('href'))
        minutes_link = mtg_row.cssselect('a.btn-meeting-minutes')
        if minutes_link:
            meeting.minutes = _docid_from_url(minutes_link[0].get('href'))

        evidence_link = mtg_row.cssselect('a.btn-meeting-evidence')
        if evidence_link:
            evidence_id = _docid_from_url(evidence_link[0].get('href'))
            if meeting.evidence_id:
                if meeting.evidence.source_id != evidence_id:
                    raise Exception("Evidence docid mismatch for %s %s: %s %s" %
                        (committee.acronym, number, evidence_id, meeting.evidence.source_id))
                else:
                    # Evidence hasn't changed; we don't need to worry about updating
                    continue
            else:
                if Document.objects.filter(source_id=evidence_id).exists():
                    raise Exception("Found evidence source_id %s, but it already exists" % evidence_id)
                meeting.evidence = Document.objects.create(
                    source_id=evidence_id,
                    date=meeting.date,
                    session=session,
                    document_type=Document.EVIDENCE)

        meeting.webcast = bool(mtg_row.cssselect('.btn-meeting-parlvu'))
        meeting.in_camera = bool(mtg_row.cssselect('.meeting-title i[title*="in camera"]'))
        if not meeting.televised:
            meeting.televised = bool(mtg_row.cssselect('.meeting-title .icon-television'))
        if not meeting.travel:
            meeting.travel = bool(mtg_row.cssselect('.meeting-title .icon-plane'))

        meeting.save()

        for study_link in mtg_row.cssselect('.meeting-card-study a'):
            name = study_link.text.strip()
            study = get_activity_by_url(study_link.get('href'),
                committee=committee, session=session)
            meeting.activities.add(study)

    return True

def get_activity_by_url(activity_url, committee, session):
    activity_id = int(re.search(r'(studyActivityId|Stac)=(\d+)', activity_url).group(2))
    activity_url = urljoin(COMMITTEE_MEETINGS_URL, activity_url)

    try:
        return CommitteeActivityInSession.objects.get(source_id=activity_id).activity
    except CommitteeActivityInSession.DoesNotExist:
        pass

    activity = CommitteeActivity(committee=committee)
    activity.study = True # not parsing this at the moment
    root = lxml.html.parse(urllib2.urlopen(activity_url)).getroot()

    activity.name_en = root.cssselect('.core-content h2')[0].text.strip()[:500]

    # See if this already exists for another session
    try:
        activity = CommitteeActivity.objects.get(
            committee=activity.committee,
            # study=activity.study,
            name_en=activity.name_en
        )
    except CommitteeActivity.DoesNotExist:
        url = activity_url.replace('/en/', '/fr/')
        root = lxml.html.parse(urllib2.urlopen(url)).getroot()
        activity.name_fr = root.cssselect('.core-content h2')[0].text.strip()[:500]
        activity.save()

    if CommitteeActivityInSession.objects.exclude(source_id=activity_id).filter(
            session=session, activity=activity).exists():
        logger.info("Apparent duplicate activity ID for %s %s %s: %s" %
                     (activity, activity.committee, session, activity_id))
        return activity

    CommitteeActivityInSession.objects.create(
        session=session,
        activity=activity,
        source_id=activity_id
    )
    return activity

# The report scraper is for a previous version of parl.gc.ca, and has not been updated.
#
# COMMITTEE_REPORT_URL = 'http://www2.parl.gc.ca/CommitteeBusiness/ReportsResponses.aspx?Cmte=%(acronym)s&Language=E&Mode=1&Parl=%(parliamentnum)d&Ses=%(sessnum)d'
# @transaction.commit_on_success
# def import_committee_reports(committee, session):
#     # FIXME rework to parse out the single all-reports page?
#     acronym = committee.get_acronym(session)
#     url = COMMITTEE_REPORT_URL % {'acronym': acronym,
#         'parliamentnum': session.parliamentnum,
#         'sessnum': session.sessnum}
#     tree = lxml.html.parse(urllib2.urlopen(url))

#     def _import_report(report_link, parent=None):
#         report_docid = _docid_from_url(report_link.get('href'))
#         try:
#             report = CommitteeReport.objects.get(committee=committee,
#                 session=session, source_id=report_docid, parent=parent)
#             if report.presented_date:
#                 # We can consider this report fully parsed
#                 return report
#         except CommitteeReport.DoesNotExist:
#             if CommitteeReport.objects.filter(source_id=report_docid).exists():
#                 if committee.parent and \
#                   CommitteeReport.objects.filter(source_id=report_docid, committee=committee.parent).exists():
#                     # Reference to parent committee report
#                     return None
#                 else:
#                     raise Exception("Duplicate report ID %s on %s" % (report_docid, url))
#             report = CommitteeReport(committee=committee,
#                 session=session, source_id=report_docid, parent=parent)
#             report_name = report_link.text.strip()
#             match = re.search(r'^Report (\d+) - (.+)', report_name)
#             if match:
#                 report.number = int(match.group(1))
#                 report.name_en = match.group(2).strip()
#             else:
#                 report.name_en = report_name
#             report.name_en = report.name_en[:500]
#             report.government_response = bool(report_link.xpath("../span[contains(., 'Government Response')]"))

#         match = re.search(r'Adopted by the Committee on ([a-zA-Z0-9, ]+)', report_link.tail or '')
#         if match:
#             report.adopted_date = _parse_date(match.group(1))
#         match = re.search(r'Presented to the House on ([a-zA-Z0-9, ]+)', report_link.tail or '')
#         if match:
#             report.presented_date = _parse_date(match.group(1))
#         report.save()
#         return report

#     for item in tree.getroot().cssselect('.TocReportItemText'):
#         report_link = item.xpath('./a')[0]
#         report = _import_report(report_link)
#         for response_link in item.cssselect('.TocResponseItemText a'):
#             _import_report(response_link, parent=report)

#     return True
<commit_msg>update committee date parsing<commit_after>import datetime
import logging
import re
import time
import urllib2
from urlparse import urljoin

from django.db import transaction

import lxml.html
import requests

from parliament.committees.models import (Committee, CommitteeMeeting,
    CommitteeActivity, CommitteeActivityInSession,
    CommitteeInSession)
from parliament.core.models import Session
from parliament.hansards.models import Document

logger = logging.getLogger(__name__)

COMMITTEE_LIST_URL = 'http://www.parl.gc.ca/Committees/en/List?parl=%d&session=%d'
@transaction.atomic
def import_committee_list(session=None):
    if session is None:
        session = Session.objects.current()

    def make_committee(name_en, acronym, parent=None):
        try:
            return Committee.objects.get_by_acronym(acronym, session)
        except Committee.DoesNotExist:
            committee, created = Committee.objects.get_or_create(name_en=name_en.strip(), parent=parent)
            if created:
                logger.warning(u"Creating committee: %s, %s" % (committee.name_en, committee.slug))
            CommitteeInSession.objects.get_or_create(
                committee=committee, session=session, acronym=acronym)
            return committee

    resp = requests.get(COMMITTEE_LIST_URL % (session.parliamentnum, session.sessnum))
    resp.raise_for_status()
    root = lxml.html.fromstring(resp.text)

    found = False
    for cmte_div in root.cssselect('.committees-list .accordion-item'):
        acronym = cmte_div.cssselect('.accordion-bar-title .committee-acronym-cell')
        assert len(acronym) == 1
        acronym = acronym[0].text_content()

        name = cmte_div.cssselect('.accordion-bar-title .committee-name')
        assert len(name) == 1
        name = name[0].text_content()
        com = make_committee(name, acronym)
        found = True

        for sub in cmte_div.cssselect('.subcommittee-item .subcommittee-name'):
            match = re.search(r'^(.+) \(([A-Z0-9]{3,5})\)$', sub.text_content())
            (name, acronym) = match.groups()
            make_committee(name, acronym, parent=com)

    if not found:
        logger.error("No committees in list")

    return True

def _docid_from_url(u):
    return int(re.search(r'(Doc|publication)Id=(\d+)&', u).group(2))

def _12hr(hour, ampm):
    hour = int(hour)
    hour += 12 * bool('p' in ampm.lower())
    if hour % 12 == 0:
        # noon, midnight
        hour -= 12
    return hour

def _parse_date(d):
    """datetime objects from e.g. March 11, 2011"""
    return datetime.date(
        *time.strptime(d, '%B %d, %Y')[:3]
    )

def import_committee_documents(session):
    for comm in Committee.objects.filter(sessions=session).order_by('-parent'):
        # subcommittees last
        import_committee_meetings(comm, session)
        #import_committee_reports(comm, session)
        #time.sleep(1)

COMMITTEE_MEETINGS_URL = 'http://www.parl.gc.ca/Committees/en/%(acronym)s/Meetings?parl=%(parliamentnum)d&session=%(sessnum)d'
@transaction.atomic
def import_committee_meetings(committee, session):

    acronym = committee.get_acronym(session)
    url = COMMITTEE_MEETINGS_URL % {'acronym': acronym,
        'parliamentnum': session.parliamentnum,
        'sessnum': session.sessnum}
    resp = urllib2.urlopen(url)
    tree = lxml.html.parse(resp)
    root = tree.getroot()
    for mtg_row in root.cssselect('#meeting-accordion .accordion-item'):
        source_id = mtg_row.get('id')
        assert source_id.startswith('meeting-item-')
        source_id = int(source_id.replace('meeting-item-', '').strip())

        number = int(re.sub(r'\D', '', mtg_row.cssselect('.meeting-title .meeting-number')[0].text))
        assert number > 0
        try:
            meeting = CommitteeMeeting.objects.select_related('evidence').get(
                committee=committee, session=session, number=number)
        except CommitteeMeeting.DoesNotExist:
            meeting = CommitteeMeeting(committee=committee,
                session=session, number=number)

        if meeting.source_id:
            if meeting.source_id != source_id:
                logger.error("Source ID mismatch for %s meeting %s %s" % (committee, number, source_id))
                continue
        else:
            meeting.source_id = source_id
            if meeting.id:
                meeting.save()

        date_string = mtg_row.cssselect('.meeting-title .date-label')[0]
        if date_string in ('Earlier Today', 'Later Today', 'In Progress', 'Tomorrow'):
            match = re.search(r'-(20\d\d)-(\d\d)-(\d\d)', mtg_row.get('class'))
            assert match
            meeting.date = datetime.date(int(match.group(1)), int(match.group(2)), int(match.group(3)))
        else:
            meeting.date = _parse_date(date_string.partition(', ')[2]) # partition is to split off day of week

        timestring = mtg_row.cssselect('.the-time')[0].text_content()
        match = re.search(r'(\d\d?):(\d\d) ([ap]m)(?: - (\d\d?):(\d\d) ([ap]m))?\s\(',
            timestring, re.UNICODE)
        meeting.start_time = datetime.time(_12hr(match.group(1), match.group(3)), int(match.group(2)))
        if match.group(4):
            meeting.end_time = datetime.time(_12hr(match.group(4), match.group(6)), int(match.group(5)))

        notice_link = mtg_row.cssselect('a.btn-meeting-notice')
        if notice_link:
            meeting.notice = _docid_from_url(notice_link[0].get('href'))
        minutes_link = mtg_row.cssselect('a.btn-meeting-minutes')
        if minutes_link:
            meeting.minutes = _docid_from_url(minutes_link[0].get('href'))

        evidence_link = mtg_row.cssselect('a.btn-meeting-evidence')
        if evidence_link:
            evidence_id = _docid_from_url(evidence_link[0].get('href'))
            if meeting.evidence_id:
                if meeting.evidence.source_id != evidence_id:
                    raise Exception("Evidence docid mismatch for %s %s: %s %s" %
                        (committee.acronym, number, evidence_id, meeting.evidence.source_id))
                else:
                    # Evidence hasn't changed; we don't need to worry about updating
                    continue
            else:
                if Document.objects.filter(source_id=evidence_id).exists():
                    raise Exception("Found evidence source_id %s, but it already exists" % evidence_id)
                meeting.evidence = Document.objects.create(
                    source_id=evidence_id,
                    date=meeting.date,
                    session=session,
                    document_type=Document.EVIDENCE)

        meeting.webcast = bool(mtg_row.cssselect('.btn-meeting-parlvu'))
        meeting.in_camera = bool(mtg_row.cssselect('.meeting-title i[title*="in camera"]'))
        if not meeting.televised:
            meeting.televised = bool(mtg_row.cssselect('.meeting-title .icon-television'))
        if not meeting.travel:
            meeting.travel = bool(mtg_row.cssselect('.meeting-title .icon-plane'))

        meeting.save()

        for study_link in mtg_row.cssselect('.meeting-card-study a'):
            name = study_link.text.strip()
            study = get_activity_by_url(study_link.get('href'),
                committee=committee, session=session)
            meeting.activities.add(study)

    return True

def get_activity_by_url(activity_url, committee, session):
    activity_id = int(re.search(r'(studyActivityId|Stac)=(\d+)', activity_url).group(2))
    activity_url = urljoin(COMMITTEE_MEETINGS_URL, activity_url)

    try:
        return CommitteeActivityInSession.objects.get(source_id=activity_id).activity
    except CommitteeActivityInSession.DoesNotExist:
        pass

    activity = CommitteeActivity(committee=committee)
    activity.study = True # not parsing this at the moment
    root = lxml.html.parse(urllib2.urlopen(activity_url)).getroot()

    activity.name_en = root.cssselect('.core-content h2')[0].text.strip()[:500]

    # See if this already exists for another session
    try:
        activity = CommitteeActivity.objects.get(
            committee=activity.committee,
            # study=activity.study,
            name_en=activity.name_en
        )
    except CommitteeActivity.DoesNotExist:
        url = activity_url.replace('/en/', '/fr/')
        root = lxml.html.parse(urllib2.urlopen(url)).getroot()
        activity.name_fr = root.cssselect('.core-content h2')[0].text.strip()[:500]
        activity.save()

    if CommitteeActivityInSession.objects.exclude(source_id=activity_id).filter(
            session=session, activity=activity).exists():
        logger.info("Apparent duplicate activity ID for %s %s %s: %s" %
                     (activity, activity.committee, session, activity_id))
        return activity

    CommitteeActivityInSession.objects.create(
        session=session,
        activity=activity,
        source_id=activity_id
    )
    return activity

# The report scraper is for a previous version of parl.gc.ca, and has not been updated.
#
# COMMITTEE_REPORT_URL = 'http://www2.parl.gc.ca/CommitteeBusiness/ReportsResponses.aspx?Cmte=%(acronym)s&Language=E&Mode=1&Parl=%(parliamentnum)d&Ses=%(sessnum)d'
# @transaction.commit_on_success
# def import_committee_reports(committee, session):
#     # FIXME rework to parse out the single all-reports page?
#     acronym = committee.get_acronym(session)
#     url = COMMITTEE_REPORT_URL % {'acronym': acronym,
#         'parliamentnum': session.parliamentnum,
#         'sessnum': session.sessnum}
#     tree = lxml.html.parse(urllib2.urlopen(url))

#     def _import_report(report_link, parent=None):
#         report_docid = _docid_from_url(report_link.get('href'))
#         try:
#             report = CommitteeReport.objects.get(committee=committee,
#                 session=session, source_id=report_docid, parent=parent)
#             if report.presented_date:
#                 # We can consider this report fully parsed
#                 return report
#         except CommitteeReport.DoesNotExist:
#             if CommitteeReport.objects.filter(source_id=report_docid).exists():
#                 if committee.parent and \
#                   CommitteeReport.objects.filter(source_id=report_docid, committee=committee.parent).exists():
#                     # Reference to parent committee report
#                     return None
#                 else:
#                     raise Exception("Duplicate report ID %s on %s" % (report_docid, url))
#             report = CommitteeReport(committee=committee,
#                 session=session, source_id=report_docid, parent=parent)
#             report_name = report_link.text.strip()
#             match = re.search(r'^Report (\d+) - (.+)', report_name)
#             if match:
#                 report.number = int(match.group(1))
#                 report.name_en = match.group(2).strip()
#             else:
#                 report.name_en = report_name
#             report.name_en = report.name_en[:500]
#             report.government_response = bool(report_link.xpath("../span[contains(., 'Government Response')]"))

#         match = re.search(r'Adopted by the Committee on ([a-zA-Z0-9, ]+)', report_link.tail or '')
#         if match:
#             report.adopted_date = _parse_date(match.group(1))
#         match = re.search(r'Presented to the House on ([a-zA-Z0-9, ]+)', report_link.tail or '')
#         if match:
#             report.presented_date = _parse_date(match.group(1))
#         report.save()
#         return report

#     for item in tree.getroot().cssselect('.TocReportItemText'):
#         report_link = item.xpath('./a')[0]
#         report = _import_report(report_link)
#         for response_link in item.cssselect('.TocResponseItemText a'):
#             _import_report(response_link, parent=report)

#     return True
<|endoftext|>


<commit_before>import numpy as np
import pytest
from sympy import Eq  # noqa

from devito import DenseData, Dimension, StencilKernel

@pytest.fixture
def i(size=3):
    return Dimension(name='i', size=size)

@pytest.fixture
def j(size=4):
    return Dimension(name='j', size=size)

@pytest.fixture
def k(size=5):
    return Dimension(name='k', size=size)

@pytest.fixture
def l(size=6):
    return Dimension(name='l', size=size)

def symbol(name, dimensions, value=0., mode='function'):
    """Short-cut for symbol creation to test "function"
    and "indexed" API."""
    assert(mode in ['function', 'indexed'])
    s = DenseData(name=name, dimensions=dimensions)
    s.data[:] = value
    return s.indexify() if mode == 'indexed' else s

@pytest.mark.parametrize('expr, result', [
    ('Eq(a, a + b + 5.)', 10.),
    ('Eq(a, b - a)', 1.),
    ('Eq(a, 4 * (b * a))', 24.),
    ('Eq(a, (6. / b) + (8. * a))', 18.),
])
@pytest.mark.parametrize('mode', ['function', 'indexed'])
def test_arithmetic_flat(i, j, expr, result, mode):
    """Tests basic point-wise arithmetic on two-dimensional data"""
    a = symbol(name='a', dimensions=(i, j), value=2., mode=mode)
    b = symbol(name='b', dimensions=(i, j), value=3., mode=mode)
    fa = a.base.function if mode == 'indexed' else a
    fb = b.base.function if mode == 'indexed' else b

    eqn = eval(expr)
    StencilKernel(eqn)(fa, fb)
    assert np.allclose(fa.data, result, rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a, a + b + 5.)', 10.),
    ('Eq(a, b - a)', 1.),
    ('Eq(a, 4 * (b * a))', 24.),
    ('Eq(a, (6. / b) + (8. * a))', 18.),
])
@pytest.mark.parametrize('mode', ['function', 'indexed'])
def test_arithmetic_deep(i, j, k, l, expr, result, mode):
    """Tests basic point-wise arithmetic on multi-dimensional data"""
    a = symbol(name='a', dimensions=(i, j, k, l), value=2., mode=mode)
    b = symbol(name='b', dimensions=(j, k), value=3., mode=mode)
    fa = a.base.function if mode == 'indexed' else a
    fb = b.base.function if mode == 'indexed' else b

    eqn = eval(expr)
    StencilKernel(eqn)(fa, fb)
    assert np.allclose(fa.data, result, rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a[k, l], a[k - 1 , l] + 1.)',
     np.meshgrid(np.arange(2., 8.), np.arange(2., 7.))[1]),
    ('Eq(a[k, l], a[k, l - 1] + 1.)',
     np.meshgrid(np.arange(2., 8.), np.arange(2., 7.))[0]),
])
def test_arithmetic_indexed_increment(i, j, k, l, expr, result):
    """Tests point-wise increments with stencil offsets in one dimension"""
    a = symbol(name='a', dimensions=(k, l), value=2., mode='indexed').base
    fa = a.function
    fa.data[1:, 1:] = 0

    eqn = eval(expr)
    StencilKernel(eqn)(fa)
    assert np.allclose(fa.data, result, rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a[k, l], b[k - 1 , l] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[k, l], b[k , l - 1] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[k, l], b[k - 1, l - 1] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[k, l], b[k + 1, l + 1] + 1.)', np.zeros((5, 6)) + 3.),
])
def test_arithmetic_indexed_stencil(i, j, k, l, expr, result):
    """Test point-wise arithmetic with stencil offsets across two
    functions in indexed expression format"""
    a = symbol(name='a', dimensions=(k, l), value=0., mode='indexed').base
    fa = a.function
    b = symbol(name='b', dimensions=(k, l), value=2., mode='indexed').base
    fb = b.function

    eqn = eval(expr)
    StencilKernel(eqn)(fa, fb)
    assert np.allclose(fa.data[1:-1, 1:-1], result[1:-1, 1:-1], rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a[1, k, l], a[0, k - 1 , l] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[1, k, l], a[0, k , l - 1] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[1, k, l], a[0, k - 1, l - 1] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[1, k, l], a[0, k + 1, l + 1] + 1.)', np.zeros((5, 6)) + 3.),
])
def test_arithmetic_indexed_buffered(i, j, k, l, expr, result):
    """Test point-wise arithmetic with stencil offsets across a single
    functions with buffering dimension in indexed expression format"""
    a = symbol(name='a', dimensions=(i, k, l), value=2., mode='indexed').base
    fa = a.function

    eqn = eval(expr)
    StencilKernel(eqn)(fa)
    assert np.allclose(fa.data[1, 1:-1, 1:-1], result[1:-1, 1:-1], rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a[1, k, l], a[0, k - 1 , l] + 1.)', np.zeros((5, 6)) + 3.),
])
def test_arithmetic_indexed_open_loops(i, j, k, l, expr, result):
    """Test point-wise arithmetic with stencil offsets and open loop
    boundaries in indexed expression format"""
    k.size = None
    l.size = None
    a = DenseData(name='a', dimensions=(i, k, l), shape=(3, 5, 6)).indexed
    fa = a.function
    fa.data[0, :, :] = 2.

    eqn = eval(expr)
    StencilKernel(eqn)(fa)
    assert np.allclose(fa.data[1, 1:-1, 1:-1], result[1:-1, 1:-1], rtol=1e-12)

def test_override(i, j, k, l):
    """Test that the call-time overriding of Operator arguments works"""
    a = symbol(name='a', dimensions=(i, j, k, l), value=2., mode='indexed').base.function
    a1 = symbol(name='a', dimensions=(i, j, k, l), value=3., mode='indexed').base.function
    a2 = symbol(name='b', dimensions=(i, j, k, l), value=4., mode='indexed').base.function
    eqn = Eq(a, a+3)
    op = StencilKernel(eqn)
    op()
    op(a=a1)
    op(a=a2)
    shape = [d.size for d in [i, j, k, l]]

    assert(np.allclose(a.data, np.zeros(shape) + 5))
    assert(np.allclose(a1.data, np.zeros(shape) + 6))
    assert(np.allclose(a2.data, np.zeros(shape) + 7))

if __name__ == "__main__":
    test_override(i(), j(), k(), l())
<commit_msg>Remove main from test<commit_after>import numpy as np
import pytest
from sympy import Eq  # noqa

from devito import DenseData, Dimension, StencilKernel

@pytest.fixture
def i(size=3):
    return Dimension(name='i', size=size)

@pytest.fixture
def j(size=4):
    return Dimension(name='j', size=size)

@pytest.fixture
def k(size=5):
    return Dimension(name='k', size=size)

@pytest.fixture
def l(size=6):
    return Dimension(name='l', size=size)

def symbol(name, dimensions, value=0., mode='function'):
    """Short-cut for symbol creation to test "function"
    and "indexed" API."""
    assert(mode in ['function', 'indexed'])
    s = DenseData(name=name, dimensions=dimensions)
    s.data[:] = value
    return s.indexify() if mode == 'indexed' else s

@pytest.mark.parametrize('expr, result', [
    ('Eq(a, a + b + 5.)', 10.),
    ('Eq(a, b - a)', 1.),
    ('Eq(a, 4 * (b * a))', 24.),
    ('Eq(a, (6. / b) + (8. * a))', 18.),
])
@pytest.mark.parametrize('mode', ['function', 'indexed'])
def test_arithmetic_flat(i, j, expr, result, mode):
    """Tests basic point-wise arithmetic on two-dimensional data"""
    a = symbol(name='a', dimensions=(i, j), value=2., mode=mode)
    b = symbol(name='b', dimensions=(i, j), value=3., mode=mode)
    fa = a.base.function if mode == 'indexed' else a
    fb = b.base.function if mode == 'indexed' else b

    eqn = eval(expr)
    StencilKernel(eqn)(fa, fb)
    assert np.allclose(fa.data, result, rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a, a + b + 5.)', 10.),
    ('Eq(a, b - a)', 1.),
    ('Eq(a, 4 * (b * a))', 24.),
    ('Eq(a, (6. / b) + (8. * a))', 18.),
])
@pytest.mark.parametrize('mode', ['function', 'indexed'])
def test_arithmetic_deep(i, j, k, l, expr, result, mode):
    """Tests basic point-wise arithmetic on multi-dimensional data"""
    a = symbol(name='a', dimensions=(i, j, k, l), value=2., mode=mode)
    b = symbol(name='b', dimensions=(j, k), value=3., mode=mode)
    fa = a.base.function if mode == 'indexed' else a
    fb = b.base.function if mode == 'indexed' else b

    eqn = eval(expr)
    StencilKernel(eqn)(fa, fb)
    assert np.allclose(fa.data, result, rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a[k, l], a[k - 1 , l] + 1.)',
     np.meshgrid(np.arange(2., 8.), np.arange(2., 7.))[1]),
    ('Eq(a[k, l], a[k, l - 1] + 1.)',
     np.meshgrid(np.arange(2., 8.), np.arange(2., 7.))[0]),
])
def test_arithmetic_indexed_increment(i, j, k, l, expr, result):
    """Tests point-wise increments with stencil offsets in one dimension"""
    a = symbol(name='a', dimensions=(k, l), value=2., mode='indexed').base
    fa = a.function
    fa.data[1:, 1:] = 0

    eqn = eval(expr)
    StencilKernel(eqn)(fa)
    assert np.allclose(fa.data, result, rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a[k, l], b[k - 1 , l] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[k, l], b[k , l - 1] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[k, l], b[k - 1, l - 1] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[k, l], b[k + 1, l + 1] + 1.)', np.zeros((5, 6)) + 3.),
])
def test_arithmetic_indexed_stencil(i, j, k, l, expr, result):
    """Test point-wise arithmetic with stencil offsets across two
    functions in indexed expression format"""
    a = symbol(name='a', dimensions=(k, l), value=0., mode='indexed').base
    fa = a.function
    b = symbol(name='b', dimensions=(k, l), value=2., mode='indexed').base
    fb = b.function

    eqn = eval(expr)
    StencilKernel(eqn)(fa, fb)
    assert np.allclose(fa.data[1:-1, 1:-1], result[1:-1, 1:-1], rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a[1, k, l], a[0, k - 1 , l] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[1, k, l], a[0, k , l - 1] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[1, k, l], a[0, k - 1, l - 1] + 1.)', np.zeros((5, 6)) + 3.),
    ('Eq(a[1, k, l], a[0, k + 1, l + 1] + 1.)', np.zeros((5, 6)) + 3.),
])
def test_arithmetic_indexed_buffered(i, j, k, l, expr, result):
    """Test point-wise arithmetic with stencil offsets across a single
    functions with buffering dimension in indexed expression format"""
    a = symbol(name='a', dimensions=(i, k, l), value=2., mode='indexed').base
    fa = a.function

    eqn = eval(expr)
    StencilKernel(eqn)(fa)
    assert np.allclose(fa.data[1, 1:-1, 1:-1], result[1:-1, 1:-1], rtol=1e-12)

@pytest.mark.parametrize('expr, result', [
    ('Eq(a[1, k, l], a[0, k - 1 , l] + 1.)', np.zeros((5, 6)) + 3.),
])
def test_arithmetic_indexed_open_loops(i, j, k, l, expr, result):
    """Test point-wise arithmetic with stencil offsets and open loop
    boundaries in indexed expression format"""
    k.size = None
    l.size = None
    a = DenseData(name='a', dimensions=(i, k, l), shape=(3, 5, 6)).indexed
    fa = a.function
    fa.data[0, :, :] = 2.

    eqn = eval(expr)
    StencilKernel(eqn)(fa)
    assert np.allclose(fa.data[1, 1:-1, 1:-1], result[1:-1, 1:-1], rtol=1e-12)

def test_override(i, j, k, l):
    """Test that the call-time overriding of Operator arguments works"""
    a = symbol(name='a', dimensions=(i, j, k, l), value=2., mode='indexed').base.function
    a1 = symbol(name='a', dimensions=(i, j, k, l), value=3., mode='indexed').base.function
    a2 = symbol(name='b', dimensions=(i, j, k, l), value=4., mode='indexed').base.function
    eqn = Eq(a, a+3)
    op = StencilKernel(eqn)
    op()
    op(a=a1)
    op(a=a2)
    shape = [d.size for d in [i, j, k, l]]

    assert(np.allclose(a.data, np.zeros(shape) + 5))
    assert(np.allclose(a1.data, np.zeros(shape) + 6))
    assert(np.allclose(a2.data, np.zeros(shape) + 7))
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""METS reader and writer."""

from __future__ import absolute_import
import logging

from .exceptions import MetsError, ParseError
from .fsentry import FSEntry
from .metadata import Agent, AMDSec, SubSection, MDRef, MDWrap
from .mets import METSDocument
from .utils import (
    NAMESPACES,
    SCHEMA_LOCATIONS,
    lxmlns,
    FILE_ID_PREFIX,
    GROUP_ID_PREFIX,
    urlencode,
    urldecode,
)
from .validate import (
    METS_XSD_PATH,
    AM_SCT_PATH,
    AM_PNTR_SCT_PATH,
    get_schematron,
    validate,
    get_xmlschema,
    xsd_validate,
    schematron_validate,
    sct_report_string,
    xsd_error_log_string,
    report_string,
)
from .di import (
    FeatureBroker,
    set_feature_broker_to_default_state,
    feature_broker,
    Dependency,
    has_class_methods,
    has_methods,
    is_class,
)
from . import plugins

LOGGER = logging.getLogger(__name__)
LOGGER.addHandler(logging.NullHandler())
__version__ = "0.3.2"

__all__ = [
    "Agent",
    "AMDSec",
    "AM_PNTR_SCT_PATH",
    "AM_SCT_PATH",
    "Dependency",
    "FILE_ID_PREFIX",
    "FSEntry",
    "FeatureBroker",
    "GROUP_ID_PREFIX",
    "MDRef",
    "MDWrap",
    "METSDocument",
    "METS_XSD_PATH",
    "MetsError",
    "NAMESPACES",
    "ParseError",
    "SCHEMA_LOCATIONS",
    "SubSection",
    "__version__",
    "feature_broker",
    "get_schematron",
    "get_xmlschema",
    "has_class_methods",
    "has_methods",
    "is_class",
    "lxmlns",
    "plugins",
    "report_string",
    "schematron_validate",
    "sct_report_string",
    "set_feature_broker_to_default_state",
    "urldecode",
    "urlencode",
    "validate",
    "xsd_error_log_string",
    "xsd_validate",
]
<commit_msg>Increment version<commit_after># -*- coding: utf-8 -*-
"""METS reader and writer."""

from __future__ import absolute_import
import logging

from .exceptions import MetsError, ParseError
from .fsentry import FSEntry
from .metadata import Agent, AMDSec, SubSection, MDRef, MDWrap
from .mets import METSDocument
from .utils import (
    NAMESPACES,
    SCHEMA_LOCATIONS,
    lxmlns,
    FILE_ID_PREFIX,
    GROUP_ID_PREFIX,
    urlencode,
    urldecode,
)
from .validate import (
    METS_XSD_PATH,
    AM_SCT_PATH,
    AM_PNTR_SCT_PATH,
    get_schematron,
    validate,
    get_xmlschema,
    xsd_validate,
    schematron_validate,
    sct_report_string,
    xsd_error_log_string,
    report_string,
)
from .di import (
    FeatureBroker,
    set_feature_broker_to_default_state,
    feature_broker,
    Dependency,
    has_class_methods,
    has_methods,
    is_class,
)
from . import plugins

LOGGER = logging.getLogger(__name__)
LOGGER.addHandler(logging.NullHandler())
__version__ = "0.3.3"

__all__ = [
    "Agent",
    "AMDSec",
    "AM_PNTR_SCT_PATH",
    "AM_SCT_PATH",
    "Dependency",
    "FILE_ID_PREFIX",
    "FSEntry",
    "FeatureBroker",
    "GROUP_ID_PREFIX",
    "MDRef",
    "MDWrap",
    "METSDocument",
    "METS_XSD_PATH",
    "MetsError",
    "NAMESPACES",
    "ParseError",
    "SCHEMA_LOCATIONS",
    "SubSection",
    "__version__",
    "feature_broker",
    "get_schematron",
    "get_xmlschema",
    "has_class_methods",
    "has_methods",
    "is_class",
    "lxmlns",
    "plugins",
    "report_string",
    "schematron_validate",
    "sct_report_string",
    "set_feature_broker_to_default_state",
    "urldecode",
    "urlencode",
    "validate",
    "xsd_error_log_string",
    "xsd_validate",
]
<|endoftext|>


<commit_before>from django.test import TestCase
from django.utils import timezone

from mock import patch, Mock

from ..models import Customer, Event, CurrentSubscription
from payments.signals import WEBHOOK_SIGNALS
from ..utils import get_user_model

class TestEventMethods(TestCase):
    def setUp(self):
        User = get_user_model()
        self.user = User.objects.create_user(username="testuser")
        self.user.save()
        self.customer = Customer.objects.create(
            stripe_id="cus_xxxxxxxxxxxxxxx",
            user=self.user
        )

    def test_link_customer_customer_created(self):
        msg = {
            "created": 1363911708,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": None,
                    "created": 1363911708,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "xxxxxxxxxx@yahoo.com",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.created"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.created",
            livemode=True,
            webhook_message=msg,
            validated_message=msg
        )
        event.link_customer()
        self.assertEquals(event.customer, self.customer)

    def test_link_customer_customer_updated(self):
        msg = {
            "created": 1346855599,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": {
                        "address_city": None,
                        "address_country": None,
                        "address_line1": None,
                        "address_line1_check": None,
                        "address_line2": None,
                        "address_state": None,
                        "address_zip": None,
                        "address_zip_check": None,
                        "country": "MX",
                        "cvc_check": "pass",
                        "exp_month": 1,
                        "exp_year": 2014,
                        "fingerprint": "XXXXXXXXXXX",
                        "last4": "7992",
                        "name": None,
                        "object": "card",
                        "type": "MasterCard"
                    },
                    "created": 1346855596,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "xxxxxxxxxx@yahoo.com",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                },
                "previous_attributes": {
                    "active_card": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.updated"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.updated",
            livemode=True,
            webhook_message=msg,
            validated_message=msg
        )
        event.link_customer()
        self.assertEquals(event.customer, self.customer)

    def test_link_customer_customer_deleted(self):
        msg = {
            "created": 1348286560,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": None,
                    "created": 1348286302,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "paltman+test@gmail.com",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.deleted"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.deleted",
            livemode=True,
            webhook_message=msg,
            validated_message=msg
        )
        event.link_customer()
        self.assertEquals(event.customer, self.customer)

    @patch("stripe.Customer.retrieve")
    def test_process_customer_deleted(self, CustomerMock):
        msg = {
            "created": 1348286560,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": None,
                    "created": 1348286302,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "paltman+test@gmail.com",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.deleted"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.deleted",
            livemode=True,
            webhook_message=msg,
            validated_message=msg,
            valid=True
        )
        event.process()
        self.assertEquals(event.customer, self.customer)
        self.assertEquals(event.customer.user, None)

    @staticmethod
    def send_signal(customer, kind):
        event = Event(customer=customer, kind=kind)
        signal = WEBHOOK_SIGNALS.get(kind)
        signal.send(sender=Event, event=event)

    @staticmethod
    def connect_webhook_signal(kind, func, **kwargs):
        signal = WEBHOOK_SIGNALS.get(kind)
        signal.connect(func, **kwargs)

    @staticmethod
    def disconnect_webhook_signal(kind, func, **kwargs):
        signal = WEBHOOK_SIGNALS.get(kind)
        signal.disconnect(func, **kwargs)

    @patch("stripe.Customer.retrieve")
    def test_customer_subscription_deleted(self, CustomerMock):
        """
        """
        kind = "customer.subscription.deleted"
        cs = CurrentSubscription(customer=self.customer, quantity=1, start=timezone.now(), amount=0)
        cs.save()
        customer = Customer.objects.get(pk=self.customer.pk)

        # Stripe objects will not have this attribute so we must delete it from the mocked object
        del customer.stripe_customer.subscription
        self.assertIsNotNone(customer.current_subscription)

        # This is the expected format of a customer.subscription.delete message
        msg = {
            "id": "evt_2eRjeAlnH1XMe8",
            "created": 1380317537,
            "livemode": True,
            "type": kind,
            "data": {
                "object": {
                    "id": "su_2ZDdGxJ3EQQc7Q",
                    "plan": {
                        "interval": "month",
                        "name": "xxx",
                        "amount": 200,
                        "currency": "usd",
                        "id": "xxx",
                        "object": "plan",
                        "livemode": True,
                        "interval_count": 1,
                        "trial_period_days": None
                    },
                    "object": "subscription",
                    "start": 1379111889,
                    "status": "canceled",
                    "customer": self.customer.stripe_id,
                    "cancel_at_period_end": False,
                    "current_period_start": 1378738246,
                    "current_period_end": 1381330246,
                    "ended_at": 1380317537,
                    "trial_start": None,
                    "trial_end": None,
                    "canceled_at": 1380317537,
                    "quantity": 1,
                    "application_fee_percent": None
                }
            },
            "object": "event",
            "pending_webhooks": 1,
            "request": "iar_2eRjQZmn0i3G9M"
        }

        # Create a test event for the message
        test_event = Event.objects.create(
            stripe_id=msg["id"],
            kind=kind,
            livemode=msg["livemode"],
            webhook_message=msg,
            validated_message=msg,
            valid=True,
            customer=customer,
        )

        def signal_handler(sender, event, **kwargs):
            # Illustrate and test what signal handlers would experience
            self.assertFalse(event.customer.current_subscription.is_valid())
            self.assertIsNone(event.customer.current_subscription.plan)
            self.assertIsNone(event.customer.current_subscription.status)
            self.assertIsNone(event.customer.current_subscription.id)

        signal_handler_mock = Mock()
        # Let's make the side effect call our real function, the mock is a proxy so we can assert it was called
        signal_handler_mock.side_effect = signal_handler
        TestEventMethods.connect_webhook_signal(kind, signal_handler_mock, weak=False, sender=Event)
        signal_handler_mock.reset_mock()

        # Now process the event - at the end of this the signal should get sent
        test_event.process()

        self.assertFalse(test_event.customer.current_subscription.is_valid())
        self.assertIsNone(test_event.customer.current_subscription.plan)
        self.assertIsNone(test_event.customer.current_subscription.status)
        self.assertIsNone(test_event.customer.current_subscription.id)

        # Verify our signal handler was called
        self.assertTrue(signal_handler_mock.called)

        TestEventMethods.disconnect_webhook_signal(kind, signal_handler_mock, weak=False, sender=Event)
<commit_msg>Fixing empty docstring<commit_after>from django.test import TestCase
from django.utils import timezone

from mock import patch, Mock

from ..models import Customer, Event, CurrentSubscription
from payments.signals import WEBHOOK_SIGNALS
from ..utils import get_user_model

class TestEventMethods(TestCase):
    def setUp(self):
        User = get_user_model()
        self.user = User.objects.create_user(username="testuser")
        self.user.save()
        self.customer = Customer.objects.create(
            stripe_id="cus_xxxxxxxxxxxxxxx",
            user=self.user
        )

    def test_link_customer_customer_created(self):
        msg = {
            "created": 1363911708,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": None,
                    "created": 1363911708,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "xxxxxxxxxx@yahoo.com",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.created"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.created",
            livemode=True,
            webhook_message=msg,
            validated_message=msg
        )
        event.link_customer()
        self.assertEquals(event.customer, self.customer)

    def test_link_customer_customer_updated(self):
        msg = {
            "created": 1346855599,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": {
                        "address_city": None,
                        "address_country": None,
                        "address_line1": None,
                        "address_line1_check": None,
                        "address_line2": None,
                        "address_state": None,
                        "address_zip": None,
                        "address_zip_check": None,
                        "country": "MX",
                        "cvc_check": "pass",
                        "exp_month": 1,
                        "exp_year": 2014,
                        "fingerprint": "XXXXXXXXXXX",
                        "last4": "7992",
                        "name": None,
                        "object": "card",
                        "type": "MasterCard"
                    },
                    "created": 1346855596,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "xxxxxxxxxx@yahoo.com",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                },
                "previous_attributes": {
                    "active_card": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.updated"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.updated",
            livemode=True,
            webhook_message=msg,
            validated_message=msg
        )
        event.link_customer()
        self.assertEquals(event.customer, self.customer)

    def test_link_customer_customer_deleted(self):
        msg = {
            "created": 1348286560,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": None,
                    "created": 1348286302,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "paltman+test@gmail.com",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.deleted"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.deleted",
            livemode=True,
            webhook_message=msg,
            validated_message=msg
        )
        event.link_customer()
        self.assertEquals(event.customer, self.customer)

    @patch("stripe.Customer.retrieve")
    def test_process_customer_deleted(self, CustomerMock):
        msg = {
            "created": 1348286560,
            "data": {
                "object": {
                    "account_balance": 0,
                    "active_card": None,
                    "created": 1348286302,
                    "delinquent": False,
                    "description": None,
                    "discount": None,
                    "email": "paltman+test@gmail.com",
                    "id": "cus_xxxxxxxxxxxxxxx",
                    "livemode": True,
                    "object": "customer",
                    "subscription": None
                }
            },
            "id": "evt_xxxxxxxxxxxxx",
            "livemode": True,
            "object": "event",
            "pending_webhooks": 1,
            "type": "customer.deleted"
        }
        event = Event.objects.create(
            stripe_id=msg["id"],
            kind="customer.deleted",
            livemode=True,
            webhook_message=msg,
            validated_message=msg,
            valid=True
        )
        event.process()
        self.assertEquals(event.customer, self.customer)
        self.assertEquals(event.customer.user, None)

    @staticmethod
    def send_signal(customer, kind):
        event = Event(customer=customer, kind=kind)
        signal = WEBHOOK_SIGNALS.get(kind)
        signal.send(sender=Event, event=event)

    @staticmethod
    def connect_webhook_signal(kind, func, **kwargs):
        signal = WEBHOOK_SIGNALS.get(kind)
        signal.connect(func, **kwargs)

    @staticmethod
    def disconnect_webhook_signal(kind, func, **kwargs):
        signal = WEBHOOK_SIGNALS.get(kind)
        signal.disconnect(func, **kwargs)

    @patch("stripe.Customer.retrieve")
    def test_customer_subscription_deleted(self, CustomerMock):
        """
        Tests to make sure downstream signal handlers do not see stale CurrentSubscription object properties
        after a customer.subscription.deleted event occurs.  While the delete method is called
        on the affected CurrentSubscription object's properties are still accessible (unless the
        Customer object for the event gets refreshed before sending the complimentary signal)
        """
        kind = "customer.subscription.deleted"
        cs = CurrentSubscription(customer=self.customer, quantity=1, start=timezone.now(), amount=0)
        cs.save()
        customer = Customer.objects.get(pk=self.customer.pk)

        # Stripe objects will not have this attribute so we must delete it from the mocked object
        del customer.stripe_customer.subscription
        self.assertIsNotNone(customer.current_subscription)

        # This is the expected format of a customer.subscription.delete message
        msg = {
            "id": "evt_2eRjeAlnH1XMe8",
            "created": 1380317537,
            "livemode": True,
            "type": kind,
            "data": {
                "object": {
                    "id": "su_2ZDdGxJ3EQQc7Q",
                    "plan": {
                        "interval": "month",
                        "name": "xxx",
                        "amount": 200,
                        "currency": "usd",
                        "id": "xxx",
                        "object": "plan",
                        "livemode": True,
                        "interval_count": 1,
                        "trial_period_days": None
                    },
                    "object": "subscription",
                    "start": 1379111889,
                    "status": "canceled",
                    "customer": self.customer.stripe_id,
                    "cancel_at_period_end": False,
                    "current_period_start": 1378738246,
                    "current_period_end": 1381330246,
                    "ended_at": 1380317537,
                    "trial_start": None,
                    "trial_end": None,
                    "canceled_at": 1380317537,
                    "quantity": 1,
                    "application_fee_percent": None
                }
            },
            "object": "event",
            "pending_webhooks": 1,
            "request": "iar_2eRjQZmn0i3G9M"
        }

        # Create a test event for the message
        test_event = Event.objects.create(
            stripe_id=msg["id"],
            kind=kind,
            livemode=msg["livemode"],
            webhook_message=msg,
            validated_message=msg,
            valid=True,
            customer=customer,
        )

        def signal_handler(sender, event, **kwargs):
            # Illustrate and test what signal handlers would experience
            self.assertFalse(event.customer.current_subscription.is_valid())
            self.assertIsNone(event.customer.current_subscription.plan)
            self.assertIsNone(event.customer.current_subscription.status)
            self.assertIsNone(event.customer.current_subscription.id)

        signal_handler_mock = Mock()
        # Let's make the side effect call our real function, the mock is a proxy so we can assert it was called
        signal_handler_mock.side_effect = signal_handler
        TestEventMethods.connect_webhook_signal(kind, signal_handler_mock, weak=False, sender=Event)
        signal_handler_mock.reset_mock()

        # Now process the event - at the end of this the signal should get sent
        test_event.process()

        self.assertFalse(test_event.customer.current_subscription.is_valid())
        self.assertIsNone(test_event.customer.current_subscription.plan)
        self.assertIsNone(test_event.customer.current_subscription.status)
        self.assertIsNone(test_event.customer.current_subscription.id)

        # Verify our signal handler was called
        self.assertTrue(signal_handler_mock.called)

        TestEventMethods.disconnect_webhook_signal(kind, signal_handler_mock, weak=False, sender=Event)
<|endoftext|>


<commit_before># coding: utf-8
from datetime import date, datetime, timedelta, tzinfo
from functools import partial

import pytest
import pytz
import six

from apscheduler.util import (
    asint, asbool, astimezone, convert_to_datetime, datetime_to_utc_timestamp, utc_timestamp_to_datetime,
    timedelta_seconds, datetime_ceil, get_callable_name, obj_to_ref, ref_to_obj, maybe_ref, check_callable_args,
    datetime_repr, repr_escape)
from tests.conftest import minpython, maxpython

try:
    from unittest.mock import Mock
except ImportError:
    from mock import Mock

class DummyClass(object):
    def meth(self):
        pass

    @staticmethod
    def staticmeth():
        pass

    @classmethod
    def classmeth(cls):
        pass

    def __call__(self):
        pass

    class InnerDummyClass(object):
        @classmethod
        def innerclassmeth(cls):
            pass

class TestAsint(object):
    @pytest.mark.parametrize('value', ['5s', 'shplse'], ids=['digit first', 'text'])
    def test_invalid_value(self, value):
        pytest.raises(ValueError, asint, value)

    def test_number(self):
        assert asint('539') == 539

    def test_none(self):
        assert asint(None) is None

class TestAsbool(object):
    @pytest.mark.parametrize('value', [' True', 'true ', 'Yes', ' yes ', '1  ', True],
                             ids=['capital true', 'lowercase true', 'capital yes', 'lowercase yes', 'one', 'True'])
    def test_true(self, value):
        assert asbool(value) is True

    @pytest.mark.parametrize('value', [' False', 'false ', 'No', ' no ', '0  ', False],
                             ids=['capital', 'lowercase false', 'capital no', 'lowercase no', 'zero', 'False'])
    def test_false(self, value):
        assert asbool(value) is False

    def test_bad_value(self):
        pytest.raises(ValueError, asbool, 'yep')

class TestAstimezone(object):
    def test_str(self):
        value = astimezone('Europe/Helsinki')
        assert isinstance(value, tzinfo)

    def test_tz(self):
        tz = pytz.timezone('Europe/Helsinki')
        value = astimezone(tz)
        assert tz is value

    def test_none(self):
        assert astimezone(None) is None

    def test_bad_timezone_type(self):
        exc = pytest.raises(TypeError, astimezone, tzinfo())
        assert 'Only timezones from the pytz library are supported' in str(exc.value)

    def test_bad_local_timezone(self):
        zone = Mock(tzinfo, localize=None, normalize=None, zone='local')
        exc = pytest.raises(ValueError, astimezone, zone)
        assert 'Unable to determine the name of the local timezone' in str(exc.value)

    def test_bad_value(self):
        exc = pytest.raises(TypeError, astimezone, 4)
        assert 'Expected tzinfo, got int instead' in str(exc.value)

class TestConvertToDatetime(object):
    @pytest.mark.parametrize('input,expected', [
        (None, None),
        (date(2009, 8, 1), datetime(2009, 8, 1)),
        (datetime(2009, 8, 1, 5, 6, 12), datetime(2009, 8, 1, 5, 6, 12)),
        ('2009-8-1', datetime(2009, 8, 1)),
        ('2009-8-1 5:16:12', datetime(2009, 8, 1, 5, 16, 12)),
        (pytz.FixedOffset(-60).localize(datetime(2009, 8, 1)), pytz.FixedOffset(-60).localize(datetime(2009, 8, 1)))
    ], ids=['None', 'date', 'datetime', 'date as text', 'datetime as text', 'existing tzinfo'])
    def test_date(self, timezone, input, expected):
        returned = convert_to_datetime(input, timezone, None)
        if expected is not None:
            assert isinstance(returned, datetime)
            expected = timezone.localize(expected) if not expected.tzinfo else expected

        assert returned == expected

    def test_invalid_input_type(self, timezone):
        exc = pytest.raises(TypeError, convert_to_datetime, 92123, timezone, 'foo')
        assert str(exc.value) == 'Unsupported type for foo: int'

    def test_invalid_input_value(self, timezone):
        exc = pytest.raises(ValueError, convert_to_datetime, '19700-12-1', timezone, None)
        assert str(exc.value) == 'Invalid date string'

    def test_missing_timezone(self):
        exc = pytest.raises(ValueError, convert_to_datetime, '2009-8-1', None, 'argname')
        assert str(exc.value) == 'The "tz" argument must be specified if argname has no timezone information'

    def test_text_timezone(self):
        returned = convert_to_datetime('2009-8-1', 'UTC', None)
        assert returned == datetime(2009, 8, 1, tzinfo=pytz.utc)

    def test_bad_timezone(self):
        exc = pytest.raises(TypeError, convert_to_datetime, '2009-8-1', tzinfo(), None)
        assert str(exc.value) == 'Only pytz timezones are supported (need the localize() and normalize() methods)'

def test_datetime_to_utc_timestamp(timezone):
    dt = timezone.localize(datetime(2014, 3, 12, 5, 40, 13, 254012))
    timestamp = datetime_to_utc_timestamp(dt)
    dt2 = utc_timestamp_to_datetime(timestamp)
    assert dt2 == dt

def test_timedelta_seconds():
    delta = timedelta(minutes=2, seconds=30)
    seconds = timedelta_seconds(delta)
    assert seconds == 150

@pytest.mark.parametrize('input,expected', [
    (datetime(2009, 4, 7, 2, 10, 16, 4000), datetime(2009, 4, 7, 2, 10, 17)),
    (datetime(2009, 4, 7, 2, 10, 16), datetime(2009, 4, 7, 2, 10, 16))
], ids=['milliseconds', 'exact'])
def test_datetime_ceil(input, expected):
    assert datetime_ceil(input) == expected

@pytest.mark.parametrize('input,expected', [
    (None, 'None'),
    (pytz.timezone('Europe/Helsinki').localize(datetime(2014, 5, 30, 7, 12, 20)), '2014-05-30 07:12:20 EEST')
], ids=['None', 'datetime+tzinfo'])
def test_datetime_repr(input, expected):
    assert datetime_repr(input) == expected

class TestGetCallableName(object):
    @pytest.mark.parametrize('input,expected', [
        (asint, 'asint'),
        (DummyClass.staticmeth, 'staticmeth'),
        (DummyClass.classmeth, 'DummyClass.classmeth'),
        (DummyClass.meth, 'meth'),
        (DummyClass().meth, 'DummyClass.meth'),
        (DummyClass, 'DummyClass'),
        (DummyClass(), 'DummyClass')
    ], ids=['function', 'static method', 'class method', 'unbounded method', 'bounded method', 'class', 'instance'])
    def test_inputs(self, input, expected):
        assert get_callable_name(input) == expected

    def test_bad_input(self):
        pytest.raises(TypeError, get_callable_name, object())

class TestObjToRef(object):
    @pytest.mark.parametrize('input', [DummyClass.meth, DummyClass.staticmeth, partial(DummyClass.meth)],
                             ids=['bound method', 'static method', 'partial/bound method'])
    def test_no_ref_found(self, input):
        exc = pytest.raises(ValueError, obj_to_ref, input)
        assert 'Cannot determine the reference to ' in str(exc.value)

    @pytest.mark.parametrize('input,expected', [
        (DummyClass.classmeth, 'tests.test_util:DummyClass.classmeth'),
        (timedelta, 'datetime:timedelta'),
    ], ids=['class method', 'timedelta'])
    def test_valid_refs(self, input, expected):
        assert obj_to_ref(input) == expected

    @minpython(3, 3)
    def test_inner_class_method(self):
        """Tests that a reference to a class method of an inner class can be discovered."""

        assert obj_to_ref(DummyClass.InnerDummyClass.innerclassmeth) == \
            'tests.test_util:DummyClass.InnerDummyClass.innerclassmeth'

class TestRefToObj(object):
    def test_valid_ref(self):
        assert ref_to_obj('datetime:timedelta') == timedelta

    @pytest.mark.parametrize('input,error', [
        (object(), TypeError),
        ('module', ValueError),
        ('module:blah', LookupError)
    ], ids=['raw object', 'module', 'module attribute'])
    def test_lookup_error(self, input, error):
        pytest.raises(error, ref_to_obj, input)

@pytest.mark.parametrize('input,expected', [
    ('datetime:timedelta', timedelta),
    (timedelta, timedelta)
], ids=['textref', 'direct'])
def test_maybe_ref(input, expected):
    assert maybe_ref(input) == expected

@pytest.mark.parametrize('input,expected', [
    (b'T\xc3\xa9st'.decode('utf-8'), 'T\\xe9st' if six.PY2 else 'Tést'),
    (1, 1)
])
@maxpython(3)
def test_repr_escape_py2(input, expected):
    assert repr_escape(input) == expected

class TestCheckCallableArgs(object):
    @pytest.fixture(params=[True, False], ids=['signature', 'getargspec'])
    def use_signature(self, request, monkeypatch):
        if not request.param:
            monkeypatch.setattr('apscheduler.util.signature', None)

    def test_invalid_callable_args(self, use_signature):
        """Tests that attempting to create a job with an invalid number of arguments raises an exception."""

        exc = pytest.raises(ValueError, check_callable_args, lambda x: None, [1, 2], {})
        assert str(exc.value) == ('The list of positional arguments is longer than the target callable can handle '
                                  '(allowed: 1, given in args: 2)')

    def test_invalid_callable_kwargs(self, use_signature):
        """Tests that attempting to schedule a job with unmatched keyword arguments raises an exception."""

        exc = pytest.raises(ValueError, check_callable_args, lambda x: None, [], {'x': 0, 'y': 1})
        assert str(exc.value) == 'The target callable does not accept the following keyword arguments: y'

    def test_missing_callable_args(self, use_signature):
        """Tests that attempting to schedule a job with missing arguments raises an exception."""

        exc = pytest.raises(ValueError, check_callable_args, lambda x, y, z: None, [1], {'y': 0})
        assert str(exc.value) == 'The following arguments have not been supplied: z'

    def test_conflicting_callable_args(self, use_signature):
        """
        Tests that attempting to schedule a job where the combination of args and kwargs are in conflict raises an
        exception.
        """

        exc = pytest.raises(ValueError, check_callable_args, lambda x, y: None, [1, 2], {'y': 1})
        assert str(exc.value) == 'The following arguments are supplied in both args and kwargs: y'

    def test_signature_positional_only(self):
        """Tests that a function where signature() fails is accepted."""

        check_callable_args(object().__setattr__, ('blah', 1), {})

    @minpython(3, 4)
    def test_positional_only_args(self):
        """Tests that an attempt to use keyword arguments for positional-only arguments raises an exception."""

        exc = pytest.raises(ValueError, check_callable_args, object.__setattr__, ['blah'], {'value': 1})
        assert str(exc.value) == 'The following arguments cannot be given as keyword arguments: value'

    @minpython(3)
    def test_unfulfilled_kwargs(self):
        """
        Tests that attempting to schedule a job where not all keyword-only arguments are fulfilled raises an
        exception.
        """

        func = eval("lambda x, *, y, z=1: None")
        exc = pytest.raises(ValueError, check_callable_args, func, [1], {})
        assert str(exc.value) == 'The following keyword-only arguments have not been supplied in kwargs: y'
<commit_msg>Improved the test for ref_to_obj()<commit_after># coding: utf-8
from datetime import date, datetime, timedelta, tzinfo
from functools import partial

import pytest
import pytz
import six

from apscheduler.util import (
    asint, asbool, astimezone, convert_to_datetime, datetime_to_utc_timestamp, utc_timestamp_to_datetime,
    timedelta_seconds, datetime_ceil, get_callable_name, obj_to_ref, ref_to_obj, maybe_ref, check_callable_args,
    datetime_repr, repr_escape)
from tests.conftest import minpython, maxpython

try:
    from unittest.mock import Mock
except ImportError:
    from mock import Mock

class DummyClass(object):
    def meth(self):
        pass

    @staticmethod
    def staticmeth():
        pass

    @classmethod
    def classmeth(cls):
        pass

    def __call__(self):
        pass

    class InnerDummyClass(object):
        @classmethod
        def innerclassmeth(cls):
            pass

class TestAsint(object):
    @pytest.mark.parametrize('value', ['5s', 'shplse'], ids=['digit first', 'text'])
    def test_invalid_value(self, value):
        pytest.raises(ValueError, asint, value)

    def test_number(self):
        assert asint('539') == 539

    def test_none(self):
        assert asint(None) is None

class TestAsbool(object):
    @pytest.mark.parametrize('value', [' True', 'true ', 'Yes', ' yes ', '1  ', True],
                             ids=['capital true', 'lowercase true', 'capital yes', 'lowercase yes', 'one', 'True'])
    def test_true(self, value):
        assert asbool(value) is True

    @pytest.mark.parametrize('value', [' False', 'false ', 'No', ' no ', '0  ', False],
                             ids=['capital', 'lowercase false', 'capital no', 'lowercase no', 'zero', 'False'])
    def test_false(self, value):
        assert asbool(value) is False

    def test_bad_value(self):
        pytest.raises(ValueError, asbool, 'yep')

class TestAstimezone(object):
    def test_str(self):
        value = astimezone('Europe/Helsinki')
        assert isinstance(value, tzinfo)

    def test_tz(self):
        tz = pytz.timezone('Europe/Helsinki')
        value = astimezone(tz)
        assert tz is value

    def test_none(self):
        assert astimezone(None) is None

    def test_bad_timezone_type(self):
        exc = pytest.raises(TypeError, astimezone, tzinfo())
        assert 'Only timezones from the pytz library are supported' in str(exc.value)

    def test_bad_local_timezone(self):
        zone = Mock(tzinfo, localize=None, normalize=None, zone='local')
        exc = pytest.raises(ValueError, astimezone, zone)
        assert 'Unable to determine the name of the local timezone' in str(exc.value)

    def test_bad_value(self):
        exc = pytest.raises(TypeError, astimezone, 4)
        assert 'Expected tzinfo, got int instead' in str(exc.value)

class TestConvertToDatetime(object):
    @pytest.mark.parametrize('input,expected', [
        (None, None),
        (date(2009, 8, 1), datetime(2009, 8, 1)),
        (datetime(2009, 8, 1, 5, 6, 12), datetime(2009, 8, 1, 5, 6, 12)),
        ('2009-8-1', datetime(2009, 8, 1)),
        ('2009-8-1 5:16:12', datetime(2009, 8, 1, 5, 16, 12)),
        (pytz.FixedOffset(-60).localize(datetime(2009, 8, 1)), pytz.FixedOffset(-60).localize(datetime(2009, 8, 1)))
    ], ids=['None', 'date', 'datetime', 'date as text', 'datetime as text', 'existing tzinfo'])
    def test_date(self, timezone, input, expected):
        returned = convert_to_datetime(input, timezone, None)
        if expected is not None:
            assert isinstance(returned, datetime)
            expected = timezone.localize(expected) if not expected.tzinfo else expected

        assert returned == expected

    def test_invalid_input_type(self, timezone):
        exc = pytest.raises(TypeError, convert_to_datetime, 92123, timezone, 'foo')
        assert str(exc.value) == 'Unsupported type for foo: int'

    def test_invalid_input_value(self, timezone):
        exc = pytest.raises(ValueError, convert_to_datetime, '19700-12-1', timezone, None)
        assert str(exc.value) == 'Invalid date string'

    def test_missing_timezone(self):
        exc = pytest.raises(ValueError, convert_to_datetime, '2009-8-1', None, 'argname')
        assert str(exc.value) == 'The "tz" argument must be specified if argname has no timezone information'

    def test_text_timezone(self):
        returned = convert_to_datetime('2009-8-1', 'UTC', None)
        assert returned == datetime(2009, 8, 1, tzinfo=pytz.utc)

    def test_bad_timezone(self):
        exc = pytest.raises(TypeError, convert_to_datetime, '2009-8-1', tzinfo(), None)
        assert str(exc.value) == 'Only pytz timezones are supported (need the localize() and normalize() methods)'

def test_datetime_to_utc_timestamp(timezone):
    dt = timezone.localize(datetime(2014, 3, 12, 5, 40, 13, 254012))
    timestamp = datetime_to_utc_timestamp(dt)
    dt2 = utc_timestamp_to_datetime(timestamp)
    assert dt2 == dt

def test_timedelta_seconds():
    delta = timedelta(minutes=2, seconds=30)
    seconds = timedelta_seconds(delta)
    assert seconds == 150

@pytest.mark.parametrize('input,expected', [
    (datetime(2009, 4, 7, 2, 10, 16, 4000), datetime(2009, 4, 7, 2, 10, 17)),
    (datetime(2009, 4, 7, 2, 10, 16), datetime(2009, 4, 7, 2, 10, 16))
], ids=['milliseconds', 'exact'])
def test_datetime_ceil(input, expected):
    assert datetime_ceil(input) == expected

@pytest.mark.parametrize('input,expected', [
    (None, 'None'),
    (pytz.timezone('Europe/Helsinki').localize(datetime(2014, 5, 30, 7, 12, 20)), '2014-05-30 07:12:20 EEST')
], ids=['None', 'datetime+tzinfo'])
def test_datetime_repr(input, expected):
    assert datetime_repr(input) == expected

class TestGetCallableName(object):
    @pytest.mark.parametrize('input,expected', [
        (asint, 'asint'),
        (DummyClass.staticmeth, 'staticmeth'),
        (DummyClass.classmeth, 'DummyClass.classmeth'),
        (DummyClass.meth, 'meth'),
        (DummyClass().meth, 'DummyClass.meth'),
        (DummyClass, 'DummyClass'),
        (DummyClass(), 'DummyClass')
    ], ids=['function', 'static method', 'class method', 'unbounded method', 'bounded method', 'class', 'instance'])
    def test_inputs(self, input, expected):
        assert get_callable_name(input) == expected

    def test_bad_input(self):
        pytest.raises(TypeError, get_callable_name, object())

class TestObjToRef(object):
    @pytest.mark.parametrize('input', [DummyClass.meth, DummyClass.staticmeth, partial(DummyClass.meth)],
                             ids=['bound method', 'static method', 'partial/bound method'])
    def test_no_ref_found(self, input):
        exc = pytest.raises(ValueError, obj_to_ref, input)
        assert 'Cannot determine the reference to ' in str(exc.value)

    @pytest.mark.parametrize('input,expected', [
        (DummyClass.classmeth, 'tests.test_util:DummyClass.classmeth'),
        (timedelta, 'datetime:timedelta'),
    ], ids=['class method', 'timedelta'])
    def test_valid_refs(self, input, expected):
        assert obj_to_ref(input) == expected

    @minpython(3, 3)
    def test_inner_class_method(self):
        """Tests that a reference to a class method of an inner class can be discovered."""

        assert obj_to_ref(DummyClass.InnerDummyClass.innerclassmeth) == \
            'tests.test_util:DummyClass.InnerDummyClass.innerclassmeth'

class TestRefToObj(object):
    def test_valid_ref(self):
        from logging.handlers import RotatingFileHandler
        assert ref_to_obj('logging.handlers:RotatingFileHandler') is RotatingFileHandler

    @pytest.mark.parametrize('input,error', [
        (object(), TypeError),
        ('module', ValueError),
        ('module:blah', LookupError)
    ], ids=['raw object', 'module', 'module attribute'])
    def test_lookup_error(self, input, error):
        pytest.raises(error, ref_to_obj, input)

@pytest.mark.parametrize('input,expected', [
    ('datetime:timedelta', timedelta),
    (timedelta, timedelta)
], ids=['textref', 'direct'])
def test_maybe_ref(input, expected):
    assert maybe_ref(input) == expected

@pytest.mark.parametrize('input,expected', [
    (b'T\xc3\xa9st'.decode('utf-8'), 'T\\xe9st' if six.PY2 else 'Tést'),
    (1, 1)
])
@maxpython(3)
def test_repr_escape_py2(input, expected):
    assert repr_escape(input) == expected

class TestCheckCallableArgs(object):
    @pytest.fixture(params=[True, False], ids=['signature', 'getargspec'])
    def use_signature(self, request, monkeypatch):
        if not request.param:
            monkeypatch.setattr('apscheduler.util.signature', None)

    def test_invalid_callable_args(self, use_signature):
        """Tests that attempting to create a job with an invalid number of arguments raises an exception."""

        exc = pytest.raises(ValueError, check_callable_args, lambda x: None, [1, 2], {})
        assert str(exc.value) == ('The list of positional arguments is longer than the target callable can handle '
                                  '(allowed: 1, given in args: 2)')

    def test_invalid_callable_kwargs(self, use_signature):
        """Tests that attempting to schedule a job with unmatched keyword arguments raises an exception."""

        exc = pytest.raises(ValueError, check_callable_args, lambda x: None, [], {'x': 0, 'y': 1})
        assert str(exc.value) == 'The target callable does not accept the following keyword arguments: y'

    def test_missing_callable_args(self, use_signature):
        """Tests that attempting to schedule a job with missing arguments raises an exception."""

        exc = pytest.raises(ValueError, check_callable_args, lambda x, y, z: None, [1], {'y': 0})
        assert str(exc.value) == 'The following arguments have not been supplied: z'

    def test_conflicting_callable_args(self, use_signature):
        """
        Tests that attempting to schedule a job where the combination of args and kwargs are in conflict raises an
        exception.
        """

        exc = pytest.raises(ValueError, check_callable_args, lambda x, y: None, [1, 2], {'y': 1})
        assert str(exc.value) == 'The following arguments are supplied in both args and kwargs: y'

    def test_signature_positional_only(self):
        """Tests that a function where signature() fails is accepted."""

        check_callable_args(object().__setattr__, ('blah', 1), {})

    @minpython(3, 4)
    def test_positional_only_args(self):
        """Tests that an attempt to use keyword arguments for positional-only arguments raises an exception."""

        exc = pytest.raises(ValueError, check_callable_args, object.__setattr__, ['blah'], {'value': 1})
        assert str(exc.value) == 'The following arguments cannot be given as keyword arguments: value'

    @minpython(3)
    def test_unfulfilled_kwargs(self):
        """
        Tests that attempting to schedule a job where not all keyword-only arguments are fulfilled raises an
        exception.
        """

        func = eval("lambda x, *, y, z=1: None")
        exc = pytest.raises(ValueError, check_callable_args, func, [1], {})
        assert str(exc.value) == 'The following keyword-only arguments have not been supplied in kwargs: y'
<|endoftext|>


<commit_before><commit_msg>reddit 122<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import django

from paypal.standard.forms import PayPalStandardBaseForm
from paypal.standard.pdt.models import PayPalPDT

class PayPalPDTForm(PayPalStandardBaseForm):
    class Meta:
        model = PayPalPDT
        if django.VERSION >= (1, 6):
            fields = '__all__'
<commit_msg>Add non-PayPal fields to exclude<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import django

from paypal.standard.forms import PayPalStandardBaseForm
from paypal.standard.pdt.models import PayPalPDT

class PayPalPDTForm(PayPalStandardBaseForm):
    class Meta:
        model = PayPalPDT
        if django.VERSION >= (1, 6):
            exclude = ('ipaddress', 'flag', 'flag_code', 'flag_info', 'query', 'response', 'created_at', 'updated', 'form_view',)
<|endoftext|>


<commit_before>"""Very simple position reconstruction algorithms"""
from pax import plugin

from pax.datastructure import ReconstructedPosition

class PosRecWeightedSum(plugin.TransformPlugin):
    """Reconstruction using charge-weighted sum.

    Charge-weighted average of PMT positions.  Class to reconstruct s2 x, y
    positions using the weighted sum of PMTs in the top array.
    """

    def startup(self):
        self.which_pmts = self.config['pmts_to_use_for_reconstruction']

        if self.which_pmts == 'top' or self.which_pmts == 'bottom':
            self.pmts = self.config['pmts_%s' % self.which_pmts]
        else:
            raise RuntimeError("Bad choice 'pmts_to_use_for_reconstruction'")

        self.pmt_locations = self.config['pmt_locations']

    def transform_event(self, event):
        for peak in event.peaks:
            self.log.debug("Left %d, Right: %d" % (peak.left, peak.right))

            # This is an array where every i-th element is how many samples
            # were seen by the i-th PMT
            hits = peak.area_per_pmt

            if hits.sum() != 0:
                sum_x = 0  # sum of x positions
                sum_y = 0  # sum of y positions

                scale = 0  # Total q

                for pmt in self.pmts:
                    value = self.pmt_locations[pmt]
                    Q = hits[pmt]

                    scale += Q

                    sum_x += Q * value['x']
                    sum_y += Q * value['y']

                peak_x = sum_x / scale
                peak_y = sum_y / scale
            else:
                peak_x = peak_y = float('NaN')  # algorithm failed

            rp = ReconstructedPosition({'x': peak_x,
                                        'y': peak_y,
                                        'z': 42,
                                        'index_of_maximum': peak.index_of_maximum,
                                        'algorithm': self.name})

            peak.reconstructed_positions.append(rp)

        return event
<commit_msg>Expand comments<commit_after>"""Very simple position reconstruction algorithms"""
from pax import plugin

from pax.datastructure import ReconstructedPosition

class PosRecWeightedSum(plugin.TransformPlugin):
    """Centroid reconstruction using a charge-weighted sum.

    Charge-weighted average of PMT positions.  Class to reconstruct S2's x, y
    positions using the weighted sum of PMTs in the top array.
    """

    def startup(self):
        """Initialize reconstruction algorithm

        Determine which PMTs to use for reconstruction.
        """

        # This can either be 'top' or 'bottom'.
        self.which_pmts = 'pmts_%s' % self.config['pmts_to_use_for_reconstruction']
        if self.which_pmts not in self.config.keys():
            raise RuntimeError("Bad choice 'pmts_to_use_for_reconstruction'")

        # List of integers of which PMTs to use
        self.pmts = self.config[self.which_pmts]

        # (x,y) locations of these PMTs.  This is stored as a dictionary such
        # that self.pmt_locations[int] = {'x' : int, 'y' : int, 'z' : None}
        self.pmt_locations = self.config['pmt_locations']

    def transform_event(self, event):
        """Reconstruct the position of S2s in an event.

        Information on how to use the 'event' object is at:

          http://xenon1t.github.io/pax/format.html
        """

        # For every S2 peak found in the event
        for peak in event.S2s():
            # Print out the left and right boundaries of a peak
            self.log.debug("Left %d, Right: %d" % (peak.left, peak.right))

            # This is an array where every i-th element is how many pe
            # were seen by the i-th PMT
            hits = peak.area_per_pmt

            sum_x = 0  # sum of x positions
            sum_y = 0  # sum of y positions

            scale = 0  # Total q

            # For every PMT
            for pmt in self.pmts:  # 'pmt' is a PMT ID
                value = self.pmt_locations[pmt]  # Dictionary {'x' : int, etc.}
                Q = hits[pmt] # Area of this S2 for this PMT

                # Add this 'Q' to total Q 'scale'
                scale += Q

                # Add charge-weighted position to running sum
                sum_x += Q * value['x']
                sum_y += Q * value['y']

            if scale != 0:  # If charge actually seen for this S2
                # Compute the positions
                peak_x = sum_x / scale
                peak_y = sum_y / scale
            else:
                peak_x = peak_y = float('NaN')  # algorithm failed

            # Create a reconstructed position object
            rp = ReconstructedPosition({'x': peak_x,
                                        'y': peak_y,
                                        'z': 42,
                                        'index_of_maximum': peak.index_of_maximum,
                                        'algorithm': self.name})

            # Append our reconstructed position object to the peak
            peak.reconstructed_positions.append(rp)

        # Return the event such that the next processor can work on it
        return event
<|endoftext|>


<commit_before>import time

def Auth(object):

    def __init__(self, encryptor, timeout=8):
        self.encryptor = encryptor
        self.timeout = timeout

    def denied(self, client, addr):
        try:
            # Do not block the recv function, and drop the connection after timeout
            client.settimeout(self.timeout)
            keydata = client.recv(4096)

            if not keydata:
                return True
            # Not equals, connection will be drop
            return encryptor.verify(keydata)
        finally:
            # Restore in blocking mode
            if client: client.setblocking(1)

        return True
<commit_msg>reverse logic<commit_after>import time

def Auth(object):

    def __init__(self, encryptor, timeout=8):
        self.encryptor = encryptor
        self.timeout = timeout

    def denied(self, client, addr):
        try:
            # Do not block the recv function, and drop the connection after timeout
            client.settimeout(self.timeout)
            keydata = client.recv(4096)

            if not keydata:
                return True
            # Not equals, connection will be drop
            return not encryptor.verify(keydata)
        finally:
            # Restore in blocking mode
            if client: client.setblocking(1)

        return True
<|endoftext|>


<commit_before># coding: utf-8
# Copyright (c) Pymatgen Development Team.
# Distributed under the terms of the MIT License.

from __future__ import unicode_literals

"""
The util package implements various utilities that are commonly used by various
packages.
"""

__author__ = "Shyue"
__date__ = "$Jun 6, 2011 7:30:05 AM$"

try:
  import coord_util_cython
except ImportError:
  import coord_util_python as coord_util_cython  # use pure-python fallback
<commit_msg>Fix spelling in coord_utils import.<commit_after># coding: utf-8
# Copyright (c) Pymatgen Development Team.
# Distributed under the terms of the MIT License.

from __future__ import unicode_literals

"""
The util package implements various utilities that are commonly used by various
packages.
"""

__author__ = "Shyue"
__date__ = "$Jun 6, 2011 7:30:05 AM$"

try:
  import coord_utils_cython
except ImportError:
  import coord_utils_python as coord_utils_cython  # use pure-python fallback
<|endoftext|>