def test_to_yaml_basic(self): a = Box(test_dict) assert yaml.load(a.to_yaml(), Loader=yaml.SafeLoader) == test_dict
def get_range(self): """Return valid range.""" return Box(self._range)
def run_test(in_file, test_spec, global_cfg): """Run a single tavern test Note that each tavern test can consist of multiple requests (log in, create, update, delete, etc). The global configuration is copied and used as an initial configuration for this test. Any values which are saved from any tests are saved into this test block and can be used for formatting in later stages in the test. Args: in_file (str): filename containing this test test_spec (dict): The specification for this test global_cfg (dict): Any global configuration for this test No Longer Raises: TavernException: If any of the tests failed """ # pylint: disable=too-many-locals # Initialise test config for this test with the global configuration before # starting test_block_config = dict(global_cfg) if "variables" not in test_block_config: test_block_config["variables"] = {} tavern_box = Box({"env_vars": dict(os.environ)}) if not test_spec: logger.warning("Empty test block in %s", in_file) return # Get included stages and resolve any into the test spec dictionary available_stages = test_block_config.get("stages", []) included_stages = _get_included_stages(tavern_box, test_block_config, test_spec, available_stages) all_stages = {s["id"]: s for s in available_stages + included_stages} test_spec["stages"] = _resolve_test_stages(test_spec, all_stages) test_block_config["variables"]["tavern"] = tavern_box test_block_name = test_spec["test_name"] # Strict on body by default default_strictness = test_block_config["strict"] logger.info("Running test : %s", test_block_name) with ExitStack() as stack: sessions = get_extra_sessions(test_spec, test_block_config) for name, session in sessions.items(): logger.debug("Entering context for %s", name) stack.enter_context(session) def getonly(stage): o = stage.get("only") if o is None: return False elif isinstance(o, bool): return o else: return strtobool(o) has_only = any(getonly(stage) for stage in test_spec["stages"]) # Run tests in a path in order for stage in test_spec["stages"]: if stage.get("skip"): continue elif has_only and not getonly(stage): continue test_block_config["strict"] = default_strictness # Can be overridden per stage # NOTE # this is hardcoded to check for the 'response' block. In the far # future there might not be a response block, but at the moment it # is the hardcoded value for any HTTP request. if stage.get("response", {}): if stage.get("response").get("strict", None) is not None: stage_strictness = stage.get("response").get( "strict", None) elif test_spec.get("strict", None) is not None: stage_strictness = test_spec.get("strict", None) else: stage_strictness = default_strictness logger.debug("Strict key checking for this stage is '%s'", stage_strictness) test_block_config["strict"] = stage_strictness elif default_strictness: logger.debug("Default strictness '%s' ignored for this stage", default_strictness) # Wrap run_stage with retry helper run_stage_with_retries = retry(stage, test_block_config)(run_stage) try: run_stage_with_retries(sessions, stage, tavern_box, test_block_config) except exceptions.TavernException as e: e.stage = stage e.test_block_config = test_block_config raise if getonly(stage): break
from minikts.monitoring import report, shorten_path def _join_path(loader, node): seq = loader.construct_sequence(node) return Path().joinpath(*seq) def _get_from_env(loader, node): return os.environ.get(node.value, None) yaml.SafeLoader.add_constructor('!join_path', _join_path) yaml.SafeLoader.add_constructor('!env', _get_from_env) _CONFIG_FILENAME = None _CONFIG_POSTLOAD_HOOKS = [] config = Box(box_dots=True) hparams = Box(box_dots=True) def load_config(filename, postload_hooks=True): global _CONFIG_FILENAME _CONFIG_FILENAME = filename loaded_config = Box.from_yaml( filename=filename, box_dots=True, Loader=yaml.SafeLoader ) report("config", f"Loaded config from [!path]{shorten_path(filename)}[/]") config.merge_update(loaded_config) if "hparams" in loaded_config: hparams.merge_update(loaded_config.hparams)
def build( source, video_track, ffmpeg, temp_dir, output_video, bitrate=None, crf=None, preset="fast", audio_tracks=(), subtitle_tracks=(), disable_hdr=False, side_data=None, pix_fmt="yuv420p", tune=None, profile="default", attachments="", **kwargs, ): filters = generate_filters(disable_hdr=disable_hdr, **kwargs) audio = build_audio(audio_tracks) subtitles = build_subtitle(subtitle_tracks) ending = generate_ending(audio=audio, subtitles=subtitles, cover=attachments, output_video=output_video, **kwargs) if not side_data: side_data = Box(default_box=True) beginning = generate_ffmpeg_start( source=source, ffmpeg=ffmpeg, encoder="libx264", video_track=video_track, filters=filters, pix_fmt=pix_fmt, **kwargs, ) beginning += f'{f"-tune {tune}" if tune else ""} ' if profile and profile != "default": beginning += f"-profile {profile} " if not disable_hdr and pix_fmt == "yuv420p10le": if side_data and side_data.get("color_primaries") == "bt2020": beginning += "-color_primaries bt2020 -color_trc smpte2084 -colorspace bt2020nc" if side_data.cll: pass extra_data = "-map_chapters 0 " # -map_metadata 0 # safe to do for rotation? pass_log_file = Path( temp_dir) / f"pass_log_file_{secrets.token_hex(10)}.log" if bitrate: command_1 = ( f"{beginning} -pass 1 " f'-passlogfile "{pass_log_file}" -b:v {bitrate} -preset {preset} -an -sn -dn -f mp4 {null}' ) command_2 = (f'{beginning} -pass 2 -passlogfile "{pass_log_file}" ' f"-b:v {bitrate} -preset {preset} {extra_data}") + ending return [ Command(re.sub("[ ]+", " ", command_1), ["ffmpeg", "output"], False, name="First pass bitrate", exe="ffmpeg"), Command(re.sub("[ ]+", " ", command_2), ["ffmpeg", "output"], False, name="Second pass bitrate", exe="ffmpeg"), ] elif crf: command = (f"{beginning} -crf {crf} " f"-preset {preset} {extra_data}") + ending return [ Command(re.sub("[ ]+", " ", command), ["ffmpeg", "output"], False, name="Single pass CRF", exe="ffmpeg") ] else: return []
def test_camel_killer_hashables(self): bx = Box(camel_killer_box=True) bx[(1, 2)] = 32 assert bx == {(1, 2): 32}
def test_type_recast(self): b = Box(id="6", box_recast={"id": int}) assert isinstance(b.id, int) with pytest.raises(ValueError): b["sub_box"] = {"id": "bad_id"}
def test_safe_attrs(self): assert Box()._safe_attr("BAD!KEY!1") == "BAD_KEY_1" assert Box(camel_killer_box=True)._safe_attr("BAD!KEY!2") == "bad_key_2" assert Box()._safe_attr((5, 6, 7)) == "x5_6_7" assert Box()._safe_attr(356) == "x356"
def test_pickle_default_box(self): if platform.python_implementation() == "PyPy": pytest.skip("Pickling does not work correctly on PyPy") bb = Box(default_box=True) loaded = pickle.loads(pickle.dumps(bb)) assert bb == loaded
def test_from_yaml(self): bx = Box.from_yaml(yaml.dump(test_dict), conversion_box=False, default_box=True) assert isinstance(bx, Box) assert bx.key1 == "value1" assert bx.Key_2 == Box()
def test_box_modify_tuples(self): bx = Box(extended_test_dict, modify_tuples_box=True) assert bx.tuples_galore[0].item == 3 assert isinstance(bx.tuples_galore[0], Box) assert isinstance(bx.tuples_galore[1], tuple)
def test_set_default_dict(self): a = Box(test_dict) new = a.setdefault("key3", {}) new.yy = 8 assert a.key3.yy == 8
def test_auto_attr(self): a = Box(test_dict, default_box=True) assert isinstance(a.a.a.a.a, Box) a.b.b = 4 assert a.b.b == 4
def test_to_yaml_file(self): a = Box(test_dict) a.to_yaml(tmp_yaml_file) with open(tmp_yaml_file) as f: data = yaml.load(f, Loader=yaml.SafeLoader) assert data == test_dict
def test_revered(self): bx = Box() bx.a = 1 bx.c = 2 assert list(reversed(bx)) == ["c", "a"]
def test_conversion_dup_only(self): with pytest.raises(BoxError): Box(movie_data, conversion_box=False, box_duplicates="error")
def test_bad_recursive(self): b = Box() bl = b.setdefault("l", []) bl.append(["foo"]) assert bl == [["foo"]], bl
def test_get_default_box(self): bx = Box(default_box=True) assert bx.get("test", 4) == 4 assert isinstance(bx.get("a"), Box) assert bx.get("test", None) is None
def test_or_boxes(self): b = Box(c=1, d={"sub": 1}, e=1) c = dict(d={"val": 2}, e=4) assert b | c == Box(c=1, d={"val": 2}, e=4) with pytest.raises(BoxError): Box() | BoxList()
def test_through_queue(self): my_box = Box(a=4, c={"d": 3}) queue = Queue() queue.put(my_box) assert queue.get()
from here_map_widget import ( FullscreenControl, MeasurementControl, ScaleBar, ZoomControl, ImageTileProvider, MapSettingsControl, TileLayer, GeoJSON, WidgetControl, LayersControl, ) basemaps = Box(xyz_to_heremap(), frozen_box=True) class Map(here_map_widget.Map): """ The Map class inherits here_map_widget.Map. The arguments you can pass to the Map can be found at https://here-map-widget-for-jupyter.readthedocs.io/en/latest/api_reference/map.html. Returns: object: here_map_widget map object. """ def __init__(self, api_key=None, **kwargs): # Authenticates Earth Engine and initializes an Earth Engine session if "ee_initialize" not in kwargs.keys():
def test_update_with_integer(self): bx = Box() bx[1] = 4 assert bx[1] == 4 bx.update({1: 2}) assert bx[1] == 2
def Boundaries(self): b = Box() path = self.path currX = currY = None additive = False currentSkip = skip = -1 coords = [] if "d" in path.attrib: coords = path.attrib["d"].split(" ") if coords[0] == "M": additive = False coords = coords[1:] elif "points" in path.attrib: additive = False coords = path.attrib["points"].split(" ") activeCommand = "" for command in coords: try: xy = command.split(",") x = y = None if (activeCommand.upper() == "H"): x = float(xy[0]) y = None elif (activeCommand.upper() == "V"): y = float(xy[0]) x = None else: x = float(xy[0]) y = float(xy[1]) if currentSkip < 0 and skip > 0: currentSkip = skip if currentSkip > 0: currentSkip -= 1 # print "skipping", command, currentSkip, skip continue if currentSkip == 0: # print "processing", command currentSkip -= 1 if not additive or currX is None: currX = (x if x is not None else currX) currY = (y if y is not None else currY) else: currX += (x if x is not None else 0) currY += (y if y is not None else 0) (transX, transY) = self.Transform(currX, currY) if b.minX == None or b.minX > transX: b.minX = transX if b.minY == None or b.minY > transY: b.minY = transY if b.maxX == None or b.maxX < transX: b.maxX = transX if b.maxY == None or b.maxY < transY: b.maxY = transY except Exception as e: skip = -1 if command == "z" or command == "Z": continue if command.upper() == command: additive = False currX = currY = None else: additive = True if command == "c" or command == "C": skip = 2 activeCommand = command return b
def test_get_box_config(self): bx = Box() bx_config = bx.__getattr__("_box_config") assert bx_config with pytest.raises(BoxKeyError): bx["_box_config"]
def visualize(fasta, width, palette, color, hide, bar, title, separate, cols, link_x, link_y, output, offline, method, dimensions, skip, mode, legend_loc, output_backend, downsample): # check filetype if fasta is None: raise ValueError("Must provide FASTA file.") # handle selecting the palette palette = small_palettes[palette] # handle setting the dimensions automatically if not specified if not dimensions: dimensions = (750, 500) if len( [record for _f in fasta for record in Fasta(_f, read_long_names=True) ]) > len(palette) and mode != "file": if len(fasta) > 1 and mode == "auto": if not skip: print( "Visualizing each file in separate color. To override, provide mode selection." ) mode = "file" else: print("Visualizing each sequence in black.") color = False elif mode == "auto": mode = "seq" # get all the sequences seqs = [] color_counter = 0 warned = False for i, _f in enumerate(fasta): for j, seq in enumerate( Fasta(_f, sequence_always_upper=True, read_long_names=True)): seqs.append( Box(color=palette[color_counter + 1 if color_counter > 2 else 3][color_counter] if color else "black", name=_f if mode == "file" else seq.name, raw_seq=str(seq))) # check the length of the seq if len(seq ) > 10000 and not skip and not warned and downsample == 1: click.confirm( "You are plotting a long sequence ({} bp). This may be very slow, although downsampling might help. " "Do you want to continue?".format(len(seq)), abort=True) warned = True if mode == "seq": color_counter += 1 if mode == "file": color_counter += 1 # warn if plotting a large number of seqs if len(seqs) > 500 and not skip: click.confirm( "You are plotting a large number of sequences ({}). This may be very slow, although downsampling might help. " "Do you want to continue?".format(len(seqs)), abort=True) # warn if using a bad method if max([len(seq.raw_seq) for seq in seqs]) > 25 and method in ["qi", "randic"] and not skip: click.confirm( "This method is not well suited to a sequence of this length. " "Do you want to continue?", abort=True) axis_labels = { "squiggle": { "x": "position (BP)", "y": None }, "gates": { "x": "C-G axis", "y": "A-T axis" }, "yau": { "x": None, "y": None }, "yau-bp": { "x": "position (BP)", "y": None }, "randic": { "x": "position (BP)", "y": "nucleotide" }, "qi": { "x": "position (BP)", "y": "dinucleotide" } } # the number of figures to draw is either the number of sequences or files (or 1) if separate: if mode == "seq": fig_count = len(seqs) elif mode == "file": fig_count = len(fasta) else: fig_count = 1 fig = [] for i in range(fig_count): # link the axes, if requested if i > 0 and link_x: x_range = fig[i - 1].x_range else: x_range = None if i > 0 and link_y: y_range = fig[i - 1].y_range else: y_range = None # the y axes for randic and qi are bases if method == "randic": y_range = ["A", "T", "G", "C"] elif method == "qi": y_range = [ 'AA', 'AC', 'AG', 'AT', 'CA', 'CC', 'CG', 'CT', 'GA', 'GC', 'GG', 'GT', 'TA', 'TC', 'TG', 'TT' ] fig.append( figure(x_axis_label=axis_labels[method]["x"], y_axis_label=axis_labels[method]["y"], title=title, x_range=x_range, y_range=y_range, plot_width=dimensions[0], plot_height=dimensions[1], output_backend=output_backend)) # show a progress bar if processing multiple files if len(seqs) > 1 and bar: _seqs = tqdm(seqs, unit=" seqs", leave=False) else: _seqs = seqs for i, seq in enumerate(_seqs): # perform the actual transformation transformed = transform(seq.raw_seq, method=method) transformed = (transformed[0][::downsample], transformed[1][::downsample]) # figure (no pun intended) which figure to plot the data on if separate: if mode == "seq": _fig = fig[i] elif mode == "file": _fig = fig[fasta.index(seq.name)] # add a title to the plot _fig.title = annotations.Title() if mode == "seq": _fig.title.text = seq.name elif mode == "file": _fig.title.text = click.format_filename(seq.name, shorten=True) else: _fig = fig[0] _fig.title = annotations.Title() # if only plotting on one figure, set up the title if title: _fig.title.text = title elif len(seqs) > 1 and not title and len(fasta) == 1: _fig.title.text = click.format_filename(fasta[0], shorten=True) elif len(seqs) == 1: # if just plotting one sequence, title it with the name of the sequence _fig.title.text = seq.name # randic and qi method's have categorical y axes if method == "randic": y = list(seq.raw_seq) elif method == "qi": y = [seq.raw_seq[i:i + 2] for i in range(len(seq.raw_seq))] y = [str(i) for i in y if len(i) == 2] else: y = transformed[1] # figure out whether to add a legend if (separate or not color or mode == "file" or len(seqs) == 1) and not hide: legend = None else: legend = click.format_filename(seq.name, shorten=True) # optimization for comparing large FASTA files without hiding try: if mode == "file" and seqs[i + 1].color != seq.color and not separate: legend = click.format_filename(seq.name, shorten=True) except IndexError: if mode == "file" and not separate: legend = click.format_filename(seq.name, shorten=True) # do the actual plotting _fig.line(x=transformed[0], y=y, line_width=width, legend=legend, color=seq.color) # set up the legend if legend is not None: _fig.legend.location = legend_loc if hide: _fig.legend.click_policy = "hide" # clean up the tqdm bar try: _seqs.close() except AttributeError: pass # lay out the figure if separate: plot = gridplot( fig, ncols=math.ceil(len(fig)**0.5) if cols == 0 else cols, toolbar_options=dict( logo=None)) # note that 0 denotes the automatic default else: plot = fig[0] if output is not None and output.endswith(".html"): output_file( output, title="Squiggle Visualization" if title is not None else title) save(plot, resources=INLINE if offline else None) else: show(plot)
def test_pop_items(self): bx = Box(a=4) assert bx.popitem() == ("a", 4) with pytest.raises(BoxKeyError): assert bx.popitem()
def __init__(self, parent, subtitle, index, enabled=True, first=False): self.loading = True super(Subtitle, self).__init__(parent) self.parent = parent self.index = index self.outdex = None self.subtitle = Box(subtitle, default_box=True) self.first = first self.last = False self.subtitle_lang = subtitle.get("tags", {}).get("language") self.subtitle_type = subtitle_types.get(subtitle["codec_name"], "text") self.setFixedHeight(60) self.widgets = Box( track_number=QtWidgets.QLabel(f"{self.index}:{self.outdex}" if enabled else "❌"), title=QtWidgets.QLabel(f" {self.subtitle.codec_long_name}"), up_button=QtWidgets.QPushButton(QtGui.QIcon(up_arrow_icon), ""), down_button=QtWidgets.QPushButton(QtGui.QIcon(down_arrow_icon), ""), enable_check=QtWidgets.QCheckBox(t("Preserve")), disposition=QtWidgets.QComboBox(), language=QtWidgets.QComboBox(), burn_in=QtWidgets.QCheckBox(t("Burn In")), ) self.widgets.up_button.setStyleSheet(no_border) self.widgets.down_button.setStyleSheet(no_border) self.widgets.disposition.addItems(dispositions) self.widgets.enable_check.setChecked(enabled) self.widgets.enable_check.toggled.connect(self.update_enable) self.widgets.burn_in.toggled.connect(self.update_burn_in) self.widgets.disposition.currentIndexChanged.connect(self.page_update) self.widgets.disposition.setCurrentIndex(0) for disposition, is_set in self.subtitle.disposition.items(): if is_set: try: self.widgets.disposition.setCurrentIndex(dispositions.index(disposition)) except ValueError: pass break self.setFixedHeight(60) self.widgets.title.setToolTip(self.subtitle.to_yaml()) self.widgets.burn_in.setToolTip( f"""{t("Overlay this subtitle track onto the video during conversion.")}\n {t("Please make sure seek method is set to exact")}.\n {t("Cannot remove afterwards!")} """ ) self.widgets.extract = QtWidgets.QPushButton(t("Extract")) self.widgets.extract.clicked.connect(self.extract) self.gif_label = QtWidgets.QLabel(self) self.movie = QtGui.QMovie(loading_movie) self.movie.setScaledSize(QtCore.QSize(25, 25)) self.gif_label.setMovie(self.movie) # self.movie.start() disposition_layout = QtWidgets.QHBoxLayout() disposition_layout.addWidget(QtWidgets.QLabel(t("Disposition"))) disposition_layout.addWidget(self.widgets.disposition) self.grid = QtWidgets.QGridLayout() self.grid.addLayout(self.init_move_buttons(), 0, 0) self.grid.addWidget(self.widgets.track_number, 0, 1) self.grid.addWidget(self.widgets.title, 0, 2) self.grid.setColumnStretch(2, True) if self.subtitle_type == "text": self.grid.addWidget(self.widgets.extract, 0, 3) self.grid.addWidget(self.gif_label, 0, 3) self.gif_label.hide() self.grid.addLayout(disposition_layout, 0, 4) self.grid.addWidget(self.widgets.burn_in, 0, 5) self.grid.addLayout(self.init_language(), 0, 6) self.grid.addWidget(self.widgets.enable_check, 0, 8) self.setLayout(self.grid) self.loading = False self.updating_burn = False self.extract_completed_signal.connect(self.extraction_complete)
def test_iter(self): bx = Box() bx.a = 1 bx.c = 2 assert list(bx.__iter__()) == ["a", "c"]
async def clanmembersearch(self, ctx, *args): """Search for member. usage: [p]crmembersearch [-h] [-t TAG] name positional arguments: name IGN optional arguments: -h, --help show this help message and exit -c CLAN, --clan CLAN Clan name -n MIN --min MIN Min Trophies -m MAX --max MAX Max Trophies -l --link Display link to cr-api.com """ parser = self.search_args_parser() try: pargs = parser.parse_args(args) except SystemExit: await self.bot.send_cmd_help(ctx) return await self.bot.type() config = self.clans_config clan_tags = [clan.tag for clan in config.clans] api_error = False clans = [] try: clans = await self.get_clans(clan_tags) dataIO.save_json(CACHE, clans) except json.decoder.JSONDecodeError: api_error = True except asyncio.TimeoutError: api_error = True if api_error: await self.bot.say("Cannot load clans from API.") return members = [] for clan in clans: for member in clan.get('members'): member = Box(member) member.clan = clan members.append(member) results = [] if pargs.name != '_': for member in members: # simple search if pargs.name.lower() in member['name'].lower(): results.append(member) else: # unidecode search s = unidecode.unidecode(member['name']) s = ''.join(re.findall(r'\w', s)) if pargs.name.lower() in s.lower(): results.append(member) else: results = members print(len(results)) # filter by clan name if pargs.clan: results = [ m for m in results if pargs.clan.lower() in m.clan.name.lower() ] # filter by trophies results = [ m for m in results if pargs.min <= m['trophies'] <= pargs.max ] limit = 10 if len(results) > limit: await self.bot.say( "Found more than {0} results. Returning top {0} only.".format( limit)) results = results[:limit] roles = { 'leader': 'Leader', 'coleader': 'Co-Leader', 'elder': 'Elder', 'member': 'Member' } if len(results): out = [] for member_model in results: member_model['role_name'] = roles[member_model['role'].lower()] out.append( "**{0.name}** #{0.tag}, {0.clan.name}, {0.role_name}, {0.trophies}" .format(member_model)) if pargs.link: out.append('http://cr-api.com/profile/{}'.format( member_model.tag)) for page in pagify('\n'.join(out)): await self.bot.say(page) else: await self.bot.say("No results found.")
def test_bad_args(self): with pytest.raises(TypeError): Box("123", "432")