Best Python code snippet using pytest
legacypath.py
Source:legacypath.py
...46 self._pytester = pytester47 @property48 def tmpdir(self) -> LEGACY_PATH:49 """Temporary directory where tests are executed."""50 return legacy_path(self._pytester.path)51 @property52 def test_tmproot(self) -> LEGACY_PATH:53 return legacy_path(self._pytester._test_tmproot)54 @property55 def request(self):56 return self._pytester._request57 @property58 def plugins(self):59 return self._pytester.plugins60 @plugins.setter61 def plugins(self, plugins):62 self._pytester.plugins = plugins63 @property64 def monkeypatch(self) -> MonkeyPatch:65 return self._pytester._monkeypatch66 def make_hook_recorder(self, pluginmanager) -> HookRecorder:67 """See :meth:`Pytester.make_hook_recorder`."""68 return self._pytester.make_hook_recorder(pluginmanager)69 def chdir(self) -> None:70 """See :meth:`Pytester.chdir`."""71 return self._pytester.chdir()72 def finalize(self) -> None:73 """See :meth:`Pytester._finalize`."""74 return self._pytester._finalize()75 def makefile(self, ext, *args, **kwargs) -> LEGACY_PATH:76 """See :meth:`Pytester.makefile`."""77 if ext and not ext.startswith("."):78 # pytester.makefile is going to throw a ValueError in a way that79 # testdir.makefile did not, because80 # pathlib.Path is stricter suffixes than py.path81 # This ext arguments is likely user error, but since testdir has82 # allowed this, we will prepend "." as a workaround to avoid breaking83 # testdir usage that worked before84 ext = "." + ext85 return legacy_path(self._pytester.makefile(ext, *args, **kwargs))86 def makeconftest(self, source) -> LEGACY_PATH:87 """See :meth:`Pytester.makeconftest`."""88 return legacy_path(self._pytester.makeconftest(source))89 def makeini(self, source) -> LEGACY_PATH:90 """See :meth:`Pytester.makeini`."""91 return legacy_path(self._pytester.makeini(source))92 def getinicfg(self, source: str) -> SectionWrapper:93 """See :meth:`Pytester.getinicfg`."""94 return self._pytester.getinicfg(source)95 def makepyprojecttoml(self, source) -> LEGACY_PATH:96 """See :meth:`Pytester.makepyprojecttoml`."""97 return legacy_path(self._pytester.makepyprojecttoml(source))98 def makepyfile(self, *args, **kwargs) -> LEGACY_PATH:99 """See :meth:`Pytester.makepyfile`."""100 return legacy_path(self._pytester.makepyfile(*args, **kwargs))101 def maketxtfile(self, *args, **kwargs) -> LEGACY_PATH:102 """See :meth:`Pytester.maketxtfile`."""103 return legacy_path(self._pytester.maketxtfile(*args, **kwargs))104 def syspathinsert(self, path=None) -> None:105 """See :meth:`Pytester.syspathinsert`."""106 return self._pytester.syspathinsert(path)107 def mkdir(self, name) -> LEGACY_PATH:108 """See :meth:`Pytester.mkdir`."""109 return legacy_path(self._pytester.mkdir(name))110 def mkpydir(self, name) -> LEGACY_PATH:111 """See :meth:`Pytester.mkpydir`."""112 return legacy_path(self._pytester.mkpydir(name))113 def copy_example(self, name=None) -> LEGACY_PATH:114 """See :meth:`Pytester.copy_example`."""115 return legacy_path(self._pytester.copy_example(name))116 def getnode(self, config: Config, arg) -> Optional[Union[Item, Collector]]:117 """See :meth:`Pytester.getnode`."""118 return self._pytester.getnode(config, arg)119 def getpathnode(self, path):120 """See :meth:`Pytester.getpathnode`."""121 return self._pytester.getpathnode(path)122 def genitems(self, colitems: List[Union[Item, Collector]]) -> List[Item]:123 """See :meth:`Pytester.genitems`."""124 return self._pytester.genitems(colitems)125 def runitem(self, source):126 """See :meth:`Pytester.runitem`."""127 return self._pytester.runitem(source)128 def inline_runsource(self, source, *cmdlineargs):129 """See :meth:`Pytester.inline_runsource`."""130 return self._pytester.inline_runsource(source, *cmdlineargs)131 def inline_genitems(self, *args):132 """See :meth:`Pytester.inline_genitems`."""133 return self._pytester.inline_genitems(*args)134 def inline_run(self, *args, plugins=(), no_reraise_ctrlc: bool = False):135 """See :meth:`Pytester.inline_run`."""136 return self._pytester.inline_run(137 *args, plugins=plugins, no_reraise_ctrlc=no_reraise_ctrlc138 )139 def runpytest_inprocess(self, *args, **kwargs) -> RunResult:140 """See :meth:`Pytester.runpytest_inprocess`."""141 return self._pytester.runpytest_inprocess(*args, **kwargs)142 def runpytest(self, *args, **kwargs) -> RunResult:143 """See :meth:`Pytester.runpytest`."""144 return self._pytester.runpytest(*args, **kwargs)145 def parseconfig(self, *args) -> Config:146 """See :meth:`Pytester.parseconfig`."""147 return self._pytester.parseconfig(*args)148 def parseconfigure(self, *args) -> Config:149 """See :meth:`Pytester.parseconfigure`."""150 return self._pytester.parseconfigure(*args)151 def getitem(self, source, funcname="test_func"):152 """See :meth:`Pytester.getitem`."""153 return self._pytester.getitem(source, funcname)154 def getitems(self, source):155 """See :meth:`Pytester.getitems`."""156 return self._pytester.getitems(source)157 def getmodulecol(self, source, configargs=(), withinit=False):158 """See :meth:`Pytester.getmodulecol`."""159 return self._pytester.getmodulecol(160 source, configargs=configargs, withinit=withinit161 )162 def collect_by_name(163 self, modcol: Collector, name: str164 ) -> Optional[Union[Item, Collector]]:165 """See :meth:`Pytester.collect_by_name`."""166 return self._pytester.collect_by_name(modcol, name)167 def popen(168 self,169 cmdargs,170 stdout=subprocess.PIPE,171 stderr=subprocess.PIPE,172 stdin=CLOSE_STDIN,173 **kw,174 ):175 """See :meth:`Pytester.popen`."""176 return self._pytester.popen(cmdargs, stdout, stderr, stdin, **kw)177 def run(self, *cmdargs, timeout=None, stdin=CLOSE_STDIN) -> RunResult:178 """See :meth:`Pytester.run`."""179 return self._pytester.run(*cmdargs, timeout=timeout, stdin=stdin)180 def runpython(self, script) -> RunResult:181 """See :meth:`Pytester.runpython`."""182 return self._pytester.runpython(script)183 def runpython_c(self, command):184 """See :meth:`Pytester.runpython_c`."""185 return self._pytester.runpython_c(command)186 def runpytest_subprocess(self, *args, timeout=None) -> RunResult:187 """See :meth:`Pytester.runpytest_subprocess`."""188 return self._pytester.runpytest_subprocess(*args, timeout=timeout)189 def spawn_pytest(190 self, string: str, expect_timeout: float = 10.0191 ) -> "pexpect.spawn":192 """See :meth:`Pytester.spawn_pytest`."""193 return self._pytester.spawn_pytest(string, expect_timeout=expect_timeout)194 def spawn(self, cmd: str, expect_timeout: float = 10.0) -> "pexpect.spawn":195 """See :meth:`Pytester.spawn`."""196 return self._pytester.spawn(cmd, expect_timeout=expect_timeout)197 def __repr__(self) -> str:198 return f"<Testdir {self.tmpdir!r}>"199 def __str__(self) -> str:200 return str(self.tmpdir)201class LegacyTestdirPlugin:202 @staticmethod203 @fixture204 def testdir(pytester: Pytester) -> Testdir:205 """206 Identical to :fixture:`pytester`, and provides an instance whose methods return207 legacy ``LEGACY_PATH`` objects instead when applicable.208 New code should avoid using :fixture:`testdir` in favor of :fixture:`pytester`.209 """210 return Testdir(pytester, _ispytest=True)211@final212@attr.s(init=False, auto_attribs=True)213class TempdirFactory:214 """Backward compatibility wrapper that implements :class:``_pytest.compat.LEGACY_PATH``215 for :class:``TempPathFactory``."""216 _tmppath_factory: TempPathFactory217 def __init__(218 self, tmppath_factory: TempPathFactory, *, _ispytest: bool = False219 ) -> None:220 check_ispytest(_ispytest)221 self._tmppath_factory = tmppath_factory222 def mktemp(self, basename: str, numbered: bool = True) -> LEGACY_PATH:223 """Same as :meth:`TempPathFactory.mktemp`, but returns a ``_pytest.compat.LEGACY_PATH`` object."""224 return legacy_path(self._tmppath_factory.mktemp(basename, numbered).resolve())225 def getbasetemp(self) -> LEGACY_PATH:226 """Backward compat wrapper for ``_tmppath_factory.getbasetemp``."""227 return legacy_path(self._tmppath_factory.getbasetemp().resolve())228class LegacyTmpdirPlugin:229 @staticmethod230 @fixture(scope="session")231 def tmpdir_factory(request: FixtureRequest) -> TempdirFactory:232 """Return a :class:`pytest.TempdirFactory` instance for the test session."""233 # Set dynamically by pytest_configure().234 return request.config._tmpdirhandler # type: ignore235 @staticmethod236 @fixture237 def tmpdir(tmp_path: Path) -> LEGACY_PATH:238 """Return a temporary directory path object which is unique to each test239 function invocation, created as a sub directory of the base temporary240 directory.241 By default, a new base temporary directory is created each test session,242 and old bases are removed after 3 sessions, to aid in debugging. If243 ``--basetemp`` is used then it is cleared each session. See :ref:`base244 temporary directory`.245 The returned object is a `legacy_path`_ object.246 .. _legacy_path: https://py.readthedocs.io/en/latest/path.html247 """248 return legacy_path(tmp_path)249def Cache_makedir(self: Cache, name: str) -> LEGACY_PATH:250 """Return a directory path object with the given name.251 Same as :func:`mkdir`, but returns a legacy py path instance.252 """253 return legacy_path(self.mkdir(name))254def FixtureRequest_fspath(self: FixtureRequest) -> LEGACY_PATH:255 """(deprecated) The file system path of the test module which collected this test."""256 return legacy_path(self.path)257def TerminalReporter_startdir(self: TerminalReporter) -> LEGACY_PATH:258 """The directory from which pytest was invoked.259 Prefer to use ``startpath`` which is a :class:`pathlib.Path`.260 :type: LEGACY_PATH261 """262 return legacy_path(self.startpath)263def Config_invocation_dir(self: Config) -> LEGACY_PATH:264 """The directory from which pytest was invoked.265 Prefer to use :attr:`invocation_params.dir <InvocationParams.dir>`,266 which is a :class:`pathlib.Path`.267 :type: LEGACY_PATH268 """269 return legacy_path(str(self.invocation_params.dir))270def Config_rootdir(self: Config) -> LEGACY_PATH:271 """The path to the :ref:`rootdir <rootdir>`.272 Prefer to use :attr:`rootpath`, which is a :class:`pathlib.Path`.273 :type: LEGACY_PATH274 """275 return legacy_path(str(self.rootpath))276def Config_inifile(self: Config) -> Optional[LEGACY_PATH]:277 """The path to the :ref:`configfile <configfiles>`.278 Prefer to use :attr:`inipath`, which is a :class:`pathlib.Path`.279 :type: Optional[LEGACY_PATH]280 """281 return legacy_path(str(self.inipath)) if self.inipath else None282def Session_stardir(self: Session) -> LEGACY_PATH:283 """The path from which pytest was invoked.284 Prefer to use ``startpath`` which is a :class:`pathlib.Path`.285 :type: LEGACY_PATH286 """287 return legacy_path(self.startpath)288def Config__getini_unknown_type(289 self, name: str, type: str, value: Union[str, List[str]]290):291 if type == "pathlist":292 # TODO: This assert is probably not valid in all cases.293 assert self.inipath is not None294 dp = self.inipath.parent295 input_values = shlex.split(value) if isinstance(value, str) else value296 return [legacy_path(str(dp / x)) for x in input_values]297 else:298 raise ValueError(f"unknown configuration type: {type}", value)299def Node_fspath(self: Node) -> LEGACY_PATH:300 """(deprecated) returns a legacy_path copy of self.path"""301 return legacy_path(self.path)302def Node_fspath_set(self: Node, value: LEGACY_PATH) -> None:303 self.path = Path(value)304@hookimpl(tryfirst=True)305def pytest_load_initial_conftests(early_config: Config) -> None:306 """Monkeypatch legacy path attributes in several classes, as early as possible."""307 mp = MonkeyPatch()308 early_config.add_cleanup(mp.undo)309 # Add Cache.makedir().310 mp.setattr(Cache, "makedir", Cache_makedir, raising=False)311 # Add FixtureRequest.fspath property.312 mp.setattr(FixtureRequest, "fspath", property(FixtureRequest_fspath), raising=False)313 # Add TerminalReporter.startdir property.314 mp.setattr(315 TerminalReporter, "startdir", property(TerminalReporter_startdir), raising=False...
run.py
Source:run.py
1#!/usr/bin/env python32# -*- encoding: utf-8 -*-3from __future__ import annotations4import argparse5import json6import logging7import sys8import zipfile9from pathlib import Path10from typing import Any11from typing import Dict12from typing import Iterable13from typing import List14from typing import Optional15from typing import TYPE_CHECKING16from typing import Tuple17from wildermyth_renderer import CharacterData18from wildermyth_renderer import FilterParams19from wildermyth_renderer import GraphRenderer20from wildermyth_renderer import RelationshipChart21from wildermyth_renderer import RelationshipStatus22from wildermyth_renderer import RendererParams23from wildermyth_renderer import extract_individual_entities24if TYPE_CHECKING:25 from wildermyth_renderer import schemas26logging.basicConfig(level=logging.INFO, stream=sys.stdout, format="[%(levelname)s] %(message)s")27log = logging.getLogger(__name__)28parser = argparse.ArgumentParser(description='KaulleN\'s Wildermyth relationship chart renderer')29parser.add_argument('legacy_path', type=Path, help='Path to legacy.json or legacy.json.zip file')30parser.add_argument('-o', '--output-path', type=Path, default=Path('chart.png'),31 help='Path to save rendered chart (.png)')32parser.add_argument('-r', '--render-dir', type=Path, default=None, help='Directory for temporary render files')33parser.add_argument('-c', '--clean-tmp-files', action='store_true',34 help='Flag to clean temporary files after rendering')35parser.add_argument('--norender', action='store_true',36 help='Flag to not render any images and instead create raw .gv files '37 '(if --clean-tmp-files is specified, nothing will be left at all; '38 'output path must still be specified in order to produce graph filenames)')39rgroup = parser.add_argument_group(title='Rendering params')40rgroup.add_argument('--no-gender-shapes', action='store_true',41 help='Flag to not choose node shapes according to character gender')42rgroup.add_argument('--no-class-colors', '--no-class-colours', action='store_true',43 help='Flag to not choose node colors according to character class')44rgroup.add_argument('-R', '--prioritize-relationships', '--prioritise-relationships', action='store_true',45 help='Flag to prioritise relationships while rendering (sometimes provides cleaner results)')46rgroup.add_argument('--hide-phantoms', action='store_true', help='Flag to hide unknown parents from chart')47rgroup.add_argument('-P', '--pack', action='store_true',48 help='Flag to pack the chart neatly instead of spreading it horizontally')49rgroup.add_argument('--pack-by-subgraphs', action='store_true',50 help='Flag to spread out different components when packing the chart')51rgroup.add_argument('-L', '--include-legend', action='store_true', help='Flag to include legend to the chart')52fgroup = parser.add_argument_group(title='Chart filtering params')53fgroup.add_argument('--include-relationships', nargs='+', default=None,54 help='List of relationships to include; entry format is status[_type]')55fgroup.add_argument('--exclude-relationships', nargs='+', default=None,56 help='List of relationships to exclude; entry format is status[_type]')57fgroup.add_argument('--include-heroes', nargs='+', default=None,58 help='List of heroes to include; accepts either name or id (short/long form)')59fgroup.add_argument('--exclude-heroes', nargs='+', default=None,60 help='List of heroes to exclude; accepts either name or id (short/long form)')61def load_legacy_json(legacy_path: Path) -> schemas.LegacyDict:62 if legacy_path.suffix.lower() == '.zip':63 with zipfile.ZipFile(legacy_path) as legacy_zip:64 legacy_json_filenames = [f for f in legacy_zip.namelist() if f.lower().endswith('.json')]65 if not legacy_json_filenames:66 raise FileNotFoundError('No JSON files found in provided archive')67 if 'legacy.json' in legacy_json_filenames:68 legacy_json_filename = 'legacy.json'69 else:70 log.warning('No `legacy.json` file found in provided archive, trying to render from %s instead',71 legacy_json_filenames[0])72 legacy_json_filename = legacy_json_filenames[0]73 with legacy_zip.open(legacy_json_filename) as legacy_file:74 return json.load(legacy_file)75 elif legacy_path.suffix.lower() == '.json':76 with legacy_path.open() as legacy_file:77 return json.load(legacy_file)78 else:79 raise ValueError(f"Path to legacy file must be either .zip or .json")80def prepare_relationship_list(rel_args: Optional[Iterable[str]]) -> Optional[List[Tuple[RelationshipStatus, str]]]:81 if rel_args is None:82 return None83 res = []84 for rel_str in rel_args:85 rel_status, has_type, rel_type = rel_str.partition('_')86 if rel_status == 'legacy':87 # common mistake88 rel_status = 'locked'89 rel_status = RelationshipStatus[rel_status.upper()]90 if has_type:91 if rel_type in ('soulmate', 'soulmates'):92 # locked lovers are called soulmates in game, it may cause confusion93 rel_type = 'lover'94 elif rel_type in ('lovers', 'rivals', 'friends'):95 # in game files all the relationships are in singular form96 rel_type = rel_type[:-1]97 else:98 rel_type = '*'99 res.append((rel_status, rel_type))100 return res101def prepare_hero_list(hero_args: Optional[Iterable[str]], chart: RelationshipChart) -> Optional[List[str]]:102 if hero_args is None:103 return None104 res = []105 label_lookup = chart.make_label_lookup()106 short_id_lookup = chart.make_short_id_lookup()107 for hero_str in hero_args:108 if hero_str in chart.nodes:109 res.append(hero_str)110 elif hero_str in short_id_lookup:111 res.append(short_id_lookup[hero_str].id)112 elif hero_str in label_lookup:113 res.extend([n.id for n in label_lookup[hero_str]])114 else:115 raise ValueError(f"Hero identifier {hero_str} not found")116 return res117def main(args_dict: Dict[str, Any]) -> None:118 log.info('Starting program')119 legacy_data = load_legacy_json(args_dict['legacy_path'])120 individual_entities = extract_individual_entities(legacy_data)121 characters = [CharacterData.from_entity_dicts(*entity) for entity in individual_entities]122 chart = RelationshipChart.from_character_data(characters)123 filter_params = FilterParams(124 include_relationships=prepare_relationship_list(args_dict['include_relationships']),125 exclude_relationships=prepare_relationship_list(args_dict['exclude_relationships']),126 include_heroes=prepare_hero_list(args_dict['include_heroes'], chart),127 exclude_heroes=prepare_hero_list(args_dict['exclude_heroes'], chart),128 )129 chart.apply_filter_params(filter_params, inplace=True)130 chart.clean_relationships(inplace=True)131 renderer_params = RendererParams(132 output_path=args_dict['output_path'].absolute(),133 norender=args_dict['norender'],134 render_dir=args_dict['render_dir'].absolute() if args_dict['render_dir'] is not None else None,135 clean_tmp_files=args_dict['clean_tmp_files'],136 gender_shapes=not args_dict['no_gender_shapes'],137 class_colors=not args_dict['no_class_colors'],138 include_legend=args_dict['include_legend'],139 prioritize_relationships=args_dict['prioritize_relationships'],140 hide_phantoms=args_dict['hide_phantoms'],141 pack_graph=args_dict['pack'],142 pack_by_subgraphs=args_dict['pack_by_subgraphs'],143 )144 renderer = GraphRenderer(renderer_params, chart)145 renderer.render()146 log.info('Successfully rendered the chart at %s', renderer_params.output_path)147if __name__ == '__main__':148 args = parser.parse_args()...
parser_compat.py
Source:parser_compat.py
1# The Qubes OS Project, http://www.qubes-os.org2#3# Copyright (C) 2019 Wojtek Porczyk <woju@invisiblethingslab.com>4#5# This library is free software; you can redistribute it and/or6# modify it under the terms of the GNU Lesser General Public7# License as published by the Free Software Foundation; either8# version 2.1 of the License, or (at your option) any later version.9#10# This library is distributed in the hope that it will be useful,11# but WITHOUT ANY WARRANTY; without even the implied warranty of12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU13# Lesser General Public License for more details.14#15# You should have received a copy of the GNU Lesser General Public16# License along with this library; if not, see <https://www.gnu.org/licenses/>.17'''This module is transitional and may go away any time.18.. autofunction:: walk_compat_files19.. autoclass:: Compat40Loader20 :members:21 :member-order: bysource22.. autoclass:: Compat40Parser23 :members:24 :member-order: bysource25.. autoclass:: TestCompat40Loader26 :members:27 :member-order: bysource28'''29import abc30import collections31import functools32import logging33import pathlib34from .. import POLICYPATH_OLD35from ..exc import PolicySyntaxError36from . import parser37IGNORED_SUFFIXES = ('.rpmsave', '.rpmnew', '.swp')38@functools.total_ordering39class _NoArgumentLastKey:40 def __init__(self, arg):41 self.arg = arg42 def __eq__(self, other):43 return self.arg == other.arg44 def __lt__(self, other):45 if self.arg == '*':46 return False47 if other.arg == '*':48 return True49 return self.arg < other.arg50def _sorted_compat_files(filepaths):51 services = collections.defaultdict(dict)52 for filepath in filepaths:53 service, argument = parser.parse_service_and_argument(filepath,54 no_arg='*')55 services[service][argument] = filepath56 for service in sorted(services):57 for argument in sorted(services[service], key=_NoArgumentLastKey):58 yield service, argument, services[service][argument]59def _list_compat_files(legacy_path):60 for filepath in legacy_path.iterdir():61 if not filepath.is_file():62 logging.info('ignoring %s (not a file)', filepath)63 continue64 if filepath.suffix in IGNORED_SUFFIXES:65 logging.info('ignoring %s (ignored suffix)')66 continue67 if filepath.name.startswith('.'):68 logging.info('ignoring %s (dotfile)')69 continue70 invalid_chars = parser.get_invalid_characters(filepath.name)71 if invalid_chars:72 logging.info('ignoring %s (invalid characters: %r)',73 filepath, invalid_chars)74 continue75 yield filepath76def walk_compat_files(legacy_path=POLICYPATH_OLD):77 '''Walks files in correct order for generating compat policy.78 Args:79 legacy_path (pathlib.Path): base path for legacy policy80 Yields:81 (service, argument, filepath)82 '''83 yield from _sorted_compat_files(_list_compat_files(legacy_path))84class Compat40Parser(parser.AbstractDirectoryLoader, parser.AbstractFileLoader):85 '''Abstract parser for compat policy. Needs :py:func:`walk_includes`.86 Args:87 master (qrexec.policy.parser.AbstractPolicyParser):88 the parser that will handle all the syntax parsed from the legacy89 policy90 '''91 def __init__(self, *, master, **kwds):92 super().__init__(**kwds)93 self.master = master94 @abc.abstractmethod95 def walk_includes(self):96 '''An iterator that walks over all files to be included via97 ``!compat-4.0`` statement.98 Yields:99 (service, argument, filepath)100 '''101 raise NotImplementedError()102 def execute(self, *, filepath, lineno):103 '''Insert the policy into :py:attr:`master` parser.'''104 for service, argument, path in self.walk_includes():105 self.handle_include_service(service, argument, path,106 filepath=filepath, lineno=lineno)107 # After each file describing particular argument we add deny lines,108 # which were implicit. After non-specific we don't do that so the109 # default policy will not be shadowed.110 if argument != '*':111 self.handle_rule(self.rule_type.from_line_service(self,112 service, argument, '@anyvm @anyvm deny',113 filepath=path, lineno=None), filepath=path, lineno=None)114 self.handle_rule(self.rule_type.from_line_service(self,115 service, argument, '@anyvm @adminvm deny',116 filepath=path, lineno=None), filepath=path, lineno=None)117 def handle_rule(self, rule, *, filepath, lineno):118 ''''''119 return self.master.handle_rule(rule, filepath=filepath, lineno=lineno)120 def collect_targets_for_ask(self, request):121 return self.master.collect_targets_for_ask(request)122 def load_policy_file(self, file, filepath):123 ''''''124 raise RuntimeError('this method should not be called')125 def handle_compat40(self, *, filepath, lineno):126 ''''''127 raise PolicySyntaxError(filepath, lineno,128 '!compat-4.0 is not recursive')129class Compat40Loader(Compat40Parser):130 '''This parser should be used as helper for executing compatibility131 statement:132 >>> class MyParser(qrexec.policy.parser.AbstractPolicyParser):133 ... def handle_compat40(self, *, filepath, lineno):134 ... subparser = Compat40Parser(master=self)135 ... subparser.execute(filepath=filepath, lineno=lineno)136 '''137 def __init__(self, *, legacy_path=POLICYPATH_OLD, **kwds):138 super().__init__(**kwds)139 self.legacy_path = pathlib.Path(legacy_path)140 def resolve_path(self, included_path):141 ''''''142 return (self.legacy_path / included_path).resolve()143 def walk_includes(self):144 ''''''145 yield from walk_compat_files(self.legacy_path)146class TestCompat40Loader(Compat40Loader, parser.TestLoader):147 '''Used for tests. See :py:class:`qrexec.policy.parser.TestPolicy`.'''148 def walk_includes(self):149 ''''''...
install_uninstall.py
Source:install_uninstall.py
1from __future__ import print_function2from __future__ import unicode_literals3import io4import itertools5import logging6import os.path7import shutil8import sys9from pre_commit import git10from pre_commit import output11from pre_commit.clientlib import load_config12from pre_commit.repository import all_hooks13from pre_commit.repository import install_hook_envs14from pre_commit.util import cmd_output15from pre_commit.util import make_executable16from pre_commit.util import mkdirp17from pre_commit.util import resource_text18logger = logging.getLogger(__name__)19# This is used to identify the hook file we install20PRIOR_HASHES = (21 '4d9958c90bc262f47553e2c073f14cfe',22 'd8ee923c46731b42cd95cc869add4062',23 '49fd668cb42069aa1b6048464be5d395',24 '79f09a650522a87b0da915d0d983b2de',25 'e358c9dae00eac5d06b38dfdb1e33a8c',26)27CURRENT_HASH = '138fd403232d2ddd5efb44317e38bf03'28TEMPLATE_START = '# start templated\n'29TEMPLATE_END = '# end templated\n'30def _hook_paths(hook_type):31 pth = os.path.join(git.get_git_dir(), 'hooks', hook_type)32 return pth, '{}.legacy'.format(pth)33def is_our_script(filename):34 if not os.path.exists(filename): # pragma: windows no cover (symlink)35 return False36 with io.open(filename) as f:37 contents = f.read()38 return any(h in contents for h in (CURRENT_HASH,) + PRIOR_HASHES)39def shebang():40 if sys.platform == 'win32':41 py = 'python'42 else:43 # Homebrew/homebrew-core#35825: be more timid about appropriate `PATH`44 path_choices = [p for p in os.defpath.split(os.pathsep) if p]45 exe_choices = [46 'python{}'.format('.'.join(str(v) for v in sys.version_info[:i]))47 for i in range(3)48 ]49 for path, exe in itertools.product(path_choices, exe_choices):50 if os.path.exists(os.path.join(path, exe)):51 py = exe52 break53 else:54 py = 'python'55 return '#!/usr/bin/env {}'.format(py)56def install(57 config_file, store,58 overwrite=False, hooks=False, hook_type='pre-commit',59 skip_on_missing_conf=False,60):61 """Install the pre-commit hooks."""62 if cmd_output('git', 'config', 'core.hooksPath', retcode=None)[1].strip():63 logger.error(64 'Cowardly refusing to install hooks with `core.hooksPath` set.\n'65 'hint: `git config --unset-all core.hooksPath`',66 )67 return 168 hook_path, legacy_path = _hook_paths(hook_type)69 mkdirp(os.path.dirname(hook_path))70 # If we have an existing hook, move it to pre-commit.legacy71 if os.path.lexists(hook_path) and not is_our_script(hook_path):72 shutil.move(hook_path, legacy_path)73 # If we specify overwrite, we simply delete the legacy file74 if overwrite and os.path.exists(legacy_path):75 os.remove(legacy_path)76 elif os.path.exists(legacy_path):77 output.write_line(78 'Running in migration mode with existing hooks at {}\n'79 'Use -f to use only pre-commit.'.format(legacy_path),80 )81 params = {82 'CONFIG': config_file,83 'HOOK_TYPE': hook_type,84 'INSTALL_PYTHON': sys.executable,85 'SKIP_ON_MISSING_CONFIG': skip_on_missing_conf,86 }87 with io.open(hook_path, 'w') as hook_file:88 contents = resource_text('hook-tmpl')89 before, rest = contents.split(TEMPLATE_START)90 to_template, after = rest.split(TEMPLATE_END)91 before = before.replace('#!/usr/bin/env python3', shebang())92 hook_file.write(before + TEMPLATE_START)93 for line in to_template.splitlines():94 var = line.split()[0]95 hook_file.write('{} = {!r}\n'.format(var, params[var]))96 hook_file.write(TEMPLATE_END + after)97 make_executable(hook_path)98 output.write_line('pre-commit installed at {}'.format(hook_path))99 # If they requested we install all of the hooks, do so.100 if hooks:101 install_hooks(config_file, store)102 return 0103def install_hooks(config_file, store):104 install_hook_envs(all_hooks(load_config(config_file), store), store)105def uninstall(hook_type='pre-commit'):106 """Uninstall the pre-commit hooks."""107 hook_path, legacy_path = _hook_paths(hook_type)108 # If our file doesn't exist or it isn't ours, gtfo.109 if not os.path.exists(hook_path) or not is_our_script(hook_path):110 return 0111 os.remove(hook_path)112 output.write_line('{} uninstalled'.format(hook_type))113 if os.path.exists(legacy_path):114 os.rename(legacy_path, hook_path)115 output.write_line('Restored previous hooks to {}'.format(hook_path))...
Looking for an in-depth tutorial around pytest? LambdaTest covers the detailed pytest tutorial that has everything related to the pytest, from setting up the pytest framework to automation testing. Delve deeper into pytest testing by exploring advanced use cases like parallel testing, pytest fixtures, parameterization, executing multiple test cases from a single file, and more.
Skim our below pytest tutorial playlist to get started with automation testing using the pytest framework.
https://www.youtube.com/playlist?list=PLZMWkkQEwOPlcGgDmHl8KkXKeLF83XlrP
Get 100 minutes of automation test minutes FREE!!