Best Python code snippet using pytest-benchmark
SConscript
Source:SConscript  
1import os2import subprocess3import sys4import platform5import atexit6import time7import SCons.Util8# because of an implementation detail commandlines are limited to 10000 characters on windows using mingw. the following fix was copied from9# http://scons.org/wiki/LongCmdLinesOnWin32 and circumvents this issue.10class ourSpawn:11	def ourspawn(self, sh, escape, cmd, args, env):12		newargs = ' '.join(args[1:])13		cmdline = cmd + " " + newargs14		startupinfo = subprocess.STARTUPINFO()15		startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW16		proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,17			stderr=subprocess.PIPE, startupinfo=startupinfo, shell=False, env=env)18		data, err = proc.communicate()19		rv = proc.wait()20		if rv:21			print("=====")22			print(err)23			print("=====")24		return rv25def SetupSpawn(env):26	buf = ourSpawn()27	buf.ourenv = env28	env['SPAWN'] = buf.ourspawn29def FatalError(message):30	print(message)31	raise SystemExit(1)32#wrapper around SCons' AddOption33def AddSconsOption(name, default, hasArgs, help):34	AddOption("--{0}".format(name), dest=name, action=("store" if hasArgs else "store_true"), default=default, help=help)35AddSconsOption('win', False, False, "Target Windows.")36AddSconsOption('lin', False, False, "Target Linux.")37AddSconsOption('mac', False, False, "Target Mac OS X.")38AddSconsOption('msvc', False, False, "Use the Microsoft Visual Studio compiler.")39AddSconsOption("tool", False, True, "Tool prefix appended before gcc/g++.")40AddSconsOption('beta', False, False, "Beta build.")41AddSconsOption('save-version', False, True, "Save version.")42AddSconsOption('minor-version', False, True, "Minor version.")43AddSconsOption('build-number', False, True, "Build number.")44AddSconsOption('snapshot', False, False, "Snapshot build.")45AddSconsOption('snapshot-id', False, True, "Snapshot build ID.")46AddSconsOption('64bit', False, False, "Compile a 64 bit binary.")47AddSconsOption('32bit', False, False, "Compile a 32 bit binary.")48AddSconsOption("universal", False, False, "compile universal binaries on Mac OS X.")49AddSconsOption('no-sse', False, False, "Disable SSE optimizations.")50AddSconsOption('sse', True, False, "Enable SSE optimizations (default).")51AddSconsOption('sse2', True, False, "Enable SSE2 optimizations (default).")52AddSconsOption('sse3', False, False, "Enable SSE3 optimizations.")53AddSconsOption('native', False, False, "Enable optimizations specific to your cpu.")54AddSconsOption('release', False, False, "Enable loop / compiling optimizations.")55AddSconsOption('debugging', False, False, "Compile with debug symbols.")56AddSconsOption('symbols', False, False, "Preserve (don't strip) symbols")57AddSconsOption('static', False, False, "Compile statically.")58AddSconsOption('opengl', False, False, "Build with OpenGL interface support.")59AddSconsOption('opengl-renderer', False, False, "Build with OpenGL renderer support (turns on --opengl).") #Note: this has nothing to do with --renderer, only tells the game to render particles with opengl60AddSconsOption('renderer', False, False, "Build the save renderer.")61AddSconsOption('font', False, False, "Build the font editor.")62AddSconsOption('wall', False, False, "Error on all warnings.")63AddSconsOption('no-warnings', False, False, "Disable all compiler warnings.")64AddSconsOption('nolua', False, False, "Disable Lua.")65AddSconsOption('luajit', False, False, "Enable LuaJIT")66AddSconsOption('lua52', False, False, "Compile using lua 5.2")67AddSconsOption('nofft', False, False, "Disable FFT.")68AddSconsOption("output", False, True, "Executable output name.")69#detect platform automatically, but it can be overrided70tool = GetOption('tool')71isX86 = platform.machine() in ["amd64", "AMD64", "i386", "i686", "x86", "x86_64"]72platform = compilePlatform = platform.system()73if GetOption('win'):74	platform = "Windows"75elif GetOption('lin'):76	platform = "Linux"77elif GetOption('mac'):78	platform = "Darwin"79elif compilePlatform not in ["Linux", "Windows", "Darwin", "FreeBSD"]:80	FatalError("Unknown platform: {0}".format(platform))81msvc = GetOption('msvc')82if msvc and platform != "Windows":83	FatalError("Error: --msvc only works on windows")84#Create SCons Environment85if GetOption('msvc'):86	env = Environment(tools=['default'], ENV=os.environ, TARGET_ARCH='x86')87elif platform == "Windows" and not GetOption('msvc'):88	env = Environment(tools=['mingw'], ENV=os.environ)89else:90	env = Environment(tools=['default'], ENV=os.environ)91#attempt to automatically find cross compiler92if not tool and compilePlatform == "Linux" and compilePlatform != platform:93	if platform == "Darwin":94		crossList = ["i686-apple-darwin9", "i686-apple-darwin10"]95	elif not GetOption('64bit'):96		crossList = ["mingw32", "i686-w64-mingw32", "i386-mingw32msvc", "i486-mingw32msvc", "i586-mingw32msvc", "i686-mingw32msvc"]97	else:98		crossList = ["x86_64-w64-mingw32", "amd64-mingw32msvc"]99	for i in crossList:100		#found a cross compiler, set tool here, which will update everything in env later101		if WhereIs("{0}-g++".format(i)):102			tool = i+"-"103			break104	if not tool:105		print("Could not automatically find cross compiler, use --tool to specify manually")106#set tool prefix107#more things may need to be set (http://clam-project.org/clam/trunk/CLAM/scons/sconstools/crossmingw.py), but this works for us108if tool:109	env['CC'] = tool+env['CC']110	env['CXX'] = tool+env['CXX']111	if platform == "Windows":112		env['RC'] = tool+env['RC']113	env['STRIP'] = tool+'strip'114	if os.path.isdir("/usr/{0}/bin".format(tool[:-1])):115		env['ENV']['PATH'] = "/usr/{0}/bin:{1}".format(tool[:-1], os.environ['PATH'])116	if platform == "Darwin":117		sdlconfigpath = "/usr/lib/apple/SDKs/MacOSX10.5.sdk/usr/bin"118		if os.path.isdir(sdlconfigpath):119			env['ENV']['PATH'] = "{0}:{1}".format(sdlconfigpath, env['ENV']['PATH'])120#copy environment variables because scons doesn't do this by default121for var in ["CC","CXX","LD","LIBPATH","STRIP"]:122	if var in os.environ:123		env[var] = os.environ[var]124		print("copying environment variable {0}={1!r}".format(var,os.environ[var]))125# variables containing several space separated things126for var in ["CFLAGS","CCFLAGS","CXXFLAGS","LINKFLAGS","CPPDEFINES","CPPPATH"]:127	if var in os.environ:128		if var in env:129			env[var] += SCons.Util.CLVar(os.environ[var])130		else:131			env[var] = SCons.Util.CLVar(os.environ[var])132		print("copying environment variable {0}={1!r}".format(var,os.environ[var]))133#Used for intro text / executable name, actual bit flags are only set if the --64bit/--32bit command line args are given134def add32bitflags(env):135	env["BIT"] = 32136def add64bitflags(env):137	if platform == "Windows":138		env.Append(CPPDEFINES=['__CRT__NO_INLINE'])139		env.Append(LINKFLAGS=['-Wl,--stack=16777216'])140	env.Append(CPPDEFINES=['_64BIT'])141	env["BIT"] = 64142#add 32/64 bit defines before configuration143if GetOption('64bit'):144	env.Append(LINKFLAGS=['-m64'])145	env.Append(CCFLAGS=['-m64'])146	add64bitflags(env)147elif GetOption('32bit'):148	env.Append(LINKFLAGS=['-m32'])149	env.Append(CCFLAGS=['-m32'])150	add32bitflags(env)151if GetOption('universal'):152	if platform != "Darwin":153		FatalError("Error: --universal only works on Mac OS X")154	else:155		env.Append(CCFLAGS=['-arch', 'i386', '-arch', 'x86_64'])156		env.Append(LINKFLAGS=['-arch', 'i386', '-arch', 'x86_64'])157env.Append(CPPPATH=['src/', 'data/', 'generated/'])158if GetOption("msvc"):159	if GetOption("static"):160		env.Append(LIBPATH=['StaticLibs/'])161	else:162		env.Append(LIBPATH=['Libraries/'])163	env.Append(CPPPATH=['includes/'])164#Check 32/64 bit165def CheckBit(context):166	context.Message('Checking if 64 bit... ')167	program = """#include <stdlib.h>168	#include <stdio.h>169	int main() {170		printf("%d", (int)sizeof(size_t));171		return 0;172	}173	"""174	ret = context.TryCompile(program, '.c')175	if ret == 0:176		return False177	ret = context.TryRun(program, '.c')178	if ret[1] == '':179		return False180	context.Result(int(ret[1]) == 8)181	if int(ret[1]) == 8:182		print("Adding 64 bit compile flags")183		add64bitflags(context.env)184	elif int(ret[1]) == 4:185		print("Adding 32 bit compile flags")186		add32bitflags(context.env)187	return ret[1]188#Custom function to check for Mac OS X frameworks189def CheckFramework(context, framework):190	import SCons.Conftest191	#Extreme hack, TODO: maybe think of a better one (like replicating CheckLib here) or at least just fix the message192	oldLinkFlags = env["LINKFLAGS"]193	context.env.Append(LINKFLAGS=["-framework", framework])194	context.Display("Checking for Darwin Framework {0}...".format(framework))195	ret = SCons.Conftest.CheckLib(context, ["m"], autoadd = 0)196	context.did_show_result = 1197	if not ret:198		context.env.Append(LINKFLAGS=["-framework", framework])199		if framework != "Cocoa":200			env.Append(CPPPATH=['/Library/Frameworks/{0}.framework/Headers/'.format(framework)])201	else:202		context.env.Replace(LINKFLAGS=oldLinkFlags)203	return not ret204#function that finds libraries and appends them to LIBS205def findLibs(env, conf):206	#Windows specific libs207	if platform == "Windows":208		if msvc:209			libChecks = ['shell32', 'wsock32', 'user32', 'Advapi32', 'ws2_32']210			if GetOption('static'):211				libChecks += ['imm32', 'version', 'Ole32', 'OleAut32']212			for i in libChecks:213				if not conf.CheckLib(i):214					FatalError("Error: some windows libraries not found or not installed, make sure your compiler is set up correctly")215		else:216			if not conf.CheckLib('mingw32') or not conf.CheckLib('ws2_32'):217				FatalError("Error: some windows libraries not found or not installed, make sure your compiler is set up correctly")218		if not GetOption('renderer') and not conf.CheckLib('SDL2main'):219			FatalError("libSDL2main not found or not installed")220	#Look for SDL221	runSdlConfig = platform == "Linux" or compilePlatform == "Linux" or platform == "FreeBSD"222	#if platform == "Darwin" and conf.CheckFramework("SDL"):223	#	runSdlConfig = False224	if not conf.CheckLib("SDL2"):225		FatalError("SDL2 development library not found or not installed")226	if runSdlConfig:227		try:228			env.ParseConfig('sdl2-config --cflags')229			if GetOption('static'):230				env.ParseConfig('sdl2-config --static-libs')231			else:232				env.ParseConfig('sdl2-config --libs')233		except:234			pass235	#look for SDL.h236	if conf.CheckCHeader('SDL2/SDL.h'):237		env.Append(CPPDEFINES=["SDL_INC"])238	elif not conf.CheckCHeader('SDL.h'):239		FatalError("SDL.h not found")240	if not GetOption('nolua') and not GetOption('renderer') and not GetOption('font'):241		#Look for Lua242		if platform == "FreeBSD":243			luaver = "lua-5.1"244		else:245			luaver = "lua5.1"246		if GetOption('luajit'):247			if not conf.CheckLib(['luajit-5.1', 'luajit5.1', 'luajit2.0', 'luajit', 'libluajit']):248				FatalError("luajit development library not found or not installed")249			env.Append(CPPDEFINES=["LUAJIT"])250			luaver = "luajit"251		elif GetOption('lua52'):252			if not conf.CheckLib(['lua5.2', 'lua-5.2', 'lua52', 'lua']):253				FatalError("lua5.2 development library not found or not installed")254			env.Append(CPPDEFINES=["LUA_COMPAT_ALL"])255			if platform == "FreeBSD":256				luaver = "lua-5.2"257			else:258				luaver = "lua5.2"259		else:260			if not conf.CheckLib(['lua5.1', 'lua-5.1', 'lua51', 'lua']):261				if platform != "Darwin" or not conf.CheckFramework("Lua"):262					FatalError("lua5.1 development library not found or not installed")263		foundpkg = False264		if platform == "Linux" or platform == "FreeBSD":265			try:266				env.ParseConfig("pkg-config --cflags {0}".format(luaver))267				env.ParseConfig("pkg-config --libs {0}".format(luaver))268				env.Append(CPPDEFINES=["LUA_R_INCL"])269				foundpkg = True270			except:271				pass272		if not foundpkg:273			#Look for lua.h274			foundheader = False275			if GetOption('luajit'):276				foundheader = conf.CheckCHeader('luajit-2.0/lua.h')277			elif GetOption('lua52'):278				foundheader = conf.CheckCHeader('lua5.2/lua.h') or conf.CheckCHeader('lua52/lua.h')279			else:280				foundheader = conf.CheckCHeader('lua5.1/lua.h') or conf.CheckCHeader('lua51/lua.h')281			if not foundheader:282				if conf.CheckCHeader('lua.h'):283					env.Append(CPPDEFINES=["LUA_R_INCL"])284				else:285					FatalError("lua.h not found")286		#needed for static lua compiles (in some cases)287		if platform == "Linux":288			conf.CheckLib('dl')289	#Look for fftw290	if not GetOption('nofft') and not conf.CheckLib(['fftw3f', 'fftw3f-3', 'libfftw3f-3', 'libfftw3f']):291			FatalError("fftw3f development library not found or not installed")292	#Look for bz2293	if not conf.CheckLib(['bz2', 'libbz2']):294		FatalError("bz2 development library not found or not installed")295	#Check bz2 header too for some reason296	if not conf.CheckCHeader('bzlib.h'):297		FatalError("bzip2 headers not found")298	#Look for libz299	if not conf.CheckLib(['z', 'zlib']):300		FatalError("libz not found or not installed")301	#Look for pthreads302	if not conf.CheckLib(['pthread', 'pthreadVC2']):303		FatalError("pthreads development library not found or not installed")304	if msvc:305		if not conf.CheckHeader('dirent.h') or not conf.CheckHeader('fftw3.h') or not conf.CheckHeader('pthread.h') or not conf.CheckHeader('zlib.h'):306			FatalError("Required headers not found")307	else:308		#Look for libm309		if not conf.CheckLib('m'):310			FatalError("libm not found or not installed")311	#Look for OpenGL libraries312	if GetOption('opengl'):313		if platform == "Linux" or platform == "FreeBSD":314			if not conf.CheckLib('GL'):315				FatalError("libGL not found or not installed")316			try:317				env.ParseConfig('pkg-config --libs glew gl glu')318			except:319				FatalError(sys.exc_info()[0])320		elif platform == "Windows":321			if not conf.CheckLib('opengl32'):322				FatalError("opengl32 not found or not installed")323			if not conf.CheckLib('glew32'):324				FatalError("glew32 not found or not installed")325		elif platform == "Darwin":326			if not conf.CheckFramework("OpenGL"):327				FatalError("OpenGL framework not found or not installed")328	if platform == "Linux" or platform == "FreeBSD":329		if not conf.CheckLib('X11'):330			FatalError("X11 development library not found or not installed")331		if not conf.CheckLib('rt'):332			FatalError("librt not found or not installed")333	elif platform == "Windows":334		#These need to go last335		if not conf.CheckLib('gdi32') or not conf.CheckLib('winmm') or (not msvc and not conf.CheckLib('dxguid')):336			FatalError("Error: some windows libraries not found or not installed, make sure your compiler is set up correctly")337	elif platform == "Darwin":338		if not conf.CheckFramework("Cocoa"):339			FatalError("Cocoa framework not found or not installed")340if GetOption('clean'):341	import shutil342	try:343		shutil.rmtree("generated/")344	except:345		print("couldn't remove build/generated/")346elif not GetOption('help'):347	conf = Configure(env)348	conf.AddTest('CheckFramework', CheckFramework)349	conf.AddTest('CheckBit', CheckBit)350	if not conf.CheckCC() or not conf.CheckCXX():351		FatalError("compiler not correctly configured")352	if platform == compilePlatform and isX86 and not GetOption('32bit') and not GetOption('64bit') and not GetOption('msvc'):353		conf.CheckBit()354	findLibs(env, conf)355	env = conf.Finish()356if not msvc:357	env.Append(CXXFLAGS=['-std=c++11', '-U__STRICT_ANSI__'])358	env.Append(CXXFLAGS=['-Wno-invalid-offsetof'])359	if platform == "Linux":360		env.Append(CXXFLAGS=['-Wno-unused-result'])361#Add platform specific flags and defines362if platform == "Windows":363	env.Append(CPPDEFINES=["WIN", "_WIN32_WINNT=0x0501", "_USING_V110_SDK71_"])364	if msvc:365		env.Append(CCFLAGS=['/Gm', '/Zi', '/EHsc', '/FS', '/GS']) #enable minimal rebuild, ?, enable exceptions, allow -j to work in debug builds, enable security check366		if GetOption('renderer'):367			env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])368		else:369			env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS,"5.01"'])370		env.Append(LINKFLAGS=['/OPT:REF', '/OPT:ICF'])371		env.Append(CPPDEFINES=['_SCL_SECURE_NO_WARNINGS']) #Disable warnings about 'std::print'372		if GetOption('static'):373			env.Append(LINKFLAGS=['/NODEFAULTLIB:msvcrt.lib', '/LTCG'])374		elif not GetOption('debugging'):375			env.Append(LINKFLAGS=['/NODEFAULTLIB:msvcrtd.lib'])376	else:377		env.Append(LINKFLAGS=['-mwindows'])378elif platform == "Linux" or platform == "FreeBSD":379	env.Append(CPPDEFINES=['LIN'])380elif platform == "Darwin":381	env.Append(CPPDEFINES=['MACOSX'])382	#env.Append(LINKFLAGS=['-headerpad_max_install_names']) #needed in some cross compiles383	if GetOption('luajit'):384		env.Append(LINKFLAGS=['-pagezero_size', '10000', '-image_base', '100000000'])385#Add architecture flags and defines386if isX86:387	env.Append(CPPDEFINES='X86')388if not GetOption('no-sse'):389	if GetOption('sse'):390		if msvc:391			if not GetOption('sse2'):392				env.Append(CCFLAGS=['/arch:SSE'])393		else:394			env.Append(CCFLAGS=['-msse'])395		env.Append(CPPDEFINES=['X86_SSE'])396	if GetOption('sse2'):397		if msvc:398			env.Append(CCFLAGS=['/arch:SSE2'])399		else:400			env.Append(CCFLAGS=['-msse2'])401		env.Append(CPPDEFINES=['X86_SSE2'])402	if GetOption('sse3'):403		if msvc:404			FatalError("--sse3 doesn't work with --msvc")405		else:406			env.Append(CCFLAGS=['-msse3'])407		env.Append(CPPDEFINES=['X86_SSE3'])408if GetOption('native') and not msvc:409	env.Append(CCFLAGS=['-march=native'])410#Add optimization flags and defines411if GetOption('debugging'):412	if msvc:413		env.Append(CCFLAGS=['/Od'])414		if GetOption('static'):415			env.Append(CCFLAGS=['/MTd'])416		else:417			env.Append(CCFLAGS=['/MDd'])418	else:419		env.Append(CCFLAGS=['-Wall', '-g'])420		env.Append(CPPDEFINES=['DEBUG'])421elif GetOption('release'):422	if msvc:423		# Certain options (like /GL and /GS) cause TPT to be flagged as a virus. Don't include them424		env.Append(CCFLAGS=['/O2', '/Oy-', '/fp:fast'])425		if GetOption('static'):426			env.Append(CCFLAGS=['/MT'])427		else:428			env.Append(CCFLAGS=['/MD'])429	else:430		env.Append(CCFLAGS=['-O3', '-ftree-vectorize', '-funsafe-math-optimizations', '-ffast-math', '-fomit-frame-pointer'])431		if platform != "Darwin":432			env.Append(CCFLAGS=['-funsafe-loop-optimizations'])433if GetOption('static'):434	if platform == "Windows":435		if compilePlatform == "Windows" and not msvc:436			env.Append(CPPDEFINES=['_PTW32_STATIC_LIB'])437		else:438			env.Append(CPPDEFINES=['PTW32_STATIC_LIB'])439		if msvc:440			env.Append(CPPDEFINES=['ZLIB_WINAPI'])441		else:442			env.Append(LINKFLAGS=['-Wl,-Bstatic'])443#Add other flags and defines444if not GetOption('nofft'):445	env.Append(CPPDEFINES=['GRAVFFT'])446if not GetOption('nolua') and not GetOption('renderer') and not GetOption('font'):447	env.Append(CPPDEFINES=['LUACONSOLE'])448if GetOption('opengl') or GetOption('opengl-renderer'):449	env.Append(CPPDEFINES=['OGLI', 'PIX32OGL'])450	if GetOption('opengl-renderer'):451		env.Append(CPPDEFINES=['OGLR'])452if GetOption('renderer'):453	env.Append(CPPDEFINES=['RENDERER'])454if GetOption('font'):455	env.Append(CPPDEFINES=['FONTEDITOR'])456if GetOption("wall"):457	if msvc:458		env.Append(CCFLAGS=['/WX'])459	else:460		env.Append(CCFLAGS=['-Werror'])461elif GetOption("no-warnings"):462	if msvc:463		env.Append(CCFLAGS=['/W0'])464	else:465		env.Append(CCFLAGS=['-w'])466#Add version defines467if GetOption('save-version'):468	env.Append(CPPDEFINES=["SAVE_VERSION={0}".format(GetOption('save-version'))])469if GetOption('minor-version'):470	env.Append(CPPDEFINES=["MINOR_VERSION={0}".format(GetOption('minor-version'))])471if GetOption('build-number'):472	env.Append(CPPDEFINES=["BUILD_NUM={0}".format(GetOption('build-number'))])473if GetOption('snapshot-id'):474	env.Append(CPPDEFINES=["SNAPSHOT", "SNAPSHOT_ID={0}".format(GetOption('snapshot-id'))])475elif GetOption('snapshot'):476	env.Append(CPPDEFINES=["SNAPSHOT", "SNAPSHOT_ID={0}".format(str(int(time.time())))])477if GetOption('beta'):478	env.Append(CPPDEFINES=['BETA'])479#Generate list of sources to compile480sources = Glob("src/*.cpp") + Glob("src/*/*.cpp") + Glob("src/*/*/*.cpp") + Glob("generated/*.cpp") + Glob("data/*.cpp")481if not GetOption('nolua') and not GetOption('renderer') and not GetOption('font'):482	sources += Glob("src/lua/socket/*.c") + Glob("src/lua/LuaCompat.c")483if platform == "Windows":484	sources += env.RES('resources/powder-res.rc')485	if not msvc:486		sources = filter(lambda source: not 'src\\simulation\\Gravity.cpp' in str(source), sources)487		sources = filter(lambda source: not 'src/simulation/Gravity.cpp' in str(source), sources)488		envCopy = env.Clone()489		envCopy.Append(CCFLAGS='-mstackrealign')490		sources += envCopy.Object('src/simulation/Gravity.cpp')491#elif platform == "Darwin":492#	sources += ["src/SDLMain.m"]493#Program output name494if GetOption('output'):495	programName = GetOption('output')496else:497	programName = "powder"498	if GetOption('renderer'):499		programName = "render"500	if GetOption('font'):501		programName = "font"502	if "BIT" in env and env["BIT"] == 64:503		programName += "64"504	if isX86 and GetOption('no-sse'):505		programName += "-legacy"506	if platform == "Windows":507		programName = programName.capitalize()508		programName += ".exe"509	elif platform == "Darwin":510		programName += "-x"511#strip binary after compilation512def strip():513	global programName514	global env515	try:516		os.system("{0} {1}/{2}".format(env['STRIP'] if 'STRIP' in env else "strip", GetOption('builddir'), programName))517	except:518		print("Couldn't strip binary")519if not GetOption('debugging') and not GetOption('symbols') and not GetOption('clean') and not GetOption('help') and not msvc:520	atexit.register(strip)521#Long command line fix for mingw on windows522if compilePlatform == "Windows" and not msvc:523	SetupSpawn(env)524#Once we get here, finally compile525env.Decider('MD5-timestamp')526SetOption('implicit_cache', 1)527t = env.Program(target=programName, source=sources)...doPlotUtils.py
Source:doPlotUtils.py  
1#!/usr/bin/env python2####################################3#4# doPlotUtils.py5#6# generic Plotting script, with importable doPlot function7#8# Laurie McClymont - UCL9# Written ~ August 201610#11###################################12import os, sys, time, argparse, copy, glob13from array import array14from math import sqrt, log, isnan, isinf15from os import path16import ROOT17from ROOT import gROOT, gStyle18gROOT.ProcessLine("gErrorIgnoreLevel > 2000;")19gStyle.SetOptTitle( 0 )20import AtlasStyle21AtlasStyle.SetAtlasStyle()22verbose=False23quiet=False24def root_colours(input):25  if input=='Red':           output=ROOT.kRed26  elif input=='Green':       output=ROOT.kGreen27  elif input=='Yellow':      output=ROOT.kYellow28  elif input=='Blue':        output=ROOT.kBlue29  elif input=='Magenta':     output=ROOT.kMagenta30  elif input=='Cyan':        output=ROOT.kCyan31  elif input=='DarkCyan':    output=ROOT.kCyan+132  elif input=='DarkGreen':   output=ROOT.kGreen+233  elif input=='Orange':      output=ROOT.kOrange34  elif input=='Black':       output=ROOT.kBlack35  elif input=='Gray':        output=ROOT.kGray36  elif input=='Grey':        output=ROOT.kGray37  elif input=='White':       output=ROOT.kWhite38  elif input=='DarkGrey':    output=ROOT.kGray+239  elif input=='Violet':      output=ROOT.kViolet+140  else:    output=int(input)41  return output42def root_markerStyles(input):43  if input=='Circle':44    output=2045  elif input=='Square':46    output=2147  elif input=='Triangle':48    output=2249  elif input=='circle':50    output=2451  elif input=='square':52    output=2553  elif input=='triangle':54    output=2655  else:56    output=int(input)57  return output58def root_fillStyles(inputRaw):59  60  try:61    input=inputRaw.lower()62  except:63    input=inputRaw64  65  if input=="solid":66    output=100167  elif input=="heavydots":68    output=3001  69  elif (input=="mediumdots" or input=="dots"):70    output=3002  71  elif input=="lightdots":72    output=3002  73    74  else:75    output=int(inputRaw)76  return output77def getListsFromString(string):78  # Make 2 comma safe79  string.replace(',,',',')80  #print "Doing make string safe"81  Lists = []82  for List in string.split(","):83    Lists.append(List.split(":"))84  return Lists85def getOptionMapFromString(optionString, verbose=False): 86    optionMap={}87    optionLists=getListsFromString(optionString)88    for optionList in optionLists:89      try:90        optionMap[optionList[0]]=optionList[1].replace("\comma",",")91      except:92        raise SystemError("doPlot: optionMap problem, optionList:", optionList)93      if(verbose): print "  ", optionList[0], ":", optionList[1]94    return optionMap95defaultOptionString="Type:Hist,nPads:2,Logx:0,Logy:0,colour:Black,pad1DrawOption:,pad2DrawOption:,atlasLabel:Internal,atlasLabelPos:0.2-0.85,plotStringPos:0.2-0.7-0.9,plotName:test"96defaultOptionString+=",yTitle:Frequency,yTitleSize:0.06,yTitleOffset:1,xTitleSize:0.05,xTitleOffset:0.02"97defaultOptionString+=",ratio_yTitle:Ratio,ratio_yTitleSize:0.13,ratio_yTitleOffset:0.5,ratio_xTitleSize:0.15,ratio_xTitleOffset:0.9"98defaultOptionString+=",ratio_xLabelSize:0.1,ratio_yLabelSize:0.1,ratio_yLabelDivisions:5-0-5"99defaultOptionString+=",pad:1,legendPos:0.6-0.7-0.9-0.9,plotSuffix:pdf-C-png,verbose:0,newRightMargin:1"100if(verbose): print101if(verbose): print "Default Settings for map"102defaultOptionMap=getOptionMapFromString(defaultOptionString)103def getOption(option, optionMap):104    try:105        ret = optionMap[option]106    except:107        try:     ret=defaultOptionMap[option]108        except:  ret = 0109    if ret=="0":  return 0110    return ret111def openHistsAndStrings(histsAndStrings, verbose=False):112  histsAndMaps=[]113  114  for histAndString in histsAndStrings:115    histAndMap=[]116    histAndMap.append(histAndString[0])117    histAndMap.append(getOptionMapFromString(histAndString[1]))118    histsAndMaps.append(histAndMap)119  return histsAndMaps120def setupCanvas(opts):121  ## Setup Canvas ##122  canvName="c"123  canv = ROOT.TCanvas(canvName,canvName,60,50,800,600)124  #canv = ROOT.TCanvas()125  canv.Clear()126  canv.cd()127  128  pad1 = ROOT.TPad("pad1","pad1",0,0.3,1,1)129  pad2 = ROOT.TPad("pad2","pad2",0,0.01,1,0.37)130  if(int(getOption('newRightMargin',opts)) > 0 ):131    pad1.SetRightMargin(0.1)132    pad2.SetRightMargin(0.1)133  pad1.Draw()134  pad2.Draw()135    136  if(getOption('verbose',opts)): print "nPads:", getOption("nPads",opts)137  if int( getOption("nPads",opts) ) > 1:138    pad2.SetTopMargin(0.03)139    pad2.SetBottomMargin(0.35) 140    pad1.Draw()141    pad2.Draw()142    pad2.SetGridx()143    pad2.SetGridy()144  else:145    pad1.SetPad(0,0,1,1)146    pad1.Draw()147  pad1.cd()148  if int(getOption("Logx",opts)) > 0:149    pad1.SetLogx()150    pad2.SetLogx()151    if(getOption('verbose',opts)): print "  Setting Logx"152  if int(getOption("Logy",opts)) > 0:153    pad1.SetLogy()154    if(getOption('verbose',opts)): print "  Setting Logy"155  if int(getOption("Logz",opts)) > 0:156    pad1.SetLogz()157    if(getOption('verbose',opts)): print "  Setting Logz"158  if int(getOption("Gridx",opts)) > 0:159    pad1.SetGridx()160    if(getOption('verbose',opts)): print "  Setting Gridx"161  if int(getOption("Gridy",opts)) > 0:162    pad1.SetGridy()163    if(getOption('verbose',opts)): print "  Setting Gridy"164  if getOption("legend",opts):165    legendPos=getOption("legendPos",opts).split("-")166    legend=ROOT.TLegend( float(legendPos[0]), float(legendPos[1]), float(legendPos[2]), float(legendPos[3]) )167    if getOption("legendFillColour",opts)!=0:168      legend.SetFillColor(int(getOption("legendFillColour",opts)))169    else:170      legend.SetFillStyle(0)171    172    if getOption("legendTextSize",opts)!=0:173      legend.SetTextSize(float(getOption("legendTextSize",opts)))174    else:175      legend.SetTextSize(0.04)176    if getOption("legendColumns",opts):177      legend.SetNColumns(int(getOption("legendColumns",opts)))178    179    opts["legend"]=legend180    if(getOption('verbose',opts)): print " Added a legend"181  return canv, pad1, pad2182def setupHist(histAndMap,opts):183  hist=histAndMap[0]184  map=histAndMap[1]185  if(getOption('verbose',opts)): print186  if(getOption('verbose',opts)): print "Setting options for histMap", hist.GetName()187  188  if( getOption("type",map)=="Function"):189      hist=histAndMap[0].GetHistogram()190  #if( getOption("type",map)=="graph"):191  #    hist=histAndMap[0].GetHistogram()192  193  xRange=getOption("xRange",opts)194  if xRange!=0:195    if ";" in xRange:196      xLow=xRange.split(";")[0]197      xUp=xRange.split(";")[1]198    else:199      xLow=xRange.split("-")[0]200      xUp=xRange.split("-")[1]201    hist.GetXaxis().SetRangeUser( float(xLow), float(xUp) )202    if(getOption('verbose',opts)): print "Setting xRange to be", str(xLow)+"-"+str(xUp)203    204  yRange=getOption("yRange",map)205  if yRange==0:206    yRange=getOption("yRange",opts)    207  if yRange!=0:208    if ";" in yRange:209      yLow=yRange.split(";")[0]210      yUp=yRange.split(";")[1]211    else:212      yLow=yRange.split("-")[0]213      yUp=yRange.split("-")[1]214    if( getOption("type",map)!="graph"):215      hist.GetYaxis().SetRangeUser( float(yLow), float(yUp) )216    else:217      hist.GetHistogram().SetMinimum( float(yLow) )218      hist.GetHistogram().SetMaximum( float(yUp)  )219    if(getOption('verbose',opts)): print "Setting yRange to be", yRange220  elif (int(getOption("Logy",opts)) > 0) and (int( getOption("pad",map) )==1):221    yLow=max(0.5,hist.GetMinimum()/20)222    yUp=hist.GetMaximum()*100223    hist.GetYaxis().SetRangeUser( float(yLow), float(yUp) )224    if(getOption('verbose',opts)): print "Setting yRange to be", str(yLow)+"-"+str(yUp)225  hist.SetLineColor( root_colours(getOption("colour",map) ) )226  hist.SetMarkerColor( root_colours(getOption("colour",map) ) )227  hist.SetMarkerStyle(root_markerStyles(getOption("markerStyle",map) ) )228  if getOption("fillColour",map): fillColour=root_colours(getOption("fillColour",map) )                                                    229  else:                           fillColour=root_colours(getOption("colour",map) )230  hist.SetFillColor(fillColour)231  hist.SetFillStyle( root_fillStyles(getOption("fillStyle",map) ) )232  233  if(getOption('verbose',opts)): print "Setting colour to ", getOption("colour",map)234  if(getOption('verbose',opts)): print "Setting fillColour to ", fillColour235  if(getOption('verbose',opts)): print "Setting markerStyle to ", getOption("markerStyle",map)236  if(getOption('verbose',opts)): print "Setting fillStyle to ", getOption("fillStyle",map)237  ##print "=> hist.SetFillStyle("+str(root_fillStyles(getOption("fillStyle",map) ) )+"), from "+str(getOption("fillStyle",map))238  239  # Check if first histogram for pad240  if int( getOption("pad",map) )==1:241    drawOption=getOption("pad1DrawOption",opts)242    pad=""243  elif int( getOption("pad",map) )==2:244    drawOption=getOption("pad2DrawOption",opts)245    pad="ratio_"246  #If first histogram247  if "same" not in drawOption:248    hist.GetXaxis().SetMoreLogLabels() # Always249    250    #Set Titles251    if  getOption("yTitle",map) != "Frequency" and getOption("yTitle",map) != 0:252      hist.GetYaxis().SetTitle(getOption("yTitle",map))    253    elif getOption(pad+"yTitle",opts) != 0:254      hist.GetYaxis().SetTitle(getOption(pad+"yTitle",opts))255    if ( int(getOption("nPads",opts)) == int( getOption("pad",map) )): 256      if getOption("xTitle",opts)!=0:257        hist.GetXaxis().SetTitle(getOption("xTitle",opts))258        if(getOption('verbose',opts)): print "xTitle:", getOption("xTitle",opts), "in pad",getOption("pad",map)259    #if getOption(pad+"xTitle",opts)!=0:260    #  hist.GetXaxis().SetTitle(getOption(pad+"xTitle",opts))261    if getOption(pad+"yTitleSize",opts)!=0:262      hist.GetYaxis().SetTitleSize(float(getOption(pad+"yTitleSize",opts)))263    if getOption(pad+"xTitleSize",opts)!=0:264      hist.GetXaxis().SetTitleSize(float(getOption(pad+"xTitleSize",opts)))265    if getOption(pad+"yTitleOffset",opts)!=0:266      hist.GetYaxis().SetTitleOffset(float(getOption(pad+"yTitleOffset",opts)))267    if getOption(pad+"xTitleOffset",opts)!=0:268      hist.GetXaxis().SetTitleOffset(float(getOption(pad+"xTitleOffset",opts)))269    #Set for labels270    if getOption(pad+"yLabelSize",opts)!=0:271      hist.GetYaxis().SetLabelSize(float(getOption(pad+"yLabelSize",opts)))272    if getOption(pad+"xLabelSize",opts)!=0:273      hist.GetXaxis().SetLabelSize(float(getOption(pad+"xLabelSize",opts)))274    if getOption(pad+"yLabelOffset",opts)!=0:275      hist.GetYaxis().SetLabelOffset(float(getOption(pad+"yLabelOffset",opts)))276    if getOption(pad+"xLabelOffset",opts)!=0:277      hist.GetXaxis().SetLabelOffset(float(getOption(pad+"xLabelOffset",opts)))278    if getOption(pad+"yLabelDivisions",opts)!=0:279      ndivisions=getOption(pad+"yLabelDivisions",opts).split('-')280      hist.GetYaxis().SetNdivisions(int(ndivisions[0]),int(ndivisions[1]),int(ndivisions[2]))281    if getOption(pad+"xLabelDivisions",opts)!=0:282      ndivisions=getOption(pad+"xLabelDivisions",opts).split('-')283      hist.GetXaxis().SetNdivisions(int(ndivisions[0]),int(ndivisions[1]),int(ndivisions[2]))284      285        286  histAndMap[0]=hist287def drawHist(histAndMap,opts,pad1,pad2):288  hist=histAndMap[0]289  map=histAndMap[1]290  drawOption=""291        292  if int( getOption("pad",map) )==1:293    drawOption=getOption("pad1DrawOption",opts)294    opts["pad1DrawOption"]="same"295    pad1.cd()296  elif int( getOption("pad",map) )==2:297    drawOption=getOption("pad2DrawOption",opts)298    opts["pad2DrawOption"]="same"299    pad2.cd()300  else:301    if(getOption('verbose',opts)): print "Don't know which pad to put", hist.GetName()302    return303  if getOption("drawOption",map):304    drawOption+=getOption("drawOption",map)305  306  hist.Draw(drawOption)307  308  ############309  ##Add to legend310  legOption="epl"311  if getOption("fillStyle",map):312    legOption="fepl"313  if getOption("legend",opts) and getOption("legend",map):314    opts["legend"].AddEntry(hist, getOption("legend",map), legOption)315    if(getOption('verbose',opts)): print " Added to legend"316    317  histAndMap[1]=map318  if(getOption('verbose',opts)): print "  Drawn hist", hist.GetName(), "with drawOption", drawOption, "in pad", int( getOption("pad",map) )319  return320def finaliseCanvas(opts, canv, pad1, pad2):321  pad1.cd()322  if(getOption('verbose',opts)): print "Let's do finalise canvas"323  if getOption("atlasLabel",opts)!=0:324    labelPosX=float(getOption("atlasLabelPos",opts).split('-')[0])325    labelPosY=float(getOption("atlasLabelPos",opts).split('-')[1])326    if(getOption('verbose',opts)): print "labelPos ",labelPosX, labelPosY327    AtlasStyle.ATLAS_LABEL(labelPosX,labelPosY, 1, getOption("atlasLabel",opts))328    AtlasStyle.myText(labelPosX,(labelPosY-0.05),1,"#scale[0.9]{#sqrt{s} = 13 TeV}");329    if getOption("lumi",opts)!=0:330      #AtlasStyle.myText(labelPosX,(labelPosY-0.12),1,"#scale[0.9]{#int L dt = "+args.lumi+ " fb^{-1}}")331      if("24.5" in getOption("lumi",opts)): print " doPlot: Doing low mass lumi fix (24.5 -> 24.3)"332      lumi=getOption("lumi",opts).replace("24.5","24.3")333      AtlasStyle.myText(labelPosX,(labelPosY-0.1),1,"#scale[0.9]{"+lumi+" fb^{-1}}");334  gStyle.SetOptStat(0)335  legend=getOption("legend",opts)336  if legend:337    legend.Draw()338  #Add a string to the plot339  plotString=getOption("plotString",opts)340  if(getOption('verbose',opts)): print "plotString is", plotString341  if plotString!=0:342    plotStringList= plotString.split('+')343    plotStringPos=getOption("plotStringPos",opts).split('-')344    yPos = float(plotStringPos[1])  # Init position of y345    for string in plotStringList:346      #print "AtlasStyle.myText(0.65,",yPos,",1,","#scale[0.9]{"+string+"}",")"347      if(getOption('verbose',opts)): print "  -",string348      AtlasStyle.myText(float(plotStringPos[0]),yPos,1,"#scale["+plotStringPos[2]+"]{"+string+"}")349      yPos=yPos-0.05350      351def doPlot( histsAndStrings, optionString):352  verbose=False353  if("verbose:" in optionString): verbose=True354  355  #getDefault()356  if verbose: print357  if verbose: print " ******************  do Plot  **********************"358 359  if verbose: print "Getting histsAndStrings"360  histsAndMaps = openHistsAndStrings(histsAndStrings , verbose )361  362  if verbose: print "Getting general options"363  opts=getOptionMapFromString(optionString, verbose )364  (canv, pad1, pad2) = setupCanvas(opts)365  # Loop over hists366  for histAndMap in histsAndMaps:367    #Setup Hist368    setupHist(histAndMap,opts)369    #Draw Hist370    drawHist(histAndMap,opts,pad1,pad2)371  # Finalise Canvas (add text to plots, legends ect...)372  finaliseCanvas(opts, canv, pad1, pad2)373  # Create directory for plot if not already done374  plotDirName=getOption("plotName",opts).rsplit('/', 1)[0]375  if not os.path.isdir(plotDirName):376    os.makedirs(plotDirName)377  378  # Print Canvas379  suffixList=getOption("plotSuffix",opts).split("-")380  for suffix in suffixList:381    canv.Print(getOption("plotName",opts)+"."+suffix)382  print "  doPlot prints to "+getOption("plotName",opts)+"."+suffixList[0]383  if verbose: print " ****************************************************"384  385  386def main():387  print "Hello"388  389  histsAndStrings=[]390  optionString="Logx:0,nPads:2,plotString:Testing+Testing2,lumi:12,legend:YesPlease"391  file=ROOT.TFile.Open("Systematics2016/BJetTrig-00-03-05_full/BJetTriggerEfficiencies.root", "READ")392  print "****", file.GetName()393  testHist1=file.Get("eff_MC_offJets70_match_hlt70_jetPt")394  testHist2=file.Get("eff_Data_offJets70_match_hlt70_jetPt")395  print "****", testHist1.GetName()396  print "****", testHist2.GetName()397  histsAndStrings=[ [testHist1,"yRange:0-2,markerStyle:Circle,pad:1,legend:test1"], [testHist2,"colour:Red,pad:2,legend:test2"] ]398  doPlot(histsAndStrings,optionString)399if __name__ == "__main__":400  main()...conftest.py
Source:conftest.py  
...152        )153    return sim154@pytest.fixture(scope="session")155def exe_cmd(request):156    return request.config.getoption("--exe_cmd")157@pytest.fixture(scope="session")158def candidate_sim(request):159    domain_dir = request.config.getoption("--domain_dir")160    compiler = request.config.getoption("--compiler")161    candidate_dir = request.config.getoption("--candidate_dir")162    configuration = request.config.getoption("--config")163    option_suite = request.config.getoption("--option_suite")164    ncores = request.config.getoption("--ncores")165    nnodes = request.config.getoption("--nnodes")166    scheduler = request.config.getoption("--scheduler")167    account = request.config.getoption("--account")168    walltime = request.config.getoption("--walltime")169    queue = request.config.getoption("--queue")170    candidate_sim = _make_sim(171        domain_dir=domain_dir,172        compiler=compiler,173        source_dir=candidate_dir,174        configuration=configuration,175        option_suite=option_suite,176        ncores=ncores,177        nnodes=nnodes,178        scheduler=scheduler,179        account=account,180        walltime=walltime,181        queue=queue182    )183    return candidate_sim184# Since we want to leverage the NWM compiles (both candidate and reference, ptoentially),185# we create additional simulation fixtures where we hard-code the alternate configurations,186# those are "channel-only" and "nwm_output_ana", currently.187@pytest.fixture(scope="session")188def candidate_channel_only_sim(request):189    domain_dir = request.config.getoption("--domain_dir")190    compiler = request.config.getoption("--compiler")191    candidate_dir = request.config.getoption("--candidate_dir")192    option_suite = request.config.getoption("--option_suite")193    ncores = request.config.getoption("--ncores")194    nnodes = request.config.getoption("--nnodes")195    scheduler = request.config.getoption("--scheduler")196    account = request.config.getoption("--account")197    walltime = request.config.getoption("--walltime")198    queue = request.config.getoption("--queue")199    configuration = "nwm_channel-only"200    candidate_channel_only_sim = _make_sim(201        domain_dir=domain_dir,202        compiler=compiler,203        source_dir=candidate_dir,204        configuration=configuration,205        option_suite=option_suite,206        ncores=ncores,207        nnodes=nnodes,208        scheduler=scheduler,209        account=account,210        walltime=walltime,211        queue=queue212    )213    return candidate_channel_only_sim214@pytest.fixture(scope="session")215def candidate_nwm_output_sim(request):216    domain_dir = request.config.getoption("--domain_dir")217    compiler = request.config.getoption("--compiler")218    candidate_dir = request.config.getoption("--candidate_dir")219    option_suite = request.config.getoption("--option_suite")220    ncores = request.config.getoption("--ncores")221    nnodes = request.config.getoption("--nnodes")222    scheduler = request.config.getoption("--scheduler")223    account = request.config.getoption("--account")224    walltime = request.config.getoption("--walltime")225    queue = request.config.getoption("--queue")226    configuration = request.config.getoption("--config")227    if configuration == 'nwm_long_range':228        configuration = "nwm_output_long_range"229    else:230        configuration = "nwm_output_ana"231    candidate_nwm_output_sim = _make_sim(232        domain_dir=domain_dir,233        compiler=compiler,234        source_dir=candidate_dir,235        configuration=configuration,236        option_suite=option_suite,237        ncores=ncores,238        nnodes=nnodes,239        scheduler=scheduler,240        account=account,241        walltime=walltime,242        queue=queue243    )244    return candidate_nwm_output_sim245@pytest.fixture(scope="session")246def reference_sim(request):247    domain_dir = request.config.getoption("--domain_dir")248    compiler = request.config.getoption("--compiler")249    reference_dir = request.config.getoption("--reference_dir")250    configuration = request.config.getoption("--config")251    option_suite = request.config.getoption("--option_suite")252    ncores = request.config.getoption("--ncores")253    nnodes = request.config.getoption("--nnodes")254    scheduler = request.config.getoption("--scheduler")255    account = request.config.getoption("--account")256    walltime = request.config.getoption("--walltime")257    queue = request.config.getoption("--queue")258    reference_sim = _make_sim(259        domain_dir=domain_dir,260        compiler=compiler,261        source_dir=reference_dir,262        configuration=configuration,263        option_suite=option_suite,264        ncores=ncores,265        nnodes=nnodes,266        scheduler=scheduler,267        account=account,268        walltime=walltime,269        queue=queue270    )271    return reference_sim272# Since we want to leverage the NWM compiles (both candidate and reference, ptoentially),273# we create additional simulation fixtures where we hard-code the alternate configurations,274# those are "channel-only" and "nwm_output_ana", currently.275@pytest.fixture(scope="session")276def reference_nwm_output_sim(request):277    domain_dir = request.config.getoption("--domain_dir")278    compiler = request.config.getoption("--compiler")279    reference_dir = request.config.getoption("--reference_dir")280    option_suite = request.config.getoption("--option_suite")281    ncores = request.config.getoption("--ncores")282    nnodes = request.config.getoption("--nnodes")283    scheduler = request.config.getoption("--scheduler")284    account = request.config.getoption("--account")285    walltime = request.config.getoption("--walltime")286    queue = request.config.getoption("--queue")287    configuration = request.config.getoption("--config")288    if configuration == 'nwm_long_range':289        configuration = "nwm_output_long_range"290    else:291        configuration = "nwm_output_ana"292    reference_nwm_output_sim = _make_sim(293        domain_dir=domain_dir,294        compiler=compiler,295        source_dir=reference_dir,296        configuration=configuration,297        option_suite=option_suite,298        ncores=ncores,299        nnodes=nnodes,300        scheduler=scheduler,301        account=account,302        walltime=walltime,303        queue=queue304    )305    return reference_nwm_output_sim306@pytest.fixture(scope="session")307def output_dir(request):308    configuration = request.config.getoption("--config")309    output_dir = request.config.getoption("--output_dir")310    use_existing_test_dir = request.config.getoption("--use_existing_test_dir")311    output_dir = pathlib.Path(output_dir)312    output_dir = output_dir / configuration313    if not use_existing_test_dir:314        output_dir.mkdir(parents=True)315    return output_dir316@pytest.fixture(scope="session")317def ncores(request):318    return int(request.config.getoption("--ncores"))319@pytest.fixture(scope="session")320def xrcmp_n_cores(request):...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
