self.m_blk_b["<STR_LIT>"] = [<NUM_LIT:1>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Model] = [<NUM_LIT:2>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.Firmware] = [<NUM_LIT:1>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.Meter_Address] = [<NUM_LIT:12>, FieldType.String, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.kWh_Tariff_1] = [<NUM_LIT:8>, FieldType.Float, ScaleType.KWH, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.kWh_Tariff_2] = [<NUM_LIT:8>, FieldType.Float, ScaleType.KWH, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.kWh_Tariff_3] = [<NUM_LIT:8>, FieldType.Float, ScaleType.KWH, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.kWh_Tariff_4] = [<NUM_LIT:8>, FieldType.Float, ScaleType.KWH, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Rev_kWh_Tariff_1] = [<NUM_LIT:8>, FieldType.Float, ScaleType.KWH, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Rev_kWh_Tariff_2] = [<NUM_LIT:8>, FieldType.Float, ScaleType.KWH, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Rev_kWh_Tariff_3] = [<NUM_LIT:8>, FieldType.Float, ScaleType.KWH, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Rev_kWh_Tariff_4] = [<NUM_LIT:8>, FieldType.Float, ScaleType.KWH, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.RMS_Volts_Ln_1] = [<NUM_LIT:4>, FieldType.Float, ScaleType.Div10, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.RMS_Volts_Ln_2] = [<NUM_LIT:4>, FieldType.Float, ScaleType.Div10, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.RMS_Volts_Ln_3] = [<NUM_LIT:4>, FieldType.Float, ScaleType.Div10, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Amps_Ln_1] = [<NUM_LIT:5>, FieldType.Float, ScaleType.Div10, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Amps_Ln_2] = [<NUM_LIT:5>, FieldType.Float, ScaleType.Div10, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Amps_Ln_3] = [<NUM_LIT:5>, FieldType.Float, ScaleType.Div10, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.RMS_Watts_Ln_1] = [<NUM_LIT:7>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.RMS_Watts_Ln_2] = [<NUM_LIT:7>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.RMS_Watts_Ln_3] = [<NUM_LIT:7>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.RMS_Watts_Tot] = [<NUM_LIT:7>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Cos_Theta_Ln_1] = [<NUM_LIT:4>, FieldType.PowerFactor, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Cos_Theta_Ln_2] = [<NUM_LIT:4>, FieldType.PowerFactor, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Cos_Theta_Ln_3] = [<NUM_LIT:4>, FieldType.PowerFactor, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.RMS_Watts_Max_Demand] = [<NUM_LIT:8>, FieldType.Float, ScaleType.Div10, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Max_Demand_Period] = [<NUM_LIT:1>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.Pulse_Ratio_1] = [<NUM_LIT:4>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.Pulse_Ratio_2] = [<NUM_LIT:4>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.Pulse_Ratio_3] = [<NUM_LIT:4>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.CT_Ratio] = [<NUM_LIT:4>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.Max_Demand_Interval_Reset] = [<NUM_LIT:1>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Pulse_Output_Ratio] = [<NUM_LIT:4>, FieldType.Int, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b["<STR_LIT>"] = [<NUM_LIT>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Status_A] = [<NUM_LIT:1>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.Status_B] = [<NUM_LIT:1>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.Status_C] = [<NUM_LIT:1>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, True]<EOL>self.m_blk_b[Field.Meter_Time] = [<NUM_LIT>, FieldType.String, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b["<STR_LIT>"] = [<NUM_LIT:2>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b["<STR_LIT>"] = [<NUM_LIT:4>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b["<STR_LIT>"] = [<NUM_LIT:2>, FieldType.Hex, ScaleType.No, "<STR_LIT>", <NUM_LIT:0>, False, False]<EOL>self.m_blk_b[Field.Net_Calc_Watts_Ln_1] = [<NUM_LIT:7>, FieldType.Int, ScaleType.No, "<STR_LIT:0>", <NUM_LIT:0>, True, False]<EOL>self.m_blk_b[Field.Net_Calc_Watts_Ln_2] = [<NUM_LIT:7>, FieldType.Int, ScaleType.No, "<STR_LIT:0>", <NUM_LIT:0>, True, False]<EOL>self.m_blk_b[Field.Net_Calc_Watts_Ln_3] = [<NUM_LIT:7>, FieldType.Int, ScaleType.No, "<STR_LIT:0>", <NUM_LIT:0>, True, False]<EOL>self.m_blk_b[Field.Net_Calc_Watts_Tot] = [<NUM_LIT:7>, FieldType.Int, ScaleType.No, "<STR_LIT:0>", <NUM_LIT:0>, True, False]<EOL>self.m_blk_b[Field.Power_Factor_Ln_1] = [<NUM_LIT:4>, FieldType.Int, ScaleType.No, "<STR_LIT:0>", <NUM_LIT:0>, True, False]<EOL>self.m_blk_b[Field.Power_Factor_Ln_2] = [<NUM_LIT:4>, FieldType.Int, ScaleType.No, "<STR_LIT:0>", <NUM_LIT:0>, True, False]<EOL>self.m_blk_b[Field.Power_Factor_Ln_3] = [<NUM_LIT:4>, FieldType.Int, ScaleType.No, "<STR_LIT:0>", <NUM_LIT:0>, True, False]<EOL>pass<EOL>

Initialize B read :class:`~ekmmeters.SerialBlock`.


self.m_lcd_lookup["<STR_LIT>"] = LCDItems.kWh_Tot<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Rev_kWh_Tot<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.RMS_Volts_Ln_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.RMS_Volts_Ln_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.RMS_Volts_Ln_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Amps_Ln_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Amps_Ln_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Amps_Ln_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.RMS_Watts_Ln_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.RMS_Watts_Ln_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.RMS_Watts_Ln_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.RMS_Watts_Tot<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Power_Factor_Ln_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Power_Factor_Ln_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Power_Factor_Ln_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.kWh_Tariff_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.kWh_Tariff_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.kWh_Tariff_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.kWh_Tariff_4<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Rev_kWh_Tariff_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Rev_kWh_Tariff_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Rev_kWh_Tariff_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Rev_kWh_Tariff_4<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Reactive_Pwr_Ln_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Reactive_Pwr_Ln_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Reactive_Pwr_Ln_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Reactive_Pwr_Tot<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Line_Freq<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Pulse_Cnt_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Pulse_Cnt_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Pulse_Cnt_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.kWh_Ln_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Rev_kWh_Ln_1<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.kWh_Ln_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Rev_kWh_Ln_2<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.kWh_Ln_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Rev_kWh_Ln_3<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Reactive_Energy_Tot<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Max_Demand_Rst<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Rev_kWh_Rst<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.State_Inputs<EOL>self.m_lcd_lookup["<STR_LIT>"] = LCDItems.Max_Demand<EOL>

Initialize lookup table for string input of LCD fields


def request(self, send_terminator = False):

try:<EOL><INDENT>retA = self.requestA()<EOL>retB = self.requestB()<EOL>if retA and retB:<EOL><INDENT>self.makeAB()<EOL>self.calculateFields()<EOL>self.updateObservers()<EOL>return True<EOL><DEDENT><DEDENT>except:<EOL><INDENT>ekm_log(traceback.format_exc(sys.exc_info()))<EOL><DEDENT>return False<EOL>

Combined A and B read for V4 meter.

        Args:
            send_terminator (bool): Send termination string at end of read.

        Returns:
            bool: True on completion.


work_context = self.getContext()<EOL>self.setContext("<STR_LIT>")<EOL>self.m_serial_port.write("<STR_LIT>".decode("<STR_LIT>") + self.m_meter_address + "<STR_LIT>".decode("<STR_LIT>"))<EOL>self.m_raw_read_a = self.m_serial_port.getResponse(self.getContext())<EOL>unpacked_read_a = self.unpackStruct(self.m_raw_read_a, self.m_blk_a)<EOL>self.convertData(unpacked_read_a, self.m_blk_a)<EOL>self.m_kwh_precision = int(self.m_blk_a[Field.kWh_Scale][MeterData.NativeValue])<EOL>self.m_a_crc = self.crcMeterRead(self.m_raw_read_a, self.m_blk_a)<EOL>self.setContext(work_context)<EOL>return self.m_a_crc<EOL>

Issue an A read on V4 meter.

        Returns:
            bool: True if CRC match at end of call.


work_context = self.getContext()<EOL>self.setContext("<STR_LIT>")<EOL>self.m_serial_port.write("<STR_LIT>".decode("<STR_LIT>") + self.m_meter_address + "<STR_LIT>".decode("<STR_LIT>"))<EOL>self.m_raw_read_b = self.m_serial_port.getResponse(self.getContext())<EOL>unpacked_read_b = self.unpackStruct(self.m_raw_read_b, self.m_blk_b)<EOL>self.convertData(unpacked_read_b, self.m_blk_b, self.m_kwh_precision)<EOL>self.m_b_crc = self.crcMeterRead(self.m_raw_read_b, self.m_blk_b)<EOL>self.setContext(work_context)<EOL>return self.m_b_crc<EOL>

Issue a B read on V4 meter.

        Returns:
            bool: True if CRC match at end of call.


for fld in self.m_blk_a:<EOL><INDENT>compare_fld = fld.upper()<EOL>if not "<STR_LIT>" in compare_fld and not "<STR_LIT>" in compare_fld:<EOL><INDENT>self.m_req[fld] = self.m_blk_a[fld]<EOL><DEDENT><DEDENT>for fld in self.m_blk_b:<EOL><INDENT>compare_fld = fld.upper()<EOL>if not "<STR_LIT>" in compare_fld and not "<STR_LIT>" in compare_fld:<EOL><INDENT>self.m_req[fld] = self.m_blk_b[fld]<EOL><DEDENT><DEDENT>pass<EOL>

Munge A and B reads into single serial block with only unique fields.


return self.m_req<EOL>

Return the read buffer containing A and B reads.

        Appropriate for JSON conversion or other processing in an agent.

        Returns:
            SerialBlock: A :class:`~ekmmeters.SerialBlock`  containing both A and B reads.


result = "<STR_LIT>"<EOL>if fld_name in self.m_req:<EOL><INDENT>result = self.m_req[fld_name][MeterData.StringValue]<EOL><DEDENT>else:<EOL><INDENT>ekm_log("<STR_LIT>" + fld_name)<EOL><DEDENT>return result<EOL>

Return :class:`~ekmmeters.Field` content, scaled and formatted.

        Args:
            fld_name (str): A `:class:~ekmmeters.Field` value which is on your meter.

        Returns:
            str: String value (scaled if numeric) for the field.


pf1 = self.m_blk_b[Field.Cos_Theta_Ln_1][MeterData.StringValue]<EOL>pf2 = self.m_blk_b[Field.Cos_Theta_Ln_2][MeterData.StringValue]<EOL>pf3 = self.m_blk_b[Field.Cos_Theta_Ln_3][MeterData.StringValue]<EOL>pf1_int = self.calcPF(pf1)<EOL>pf2_int = self.calcPF(pf2)<EOL>pf3_int = self.calcPF(pf3)<EOL>self.m_blk_b[Field.Power_Factor_Ln_1][MeterData.StringValue] = str(pf1_int)<EOL>self.m_blk_b[Field.Power_Factor_Ln_2][MeterData.StringValue] = str(pf2_int)<EOL>self.m_blk_b[Field.Power_Factor_Ln_3][MeterData.StringValue] = str(pf3_int)<EOL>self.m_blk_b[Field.Power_Factor_Ln_1][MeterData.NativeValue] = pf1_int<EOL>self.m_blk_b[Field.Power_Factor_Ln_2][MeterData.NativeValue] = pf2_int<EOL>self.m_blk_b[Field.Power_Factor_Ln_3][MeterData.NativeValue] = pf2_int<EOL>rms_watts_1 = self.m_blk_b[Field.RMS_Watts_Ln_1][MeterData.NativeValue]<EOL>rms_watts_2 = self.m_blk_b[Field.RMS_Watts_Ln_2][MeterData.NativeValue]<EOL>rms_watts_3 = self.m_blk_b[Field.RMS_Watts_Ln_3][MeterData.NativeValue]<EOL>sign_rms_watts_1 = <NUM_LIT:1><EOL>sign_rms_watts_2 = <NUM_LIT:1><EOL>sign_rms_watts_3 = <NUM_LIT:1><EOL>direction_byte = self.m_blk_a[Field.State_Watts_Dir][MeterData.NativeValue]<EOL>if direction_byte == DirectionFlag.ForwardForwardForward:<EOL><INDENT>pass<EOL><DEDENT>if direction_byte == DirectionFlag.ForwardForwardReverse:<EOL><INDENT>sign_rms_watts_3 = -<NUM_LIT:1><EOL>pass<EOL><DEDENT>if direction_byte == DirectionFlag.ForwardReverseForward:<EOL><INDENT>sign_rms_watts_2 = -<NUM_LIT:1><EOL>pass<EOL><DEDENT>if direction_byte == DirectionFlag.ReverseForwardForward:<EOL><INDENT>sign_rms_watts_1 = -<NUM_LIT:1><EOL>pass<EOL><DEDENT>if direction_byte == DirectionFlag.ForwardReverseReverse:<EOL><INDENT>sign_rms_watts_2 = -<NUM_LIT:1><EOL>sign_rms_watts_3 = -<NUM_LIT:1><EOL>pass<EOL><DEDENT>if direction_byte == DirectionFlag.ReverseForwardReverse:<EOL><INDENT>sign_rms_watts_1 = -<NUM_LIT:1><EOL>sign_rms_watts_3 = -<NUM_LIT:1><EOL>pass<EOL><DEDENT>if direction_byte == DirectionFlag.ReverseReverseForward:<EOL><INDENT>sign_rms_watts_1 = -<NUM_LIT:1><EOL>sign_rms_watts_2 = -<NUM_LIT:1><EOL>pass<EOL><DEDENT>if direction_byte == DirectionFlag.ReverseReverseReverse:<EOL><INDENT>sign_rms_watts_1 = -<NUM_LIT:1><EOL>sign_rms_watts_2 = -<NUM_LIT:1><EOL>sign_rms_watts_3 = -<NUM_LIT:1><EOL>pass<EOL><DEDENT>net_watts_1 = rms_watts_1 * sign_rms_watts_1<EOL>net_watts_2 = rms_watts_2 * sign_rms_watts_2<EOL>net_watts_3 = rms_watts_3 * sign_rms_watts_3<EOL>net_watts_tot = net_watts_1 + net_watts_2 + net_watts_3<EOL>self.m_blk_b[Field.Net_Calc_Watts_Ln_1][MeterData.NativeValue] = net_watts_1<EOL>self.m_blk_b[Field.Net_Calc_Watts_Ln_2][MeterData.NativeValue] = net_watts_2<EOL>self.m_blk_b[Field.Net_Calc_Watts_Ln_3][MeterData.NativeValue] = net_watts_3<EOL>self.m_blk_b[Field.Net_Calc_Watts_Tot][MeterData.NativeValue] = net_watts_tot<EOL>self.m_blk_b[Field.Net_Calc_Watts_Ln_1][MeterData.StringValue] = str(net_watts_1)<EOL>self.m_blk_b[Field.Net_Calc_Watts_Ln_2][MeterData.StringValue] = str(net_watts_2)<EOL>self.m_blk_b[Field.Net_Calc_Watts_Ln_3][MeterData.StringValue] = str(net_watts_3)<EOL>self.m_blk_b[Field.Net_Calc_Watts_Tot][MeterData.StringValue] = str(net_watts_tot)<EOL>pass<EOL>

Write calculated fields for read buffer.


for observer in self.m_observers:<EOL><INDENT>observer.update(self.m_req)<EOL><DEDENT>

Call the update() method in all attached  observers in order of attachment.

        Called internally after request().


if meter_db:<EOL><INDENT>meter_db.dbInsert(self.m_req, self.m_raw_read_a, self.m_raw_read_b)<EOL><DEDENT>else:<EOL><INDENT>ekm_log("<STR_LIT>")<EOL><DEDENT>pass<EOL>

Insert to :class:`~ekmmeters.MeterDB`  subclass.

        Please note MeterDB subclassing is only for simplest-case.

        Args:
            meter_db (MeterDB): Instance of subclass of MeterDB.


if item_str in self.m_lcd_lookup:<EOL><INDENT>return self.m_lcd_lookup[item_str]<EOL><DEDENT>else:<EOL><INDENT>return <NUM_LIT:0><EOL><DEDENT>

Translate a string to corresponding LCD field integer

        Args:
            item_str (str): String identical to :class:`~ekmmeters.LcdItems` entry.

        Returns:
            int:  :class:`~ekmmeters.LcdItems` integer or 0 if not found.


def setLCDCmd(self, display_list, password="<STR_LIT>"):

result = False<EOL>try:<EOL><INDENT>self.initLcd()<EOL>item_cnt = len(display_list)<EOL>if (item_cnt > <NUM_LIT>) or (item_cnt <= <NUM_LIT:0>):<EOL><INDENT>ekm_log("<STR_LIT>")<EOL>return False<EOL><DEDENT>for display_item in display_list:<EOL><INDENT>self.addLcdItem(int(display_item))<EOL><DEDENT>result = self.setLCD(password)<EOL><DEDENT>except:<EOL><INDENT>ekm_log(traceback.format_exc(sys.exc_info()))<EOL><DEDENT>return result<EOL>

Single call wrapper for LCD set."

        Wraps :func:`~ekmmeters.V4Meter.setLcd` and associated init and add methods.

        Args:
            display_list (list): List composed of :class:`~ekmmeters.LCDItems`
            password (str): Optional password.

        Returns:
            bool: Passthrough from :func:`~ekmmeters.V4Meter.setLcd`


def setRelay(self, seconds, relay, status, password="<STR_LIT>"):

result = False<EOL>self.setContext("<STR_LIT>")<EOL>try:<EOL><INDENT>self.clearCmdMsg()<EOL>if len(password) != <NUM_LIT:8>:<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL>self.setContext("<STR_LIT>")<EOL>return result<EOL><DEDENT>if seconds < <NUM_LIT:0> or seconds > <NUM_LIT>:<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL>self.setContext("<STR_LIT>")<EOL>return result<EOL><DEDENT>if not self.requestA():<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>if not self.serialCmdPwdAuth(password):<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>req_str = "<STR_LIT>"<EOL>req_str = ("<STR_LIT>" +<EOL>binascii.hexlify(str(relay)).zfill(<NUM_LIT:2>) +<EOL>"<STR_LIT>" +<EOL>binascii.hexlify(str(status)).zfill(<NUM_LIT:2>) +<EOL>binascii.hexlify(str(seconds).zfill(<NUM_LIT:4>)) + "<STR_LIT>")<EOL>req_str += self.calc_crc16(req_str[<NUM_LIT:2>:].decode("<STR_LIT>"))<EOL>self.m_serial_port.write(req_str.decode("<STR_LIT>"))<EOL>if self.m_serial_port.getResponse(self.getContext()).encode("<STR_LIT>") == "<STR_LIT>":<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL>result = True<EOL><DEDENT><DEDENT><DEDENT>self.serialPostEnd()<EOL><DEDENT>except:<EOL><INDENT>ekm_log(traceback.format_exc(sys.exc_info()))<EOL><DEDENT>self.setContext("<STR_LIT>")<EOL>return result<EOL>

Serial call to set relay.

        Args:
            seconds (int): Seconds to hold, ero is hold forever. See :class:`~ekmmeters.RelayInterval`.
            relay (int): Selected relay, see :class:`~ekmmeters.Relay`.
            status (int): Status to set, see :class:`~ekmmeters.RelayState`
            password (str): Optional password

        Returns:
            bool: True on completion and ACK.


ekm_log("<STR_LIT>" + self.m_context + "<STR_LIT:)>")<EOL>try:<EOL><INDENT>self.m_serial_port.write("<STR_LIT>".decode("<STR_LIT>"))<EOL><DEDENT>except:<EOL><INDENT>ekm_log(traceback.format_exc(sys.exc_info()))<EOL><DEDENT>pass<EOL>

Send termination string to implicit current meter.


def setPulseInputRatio(self, line_in, new_cnst, password="<STR_LIT>"):

result = False<EOL>self.setContext("<STR_LIT>")<EOL>try:<EOL><INDENT>if not self.requestA():<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>if not self.serialCmdPwdAuth(password):<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>req_const = binascii.hexlify(str(new_cnst).zfill(<NUM_LIT:4>))<EOL>line_const = binascii.hexlify(str(line_in - <NUM_LIT:1>))<EOL>req_str = "<STR_LIT>" + line_const + "<STR_LIT>" + req_const + "<STR_LIT>"<EOL>req_str += self.calc_crc16(req_str[<NUM_LIT:2>:].decode("<STR_LIT>"))<EOL>self.m_serial_port.write(req_str.decode("<STR_LIT>"))<EOL>if self.m_serial_port.getResponse(self.getContext()).encode("<STR_LIT>") == "<STR_LIT>":<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL>result = True<EOL><DEDENT><DEDENT><DEDENT>self.serialPostEnd()<EOL><DEDENT>except:<EOL><INDENT>ekm_log(traceback.format_exc(sys.exc_info()))<EOL><DEDENT>self.setContext("<STR_LIT>")<EOL>return result<EOL>

Serial call to set pulse input ratio on a line.

        Args:
            line_in (int): Member of :class:`~ekmmeters.Pulse`
            new_cnst (int): New pulse input ratio
            password (str): Optional password

        Returns:


result = False<EOL>self.setContext("<STR_LIT>")<EOL>try:<EOL><INDENT>if not self.requestA():<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>if not self.serialCmdPwdAuth(password):<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>req_str = "<STR_LIT>"<EOL>req_str += self.calc_crc16(req_str[<NUM_LIT:2>:].decode("<STR_LIT>"))<EOL>self.m_serial_port.write(req_str.decode("<STR_LIT>"))<EOL>if self.m_serial_port.getResponse(self.getContext()).encode("<STR_LIT>") == "<STR_LIT>":<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL>result = True<EOL><DEDENT><DEDENT><DEDENT>self.serialPostEnd()<EOL><DEDENT>except:<EOL><INDENT>ekm_log(traceback.format_exc(sys.exc_info()))<EOL><DEDENT>self.setContext("<STR_LIT>")<EOL>return result<EOL>

Serial call to zero resettable kWh registers.

        Args:
            password (str): Optional password.

        Returns:
            bool: True on completion and ACK.


def setPulseOutputRatio(self, new_pout, password="<STR_LIT>"):

result = False<EOL>self.setContext("<STR_LIT>")<EOL>try:<EOL><INDENT>if not self.requestA():<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>if not self.serialCmdPwdAuth(password):<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>req_str = "<STR_LIT>" + binascii.hexlify(str(new_pout).zfill(<NUM_LIT:4>)) + "<STR_LIT>"<EOL>req_str += self.calc_crc16(req_str[<NUM_LIT:2>:].decode("<STR_LIT>"))<EOL>self.m_serial_port.write(req_str.decode("<STR_LIT>"))<EOL>if self.m_serial_port.getResponse(self.getContext()).encode("<STR_LIT>") == "<STR_LIT>":<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL>result = True<EOL><DEDENT><DEDENT><DEDENT>self.serialPostEnd()<EOL><DEDENT>except:<EOL><INDENT>ekm_log(traceback.format_exc(sys.exc_info()))<EOL><DEDENT>self.setContext("<STR_LIT>")<EOL>return result<EOL>

Serial call to set pulse output ratio.

        Args:
            new_pout (int):  Legal output, member of  :class:`~ekmmeters.PulseOutput` .
            password (str): Optional password

        Returns:
            bool: True on completion and ACK


self.m_lcd_items = []<EOL>pass<EOL>


self.m_lcd_items.append(lcd_item_no)<EOL>pass<EOL>

Simple append to internal buffer.

Used with :func:`~ekmmeters.V4Meter.setLcd` and :func:`~ekmmeters.V4Meter.initLcd`

Args:
    lcd_item_no (int): Member of :class:`~ekmmeters.LCDItems`


result = False<EOL>self.setContext("<STR_LIT>")<EOL>try:<EOL><INDENT>self.clearCmdMsg()<EOL>if len(password) != <NUM_LIT:8>:<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL>self.setContext("<STR_LIT>")<EOL>return result<EOL><DEDENT>if not self.request():<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>if not self.serialCmdPwdAuth(password):<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>req_table = "<STR_LIT>"<EOL>fill_len = <NUM_LIT> - len(self.m_lcd_items)<EOL>for lcdid in self.m_lcd_items:<EOL><INDENT>append_val = binascii.hexlify(str(lcdid).zfill(<NUM_LIT:2>))<EOL>req_table += append_val<EOL><DEDENT>for i in range(<NUM_LIT:0>, fill_len):<EOL><INDENT>append_val = binascii.hexlify(str(<NUM_LIT:0>).zfill(<NUM_LIT:2>))<EOL>req_table += append_val<EOL><DEDENT>req_str = "<STR_LIT>" + req_table + "<STR_LIT>"<EOL>req_str += self.calc_crc16(req_str[<NUM_LIT:2>:].decode("<STR_LIT>"))<EOL>self.m_serial_port.write(req_str.decode("<STR_LIT>"))<EOL>if self.m_serial_port.getResponse(self.getContext()).encode("<STR_LIT>") == "<STR_LIT>":<EOL><INDENT>self.writeCmdMsg("<STR_LIT>")<EOL>result = True<EOL><DEDENT><DEDENT><DEDENT>self.serialPostEnd()<EOL><DEDENT>except:<EOL><INDENT>ekm_log(traceback.format_exc(sys.exc_info()))<EOL><DEDENT>self.setContext("<STR_LIT>")<EOL>return result<EOL>

Serial call to set LCD using meter object bufer.

        Used with :func:`~ekmmeters.V4Meter.addLcdItem`.

        Args:
            password (str): Optional password

        Returns:
            bool: True on completion and ACK.


test_ini = configparser.ConfigParser()<EOL>test_ini.read('<STR_LIT>')<EOL>test_port = test_ini.get("<STR_LIT>", '<STR_LIT>')<EOL>v3_addr = test_ini.get("<STR_LIT>", '<STR_LIT>')<EOL>v4_addr = test_ini.get("<STR_LIT>", '<STR_LIT>')<EOL>dbpath = test_ini.get("<STR_LIT>", '<STR_LIT>')<EOL>user_prompts = test_ini.getboolean("<STR_LIT>", "<STR_LIT>")<EOL>wait = test_ini.getfloat("<STR_LIT>", "<STR_LIT>")<EOL>return (wait, test_port, v3_addr, v4_addr, dbpath, user_prompts)<EOL>

Helper.  Call at start of any test function which needs the meter and port
(all of them)


super(MeterObserver, self).__init__()<EOL>pass<EOL>


pass<EOL>

Required override of update() for this observer

Parameters
----------
definition_buffer : collections.OrderedDict
    Results of last read


qr = qrc.QRCode(<EOL>version=version,<EOL>error_correction=cls.correction_levels[error_correction],<EOL>box_size=box_size,<EOL>border=border,<EOL>)<EOL>qr.add_data(data)<EOL>qr.make(fit=fit)<EOL>fcolor = (<EOL>fill_color<EOL>if fill_color.lower() in cls.color or fill_color.startswith("<STR_LIT:#>")<EOL>else "<STR_LIT:#>" + fill_color<EOL>)<EOL>bcolor = (<EOL>back_color<EOL>if back_color.lower() in cls.color or back_color.startswith("<STR_LIT:#>")<EOL>else "<STR_LIT:#>" + back_color<EOL>)<EOL>out = BytesIO()<EOL>qr_img = qr.make_image(back_color=bcolor, fill_color=fcolor)<EOL>qr_img = qr_img.convert("<STR_LIT>")<EOL>qr_img = cls._insert_img(qr_img, **kwargs)<EOL>qr_img.save(out, "<STR_LIT>")<EOL>out.seek(<NUM_LIT:0>)<EOL>if mode == "<STR_LIT>":<EOL><INDENT>return u"<STR_LIT>" + base64.b64encode(out.getvalue()).decode(<EOL>"<STR_LIT:ascii>"<EOL>)<EOL><DEDENT>elif mode == "<STR_LIT>":<EOL><INDENT>return out<EOL><DEDENT>

Makes qr image using qrcode as qrc. See documentation
        for qrcode (https://pypi.python.org/pypi/qrcode) package for more info.

        :param data: String data.
        :param mode: Output mode, [base64|raw].
        :param version: The size of the QR Code (1-40).
        :param error_correction: The error correction used for the QR Code.
        :param box_size: The number of pixels for each "box" of the QR code.
        :param border: The number of box for border.
        :param fit: If `True`, find the best fit for the data.
        :param fill_color: Frontend color.
        :param back_color: Background color.

        :param icon_img: Small icon image name or url.
        :param factor: Resize for icon image (default: 4, one-fourth of QRCode)
        :param icon_box: Icon image position [left, top] (default: image center)


@staticmethod<EOL><INDENT>def _insert_img(qr_img, icon_img=None, factor=<NUM_LIT:4>, icon_box=None, static_dir=None):<DEDENT>

img_w, img_h = qr_img.size<EOL>size_w = int(img_w) / int(factor)<EOL>size_h = int(img_h) / int(factor)<EOL>try:<EOL><INDENT>icon_fp = os.path.join(icon_img)<EOL>if static_dir:<EOL><INDENT>icon_fp = os.path.join(static_dir, icon_img)<EOL><DEDENT>if icon_img.split("<STR_LIT>")[<NUM_LIT:0>] in ["<STR_LIT:http>", "<STR_LIT>", "<STR_LIT>"]:<EOL><INDENT>icon_fp = BytesIO(urlopen(icon_img).read())  <EOL><DEDENT>icon = Image.open(icon_fp)<EOL><DEDENT>except:<EOL><INDENT>return qr_img<EOL><DEDENT>icon_w, icon_h = icon.size<EOL>icon_w = size_w if icon_w > size_w else icon_w<EOL>icon_h = size_h if icon_h > size_h else icon_h<EOL>icon = icon.resize((int(icon_w), int(icon_h)), Image.ANTIALIAS)<EOL>icon = icon.convert("<STR_LIT>")<EOL>left = int((img_w - icon_w) / <NUM_LIT:2>)<EOL>top = int((img_h - icon_h) / <NUM_LIT:2>)<EOL>icon_box = (int(icon_box[<NUM_LIT:0>]), int(icon_box[<NUM_LIT:1>])) if icon_box else (left, top)<EOL>qr_img.paste(im=icon, box=icon_box, mask=icon)<EOL>return qr_img<EOL>


def search(term=None, phrase=None, limit=DEFAULT_SEARCH_LIMIT,<EOL>api_key=GIPHY_PUBLIC_KEY, strict=False, rating=None):

return Giphy(api_key=api_key, strict=strict).search(<EOL>term=term, phrase=phrase, limit=limit, rating=rating)<EOL>

Shorthand for creating a Giphy api wrapper with the given api key
and then calling the search method. Note that this will return a generator


def search_list(term=None, phrase=None, limit=DEFAULT_SEARCH_LIMIT,<EOL>api_key=GIPHY_PUBLIC_KEY, strict=False, rating=None):

return Giphy(api_key=api_key, strict=strict).search_list(<EOL>term=term, phrase=phrase, limit=limit, rating=rating)<EOL>

Shorthand for creating a Giphy api wrapper with the given api key
and then calling the search_list method.


def translate(term=None, phrase=None, api_key=GIPHY_PUBLIC_KEY, strict=False,<EOL>rating=None):

return Giphy(api_key=api_key, strict=strict).translate(<EOL>term=term, phrase=phrase, rating=rating)<EOL>

Shorthand for creating a Giphy api wrapper with the given api key
and then calling the translate method.


def trending(limit=DEFAULT_SEARCH_LIMIT, api_key=GIPHY_PUBLIC_KEY,<EOL>strict=False, rating=None):

return Giphy(api_key=api_key, strict=strict).trending(<EOL>limit=limit, rating=rating)<EOL>

Shorthand for creating a Giphy api wrapper with the given api key
and then calling the trending method. Note that this will return
a generator


def trending_list(limit=DEFAULT_SEARCH_LIMIT, api_key=GIPHY_PUBLIC_KEY,<EOL>strict=False, rating=None):

return Giphy(api_key=api_key, strict=strict).trending_list(<EOL>limit=limit, rating=rating)<EOL>

Shorthand for creating a Giphy api wrapper with the given api key
and then calling the trending_list method.


def gif(gif_id, api_key=GIPHY_PUBLIC_KEY, strict=False):

return Giphy(api_key=api_key, strict=strict).gif(gif_id)<EOL>

Shorthand for creating a Giphy api wrapper with the given api key
and then calling the gif method.


def screensaver(tag=None, api_key=GIPHY_PUBLIC_KEY, strict=False):

return Giphy(api_key=api_key, strict=strict).screensaver(tag=tag)<EOL>

Shorthand for creating a Giphy api wrapper with the given api key
and then calling the screensaver method.


def upload(tags, file_path, username=None, api_key=GIPHY_PUBLIC_KEY,<EOL>strict=False):

return Giphy(api_key=api_key, strict=strict).upload(<EOL>tags, file_path, username)<EOL>

Shorthand for creating a Giphy api wrapper with the given api key
and then calling the upload method.


<EOL>import webbrowser<EOL>webbrowser.open(self.url)<EOL>


return self.original.url<EOL>

The media URL of the gif at its original size


return self.original.frames<EOL>


return self.original.width<EOL>

The width of the gif at its original size


return self.original.height<EOL>

The height of the gif at its original size


return self.original.size<EOL>

The size of the original size file in bytes


<EOL>process = ('<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>')<EOL>for key in process:<EOL><INDENT>data = images.get(key)<EOL>if not data:<EOL><INDENT>continue<EOL><DEDENT>parts = key.split('<STR_LIT:_>')<EOL>if len(parts) > <NUM_LIT:2>:<EOL><INDENT>attr, subattr = '<STR_LIT:_>'.join(parts[:-<NUM_LIT:1>]), parts[-<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>attr, subattr = '<STR_LIT:_>'.join(parts), None<EOL><DEDENT>img = AttrDict(self._normalized(data))<EOL>if subattr is None:<EOL><INDENT>setattr(self, attr, img)<EOL><DEDENT>else:<EOL><INDENT>setattr(getattr(self, attr), subattr, img)<EOL><DEDENT><DEDENT>

Takes an image dict from the giphy api and converts it to attributes.
Any fields expected to be int (width, height, size, frames) will be attempted
to be converted. Also, the keys of `data` serve as the attribute names, but
with special action taken. Keys are split by the last underscore; anything prior
becomes the attribute name, anything after becomes a sub-attribute. For example:
fixed_width_downsampled will end up at `self.fixed_width.downsampled`


int_keys = ('<STR_LIT>', '<STR_LIT:width>', '<STR_LIT>', '<STR_LIT:size>')<EOL>for key in int_keys:<EOL><INDENT>if key not in data:<EOL><INDENT>continue<EOL><DEDENT>try:<EOL><INDENT>data[key] = int(data[key])<EOL><DEDENT>except ValueError:<EOL><INDENT>pass  <EOL><DEDENT><DEDENT>return data<EOL>

Does a normalization of sorts on image type data so that values
that should be integers are converted from strings


def _fetch(self, endpoint_name, **params):

params['<STR_LIT>'] = self.api_key<EOL>resp = requests.get(self._endpoint(endpoint_name), params=params)<EOL>resp.raise_for_status()<EOL>data = resp.json()<EOL>self._check_or_raise(data.get('<STR_LIT>', {}))<EOL>return data<EOL>

Wrapper for making an api request from giphy


def search(self, term=None, phrase=None, limit=DEFAULT_SEARCH_LIMIT,<EOL>rating=None):

assert any((term, phrase)), '<STR_LIT>'<EOL>if phrase:<EOL><INDENT>phrase = phrase.replace('<STR_LIT:U+0020>', '<STR_LIT:->')<EOL><DEDENT>results_yielded = <NUM_LIT:0>  <EOL>page, per_page = <NUM_LIT:0>, <NUM_LIT><EOL>params = {'<STR_LIT:q>': (term or phrase)}<EOL>if rating:<EOL><INDENT>params.update({'<STR_LIT>': rating})<EOL><DEDENT>fetch = partial(self._fetch, '<STR_LIT>', **params)<EOL>while True:<EOL><INDENT>data = fetch(offset=page, limit=per_page)<EOL>page += per_page<EOL>if not data['<STR_LIT:data>']:<EOL><INDENT>raise StopIteration<EOL><DEDENT>for item in data['<STR_LIT:data>']:<EOL><INDENT>results_yielded += <NUM_LIT:1><EOL>yield GiphyImage(item)<EOL>if limit is not None and results_yielded >= limit:<EOL><INDENT>raise StopIteration<EOL><DEDENT><DEDENT>if (page >= data['<STR_LIT>']['<STR_LIT>'] or<EOL>(limit is not None and results_yielded >= limit)):<EOL><INDENT>raise StopIteration<EOL><DEDENT><DEDENT>

Search for gifs with a given word or phrase. Punctuation is ignored.
By default, this will perform a `term` search. If you want to search
by phrase, use the `phrase` keyword argument. What's the difference
between `term` and `phrase` searches? Simple: a term search will
return results matching any words given, whereas a phrase search will
match all words.

Note that this method is a GiphyImage generator that
automatically handles api paging. Optionally accepts a limit that will
terminate the generation after a specified number of results have been
yielded. This defaults to 25 results; a None implies no limit

:param term: Search term or terms
:type term: string
:param phrase: Search phrase
:type phrase: string
:param limit: Maximum number of results to yield
:type limit: int
:param rating: limit results to those rated (y,g, pg, pg-13 or r).
:type rating: string


def search_list(self, term=None, phrase=None, limit=DEFAULT_SEARCH_LIMIT,<EOL>rating=None):

return list(self.search(term=term, phrase=phrase, limit=limit,<EOL>rating=rating))<EOL>

Suppose you expect the `search` method to just give you a list rather
than a generator. This method will have that effect. Equivalent to::

    >>> g = Giphy()
    >>> results = list(g.search('foo'))


def translate(self, term=None, phrase=None, strict=False, rating=None):

assert any((term, phrase)), '<STR_LIT>'<EOL>if phrase:<EOL><INDENT>phrase = phrase.replace('<STR_LIT:U+0020>', '<STR_LIT:->')<EOL><DEDENT>params = {'<STR_LIT:s>': (term or phrase)}<EOL>if rating:<EOL><INDENT>params.update({'<STR_LIT>': rating})<EOL><DEDENT>resp = self._fetch('<STR_LIT>', **params)<EOL>if resp['<STR_LIT:data>']:<EOL><INDENT>return GiphyImage(resp['<STR_LIT:data>'])<EOL><DEDENT>elif strict or self.strict:<EOL><INDENT>raise GiphyApiException(<EOL>"<STR_LIT>" %<EOL>(term or phrase))<EOL><DEDENT>

Retrieve a single image that represents a transalation of a term or
phrase into an animated gif. Punctuation is ignored. By default, this
will perform a `term` translation. If you want to translate by phrase,
use the `phrase` keyword argument.

:param term: Search term or terms
:type term: string
:param phrase: Search phrase
:type phrase: string
:param strict: Whether an exception should be raised when no results
:type strict: boolean
:param rating: limit results to those rated (y,g, pg, pg-13 or r).
:type rating: string


def trending(self, rating=None, limit=DEFAULT_SEARCH_LIMIT):

results_yielded = <NUM_LIT:0>  <EOL>page, per_page = <NUM_LIT:0>, <NUM_LIT><EOL>params = {'<STR_LIT>': rating} if rating else {}<EOL>fetch = partial(self._fetch, '<STR_LIT>', **params)<EOL>while True:<EOL><INDENT>data = fetch(offset=page, limit=per_page)<EOL>page += per_page<EOL>if not data['<STR_LIT:data>']:<EOL><INDENT>raise StopIteration<EOL><DEDENT>for item in data['<STR_LIT:data>']:<EOL><INDENT>results_yielded += <NUM_LIT:1><EOL>yield GiphyImage(item)<EOL>if limit is not None and results_yielded >= limit:<EOL><INDENT>raise StopIteration<EOL><DEDENT><DEDENT>if (page >= data['<STR_LIT>']['<STR_LIT>'] or<EOL>(limit is not None and results_yielded >= limit)):<EOL><INDENT>raise StopIteration<EOL><DEDENT><DEDENT>

Retrieve GIFs currently trending online. The data returned mirrors
that used to create The Hot 100 list of GIFs on Giphy.

:param rating: limit results to those rated (y,g, pg, pg-13 or r).
:type rating: string
:param limit: Maximum number of results to yield
:type limit: int


def trending_list(self, rating=None, limit=DEFAULT_SEARCH_LIMIT):

return list(self.trending(limit=limit, rating=rating))<EOL>

Suppose you expect the `trending` method to just give you a list rather
than a generator. This method will have that effect. Equivalent to::

    >>> g = Giphy()
    >>> results = list(g.trending())


resp = self._fetch(gif_id)<EOL>if resp['<STR_LIT:data>']:<EOL><INDENT>return GiphyImage(resp['<STR_LIT:data>'])<EOL><DEDENT>elif strict or self.strict:<EOL><INDENT>raise GiphyApiException(<EOL>"<STR_LIT>" % gif_id)<EOL><DEDENT>

Retrieves a specifc gif from giphy based on unique id

:param gif_id: Unique giphy gif ID
:type gif_id: string
:param strict: Whether an exception should be raised when no results
:type strict: boolean


def screensaver(self, tag=None, strict=False):

params = {'<STR_LIT>': tag} if tag else {}<EOL>resp = self._fetch('<STR_LIT>', **params)<EOL>if resp['<STR_LIT:data>'] and resp['<STR_LIT:data>']['<STR_LIT:id>']:<EOL><INDENT>return self.gif(resp['<STR_LIT:data>']['<STR_LIT:id>'])<EOL><DEDENT>elif strict or self.strict:<EOL><INDENT>raise GiphyApiException(<EOL>"<STR_LIT>" % tag)<EOL><DEDENT>

Returns a random giphy image, optionally based on a search of a given tag.
Note that this method will both query for a screensaver image and fetch the
full details of that image (2 request calls)

:param tag: Tag to retrieve a screensaver image
:type tag: string
:param strict: Whether an exception should be raised when no results
:type strict: boolean


def upload(self, tags, file_path, username=None):

params = {<EOL>'<STR_LIT>': self.api_key,<EOL>'<STR_LIT>': '<STR_LIT:U+002C>'.join(tags)<EOL>}<EOL>if username is not None:<EOL><INDENT>params['<STR_LIT:username>'] = username<EOL><DEDENT>with open(file_path, '<STR_LIT:rb>') as f:<EOL><INDENT>resp = requests.post(<EOL>GIPHY_UPLOAD_ENDPOINT, params=params, files={'<STR_LIT:file>': f})<EOL><DEDENT>resp.raise_for_status()<EOL>data = resp.json()<EOL>self._check_or_raise(data.get('<STR_LIT>', {}))<EOL>return self.gif(data['<STR_LIT:data>']['<STR_LIT:id>'])<EOL>

Uploads a gif from the filesystem to Giphy.

:param tags: Tags to apply to the uploaded image
:type tags: list
:param file_path: Path at which the image can be found
:type file_path: string
:param username: Your channel username if not using public API key


keys, values = zip(*mapping.items())<EOL>return dict(zip(values, keys))<EOL>

For every key, value pair, return the mapping for the
equivalent value, key pair

>>> reverse_mapping({'a': 'b'}) == {'b': 'a'}
True


return {<EOL>key: value<EOL>for keys, value in mapping.items()<EOL>for key in always_iterable(keys)<EOL>}<EOL>

For every key that has an __iter__ method, assign the values
to a key for each.

>>> flatten_mapping({'ab': 3, ('c','d'): 4}) == {'ab': 3, 'c': 4, 'd': 4}
True


def float_range(start=<NUM_LIT:0>, stop=None, step=<NUM_LIT:1>):

start = float(start)<EOL>while start < stop:<EOL><INDENT>yield start<EOL>start += step<EOL><DEDENT>

Much like the built-in function range, but accepts floats

>>> tuple(float_range(0, 9, 1.5))
(0.0, 1.5, 3.0, 4.5, 6.0, 7.5)


return self._scale_x_divisions<EOL>

Determines the scaling for the X axis divisions.

graph.scale_x_divisions = 2

would cause the graph to attempt to generate labels
stepped by 2; e.g.:
0,2,4,6,8...


def get_single_axis_values(self, axis, dataset):

data_index = getattr(self, '<STR_LIT>' % axis)<EOL>return [p[data_index] for p in dataset['<STR_LIT:data>']]<EOL>

Return all the values for a single axis of the data.


value, label, style = value_label_style<EOL>start = self.transform_output_coordinates((<NUM_LIT:0>, value))[<NUM_LIT:1>]<EOL>stop = self.graph_width<EOL>path = etree.SubElement(self.graph, '<STR_LIT:path>', {<EOL>'<STR_LIT:d>': '<STR_LIT>' % locals(),<EOL>'<STR_LIT:class>': '<STR_LIT>'})<EOL>if style:<EOL><INDENT>path.set('<STR_LIT>', style)<EOL><DEDENT>text = etree.SubElement(self.graph, '<STR_LIT:text>', {<EOL>'<STR_LIT:x>': str(<NUM_LIT:2>),<EOL>'<STR_LIT:y>': str(start - <NUM_LIT:2>),<EOL>'<STR_LIT:class>': '<STR_LIT>'})<EOL>text.text = label<EOL>

Draw a constant line on the y-axis with the label


x_min, x_max, x_div = self.x_range()<EOL>y_min, y_max, y_div = self.y_range()<EOL>x_step = (float(self.graph_width) - self.font_size * <NUM_LIT:2>) /(x_max - x_min)<EOL>y_step = (float(self.graph_height) - self.font_size * <NUM_LIT:2>) /(y_max - y_min)<EOL>self.__transform_parameters = dict(locals())<EOL>del self.__transform_parameters['<STR_LIT>']<EOL>

Cache the parameters necessary to transform x & y coordinates


while start < stop:<EOL><INDENT>yield float(start)<EOL>start += step<EOL><DEDENT>

Much like the built-in function range, but accepts floats


def _fill_class(self, dataset_index, field_index):

return '<STR_LIT>' % (dataset_index + <NUM_LIT:1>)<EOL>

Return the CSS class for the indicated data parameters.

dataset_index is the index into the current dataset.
field_index is the index into the current field set.


<EOL>super(Schedule, self).add_data(data)<EOL>

Add data to the plot::

        # A data set with 1 point: Lunch from 12:30 to 14:00
        d1 = [ "Lunch", "12:30", "14:00" ]

        # A data set with 2 points: "Cats" runs from 5/11/03 to 7/15/04, and
        #                           "Henry V" runs from 6/12/03 to 8/20/03
        d2 = [
                "Cats",    "5/11/03", "7/15/04",
                "Henry V", "6/12/03", "8/20/03",
        ]

        sched.add_data(dict(
                data = d1,
                title = 'Meetings',
        ))
        sched.add_data(dict(
                data = d2,
                title = 'Plays',
        ))

Note that the data must be in time,value pairs, and that the date format
may be any date that is parseable by dateutil.
Also note that, in this example, we're mixing scales; the data from d1
will probably not be discernable if both data sets are plotted on the same
graph, since d1 is too granular.


try:<EOL><INDENT>return cls._rdp_map()[unit_string.lower()]<EOL><DEDENT>except KeyError:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>

>>> lrp = Schedule.lookup_relativedelta_parameter
>>> lrp('Years')
'years'
>>> lrp('yr')
'years'
>>> lrp('s')
'seconds'


if self.__class__ is Graph:<EOL><INDENT>raise NotImplementedError("<STR_LIT>")<EOL><DEDENT>self.load_config(config)<EOL>self.clear_data()<EOL>self.style = {}<EOL>

Initialize the graph object with the graph settings.


self.validate_data(conf)<EOL>self.process_data(conf)<EOL>self.data.append(conf)<EOL>

Add data to the graph object. May be called several times to add
additional data sets.

conf should be a dictionary including 'data' and 'title' keys


self.data = []<EOL>

This method removes all data from the object to create a new graph
with the same config options.


if not self.data:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if hasattr(self, '<STR_LIT>'):<EOL><INDENT>self.calculations()<EOL><DEDENT>self.start_svg()<EOL>self.calculate_graph_dimensions()<EOL>self.foreground = etree.Element("<STR_LIT:g>")<EOL>self.draw_graph()<EOL>self.draw_titles()<EOL>self.draw_legend()<EOL>self.draw_data()<EOL>self.graph.append(self.foreground)<EOL>self.render_inline_styles()<EOL>return self.render(self.root)<EOL>

Process the template with the data and
config which has been set and return the resulting SVG.

Raises ValueError when no data set has
been added to the graph object.


bl = <NUM_LIT:7><EOL>if self.rotate_y_labels:<EOL><INDENT>max_y_label_height_px = self.y_label_font_size<EOL><DEDENT>else:<EOL><INDENT>label_lengths = map(len, self.get_y_labels())<EOL>max_y_label_len = max(label_lengths)<EOL>max_y_label_height_px = <NUM_LIT> * max_y_label_len * self.y_label_font_size<EOL><DEDENT>if self.show_y_labels:<EOL><INDENT>bl += max_y_label_height_px<EOL><DEDENT>if self.stagger_y_labels:<EOL><INDENT>bl += max_y_label_height_px + <NUM_LIT:10><EOL><DEDENT>if self.show_y_title:<EOL><INDENT>bl += self.y_title_font_size + <NUM_LIT:5><EOL><DEDENT>self.border_left = bl<EOL>

Calculates the margin to the left of the plot area, setting
border_left.


if self.rotate_y_labels:<EOL><INDENT>return self.font_size<EOL><DEDENT>

Calculate the width of the widest Y label.  This will be the
character height if the Y labels are rotated.


br = <NUM_LIT:7><EOL>if self.key and self.key_position == '<STR_LIT:right>':<EOL><INDENT>max_key_len = max(map(len, self.keys()))<EOL>br += max_key_len * self.key_font_size * <NUM_LIT><EOL>br += self.KEY_BOX_SIZE<EOL>br += <NUM_LIT:10>  <EOL><DEDENT>self.border_right = br<EOL>

Calculate the margin in pixels to the right of the plot area,
setting border_right.


self.border_top = <NUM_LIT:5><EOL>if self.show_graph_title:<EOL><INDENT>self.border_top += self.title_font_size<EOL><DEDENT>self.border_top += <NUM_LIT:5><EOL>if self.show_graph_subtitle:<EOL><INDENT>self.border_top += self.subtitle_font_size<EOL><DEDENT>

Calculate the margin in pixels above the plot area, setting
border_top.


<EOL>name = name.replace('<STR_LIT::>', '<STR_LIT:->')<EOL>name = name.replace('<STR_LIT:U+0020>', '<STR_LIT:_>')<EOL>


txt_width = len(label) * self.font_size * <NUM_LIT> + <NUM_LIT:10><EOL>tx = x + [<NUM_LIT:5>, -<NUM_LIT:5>][int(x + txt_width > self.width)]<EOL>anchor = ['<STR_LIT:start>', '<STR_LIT:end>'][x + txt_width > self.width]<EOL>style = '<STR_LIT>' % anchor<EOL>id = '<STR_LIT>' % self._w3c_name(label)<EOL>attrs = {<EOL>'<STR_LIT:x>': str(tx),<EOL>'<STR_LIT:y>': str(y - self.font_size),<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': style,<EOL>'<STR_LIT:text>': label,<EOL>'<STR_LIT:id>': id,<EOL>}<EOL>etree.SubElement(self.foreground, '<STR_LIT:text>', attrs)<EOL>vis_tmpl = (<EOL>"<STR_LIT>"<EOL>)<EOL>attrs = {<EOL>'<STR_LIT>': str(x),<EOL>'<STR_LIT>': str(y),<EOL>'<STR_LIT:r>': str(<NUM_LIT:10>),<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': vis_tmpl.format(val='<STR_LIT>', id=id),<EOL>'<STR_LIT>': vis_tmpl.format(val='<STR_LIT>', id=id),<EOL>}<EOL>etree.SubElement(self.foreground, '<STR_LIT>', attrs)<EOL>

Add pop-up information to a point on the graph.


bb = <NUM_LIT:7><EOL>if self.key and self.key_position == '<STR_LIT>':<EOL><INDENT>bb += len(self.data) * (self.font_size + <NUM_LIT:5>)<EOL>bb += <NUM_LIT:10><EOL><DEDENT>if self.show_x_labels:<EOL><INDENT>max_x_label_height_px = self.x_label_font_size<EOL>if self.rotate_x_labels:<EOL><INDENT>label_lengths = map(len, self.get_x_labels())<EOL>max_x_label_len = functools.reduce(max, label_lengths)<EOL>max_x_label_height_px *= <NUM_LIT> * max_x_label_len<EOL><DEDENT>bb += max_x_label_height_px<EOL>if self.stagger_x_labels:<EOL><INDENT>bb += max_x_label_height_px + <NUM_LIT:10><EOL><DEDENT><DEDENT>if self.show_x_title:<EOL><INDENT>bb += self.x_title_font_size + <NUM_LIT:5><EOL><DEDENT>self.border_bottom = bb<EOL>

Calculate the margin in pixels below the plot area, setting
border_bottom.


transform = '<STR_LIT>' % (self.border_left, self.border_top)<EOL>self.graph = etree.SubElement(self.root, '<STR_LIT:g>', transform=transform)<EOL>etree.SubElement(self.graph, '<STR_LIT>', {<EOL>'<STR_LIT:x>': '<STR_LIT:0>',<EOL>'<STR_LIT:y>': '<STR_LIT:0>',<EOL>'<STR_LIT:width>': str(self.graph_width),<EOL>'<STR_LIT>': str(self.graph_height),<EOL>'<STR_LIT:class>': '<STR_LIT>'<EOL>})<EOL>etree.SubElement(self.graph, '<STR_LIT:path>', {<EOL>'<STR_LIT:d>': '<STR_LIT>' % self.graph_height,<EOL>'<STR_LIT:class>': '<STR_LIT>',<EOL>'<STR_LIT:id>': '<STR_LIT>'<EOL>})<EOL>etree.SubElement(self.graph, '<STR_LIT:path>', {<EOL>'<STR_LIT:d>': '<STR_LIT>' % (self.graph_height, self.graph_width),<EOL>'<STR_LIT:class>': '<STR_LIT>',<EOL>'<STR_LIT:id>': '<STR_LIT>'<EOL>})<EOL>self.draw_x_labels()<EOL>self.draw_y_labels()<EOL>

The central logic for drawing the graph.

Sets self.graph (the 'g' element in the SVG root)


<EOL>return <NUM_LIT:0><EOL>

Return an offset for drawing the x label. Currently returns 0.


def make_datapoint_text(self, x, y, value, style=None):

if not self.show_data_values:<EOL><INDENT>return<EOL><DEDENT>e = etree.SubElement(self.foreground, '<STR_LIT:text>', {<EOL>'<STR_LIT:x>': str(x),<EOL>'<STR_LIT:y>': str(y),<EOL>'<STR_LIT:class>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>' % vars(),<EOL>})<EOL>e.text = str(value)<EOL>e = etree.SubElement(self.foreground, '<STR_LIT:text>', {<EOL>'<STR_LIT:x>': str(x),<EOL>'<STR_LIT:y>': str(y),<EOL>'<STR_LIT:class>': '<STR_LIT>'})<EOL>e.text = str(value)<EOL>if style:<EOL><INDENT>e.set('<STR_LIT>', style)<EOL><DEDENT>


if self.show_x_labels:<EOL><INDENT>labels = self.get_x_labels()<EOL>count = len(labels)<EOL>labels = enumerate(iter(labels))<EOL>start = int(not self.step_include_first_x_label)<EOL>labels = itertools.islice(labels, start, None, self.step_x_labels)<EOL>list(map(self.draw_x_label, labels))<EOL>self.draw_x_guidelines(self.field_width(), count)<EOL><DEDENT>


<EOL>return <NUM_LIT:0><EOL>

Return an offset for drawing the y label. Currently returns 0.


if not self.show_y_labels:<EOL><INDENT>return<EOL><DEDENT>labels = self.get_y_labels()<EOL>count = len(labels)<EOL>labels = enumerate(iter(labels))<EOL>start = int(not self.step_include_first_y_label)<EOL>labels = itertools.islice(labels, start, None, self.step_y_labels)<EOL>list(map(self.draw_y_label, labels))<EOL>self.draw_y_guidelines(self.field_height(), count)<EOL>


def draw_x_guidelines(self, label_height, count):

if not self.show_x_guidelines:<EOL><INDENT>return<EOL><DEDENT>for count in range(<NUM_LIT:1>, count):<EOL><INDENT>move = '<STR_LIT>'.format(<EOL>start=label_height * count,<EOL>stop=self.graph_height,<EOL>)<EOL>path = {'<STR_LIT:d>': move, '<STR_LIT:class>': '<STR_LIT>'}<EOL>etree.SubElement(self.graph, '<STR_LIT:path>', path)<EOL><DEDENT>


def draw_y_guidelines(self, label_height, count):

if not self.show_y_guidelines:<EOL><INDENT>return<EOL><DEDENT>for count in range(<NUM_LIT:1>, count):<EOL><INDENT>move = '<STR_LIT>'.format(<EOL>start=self.graph_height - label_height * count,<EOL>stop=self.graph_width,<EOL>)<EOL>path = {'<STR_LIT:d>': move, '<STR_LIT:class>': '<STR_LIT>'}<EOL>etree.SubElement(self.graph, '<STR_LIT:path>', path)<EOL><DEDENT>


if not self.css_inline:<EOL><INDENT>return<EOL><DEDENT>styles = self.parse_css()<EOL>for node in self.root.xpath('<STR_LIT>'):<EOL><INDENT>cl = '<STR_LIT:.>' + node.attrib['<STR_LIT:class>']<EOL>if cl not in styles:<EOL><INDENT>continue<EOL><DEDENT>style = styles[cl]<EOL>if '<STR_LIT>' in node.attrib:<EOL><INDENT>style += node.attrib['<STR_LIT>']<EOL><DEDENT>node.attrib['<STR_LIT>'] = style<EOL><DEDENT>

Hard-code the styles into the SVG XML if style sheets are not used.


<EOL>cssutils.ser.prefs.useMinified()<EOL>pairs = (<EOL>(r.selectorText, r.style.cssText)<EOL>for r in self.get_stylesheet()<EOL>if not isinstance(r, cssutils.css.CSSComment)<EOL>)<EOL>return dict(pairs)<EOL>

Take a .css file (classes only please) and parse it into a dictionary
of class/style pairs.


Override and place code to add defs here. TODO: what are defs?


SVG_NAMESPACE = '<STR_LIT>'<EOL>SVG = '<STR_LIT>' % SVG_NAMESPACE<EOL>NSMAP = {<EOL>None: SVG_NAMESPACE,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>}<EOL>root_attrs = self._get_root_attributes()<EOL>self.root = etree.Element(SVG + "<STR_LIT>", attrib=root_attrs, nsmap=NSMAP)<EOL>if hasattr(self, '<STR_LIT>'):<EOL><INDENT>pi = etree.ProcessingInstruction(<EOL>'<STR_LIT>',<EOL>'<STR_LIT>' % self.style_sheet_href<EOL>)<EOL>self.root.addprevious(pi)<EOL><DEDENT>comment_strings = (<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT>',<EOL>'<STR_LIT:U+0020>' + '<STR_LIT:/>' * <NUM_LIT>,<EOL>)<EOL>list(map(self.root.append, map(etree.Comment, comment_strings)))<EOL>defs = etree.SubElement(self.root, '<STR_LIT>')<EOL>self.add_defs(defs)<EOL>if not hasattr(self, '<STR_LIT>') and not self.css_inline:<EOL><INDENT>self.root.append(etree.Comment(<EOL>'<STR_LIT>'))<EOL>style = etree.SubElement(defs, '<STR_LIT>', type='<STR_LIT>')<EOL>style.text = self.get_stylesheet().cssText<EOL><DEDENT>self.root.append(etree.Comment('<STR_LIT>'))<EOL>etree.SubElement(self.root, '<STR_LIT>', {<EOL>'<STR_LIT:width>': str(self.width),<EOL>'<STR_LIT>': str(self.height),<EOL>'<STR_LIT:x>': '<STR_LIT:0>',<EOL>'<STR_LIT:y>': '<STR_LIT:0>',<EOL>'<STR_LIT:class>': '<STR_LIT>'})<EOL>


<EOL>class_vars = class_dict(self)<EOL>loader = functools.partial(<EOL>self.load_resource_stylesheet,<EOL>subs=class_vars)<EOL>sheets = list(map(loader, self.stylesheet_names))<EOL>return sheets<EOL>


super(Plot, self).add_data(data)<EOL>

Add data to the plot::

        # A data set with 1 point: ("12:30", 2)
        d1 = ["12:30", 2]

        # A data set with 2 points: ("01:00", 2) and
        #                           ("14:20", 6)
        d2 = ["01:00", 2, "14:20", 6]

        graph.add_data(
                data = d1,
                title = 'One',
        )
        graph.add_data(
                data = d2,
                title = 'Two',
        )

Note that the data must be in (time, value) pairs, and
the date format
may be any date that is parseable by dateutil.


if a is None:<EOL><INDENT>a = <NUM_LIT:0><EOL><DEDENT>if b is None:<EOL><INDENT>b = <NUM_LIT:0><EOL><DEDENT>return a + b<EOL>


pairs = itertools.zip_longest(self.data, data_descriptor['<STR_LIT:data>'])<EOL>self.data = list(itertools.starmap(robust_add, pairs))<EOL>

Add a data set to the graph

>>> graph.add_data({data:[1,2,3,4]}) # doctest: +SKIP

Note that a 'title' key is ignored.

Multiple calls to add_data will sum the elements, and the pie will
display the aggregated data.  e.g.

>>> graph.add_data({data:[1,2,3,4]}) # doctest: +SKIP
>>> graph.add_data({data:[2,3,5,7]}) # doctest: +SKIP

is the same as:

>>> graph.add_data({data:[3,5,8,11]}) # doctest: +SKIP

If data is added of with differing lengths, the corresponding
values will be assumed to be zero.

>>> graph.add_data({data:[1,2,3,4]}) # doctest: +SKIP
>>> graph.add_data({data:[5,7]}) # doctest: +SKIP

is the same as:

>>> graph.add_data({data:[5,7]}) # doctest: +SKIP
>>> graph.add_data({data:[1,2,3,4]}) # doctest: +SKIP

and

>>> graph.add_data({data:[6,9,3,4]}) # doctest: +SKIP


pass<EOL>

Here we don't need the graph (consider refactoring)


return ['<STR_LIT>']<EOL>


sets = map(itemgetter('<STR_LIT:data>'), self.data)<EOL>if not sets:<EOL><INDENT>return<EOL><DEDENT>sum = sets.pop(<NUM_LIT:0>)<EOL>yield sum<EOL>while sets:<EOL><INDENT>sum = map(add, sets.pop(<NUM_LIT:0>))<EOL>yield sum<EOL><DEDENT>

Get the data as it will be charted.  The first set will be
        the actual first data set.  The second will be the sum of the
        first and the second, etc.


if self.config.file_header:<EOL><INDENT>if sys.version_info[<NUM_LIT:0>] < <NUM_LIT:3>:<EOL><INDENT>pattern = re.compile(<EOL>'<STR_LIT>' + self.config.file_header, re.LOCALE | re.MULTILINE)<EOL><DEDENT>else:<EOL><INDENT>pattern = re.compile(<EOL>'<STR_LIT>' + self.config.file_header, re.MULTILINE)<EOL><DEDENT>content = None<EOL>with node.stream() as stream:<EOL><INDENT>content = stream.read().decode('<STR_LIT:utf-8>')<EOL><DEDENT>matches = pattern.findall(content)<EOL>if len(matches) != <NUM_LIT:1>:<EOL><INDENT>self.add_message('<STR_LIT>', <NUM_LIT:1>,<EOL>args=self.config.file_header)<EOL><DEDENT><DEDENT>


linter.register_checker(FileHeaderChecker(linter))<EOL>

Required method to auto register this checker.
    Args:
        linter: Main interface object for Pylint plugins.


def format_expected(self, expected, webasset):

from pyramid.path import AssetResolver<EOL>if '<STR_LIT:%>' not in expected:<EOL><INDENT>return expected<EOL><DEDENT>if '<STR_LIT::>' in webasset:<EOL><INDENT>name = AssetResolver(None).resolve(webasset).abspath()<EOL><DEDENT>else:<EOL><INDENT>name = self.temp.tempdir + '<STR_LIT>' + webasset<EOL><DEDENT>if webassets_version > (<NUM_LIT:0>, <NUM_LIT:9>):<EOL><INDENT>hashed_filename = hashlib.md5(name.encode("<STR_LIT:utf-8>")).hexdigest()<EOL><DEDENT>else:<EOL><INDENT>hashed_filename = hash(name) & ((<NUM_LIT:1> << <NUM_LIT:64>) - <NUM_LIT:1>)<EOL><DEDENT>external = '<STR_LIT>' % hashed_filename<EOL>return expected % {'<STR_LIT>': external}<EOL>

Formats the expected url when the webasset is external


if isinstance(value, six.string_types) and value.lower() in booly:<EOL><INDENT>return asbool(value)  <EOL><DEDENT>return value<EOL>

If `value` is a string type, attempts to convert it to a boolean
if it looks like it might be one, otherwise returns the value
unchanged. The difference between this and
:func:`pyramid.settings.asbool` is how non-bools are handled: this
returns the original value, whereas `asbool` returns False.


<EOL>kwargs = {}   <EOL>cut_prefix = len(prefix) + <NUM_LIT:1><EOL>for k in settings:<EOL><INDENT>if k.startswith(prefix):<EOL><INDENT>val = settings[k]<EOL>if isinstance(val, six.string_types):<EOL><INDENT>if val.lower() in auto_booly:<EOL><INDENT>val = asbool(val)<EOL><DEDENT>elif val.lower().startswith('<STR_LIT>') and k[cut_prefix:] != '<STR_LIT>':<EOL><INDENT>val = json.loads(val[<NUM_LIT:5>:])<EOL><DEDENT><DEDENT>kwargs[k[cut_prefix:]] = val<EOL><DEDENT><DEDENT>if '<STR_LIT>' not in kwargs:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>if '<STR_LIT>' not in kwargs:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>asset_dir = kwargs.pop('<STR_LIT>')<EOL>asset_url = kwargs.pop('<STR_LIT>')<EOL>if '<STR_LIT::>' in asset_dir:<EOL><INDENT>try:<EOL><INDENT>resolved_dir = AssetResolver(None).resolve(asset_dir).abspath()<EOL><DEDENT>except ImportError:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>kwargs['<STR_LIT>'] = asset_dir<EOL>asset_dir = resolved_dir<EOL><DEDENT><DEDENT>if not asset_url.startswith('<STR_LIT:/>'):<EOL><INDENT>if six.moves.urllib.parse.urlparse(asset_url).scheme == '<STR_LIT>':<EOL><INDENT>asset_url = '<STR_LIT:/>' + asset_url<EOL><DEDENT><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = maybebool(kwargs['<STR_LIT>'])<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>cache = kwargs['<STR_LIT>'] = maybebool(kwargs['<STR_LIT>'])<EOL>if cache and isinstance(cache, six.string_types) and not path.isdir(cache):<EOL><INDENT>makedirs(cache)<EOL><DEDENT><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = maybebool(kwargs['<STR_LIT>'])<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = kwargs.pop('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = kwargs.pop('<STR_LIT>')<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = maybebool(kwargs['<STR_LIT>'])<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = maybebool(kwargs['<STR_LIT>'])<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = asbool(kwargs['<STR_LIT>'])<EOL><DEDENT>else:<EOL><INDENT>kwargs['<STR_LIT>'] = False<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>kwargs['<STR_LIT>'] = int(kwargs.pop('<STR_LIT>'))<EOL><DEDENT>else:<EOL><INDENT>kwargs['<STR_LIT>'] = None<EOL><DEDENT>if '<STR_LIT>' in kwargs:<EOL><INDENT>if not isinstance(kwargs['<STR_LIT>'], list):<EOL><INDENT>kwargs['<STR_LIT>'] = kwargs['<STR_LIT>'].split()<EOL><DEDENT><DEDENT>paths = kwargs.pop('<STR_LIT>', None)<EOL>if '<STR_LIT>' in kwargs:<EOL><INDENT>if isinstance(kwargs['<STR_LIT>'], six.string_types):<EOL><INDENT>kwargs['<STR_LIT>'] = kwargs['<STR_LIT>'].split()<EOL><DEDENT><DEDENT>bundles = kwargs.pop('<STR_LIT>', None)<EOL>assets_env = Environment(asset_dir, asset_url, **kwargs)<EOL>if paths is not None:<EOL><INDENT>for map_path, map_url in json.loads(paths).items():<EOL><INDENT>assets_env.append_path(map_path, map_url)<EOL><DEDENT><DEDENT>def yaml_stream(fname, mode):<EOL><INDENT>if path.exists(fname):<EOL><INDENT>return open(fname, mode)<EOL><DEDENT>else:<EOL><INDENT>return assets_env.resolver.resolver.resolve(fname).stream()<EOL><DEDENT><DEDENT>if isinstance(bundles, list):<EOL><INDENT>fnames = reversed(bundles)<EOL>fin = fileinput.input(fnames, openhook=yaml_stream)<EOL>with closing(fin):<EOL><INDENT>lines = [text(line).rstrip() for line in fin]<EOL><DEDENT>yamlin = six.StringIO('<STR_LIT:\n>'.join(lines))<EOL>loader = YAMLLoader(yamlin)<EOL>result = loader.load_bundles()<EOL>assets_env.register(result)<EOL><DEDENT>elif isinstance(bundles, dict):<EOL><INDENT>assets_env.register(bundles)<EOL><DEDENT>return assets_env<EOL>

This function will take all webassets.* parameters, and
    call the ``Environment()`` constructor with kwargs passed in.

    The only two parameters that are not passed as keywords are:

    * base_dir
    * base_url

    which are passed in positionally.

    Read the ``WebAssets`` docs for ``Environment`` for more details.


return request.registry.queryUtility(IWebAssetsEnvironment)<EOL>

Get the webassets environment in the registry from the request.


global _chr<EOL>if isinstance(x, int):<EOL><INDENT>if x > <NUM_LIT>:<EOL><INDENT>if SUPPRESS_ERRORS:<EOL><INDENT>x = x % <NUM_LIT><EOL><DEDENT><DEDENT>return toBytes(_chr(x))<EOL><DEDENT>elif isinstance(x, bytes):<EOL><INDENT>x = fromBytes(x)<EOL>if len(x) > <NUM_LIT:1>:<EOL><INDENT>if not SUPPRESS_ERRORS:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>x = x[<NUM_LIT:0>]<EOL><DEDENT>return toBytes(x)<EOL><DEDENT>elif isinstance(x, str):<EOL><INDENT>if len(x) > <NUM_LIT:1>:<EOL><INDENT>if not SUPPRESS_ERRORS:<EOL><INDENT>raise TypeError('<STR_LIT>')<EOL><DEDENT>x = x[<NUM_LIT:0>]<EOL><DEDENT>return toBytes(x)<EOL><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>', str(type(x)))<EOL><DEDENT>

x-->int / byte
Returns-->BYTE (not str in python3)
    Behaves like PY2 chr() in PY2 or PY3
if x is str of length > 1 or int > 256
    raises ValueError/TypeError is not SUPPRESS_ERRORS


global _ord<EOL>if isinstance(x, int):<EOL><INDENT>if x > <NUM_LIT>:<EOL><INDENT>if not SUPPRESS_ERRORS:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT><DEDENT>return x % <NUM_LIT><EOL><DEDENT>elif isinstance(x, bytes):<EOL><INDENT>x = fromBytes(x)<EOL>if len(x) > <NUM_LIT:1>:<EOL><INDENT>if SUPPRESS_ERRORS:<EOL><INDENT>x = x[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>return _ord(x)<EOL><DEDENT>elif isinstance(x, str):<EOL><INDENT>if len(x) > <NUM_LIT:1>:<EOL><INDENT>if SUPPRESS_ERRORS:<EOL><INDENT>x = x[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>return _ord(x)<EOL><DEDENT>else:<EOL><INDENT>raise TypeError('<STR_LIT>', str(type(x)))<EOL><DEDENT>

x-->char (str of length 1)
Returns-->int
    Behaves like PY2 ord() in PY2 or PY3
if x is str of length > 1 or int > 256
    raises ValueError/TypeError is not SUPPRESS_ERRORS


if isinstance(x, bytearray):<EOL><INDENT>x = bytes(x)<EOL><DEDENT>return encode(x, '<STR_LIT>')<EOL>

x-->bytes | bytearray
Returns-->bytes: hex-encoded


if isinstance(x, unicode):<EOL><INDENT>return x<EOL><DEDENT>if isinstance(x, bytearray):<EOL><INDENT>x = bytes(x)<EOL><DEDENT>elif isinstance(x, bytes):<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>return x  <EOL><DEDENT>return decode(x, DEF_ENCODING)<EOL>

x-->unicode string | bytearray | bytes
Returns-->unicode string, with encoding=latin1


if isinstance(x, bytes):<EOL><INDENT>return x<EOL><DEDENT>elif isinstance(x, bytearray):<EOL><INDENT>return bytes(x)<EOL><DEDENT>elif isinstance(x, unicode):<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>return x  <EOL><DEDENT>return encode(x, DEF_ENCODING)<EOL>

x-->unicode string | bytearray | bytes
Returns-->bytes
If x is unicode, MUST have encoding=latin1


def inputFromBytes(func, *args, **kwargs):

return _convInputs(func, fromBytes, *args, **kwargs)<EOL>

Decorator that converts all arguments to latin1-encoded unicode


def inputToBytes(func, *args, **kwargs):

return _convInputs(func, toBytes, *args, **kwargs)<EOL>

Decorator that converts all arguments to bytes


def outputToBytes(func, *args, **kwargs):

return _convResults(func, toBytes, *args, **kwargs)<EOL>

Decorator that converts all return values to bytes


def outputFromBytes(func, *args, **kwargs):

return _convResults(func, fromBytes, *args, **kwargs)<EOL>

Decorator that converts all return values to latin1-encoded unicode


UNICODE_LIMIT = <NUM_LIT><EOL>SURROGATE_RANGE = (<NUM_LIT>, <NUM_LIT>)<EOL>if encoding not in ENCODINGS:<EOL><INDENT>raise ValueError('<STR_LIT>' + str(encoding))<EOL><DEDENT>if encoding == '<STR_LIT:ascii>':<EOL><INDENT>maxord = <NUM_LIT:2> ** <NUM_LIT:7><EOL><DEDENT>elif encoding == '<STR_LIT>':<EOL><INDENT>maxord = <NUM_LIT:2> ** <NUM_LIT:8><EOL><DEDENT>elif encoding == '<STR_LIT>':<EOL><INDENT>maxord = <NUM_LIT:2> ** <NUM_LIT:16><EOL><DEDENT>elif encoding == '<STR_LIT:utf8>':<EOL><INDENT>maxord = <NUM_LIT:2> ** <NUM_LIT:32><EOL><DEDENT>elif encoding == '<STR_LIT>':<EOL><INDENT>maxord = <NUM_LIT:2> ** <NUM_LIT:32><EOL><DEDENT>rndint = random.randrange(<NUM_LIT:0>, min(maxord, UNICODE_LIMIT))<EOL>while (<EOL>(rndint in avoid) or<EOL>(SURROGATE_RANGE[<NUM_LIT:0>] <= rndint <= SURROGATE_RANGE[<NUM_LIT:1>])<EOL>):<EOL><INDENT>rndint = random.randrange(<NUM_LIT:0>, min(maxord, UNICODE_LIMIT))<EOL><DEDENT>return rndint<EOL>

encoding-->str: one of ENCODINGS
avoid-->list of int: to void (unprintable chars etc)
Returns-->int that can be converted to requested encoding
          which is NOT in avoid


def get_rand_str(encoding='<STR_LIT>', l=<NUM_LIT:64>, avoid=[]):

ret = unicode('<STR_LIT>')<EOL>while len(ret) < l:<EOL><INDENT>rndint = get_rand_int(encoding=encoding, avoid=avoid)<EOL>ret += unichr(rndint)<EOL><DEDENT>return ret<EOL>

encoding-->str: one of ENCODINGS
l-->int: length of returned str
avoid-->list of int: to void (unprintable chars etc)
Returns-->unicode str of the requested encoding


def get_rand_bytes(encoding='<STR_LIT>', l=<NUM_LIT:64>, avoid=[]):

return encode(<EOL>get_rand_str(encoding=encoding, l=l, avoid=avoid),<EOL>encoding=encoding<EOL>)<EOL>

encoding-->str: one of ENCODINGS
l-->int: length of unicode str
avoid-->list of int: to void (unprintable chars etc)
Returns-->bytes representing unicode str of the requested encoding


def get_lib_ffi_resource(module_name, libpath, c_hdr):

lib = SharedLibWrapper(libpath, c_hdr, module_name=module_name)<EOL>ffi = lib.ffi<EOL>return (ffi, lib)<EOL>

module_name-->str: module name to retrieve resource
libpath-->str: shared library filename with optional path
c_hdr-->str: C-style header definitions for functions to wrap
Returns-->(ffi, lib)

Use this method when you are loading a package-specific shared library
If you want to load a system-wide shared library, use get_lib_ffi_shared
instead


lib = SharedLibWrapper(libpath, c_hdr)<EOL>ffi = lib.ffi<EOL>return (ffi, lib)<EOL>

libpath-->str: shared library filename with optional path
c_hdr-->str: C-style header definitions for functions to wrap
Returns-->(ffi, lib)


def __init__(self, libpath, c_hdr, module_name=None):

self._libpath = libpath<EOL>self._c_hdr = c_hdr<EOL>self._module_name = module_name<EOL>self.ffi = FFIExt()<EOL>self.lib = None<EOL>self.ffi.cdef(self._c_hdr)<EOL>self._libloaded = False<EOL>

libpath-->str: library name; can also be full path
c_hdr-->str: C-style header definitions for functions to wrap
ffi-->FFIExt or cffi.FFI


try:<EOL><INDENT>self.__openlib()<EOL>return self.lib is not None<EOL><DEDENT>except OSError:<EOL><INDENT>return False<EOL><DEDENT>

Returns-->boolean: whether library could be loaded
When this is called, the library would have been loaded if possible
If this is not called, the first invocation of a method in lib
CAN raise OSError if shared library cannot be loaded


if self.__getattribute__('<STR_LIT>'):<EOL><INDENT>return<EOL><DEDENT>libpath_list = self.__get_libres()<EOL>for p in libpath_list:<EOL><INDENT>try:<EOL><INDENT>libres = resource_filename(self._module_name, p)<EOL>self.lib = self.ffi.dlopen(libres)<EOL>return<EOL><DEDENT>except:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>try:<EOL><INDENT>libres = resource_filename(self._module_name, self._libpath)<EOL>self.lib = self.ffi.dlopen(libres)<EOL><DEDENT>except:<EOL><INDENT>try:<EOL><INDENT>self._libloaded = True<EOL>libdir = '<STR_LIT>'<EOL>if self._module_name is not None:<EOL><INDENT>mod = sys.modules.get(self._module_name, None)<EOL>if mod is not None:<EOL><INDENT>libdir = os.path.dirname(mod.__file__) or os.getcwd()<EOL><DEDENT><DEDENT>libres = os.path.join(libdir, self._libpath)<EOL>self.lib = self.ffi.dlopen(libres)<EOL><DEDENT>except:<EOL><INDENT>return None<EOL><DEDENT><DEDENT>

Actual (lazy) dlopen() only when an attribute is accessed


if self._module_name is None:<EOL><INDENT>return []<EOL><DEDENT>ending = '<STR_LIT>'<EOL>base = self._libpath.rsplit(ending, <NUM_LIT:1>)[<NUM_LIT:0>]<EOL>abi = sysconfig.get_config_var('<STR_LIT>')<EOL>if abi is not None:<EOL><INDENT>abi = '<STR_LIT:.>' + abi<EOL><DEDENT>else:<EOL><INDENT>abi = '<STR_LIT>'<EOL><DEDENT>multi_arch = sysconfig.get_config_var('<STR_LIT>')<EOL>if multi_arch is None:<EOL><INDENT>multi_arch = '<STR_LIT>'<EOL><DEDENT>else:<EOL><INDENT>multi_arch = '<STR_LIT:->' + multi_arch<EOL><DEDENT>if PYPY:<EOL><INDENT>n1 = base + abi + multi_arch + ending<EOL>n2 = base + abi + ending<EOL><DEDENT>else:<EOL><INDENT>n1 = base + abi + ending<EOL>n2 = base + abi + multi_arch + ending<EOL><DEDENT>if PYPY:<EOL><INDENT>n3 = base + '<STR_LIT>' + ending<EOL>return [n1, n2, n3]<EOL><DEDENT>else:<EOL><INDENT>return [n1, n2]<EOL><DEDENT>

Computes libpath based on whether module_name is set or not
Returns-->list of str lib paths to try

PEP3140: ABI version tagged .so files:
    https://www.python.org/dev/peps/pep-3149/

There's still one unexplained bit: pypy adds '-' + sys._multiarch()
at the end (looks like 'x86_64-linux-gnu'), but neither py2 or py3 do

Additionally, in older releases of pypy (e.g. build f3ad1e1e1d62
Aug-28-2015), sysconfig.get_config_var('SOABI') returns '' but
shared library still has '.pypy-26' in the name!

So for pypy we try this this variant anyway!

_I_ think Py2 and Py3 _MAY_ start adding sys._multiarch at some time

So, we generate three forms:
    1. With sys._multiarch
    2. Without sys._multiarch
    3. libpath as-is - always tried by self.__openlib anyway
For different versions we try in different order (for efficiency):
    Python2                 Python3                 Pypy

    2 --> 1 --> 3           2 --> 1 --> 3           1 --> 2 --> 3


res = tuple([<EOL>self.from_buffer(x) for x in args<EOL>])<EOL>if len(res) == <NUM_LIT:0>:<EOL><INDENT>return None<EOL><DEDENT>elif len(res) == <NUM_LIT:1>:<EOL><INDENT>return res[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>return res<EOL><DEDENT>

all args-->_cffi_backend.buffer
Returns-->cdata (if a SINGLE argument was provided)
          LIST of cdata (if a args was a tuple or list)


res = tuple([<EOL>self.buffer(x) for x in args<EOL>])<EOL>if len(res) == <NUM_LIT:0>:<EOL><INDENT>return None<EOL><DEDENT>elif len(res) == <NUM_LIT:1>:<EOL><INDENT>return res[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>return res<EOL><DEDENT>

all args-->_cffi_backend.CDataOwn
Must be a pointer or an array
Returns-->buffer (if a SINGLE argument was provided)
          LIST of buffer (if a args was a tuple or list)


res = tuple([<EOL>bytes(self.buffer(x)) for x in args<EOL>])<EOL>if len(res) == <NUM_LIT:0>:<EOL><INDENT>return None<EOL><DEDENT>elif len(res) == <NUM_LIT:1>:<EOL><INDENT>return res[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>return res<EOL><DEDENT>

all args-->_cffi_backend.CDataOwn
Must be a pointer or an array
Returns-->bytes (if a SINGLE argument was provided)
          LIST of bytes (if a args was a tuple or list)


import setupext<EOL>setupext.config['<STR_LIT>']['<STR_LIT>']['<STR_LIT>'] = [cmd]<EOL>return setupext.get_cmdclass()<EOL>


files = ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>for f in files:<EOL><INDENT>try:<EOL><INDENT>return open(f, '<STR_LIT:r>').read()<EOL><DEDENT>except:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>return default<EOL>


ret = []<EOL>curdir = os.getcwd()<EOL>if not os.path.isdir(topdir):<EOL><INDENT>return ret<EOL><DEDENT>os.chdir(topdir)<EOL>try:<EOL><INDENT>for dirname in dirlist:<EOL><INDENT>if not os.path.isdir(dirname):<EOL><INDENT>continue<EOL><DEDENT>for (d, ds, fs) in os.walk(dirname):<EOL><INDENT>for f in fs:<EOL><INDENT>ret += [os.path.join(d, f)]<EOL><DEDENT><DEDENT><DEDENT>return ret<EOL><DEDENT>except:<EOL><INDENT>return ret<EOL><DEDENT>finally:<EOL><INDENT>os.chdir(curdir)<EOL><DEDENT>

topdir-->str: must be name of a dir under current working dir
dirlist-->list of str: must all be names of dirs under topdir


if PROJ_ARCHIVE is None:<EOL><INDENT>bail('<STR_LIT>')<EOL><DEDENT>if not os.path.isdir(PROJ_ARCHIVE):<EOL><INDENT>bail('<STR_LIT>' + PROJ_ARCHIVE)<EOL><DEDENT>

proj is a tool for managing many different projects, and archiving
projects that you're no longer actively working on.

It assumes you have a working folder containing active projects,
and an archive folder with inactive projects. proj helps organise
inactive projects by year and by quarter (e.g. 2013/q3/my-project).

proj needs an archive directory specified by the PROJ_ARCHIVE
environment variable.


<EOL>for f in folder:<EOL><INDENT>if not os.path.exists(f):<EOL><INDENT>bail('<STR_LIT>' + f)<EOL><DEDENT><DEDENT>_archive_safe(folder, PROJ_ARCHIVE, dry_run=dry_run)<EOL>


isdir = os.path.isdir<EOL>stack = [os.path.abspath(p)]<EOL>while not isdir(stack[-<NUM_LIT:1>]):<EOL><INDENT>parent_dir = os.path.dirname(stack[-<NUM_LIT:1>])<EOL>stack.append(parent_dir)<EOL><DEDENT>while stack:<EOL><INDENT>p = stack.pop()<EOL>if not isdir(p):<EOL><INDENT>os.mkdir(p)<EOL><DEDENT><DEDENT>


<EOL>globs = ['<STR_LIT>'.format(p) for p in pattern] + ['<STR_LIT:*>']<EOL>matches = []<EOL>offset = len(PROJ_ARCHIVE) + <NUM_LIT:1><EOL>for suffix in globs:<EOL><INDENT>glob_pattern = os.path.join(PROJ_ARCHIVE, '<STR_LIT:*>', '<STR_LIT:*>', suffix)<EOL>matches.append(set(<EOL>f[offset:] for f in glob.glob(glob_pattern)<EOL>))<EOL><DEDENT>matches = reduce(lambda x, y: x.intersection(y),<EOL>matches)<EOL>for m in sorted(matches):<EOL><INDENT>print(m)<EOL><DEDENT>

List the contents of the archive directory.


if os.path.isdir(folder):<EOL><INDENT>bail('<STR_LIT>')<EOL><DEDENT>pattern = os.path.join(PROJ_ARCHIVE, '<STR_LIT:*>', '<STR_LIT:*>', folder)<EOL>matches = glob.glob(pattern)<EOL>if not matches:<EOL><INDENT>bail('<STR_LIT>' + folder)<EOL><DEDENT>if len(matches) > <NUM_LIT:1>:<EOL><INDENT>print('<STR_LIT>',<EOL>file=sys.stderr)<EOL><DEDENT>source = sorted(matches)[-<NUM_LIT:1>]<EOL>print(source, '<STR_LIT>', folder)<EOL>shutil.move(source, '<STR_LIT:.>')<EOL>


return route53.connect(<EOL>aws_access_key_id=AWS_ACCESS_KEY_ID,<EOL>aws_secret_access_key=AWS_SECRET_ACCESS_KEY,<EOL>)<EOL>

All unit tests go through here for Route53Connection objects.

:rtype: Route53Connection


if re.search('<STR_LIT>', time_str):<EOL><INDENT>submitted_at = datetime.datetime.strptime(time_str,'<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>submitted_at = datetime.datetime.strptime(time_str,'<STR_LIT>')<EOL><DEDENT>return submitted_at.replace(tzinfo=UTC_TIMEZONE)<EOL>

Parses a standard ISO 8601 time string. The Route53 API uses these here
and there.

:param str time_str: An ISO 8601 time string.
:rtype: datetime.datetime
:returns: A timezone aware (UTC) datetime.datetime instance.


return etree.tostring(element, pretty_print=True).decode('<STR_LIT:utf-8>')<EOL>

A rough and dirty way to prettyprint an Element with indention.

:param lxml.etree._Element element: The Element or ElementTree to format.
:rtype: str
:returns: A prettyprinted representation of the element.


def __init__(self, aws_access_key_id, aws_secret_access_key):

self._endpoint = '<STR_LIT>' % self.endpoint_version<EOL>self._xml_namespace = '<STR_LIT>' % self.endpoint_version<EOL>self._aws_access_key_id = aws_access_key_id<EOL>self._aws_secret_access_key = aws_secret_access_key<EOL>self._transport = RequestsTransport(self)<EOL>

:param str aws_access_key_id: An account's access key ID.
:param str aws_secret_access_key: An account's secret access key.


def _send_request(self, path, data, method):

response_body = self._transport.send_request(path, data, method)<EOL>root = etree.fromstring(response_body)<EOL>return root<EOL>

Uses the HTTP transport to query the Route53 API. Runs the response
through lxml's parser, before we hand it off for further picking
apart by our call-specific parsers.

:param str path: The RESTful path to tack on to the :py:attr:`endpoint`.
:param data: The params to send along with the request.
:type data: Either a dict or bytes, depending on the request type.
:param str method: One of 'GET', 'POST', or 'DELETE'.
:rtype: lxml.etree._Element
:returns: An lxml Element root.


def _do_autopaginating_api_call(self, path, params, method, parser_func,<EOL>next_marker_xpath, next_marker_param_name,<EOL>next_type_xpath=None, parser_kwargs=None):

if not parser_kwargs:<EOL><INDENT>parser_kwargs = {}<EOL><DEDENT>while True:<EOL><INDENT>root = self._send_request(path, params, method)<EOL>for record in parser_func(root, connection=self, **parser_kwargs):<EOL><INDENT>yield record<EOL><DEDENT>next_marker = root.find(next_marker_xpath)<EOL>if next_marker is None:<EOL><INDENT>break<EOL><DEDENT>params[next_marker_param_name] = next_marker.text<EOL>if next_type_xpath:<EOL><INDENT>next_type = root.find(next_type_xpath)<EOL>params['<STR_LIT:type>'] = next_type.text<EOL><DEDENT><DEDENT>

Given an API method, the arguments passed to it, and a function to
hand parsing off to, loop through the record sets in the API call
until all records have been yielded.

:param str method: The API method on the endpoint.
:param dict params: The kwargs from the top-level API method.
:param callable parser_func: A callable that is used for parsing the
    output from the API call.
:param str next_marker_param_name: The XPath to the marker tag that
    will determine whether we continue paginating.
:param str next_marker_param_name: The parameter name to manipulate
    in the request data to bring up the next page on the next
    request loop.
:keyword str next_type_xpath: For the
    py:meth:`list_resource_record_sets_by_zone_id` method, there's
    an additional paginator token. Specifying this XPath looks for it.
:keyword dict parser_kwargs: Optional dict of additional kwargs to pass
    on to the parser function.
:rtype: generator
:returns: Returns a generator that may be returned by the top-level
    API method.


List all hosted zones associated with this connection's account. Since
this method returns a generator, you can pull as many or as few
entries as you'd like, without having to query and receive every
hosted zone you may have.

:keyword int page_chunks: This API call is "paginated" behind-the-scenes
    in order to break up large result sets. This number determines
    the maximum number of
    :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
    instances to retrieve per request. The default is fine for almost
    everyone.

:rtype: generator
:returns: A generator of :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
    instances.


def create_hosted_zone(self, name, caller_reference=None, comment=None):

Creates and returns a new hosted zone. Once a hosted zone is created,
its details can't be changed.

:param str name: The name of the hosted zone to create.
:keyword str caller_reference: A unique string that identifies the
    request and that allows failed create_hosted_zone requests to be
    retried without the risk of executing the operation twice. If no
    value is given, we'll generate a Type 4 UUID for you.
:keyword str comment: An optional comment to attach to the zone.
:rtype: tuple
:returns: A tuple in the form of ``(hosted_zone, change_info)``.
    The ``hosted_zone`` variable contains a
    :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
    instance matching the newly created zone, and ``change_info``
    is a dict with some details about the API request.


root = self._send_request(<EOL>path='<STR_LIT>' % id,<EOL>data={},<EOL>method='<STR_LIT:GET>',<EOL>)<EOL>return xml_parsers.get_hosted_zone_by_id_parser(<EOL>root=root,<EOL>connection=self,<EOL>)<EOL>

Retrieves a hosted zone, by hosted zone ID (not name).

:param str id: The hosted zone's ID (a short hash string).
:rtype: :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
:returns: An :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
    instance representing the requested hosted zone.


root = self._send_request(<EOL>path='<STR_LIT>' % id,<EOL>data={},<EOL>method='<STR_LIT>',<EOL>)<EOL>return xml_parsers.delete_hosted_zone_by_id_parser(<EOL>root=root,<EOL>connection=self,<EOL>)<EOL>

Deletes a hosted zone, by hosted zone ID (not name).

.. tip:: For most cases, we recommend deleting hosted zones via a
    :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
    instance's
    :py:meth:`HostedZone.delete <route53.hosted_zone.HostedZone.delete>`
    method, but this saves an HTTP request if you already know the zone's ID.

.. note:: Unlike
    :py:meth:`HostedZone.delete <route53.hosted_zone.HostedZone.delete>`,
    this method has no optional ``force`` kwarg.

:param str id: The hosted zone's ID (a short hash string).
:rtype: dict
:returns: A dict of change info, which contains some details about
    the request.


def _list_resource_record_sets_by_zone_id(self, id, rrset_type=None,<EOL>identifier=None, name=None,<EOL>page_chunks=<NUM_LIT:100>):

params = {<EOL>'<STR_LIT:name>': name,<EOL>'<STR_LIT:type>': rrset_type,<EOL>'<STR_LIT>': identifier,<EOL>'<STR_LIT>': page_chunks,<EOL>}<EOL>return  self._do_autopaginating_api_call(<EOL>path='<STR_LIT>' % id,<EOL>params=params,<EOL>method='<STR_LIT:GET>',<EOL>parser_func=xml_parsers.list_resource_record_sets_by_zone_id_parser,<EOL>parser_kwargs={'<STR_LIT>': id},<EOL>next_marker_xpath="<STR_LIT>",<EOL>next_marker_param_name="<STR_LIT:name>",<EOL>next_type_xpath="<STR_LIT>"<EOL>)<EOL>

Lists a hosted zone's resource record sets by Zone ID, if you
already know it.

.. tip:: For most cases, we recommend going through a
    :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
    instance's
    :py:meth:`HostedZone.record_sets <route53.hosted_zone.HostedZone.record_sets>`
    property, but this saves an HTTP request if you already know the
    zone's ID.

:param str id: The ID of the zone whose record sets we're listing.
:keyword str rrset_type: The type of resource record set to begin the
    record listing from.
:keyword str identifier: Weighted and latency resource record sets
    only: If results were truncated for a given DNS name and type,
    the value of SetIdentifier for the next resource record set
    that has the current DNS name and type.
:keyword str name: Not really sure what this does.
:keyword int page_chunks: This API call is paginated behind-the-scenes
    by this many ResourceRecordSet instances. The default should be
    fine for just about everybody, aside from those with tons of RRS.

:rtype: generator
:returns: A generator of ResourceRecordSet instances.


def _change_resource_record_sets(self, change_set, comment=None):

body = xml_generators.change_resource_record_set_writer(<EOL>connection=self,<EOL>change_set=change_set,<EOL>comment=comment<EOL>)<EOL>root = self._send_request(<EOL>path='<STR_LIT>' % change_set.hosted_zone_id,<EOL>data=body,<EOL>method='<STR_LIT:POST>',<EOL>)<EOL>e_change_info = root.find('<STR_LIT>')<EOL>if e_change_info is None:<EOL><INDENT>error = root.find('<STR_LIT>').find('<STR_LIT>').text<EOL>raise Route53Error(error)<EOL><DEDENT>return parse_change_info(e_change_info)<EOL>

Given a ChangeSet, POST it to the Route53 API.

.. note:: You probably shouldn't be using this method directly,
    as there are convenience methods on the ResourceRecordSet
    sub-classes.

:param change_set.ChangeSet change_set: The ChangeSet object to create
    the XML doc from.
:keyword str comment: An optional comment to go along with the request.
:rtype: dict
:returns: A dict of change info, which contains some details about
    the request.


def __init__(self, connection, hosted_zone_id):

self.connection = connection<EOL>self.hosted_zone_id = hosted_zone_id<EOL>self.creations = []<EOL>self.deletions = []<EOL>

:param Route53Connection connection: The connection instance being
    used to send the change request.
:param str hosted_zone_id: The ID of the hosted zone this change set
    pertains to.


def add_change(self, action, record_set):

action = action.upper()<EOL>if action not in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>raise Route53Error("<STR_LIT>")<EOL><DEDENT>change_tuple = (action, record_set)<EOL>if action == '<STR_LIT>':<EOL><INDENT>self.creations.append(change_tuple)<EOL><DEDENT>else:<EOL><INDENT>self.deletions.append(change_tuple)<EOL><DEDENT>

Adds a change to this change set.

:param str action: Must be one of either 'CREATE' or 'DELETE'.
:param resource_record_set.ResourceRecordSet record_set: The
    ResourceRecordSet object that was created or deleted.


def __init__(self, connection, zone_id, name, ttl, records, weight=None,<EOL>region=None, set_identifier=None):

self.connection = connection<EOL>self.zone_id = zone_id<EOL>self.name = name<EOL>self.ttl = int(ttl) if ttl else None<EOL>self.records = records<EOL>self.region = region<EOL>self.weight = weight<EOL>self.set_identifier = set_identifier<EOL>self._initial_vals = dict(<EOL>connection=connection,<EOL>zone_id=zone_id,<EOL>name=name,<EOL>ttl=ttl,<EOL>records=records[:],<EOL>region=region,<EOL>weight=weight,<EOL>set_identifier=set_identifier,<EOL>)<EOL>

:param Route53Connection connection: The connection instance that
    was used to query the Route53 API, leading to this object's
    creation.
:param str zone_id: The zone ID of the HostedZone that this
    resource record set belongs to.
:param str name: The fully qualified name of the resource record set.
:param int ttl: The time-to-live. A Aliases have no TTL, so this can
    be None in that case.
:param list records: A list of resource record strings. For some
    types (A entries that are Aliases), this is an empty list.
:keyword int weight: For weighted record sets only. Among resource record
    sets that have the same combination of DNS name and type, a value
    that determines what portion of traffic for the current resource
    record set is routed to the associated location. Ranges from 0-255.
:keyword str region: For latency-based record sets. The Amazon EC2 region
    where the resource that is specified in this resource record set
    resides.
:keyword str set_identifier: For weighted and latency resource record
    sets only. An identifier that differentiates among multiple
    resource record sets that have the same combination of DNS name
    and type. 1-128 chars.


return self.connection.get_hosted_zone_by_id(self.zone_id)<EOL>

Queries for this record set's HostedZone.

.. note:: This is not cached, it will always return the latest
    data from the Route 53 API.

:rtype: :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
:returns: The matching :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
    for this record set.


for key, val in self._initial_vals.items():<EOL><INDENT>if getattr(self, key) != val:<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>

Determines whether this record set has been modified since the
last retrieval or save.

:rtype: bool
:returns: ``True` if the record set has been modified,
    and ``False`` if not.


cset = ChangeSet(connection=self.connection, hosted_zone_id=self.zone_id)<EOL>cset.add_change('<STR_LIT>', self)<EOL>return self.connection._change_resource_record_sets(cset)<EOL>


cset = ChangeSet(connection=self.connection, hosted_zone_id=self.zone_id)<EOL>cset.add_change('<STR_LIT>', self)<EOL>cset.add_change('<STR_LIT>', self)<EOL>retval = self.connection._change_resource_record_sets(cset)<EOL>for key, val in self._initial_vals.items():<EOL><INDENT>self._initial_vals[key] = getattr(self, key)<EOL><DEDENT>return retval<EOL>


<EOL>return False<EOL>

Checks whether this is an A record in Alias mode.

:rtype: bool
:returns: ``True`` if this is an A record in Alias mode, and
    ``False`` otherwise.


def __init__(self, alias_hosted_zone_id=None, alias_dns_name=None, *args, **kwargs):

super(AResourceRecordSet, self).__init__(*args, **kwargs)<EOL>self.alias_hosted_zone_id = alias_hosted_zone_id<EOL>self.alias_dns_name = alias_dns_name<EOL>self._initial_vals.update(<EOL>dict(<EOL>alias_hosted_zone_id=alias_hosted_zone_id,<EOL>alias_dns_name=alias_dns_name,<EOL>)<EOL>)<EOL>

:keyword str alias_hosted_zone_id: Alias A records have this specified.
    It appears to be the hosted zone ID for the ELB the Alias points at.
:keyword str alias_dns_name: Alias A records have this specified. It is
    the DNS name for the ELB that the Alias points to.


return self.alias_hosted_zone_id or self.alias_dns_name<EOL>


super(CNAMEResourceRecordSet, self).__init__(*args, **kwargs)<EOL>self.alias_hosted_zone_id = alias_hosted_zone_id<EOL>self.alias_dns_name = alias_dns_name<EOL>self._initial_vals.update(<EOL>dict(<EOL>alias_hosted_zone_id=alias_hosted_zone_id,<EOL>alias_dns_name=alias_dns_name,<EOL>)<EOL>)<EOL>

:keyword str alias_hosted_zone_id: Alias CNAME records have this specified.
    It appears to be the hosted zone ID for the ELB the Alias points at.
:keyword str alias_dns_name: Alias CNAME records have this specified. It is
    the DNS name for the ELB that the Alias points to.


raise Route53Error("<STR_LIT>")<EOL>

SOA records can't be created or deleted.


def create_hosted_zone_writer(connection, name, caller_reference, comment):

if not caller_reference:<EOL><INDENT>caller_reference = str(uuid.uuid4())<EOL><DEDENT>e_root = etree.Element(<EOL>"<STR_LIT>",<EOL>xmlns=connection._xml_namespace<EOL>)<EOL>e_name = etree.SubElement(e_root, "<STR_LIT:Name>")<EOL>e_name.text = name<EOL>e_caller_reference = etree.SubElement(e_root, "<STR_LIT>")<EOL>e_caller_reference.text = caller_reference<EOL>if comment:<EOL><INDENT>e_config = etree.SubElement(e_root, "<STR_LIT>")<EOL>e_comment = etree.SubElement(e_config, "<STR_LIT>")<EOL>e_comment.text = comment<EOL><DEDENT>e_tree = etree.ElementTree(element=e_root)<EOL>fobj = BytesIO()<EOL>e_tree.write(fobj, xml_declaration=True, encoding='<STR_LIT:utf-8>', method="<STR_LIT>")<EOL>return fobj.getvalue().decode('<STR_LIT:utf-8>')<EOL>

Forms an XML string that we'll send to Route53 in order to create
a new hosted zone.

:param Route53Connection connection: The connection instance used to
    query the API.
:param str name: The name of the hosted zone to create.


action, rrset = change<EOL>if action == '<STR_LIT>':<EOL><INDENT>values = dict()<EOL>for key, val in rrset._initial_vals.items():<EOL><INDENT>values[key] = getattr(rrset, key)<EOL><DEDENT>return values<EOL><DEDENT>else:<EOL><INDENT>return rrset._initial_vals<EOL><DEDENT>

In the case of deletions, we pull the change values for the XML request
from the ResourceRecordSet._initial_vals dict, since we want the original
values. For creations, we pull from the attributes on ResourceRecordSet.

Since we're dealing with attributes vs. dict key/vals, we'll abstract
this part away here and just always pass a dict to write_change.

:rtype: dict
:returns: A dict of change data, used by :py:func:`write_change` to
    write the change request XML.


action, rrset = change<EOL>change_vals = get_change_values(change)<EOL>e_change = etree.Element("<STR_LIT>")<EOL>e_action = etree.SubElement(e_change, "<STR_LIT>")<EOL>e_action.text = action<EOL>e_rrset = etree.SubElement(e_change, "<STR_LIT>")<EOL>e_name = etree.SubElement(e_rrset, "<STR_LIT:Name>")<EOL>e_name.text = change_vals['<STR_LIT:name>']<EOL>e_type = etree.SubElement(e_rrset, "<STR_LIT>")<EOL>e_type.text = rrset.rrset_type<EOL>if change_vals.get('<STR_LIT>'):<EOL><INDENT>e_set_id = etree.SubElement(e_rrset, "<STR_LIT>")<EOL>e_set_id.text = change_vals['<STR_LIT>']<EOL><DEDENT>if change_vals.get('<STR_LIT>'):<EOL><INDENT>e_weight = etree.SubElement(e_rrset, "<STR_LIT>")<EOL>e_weight.text = change_vals['<STR_LIT>']<EOL><DEDENT>if change_vals.get('<STR_LIT>') or change_vals.get('<STR_LIT>'):<EOL><INDENT>e_alias_target = etree.SubElement(e_rrset, "<STR_LIT>")<EOL>e_hosted_zone_id = etree.SubElement(e_alias_target, "<STR_LIT>")<EOL>e_hosted_zone_id.text = change_vals['<STR_LIT>']<EOL>e_dns_name = etree.SubElement(e_alias_target, "<STR_LIT>")<EOL>e_dns_name.text = change_vals['<STR_LIT>']<EOL><DEDENT>if change_vals.get('<STR_LIT>'):<EOL><INDENT>e_weight = etree.SubElement(e_rrset, "<STR_LIT>")<EOL>e_weight.text = change_vals['<STR_LIT>']<EOL><DEDENT>e_ttl = etree.SubElement(e_rrset, "<STR_LIT>")<EOL>e_ttl.text = str(change_vals['<STR_LIT>'])<EOL>if rrset.is_alias_record_set():<EOL><INDENT>return e_change<EOL><DEDENT>e_resource_records = etree.SubElement(e_rrset, "<STR_LIT>")<EOL>for value in change_vals['<STR_LIT>']:<EOL><INDENT>e_resource_record = etree.SubElement(e_resource_records, "<STR_LIT>")<EOL>e_value = etree.SubElement(e_resource_record, "<STR_LIT>")<EOL>e_value.text = value<EOL><DEDENT>return e_change<EOL>

Creates an XML element for the change.

:param tuple change: A change tuple from a ChangeSet. Comes in the form
    of ``(action, rrset)``.
:rtype: lxml.etree._Element
:returns: A fully baked Change tag.


def change_resource_record_set_writer(connection, change_set, comment=None):

e_root = etree.Element(<EOL>"<STR_LIT>",<EOL>xmlns=connection._xml_namespace<EOL>)<EOL>e_change_batch = etree.SubElement(e_root, "<STR_LIT>")<EOL>if comment:<EOL><INDENT>e_comment = etree.SubElement(e_change_batch, "<STR_LIT>")<EOL>e_comment.text = comment<EOL><DEDENT>e_changes = etree.SubElement(e_change_batch, "<STR_LIT>")<EOL>for change in change_set.deletions + change_set.creations:<EOL><INDENT>e_changes.append(write_change(change))<EOL><DEDENT>e_tree = etree.ElementTree(element=e_root)<EOL>fobj = BytesIO()<EOL>e_tree.write(fobj, xml_declaration=True, encoding='<STR_LIT:utf-8>', method="<STR_LIT>")<EOL>return fobj.getvalue().decode('<STR_LIT:utf-8>')<EOL>

Forms an XML string that we'll send to Route53 in order to change
record sets.

:param Route53Connection connection: The connection instance used to
    query the API.
:param change_set.ChangeSet change_set: The ChangeSet object to create the
    XML doc from.
:keyword str comment: An optional comment to go along with the request.


def __init__(self, connection, id, name, caller_reference,<EOL>resource_record_set_count, comment):

self.connection = connection<EOL>self.id = id<EOL>self.name = name<EOL>self.caller_reference = caller_reference<EOL>self.resource_record_set_count = int(resource_record_set_count)<EOL>self.comment = comment<EOL>self._nameservers = []<EOL>self._is_deleted = False<EOL>

:param Route53Connection connection: The connection instance that
    was used to query the Route53 API, leading to this object's
    creation.
:param str id: Route53's unique ID for this hosted zone.
:param str name: The name of the domain.
:param str caller_reference: A unique string that identifies the
    request to create the hosted zone.
:param int resource_record_set_count: The number of resource record
    sets in the hosted zone.


<EOL>if not self._nameservers:<EOL><INDENT>hosted_zone = self.connection.get_hosted_zone_by_id(self.id)<EOL>self._nameservers = hosted_zone._nameservers<EOL><DEDENT>return self._nameservers<EOL>

:rtype: list
:returns: A list of nameserver strings for this hosted zone.


for rrset in self.connection._list_resource_record_sets_by_zone_id(self.id):<EOL><INDENT>yield rrset<EOL><DEDENT>

Queries for the Resource Record Sets that are under this HostedZone.
This is typically the way to go to find specific record sets, or
to list them all.

We don't currently implement any filtering convenience method,
since it is very easy to do this yourself, catered to your own needs.
For example, if you find your match, you may choose to stop iterating
on the generator, potentially saving yourself extra API queries
(behind the scenes).

.. warning:: This result set can get pretty large if you have a ton
    of records.

:rtype: generator
:returns: A generator of ResourceRecordSet sub-classes.


self._halt_if_already_deleted()<EOL>if force:<EOL><INDENT>cset = ChangeSet(connection=self.connection, hosted_zone_id=self.id)<EOL>for rrset in self.record_sets:<EOL><INDENT>if rrset.rrset_type not in ['<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>cset.add_change('<STR_LIT>', rrset)<EOL><DEDENT><DEDENT>if cset.deletions or cset.creations:<EOL><INDENT>self.connection._change_resource_record_sets(cset)<EOL><DEDENT><DEDENT>retval = self.connection.delete_hosted_zone_by_id(self.id)<EOL>self._is_deleted = True<EOL>return retval<EOL>

Deletes this hosted zone. After this method is ran, you won't be able
to add records, or do anything else with the zone. You'd need to
re-create it, as zones are read-only after creation.

:keyword bool force: If ``True``, delete the
    :py:class:`HostedZone <route53.hosted_zone.HostedZone>`, even if it
    means nuking all associated record sets. If ``False``, an
    exception is raised if this
    :py:class:`HostedZone <route53.hosted_zone.HostedZone>`
    has record sets.
:rtype: dict
:returns: A dict of change info, which contains some details about
    the request.


if self._is_deleted:<EOL><INDENT>raise AlreadyDeletedError("<STR_LIT>")<EOL><DEDENT>

Convenience method used to raise an AlreadyDeletedError exception if
this HostedZone has been deleted.

:raises: AlreadyDeletedError


def _add_record(self, record_set_class, name, values, ttl=<NUM_LIT>, weight=None,<EOL>region=None,set_identifier=None, alias_hosted_zone_id=None,<EOL>alias_dns_name=None):

self._halt_if_already_deleted()<EOL>rrset_kwargs = dict(<EOL>connection=self.connection,<EOL>zone_id=self.id,<EOL>name=name,<EOL>ttl=ttl,<EOL>records=values,<EOL>weight=weight,<EOL>region=region,<EOL>set_identifier=set_identifier,<EOL>)<EOL>if alias_hosted_zone_id or alias_dns_name:<EOL><INDENT>rrset_kwargs.update(dict(<EOL>alias_hosted_zone_id=alias_hosted_zone_id,<EOL>alias_dns_name=alias_dns_name<EOL>))<EOL><DEDENT>rrset = record_set_class(**rrset_kwargs)<EOL>cset = ChangeSet(connection=self.connection, hosted_zone_id=self.id)<EOL>cset.add_change('<STR_LIT>', rrset)<EOL>change_info = self.connection._change_resource_record_sets(cset)<EOL>return rrset, change_info<EOL>

Convenience method for creating ResourceRecordSets. Most of the calls
are basically the same, this saves on repetition.

:rtype: tuple
:returns: A tuple in the form of ``(rrset, change_info)``, where
    ``rrset`` is the newly created ResourceRecordSet sub-class
     instance.