diff options
Diffstat (limited to 'infra/libkookie/nixpkgs/pkgs/development/interpreters/python')
12 files changed, 251 insertions, 50 deletions
diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/2.7/default.nix b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/2.7/default.nix index 2cfaa69a4c8b..e6ab1f218795 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/2.7/default.nix +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/2.7/default.nix @@ -18,12 +18,17 @@ , ucsEncoding ? 4 # For the Python package set , packageOverrides ? (self: super: {}) -, buildPackages +, pkgsBuildBuild +, pkgsBuildHost +, pkgsBuildTarget +, pkgsHostHost +, pkgsTargetTarget , sourceVersion , sha256 , passthruFun , static ? false , enableOptimizations ? (!stdenv.isDarwin) +, pythonAttr ? "python${sourceVersion.major}${sourceVersion.minor}" }: assert x11Support -> tcl != null @@ -34,8 +39,8 @@ assert x11Support -> tcl != null with stdenv.lib; let - - pythonForBuild = buildPackages.${"python${sourceVersion.major}${sourceVersion.minor}"}; + buildPackages = pkgsBuildHost; + inherit (passthru) pythonForBuild; passthru = passthruFun rec { inherit self sourceVersion packageOverrides; @@ -44,7 +49,12 @@ let executable = libPrefix; pythonVersion = with sourceVersion; "${major}.${minor}"; sitePackages = "lib/${libPrefix}/site-packages"; - inherit hasDistutilsCxxPatch pythonForBuild; + inherit hasDistutilsCxxPatch; + pythonOnBuildForBuild = pkgsBuildBuild.${pythonAttr}; + pythonOnBuildForHost = pkgsBuildHost.${pythonAttr}; + pythonOnBuildForTarget = pkgsBuildTarget.${pythonAttr}; + pythonOnHostForHost = pkgsHostHost.${pythonAttr}; + pythonOnTargetForTarget = pkgsTargetTarget.${pythonAttr} or {}; } // { inherit ucsEncoding; }; diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/3.10/no-ldconfig.patch b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/3.10/no-ldconfig.patch new file mode 100644 index 000000000000..c259aed72b99 --- /dev/null +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/3.10/no-ldconfig.patch @@ -0,0 +1,107 @@ +From 084c6dd6352077e64f10cf7aa168f95d800f3819 Mon Sep 17 00:00:00 2001 +From: Jonathan Ringer <jonringer117@gmail.com> +Date: Mon, 9 Nov 2020 10:24:35 -0800 +Subject: [PATCH] CPython: Don't use ldconfig + +--- + Lib/ctypes/util.py | 77 ++-------------------------------------------- + 1 file changed, 2 insertions(+), 75 deletions(-) + +diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py +index 0c2510e..7fb98af 100644 +--- a/Lib/ctypes/util.py ++++ b/Lib/ctypes/util.py +@@ -100,53 +100,7 @@ elif os.name == "posix": + return thefile.read(4) == elf_header + + def _findLib_gcc(name): +- # Run GCC's linker with the -t (aka --trace) option and examine the +- # library name it prints out. The GCC command will fail because we +- # haven't supplied a proper program with main(), but that does not +- # matter. +- expr = os.fsencode(r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)) +- +- c_compiler = shutil.which('gcc') +- if not c_compiler: +- c_compiler = shutil.which('cc') +- if not c_compiler: +- # No C compiler available, give up +- return None +- +- temp = tempfile.NamedTemporaryFile() +- try: +- args = [c_compiler, '-Wl,-t', '-o', temp.name, '-l' + name] +- +- env = dict(os.environ) +- env['LC_ALL'] = 'C' +- env['LANG'] = 'C' +- try: +- proc = subprocess.Popen(args, +- stdout=subprocess.PIPE, +- stderr=subprocess.STDOUT, +- env=env) +- except OSError: # E.g. bad executable +- return None +- with proc: +- trace = proc.stdout.read() +- finally: +- try: +- temp.close() +- except FileNotFoundError: +- # Raised if the file was already removed, which is the normal +- # behaviour of GCC if linking fails +- pass +- res = re.findall(expr, trace) +- if not res: +- return None +- +- for file in res: +- # Check if the given file is an elf file: gcc can report +- # some files that are linker scripts and not actual +- # shared objects. See bpo-41976 for more details +- if not _is_elf(file): +- continue +- return os.fsdecode(file) ++ return None + + + if sys.platform == "sunos5": +@@ -268,34 +222,7 @@ elif os.name == "posix": + else: + + def _findSoname_ldconfig(name): +- import struct +- if struct.calcsize('l') == 4: +- machine = os.uname().machine + '-32' +- else: +- machine = os.uname().machine + '-64' +- mach_map = { +- 'x86_64-64': 'libc6,x86-64', +- 'ppc64-64': 'libc6,64bit', +- 'sparc64-64': 'libc6,64bit', +- 's390x-64': 'libc6,64bit', +- 'ia64-64': 'libc6,IA-64', +- } +- abi_type = mach_map.get(machine, 'libc6') +- +- # XXX assuming GLIBC's ldconfig (with option -p) +- regex = r'\s+(lib%s\.[^\s]+)\s+\(%s' +- regex = os.fsencode(regex % (re.escape(name), abi_type)) +- try: +- with subprocess.Popen(['/sbin/ldconfig', '-p'], +- stdin=subprocess.DEVNULL, +- stderr=subprocess.DEVNULL, +- stdout=subprocess.PIPE, +- env={'LC_ALL': 'C', 'LANG': 'C'}) as p: +- res = re.search(regex, p.stdout.read()) +- if res: +- return os.fsdecode(res.group(1)) +- except OSError: +- pass ++ return None + + def _findLib_ld(name): + # See issue #9998 for why this is needed +-- +2.28.0 + diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/default.nix b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/default.nix index b25d613eb7f3..cd06c2b63670 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/default.nix +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/cpython/default.nix @@ -14,12 +14,16 @@ , self , configd , autoreconfHook +, autoconf-archive , python-setup-hook , nukeReferences # For the Python package set , packageOverrides ? (self: super: {}) -, buildPackages -, pythonForBuild ? buildPackages.${"python${sourceVersion.major}${sourceVersion.minor}"} +, pkgsBuildBuild +, pkgsBuildHost +, pkgsBuildTarget +, pkgsHostHost +, pkgsTargetTarget , sourceVersion , sha256 , passthruFun @@ -35,6 +39,7 @@ # Not using optimizations on Darwin # configure: error: llvm-profdata is required for a --enable-optimizations build but could not be found. , enableOptimizations ? (!stdenv.isDarwin) +, pythonAttr ? "python${sourceVersion.major}${sourceVersion.minor}" }: # Note: this package is used for bootstrapping fetchurl, and thus @@ -52,6 +57,8 @@ assert bluezSupport -> bluez != null; with stdenv.lib; let + buildPackages = pkgsBuildHost; + inherit (passthru) pythonForBuild; passthru = passthruFun rec { inherit self sourceVersion packageOverrides; @@ -60,13 +67,20 @@ let executable = libPrefix; pythonVersion = with sourceVersion; "${major}.${minor}"; sitePackages = "lib/${libPrefix}/site-packages"; - inherit hasDistutilsCxxPatch pythonForBuild; + inherit hasDistutilsCxxPatch; + pythonOnBuildForBuild = pkgsBuildBuild.${pythonAttr}; + pythonOnBuildForHost = pkgsBuildHost.${pythonAttr}; + pythonOnBuildForTarget = pkgsBuildTarget.${pythonAttr}; + pythonOnHostForHost = pkgsHostHost.${pythonAttr}; + pythonOnTargetForTarget = pkgsTargetTarget.${pythonAttr} or {}; }; version = with sourceVersion; "${major}.${minor}.${patch}${suffix}"; nativeBuildInputs = optionals (!stdenv.isDarwin) [ autoreconfHook + ] ++ optionals (!stdenv.isDarwin && passthru.pythonAtLeast "3.10") [ + autoconf-archive # needed for AX_CHECK_COMPILE_FLAG ] ++ [ nukeReferences ] ++ optionals (stdenv.hostPlatform != stdenv.buildPlatform) [ @@ -82,8 +96,6 @@ let hasDistutilsCxxPatch = !(stdenv.cc.isGNU or false); - inherit pythonForBuild; - pythonForBuildInterpreter = if stdenv.hostPlatform == stdenv.buildPlatform then "$out/bin/python" else pythonForBuild.interpreter; @@ -291,13 +303,6 @@ in with passthru; stdenv.mkDerivation { find $out -name "*.py" | ${pythonForBuildInterpreter} -OO -m compileall -q -f -x "lib2to3" -i - '' + optionalString stripBytecode '' find $out -type d -name __pycache__ -print0 | xargs -0 -I {} rm -rf "{}" - '' + '' - # *strip* shebang from libpython gdb script - it should be dual-syntax and - # interpretable by whatever python the gdb in question is using, which may - # not even match the major version of this python. doing this after the - # bytecode compilations for the same reason. - mkdir -p $out/share/gdb - sed '/^#!/d' Tools/gdb/libpython.py > $out/share/gdb/libpython.py ''; preFixup = stdenv.lib.optionalString (stdenv.hostPlatform != stdenv.buildPlatform) '' @@ -315,8 +320,6 @@ in with passthru; stdenv.mkDerivation { pythonForBuild buildPackages.bash ]; - separateDebugInfo = true; - inherit passthru; enableParallelBuilding = true; diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/default.nix b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/default.nix index 90b6e8ee0cb0..7c3f94dcd16e 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/default.nix +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/default.nix @@ -14,13 +14,70 @@ with pkgs; , packageOverrides , sitePackages , hasDistutilsCxxPatch - , pythonForBuild - , self + , pythonOnBuildForBuild + , pythonOnBuildForHost + , pythonOnBuildForTarget + , pythonOnHostForHost + , pythonOnTargetForTarget + , self # is pythonOnHostForTarget }: let - pythonPackages = callPackage ../../../top-level/python-packages.nix { - python = self; - overrides = packageOverrides; - }; + pythonPackages = callPackage + ({ pkgs, stdenv, python, overrides }: let + pythonPackagesFun = import ../../../top-level/python-packages.nix { + inherit stdenv pkgs; + python = self; + }; + otherSplices = { + selfBuildBuild = pythonOnBuildForBuild.pkgs; + selfBuildHost = pythonOnBuildForHost.pkgs; + selfBuildTarget = pythonOnBuildForTarget.pkgs; + selfHostHost = pythonOnHostForHost.pkgs; + selfTargetTarget = pythonOnTargetForTarget.pkgs or {}; # There is no Python TargetTarget. + }; + keep = self: { + # TODO maybe only define these here so nothing is needed to be kept in sync. + inherit (self) + isPy27 isPy35 isPy36 isPy37 isPy38 isPy39 isPy3k isPyPy pythonAtLeast pythonOlder + python bootstrapped-pip buildPythonPackage buildPythonApplication + fetchPypi + hasPythonModule requiredPythonModules makePythonPath disabledIf + toPythonModule toPythonApplication + buildSetupcfg + + eggUnpackHook + eggBuildHook + eggInstallHook + flitBuildHook + pipBuildHook + pipInstallHook + pytestCheckHook + pythonCatchConflictsHook + pythonImportsCheckHook + pythonNamespacesHook + pythonRecompileBytecodeHook + pythonRemoveBinBytecodeHook + pythonRemoveTestsDirHook + setuptoolsBuildHook + setuptoolsCheckHook + venvShellHook + wheelUnpackHook + + wrapPython + + pythonPackages + + recursivePthLoader + ; + }; + in lib.makeScopeWithSplicing + pkgs.splicePackages + pkgs.newScope + otherSplices + keep + (lib.extends overrides pythonPackagesFun)) + { + overrides = packageOverrides; + }; in rec { isPy27 = pythonVersion == "2.7"; isPy35 = pythonVersion == "3.5"; @@ -28,6 +85,7 @@ with pkgs; isPy37 = pythonVersion == "3.7"; isPy38 = pythonVersion == "3.8"; isPy39 = pythonVersion == "3.9"; + isPy310 = pythonVersion == "3.10"; isPy2 = lib.strings.substring 0 1 pythonVersion == "2"; isPy3 = lib.strings.substring 0 1 pythonVersion == "3"; isPy3k = isPy3; @@ -41,13 +99,15 @@ with pkgs; inherit sourceVersion; pythonAtLeast = lib.versionAtLeast pythonVersion; pythonOlder = lib.versionOlder pythonVersion; - inherit hasDistutilsCxxPatch pythonForBuild; + inherit hasDistutilsCxxPatch; + # TODO: rename to pythonOnBuild + # Not done immediately because its likely used outside Nixpkgs. + pythonForBuild = pythonOnBuildForHost.override { inherit packageOverrides; self = pythonForBuild; }; tests = callPackage ./tests.nix { python = self; }; }; - in { python27 = callPackage ./cpython/2.7 { @@ -115,10 +175,22 @@ in { inherit passthruFun; }; + python310 = callPackage ./cpython { + self = python310; + sourceVersion = { + major = "3"; + minor = "10"; + patch = "0"; + suffix = "a2"; + }; + sha256 = "0zl5h61s8n2w2v1n40af0mwaw7lqh5fl1ys7kyjgcph60vb9wzjr"; + inherit (darwin) configd; + inherit passthruFun; + }; + # Minimal versions of Python (built without optional dependencies) python3Minimal = (python38.override { self = python3Minimal; - pythonForBuild = pkgs.buildPackages.python3Minimal; # strip down that python version as much as possible openssl = null; readline = null; diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/default.nix b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/default.nix index d14eb9cbb09d..1a64c79232bc 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/default.nix +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/default.nix @@ -1,14 +1,15 @@ # Hooks for building Python packages. { python , lib -, callPackage , makeSetupHook , disabledIf , isPy3k , ensureNewerSourcesForZipFilesHook +, findutils }: let + callPackage = python.pythonForBuild.pkgs.callPackage; pythonInterpreter = python.pythonForBuild.interpreter; pythonSitePackages = python.sitePackages; pythonCheckInterpreter = python.interpreter; @@ -94,7 +95,7 @@ in rec { makeSetupHook { name = "python-namespaces-hook.sh"; substitutions = { - inherit pythonSitePackages; + inherit pythonSitePackages findutils; }; } ./python-namespaces-hook.sh) {}; diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/pip-install-hook.sh b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/pip-install-hook.sh index 770739b36bde..a4f08b8b14cb 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/pip-install-hook.sh +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/pip-install-hook.sh @@ -11,9 +11,7 @@ pipInstallPhase() { export PYTHONPATH="$out/@pythonSitePackages@:$PYTHONPATH" pushd dist || return 1 - mkdir tmpbuild - NIX_PIP_INSTALL_TMPDIR=tmpbuild @pythonInterpreter@ -m pip install ./*.whl --no-index --prefix="$out" --no-cache $pipInstallFlags - rm -rf tmpbuild + @pythonInterpreter@ -m pip install ./*.whl --no-index --no-warn-script-location --prefix="$out" --no-cache $pipInstallFlags popd || return 1 runHook postInstall diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/python-namespaces-hook.sh b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/python-namespaces-hook.sh index 50f21819d176..15d2bd0eb34c 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/python-namespaces-hook.sh +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/hooks/python-namespaces-hook.sh @@ -17,16 +17,17 @@ pythonNamespacesHook() { for pathSegment in ${pathSegments[@]}; do constructedPath=${constructedPath}/${pathSegment} pathToRemove=${constructedPath}/__init__.py - pycachePath=${constructedPath}/__pycache__/__init__* + pycachePath=${constructedPath}/__pycache__/ + # remove __init__.py if [ -f "$pathToRemove" ]; then - echo "Removing $pathToRemove" - rm "$pathToRemove" + rm -v "$pathToRemove" fi - if [ -f "$pycachePath" ]; then - echo "Removing $pycachePath" - rm "$pycachePath" + # remove __pycache__/ entry, can be interpreter specific. E.g. __init__.cpython-38.pyc + # use null characters to perserve potential whitespace in filepath + if [ -d "$pycachePath" ]; then + @findutils@/bin/find "$pycachePath" -name '__init__*' -exec rm -v "{}" + fi done done diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/mk-python-derivation.nix b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/mk-python-derivation.nix index c3be76790ebd..670c870f1077 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/mk-python-derivation.nix +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/mk-python-derivation.nix @@ -17,7 +17,6 @@ , pythonCatchConflictsHook , pythonImportsCheckHook , pythonNamespacesHook -, pythonRecompileBytecodeHook , pythonRemoveBinBytecodeHook , pythonRemoveTestsDirHook , setuptoolsBuildHook @@ -54,7 +53,9 @@ , disabled ? false # Raise an error if two packages are installed with the same name -, catchConflicts ? true +# TODO: For cross we probably need a different PYTHONPATH, or not +# add the runtime deps until after buildPhase. +, catchConflicts ? (python.stdenv.hostPlatform == python.stdenv.buildPlatform) # Additional arguments to pass to the makeWrapper function, which wraps # generated binaries. @@ -113,7 +114,6 @@ let python wrapPython ensureNewerSourcesForZipFilesHook # move to wheel installer (pip) or builder (setuptools, flit, ...)? - pythonRecompileBytecodeHook # Remove when solved https://github.com/NixOS/nixpkgs/issues/81441 pythonRemoveTestsDirHook ] ++ lib.optionals catchConflicts [ setuptools pythonCatchConflictsHook @@ -167,9 +167,6 @@ let # Python packages built through cross-compilation are always for the host platform. disallowedReferences = lib.optionals (python.stdenv.hostPlatform != python.stdenv.buildPlatform) [ python.pythonForBuild ]; - # For now, revert recompilation of bytecode. - dontUsePythonRecompileBytecode = true; - meta = { # default to python's platforms platforms = python.meta.platforms; diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/pypy/default.nix b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/pypy/default.nix index 10073602071a..8feeb3c51bf3 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/pypy/default.nix +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/pypy/default.nix @@ -5,10 +5,16 @@ , python-setup-hook # For the Python package set , packageOverrides ? (self: super: {}) +, pkgsBuildBuild +, pkgsBuildHost +, pkgsBuildTarget +, pkgsHostHost +, pkgsTargetTarget , sourceVersion , pythonVersion , sha256 , passthruFun +, pythonAttr ? "pypy${stdenv.lib.substring 0 1 pythonVersion}${stdenv.lib.substring 2 3 pythonVersion}" }: assert zlibSupport -> zlib != null; @@ -22,9 +28,14 @@ let implementation = "pypy"; libPrefix = "pypy${pythonVersion}"; executable = "pypy${if isPy3k then "3" else ""}"; - pythonForBuild = self; # No cross-compiling for now. sitePackages = "site-packages"; hasDistutilsCxxPatch = false; + + pythonOnBuildForBuild = pkgsBuildBuild.${pythonAttr}; + pythonOnBuildForHost = pkgsBuildHost.${pythonAttr}; + pythonOnBuildForTarget = pkgsBuildTarget.${pythonAttr}; + pythonOnHostForHost = pkgsHostHost.${pythonAttr}; + pythonOnTargetForTarget = pkgsTargetTarget.${pythonAttr} or {}; }; pname = passthru.executable; version = with sourceVersion; "${major}.${minor}.${patch}"; @@ -151,7 +162,7 @@ in with passthru; stdenv.mkDerivation rec { homepage = "http://pypy.org/"; description = "Fast, compliant alternative implementation of the Python language (${pythonVersion})"; license = licenses.mit; - platforms = [ "i686-linux" "x86_64-linux" "x86_64-darwin" ]; + platforms = [ "aarch64-linux" "i686-linux" "x86_64-linux" "x86_64-darwin" ]; maintainers = with maintainers; [ andersk ]; }; } diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/tests.nix b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/tests.nix index dcfa41cc308e..a291919b3277 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/tests.nix +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/tests.nix @@ -1,4 +1,5 @@ -{ python +{ stdenv +, python , runCommand , substituteAll , lib @@ -92,4 +93,4 @@ let -in environmentTests // integrationTests +in stdenv.lib.optionalAttrs (stdenv.hostPlatform == stdenv.buildPlatform ) (environmentTests // integrationTests) diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/tests/test_nix_pythonprefix/default.nix b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/tests/test_nix_pythonprefix/default.nix index 05798cbaf1b8..572cbdccbfb2 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/tests/test_nix_pythonprefix/default.nix +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/tests/test_nix_pythonprefix/default.nix @@ -4,7 +4,7 @@ let python = let packageOverrides = self: super: { - typeddep = super.callPackage ./typeddep {}; + typeddep = self.callPackage ./typeddep {}; }; in interpreter.override {inherit packageOverrides; self = python;}; diff --git a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/update-python-libraries/default.nix b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/update-python-libraries/default.nix index 762ca2bdd34b..81975bc5250e 100644 --- a/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/update-python-libraries/default.nix +++ b/infra/libkookie/nixpkgs/pkgs/development/interpreters/python/update-python-libraries/default.nix @@ -9,4 +9,4 @@ runCommand "update-python-libraries" { cp ${./update-python-libraries.py} $out patchShebangs $out substituteInPlace $out --replace 'GIT = "git"' 'GIT = "${git}/bin/git"' -''
\ No newline at end of file +'' |