diff --git a/lib/modules/manager/gradle-wrapper/utils.ts b/lib/modules/manager/gradle-wrapper/utils.ts
index b4322f3fcc4430668ee6e52316480cc656a918dd..b0edcccdc0cbf6094d7e3b1d6c4a6397ffb7d361 100644
--- a/lib/modules/manager/gradle-wrapper/utils.ts
+++ b/lib/modules/manager/gradle-wrapper/utils.ts
@@ -60,7 +60,7 @@ export async function prepareGradleCommand(
  */
 export function getJavaConstraint(
   gradleVersion: string | null | undefined
-): string | null {
+): string {
   const major = gradleVersion ? gradleVersioning.getMajor(gradleVersion) : null;
   const minor = gradleVersion ? gradleVersioning.getMinor(gradleVersion) : null;
   if (major && (major > 7 || (major >= 7 && minor && minor >= 3))) {
diff --git a/lib/modules/manager/pip-compile/artifacts.spec.ts b/lib/modules/manager/pip-compile/artifacts.spec.ts
index 94c8463f29e48d5195f2e296ee81e77f23766fdc..b410cbce2a310b44ac535fc9f30622014269d96d 100644
--- a/lib/modules/manager/pip-compile/artifacts.spec.ts
+++ b/lib/modules/manager/pip-compile/artifacts.spec.ts
@@ -1,21 +1,25 @@
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
 import { Fixtures } from '../../../../test/fixtures';
-import { env, fs, git, partial } from '../../../../test/util';
+import { env, fs, git, mocked, partial } from '../../../../test/util';
 import { GlobalConfig } from '../../../config/global';
 import type { RepoGlobalConfig } from '../../../config/types';
 import { logger } from '../../../logger';
 import * as docker from '../../../util/exec/docker';
 import type { StatusResult } from '../../../util/git/types';
+import * as _datasource from '../../datasource';
 import type { UpdateArtifactsConfig } from '../types';
 import { constructPipCompileCmd, extractResolver } from './artifacts';
 import { updateArtifacts } from '.';
 
+const datasource = mocked(_datasource);
+
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/fs');
 jest.mock('../../../util/git');
 jest.mock('../../../util/host-rules');
 jest.mock('../../../util/http');
+jest.mock('../../datasource');
 
 const adminConfig: RepoGlobalConfig = {
   // `join` fixes Windows CI
@@ -96,6 +100,10 @@ describe('modules/manager/pip-compile/artifacts', () => {
 
   it('supports docker mode', async () => {
     GlobalConfig.set(dockerAdminConfig);
+    // pip-tools
+    datasource.getPkgReleases.mockResolvedValueOnce({
+      releases: [{ version: '6.13.0' }],
+    });
     const execSnapshots = mockExecAll();
     git.getRepoStatus.mockResolvedValue(
       partial<StatusResult>({
@@ -129,7 +137,7 @@ describe('modules/manager/pip-compile/artifacts', () => {
           'bash -l -c "' +
           'install-tool python 3.10.2 ' +
           '&& ' +
-          'pip install --user pip-tools ' +
+          'install-tool pip-tools 6.13.0 ' +
           '&& ' +
           'pip-compile requirements.in' +
           '"',
@@ -139,6 +147,10 @@ describe('modules/manager/pip-compile/artifacts', () => {
 
   it('supports install mode', async () => {
     GlobalConfig.set({ ...adminConfig, binarySource: 'install' });
+    // pip-tools
+    datasource.getPkgReleases.mockResolvedValueOnce({
+      releases: [{ version: '6.13.0' }],
+    });
     const execSnapshots = mockExecAll();
     git.getRepoStatus.mockResolvedValue(
       partial<StatusResult>({
@@ -157,7 +169,7 @@ describe('modules/manager/pip-compile/artifacts', () => {
 
     expect(execSnapshots).toMatchObject([
       { cmd: 'install-tool python 3.10.2' },
-      { cmd: 'pip install --user pip-tools' },
+      { cmd: 'install-tool pip-tools 6.13.0' },
       {
         cmd: 'pip-compile requirements.in',
         options: { cwd: '/tmp/github/some/repo' },
@@ -210,6 +222,10 @@ describe('modules/manager/pip-compile/artifacts', () => {
 
   it('uses pip-compile version from config', async () => {
     GlobalConfig.set(dockerAdminConfig);
+    // pip-tools
+    datasource.getPkgReleases.mockResolvedValueOnce({
+      releases: [{ version: '6.13.0' }],
+    });
     const execSnapshots = mockExecAll();
     git.getRepoStatus.mockResolvedValue(
       partial<StatusResult>({
@@ -225,7 +241,7 @@ describe('modules/manager/pip-compile/artifacts', () => {
         newPackageFileContent: 'some new content',
         config: {
           ...config,
-          constraints: { python: '3.10.2', pipTools: '==1.2.3' },
+          constraints: { python: '3.10.2', pipTools: '6.13.0' },
         },
       })
     ).not.toBeNull();
@@ -246,7 +262,7 @@ describe('modules/manager/pip-compile/artifacts', () => {
           'bash -l -c "' +
           'install-tool python 3.10.2 ' +
           '&& ' +
-          'pip install --user pip-tools==1.2.3 ' +
+          'install-tool pip-tools 6.13.0 ' +
           '&& ' +
           'pip-compile requirements.in' +
           '"',
diff --git a/lib/modules/manager/pip-compile/artifacts.ts b/lib/modules/manager/pip-compile/artifacts.ts
index 495cf342c98819b4732b8c59b3daa88fb91d1cc7..66d1c2d25733751f287e532138f5e264aa9e79f2 100644
--- a/lib/modules/manager/pip-compile/artifacts.ts
+++ b/lib/modules/manager/pip-compile/artifacts.ts
@@ -126,14 +126,15 @@ export async function updateArtifacts({
     const execOptions: ExecOptions = {
       cwdFile: inputFileName,
       docker: {},
-      preCommands: [
-        `pip install --user ${quote(`pip-tools${pipToolsConstraint}`)}`,
-      ],
       toolConstraints: [
         {
           toolName: 'python',
           constraint,
         },
+        {
+          toolName: 'pip-tools',
+          constraint: pipToolsConstraint,
+        },
       ],
       extraEnv: {
         PIP_CACHE_DIR: await ensureCacheDir('pip'),
diff --git a/lib/modules/manager/pip_requirements/artifacts.spec.ts b/lib/modules/manager/pip_requirements/artifacts.spec.ts
index 69e2152cea29b22d6efebf005408cd20434b806b..adaeacf6d35df9b58176a0cbae41acd4fdabdcd5 100644
--- a/lib/modules/manager/pip_requirements/artifacts.spec.ts
+++ b/lib/modules/manager/pip_requirements/artifacts.spec.ts
@@ -1,11 +1,14 @@
 import { join } from 'upath';
 import { mockExecAll } from '../../../../test/exec-util';
-import { fs } from '../../../../test/util';
+import { fs, mocked } from '../../../../test/util';
 import { GlobalConfig } from '../../../config/global';
 import type { RepoGlobalConfig } from '../../../config/types';
+import * as _datasource from '../../datasource';
 import type { UpdateArtifactsConfig } from '../types';
 import { updateArtifacts } from '.';
 
+const datasource = mocked(_datasource);
+
 jest.mock('../../../util/exec/common');
 jest.mock('../../../util/fs');
 jest.mock('../../datasource');
@@ -187,6 +190,10 @@ describe('modules/manager/pip_requirements/artifacts', () => {
     GlobalConfig.set({ ...adminConfig, binarySource: 'docker' });
     fs.readLocalFile.mockResolvedValueOnce('new content');
     fs.ensureCacheDir.mockResolvedValueOnce('/tmp/cache');
+    // hashin
+    datasource.getPkgReleases.mockResolvedValueOnce({
+      releases: [{ version: '0.1.7' }],
+    });
     const execSnapshots = mockExecAll();
 
     expect(
@@ -222,7 +229,7 @@ describe('modules/manager/pip_requirements/artifacts', () => {
           'bash -l -c "' +
           'install-tool python 3.10.2 ' +
           '&& ' +
-          'pip install --user hashin ' +
+          'install-tool hashin 0.1.7 ' +
           '&& ' +
           'hashin atomicwrites==1.4.0 -r requirements.txt' +
           '"',
@@ -233,6 +240,10 @@ describe('modules/manager/pip_requirements/artifacts', () => {
   it('supports install mode', async () => {
     GlobalConfig.set({ ...adminConfig, binarySource: 'install' });
     fs.readLocalFile.mockResolvedValueOnce('new content');
+    // hashin
+    datasource.getPkgReleases.mockResolvedValueOnce({
+      releases: [{ version: '0.1.7' }],
+    });
     const execSnapshots = mockExecAll();
 
     expect(
@@ -253,7 +264,7 @@ describe('modules/manager/pip_requirements/artifacts', () => {
     ]);
     expect(execSnapshots).toMatchObject([
       { cmd: 'install-tool python 3.10.2' },
-      { cmd: 'pip install --user hashin' },
+      { cmd: 'install-tool hashin 0.1.7' },
       {
         cmd: 'hashin atomicwrites==1.4.0 -r requirements.txt',
         options: { cwd: '/tmp/github/some/repo' },
diff --git a/lib/modules/manager/pip_requirements/artifacts.ts b/lib/modules/manager/pip_requirements/artifacts.ts
index bde3664994261f4a0d36df4337204456582d505e..53fd1587f49f72f17d7f21d846f2effde83dc235 100644
--- a/lib/modules/manager/pip_requirements/artifacts.ts
+++ b/lib/modules/manager/pip_requirements/artifacts.ts
@@ -69,9 +69,9 @@ export async function updateArtifacts({
     const execOptions: ExecOptions = {
       cwdFile: '.',
       docker: {},
-      preCommands: ['pip install --user hashin'],
       toolConstraints: [
         { toolName: 'python', constraint: config.constraints?.python },
+        { toolName: 'hashin' },
       ],
       extraEnv: {
         PIP_CACHE_DIR: await ensureCacheDir('pip'),
diff --git a/lib/modules/manager/pipenv/__snapshots__/artifacts.spec.ts.snap b/lib/modules/manager/pipenv/__snapshots__/artifacts.spec.ts.snap
index 81581b65c5806eb6acb2ce737182931da9f77cf3..184fb21b84520bbc3e65bd1506f6b78f3233a9c1 100644
--- a/lib/modules/manager/pipenv/__snapshots__/artifacts.spec.ts.snap
+++ b/lib/modules/manager/pipenv/__snapshots__/artifacts.spec.ts.snap
@@ -111,7 +111,7 @@ exports[`modules/manager/pipenv/artifacts supports docker mode 1`] = `
     },
   },
   {
-    "cmd": "docker run --rm --name=renovate_sidecar --label=renovate_child -v "/tmp/github/some/repo":"/tmp/github/some/repo" -v "/tmp/renovate/cache":"/tmp/renovate/cache" -e PIPENV_CACHE_DIR -e PIP_CACHE_DIR -e BUILDPACK_CACHE_DIR -e CONTAINERBASE_CACHE_DIR -w "/tmp/github/some/repo" containerbase/sidecar bash -l -c "install-tool python 3.7.6 && pip install --user pipenv && pipenv lock"",
+    "cmd": "docker run --rm --name=renovate_sidecar --label=renovate_child -v "/tmp/github/some/repo":"/tmp/github/some/repo" -v "/tmp/renovate/cache":"/tmp/renovate/cache" -e PIPENV_CACHE_DIR -e PIP_CACHE_DIR -e BUILDPACK_CACHE_DIR -e CONTAINERBASE_CACHE_DIR -w "/tmp/github/some/repo" containerbase/sidecar bash -l -c "install-tool python 3.7.6 && install-tool pipenv 2023.1.2 && pipenv lock"",
     "options": {
       "cwd": "/tmp/github/some/repo",
       "encoding": "utf-8",
@@ -150,7 +150,7 @@ exports[`modules/manager/pipenv/artifacts uses pipenv version from Pipfile 1`] =
     },
   },
   {
-    "cmd": "docker run --rm --name=renovate_sidecar --label=renovate_child -v "/tmp/github/some/repo":"/tmp/github/some/repo" -v "/tmp/renovate/cache":"/tmp/renovate/cache" -e PIPENV_CACHE_DIR -e BUILDPACK_CACHE_DIR -e CONTAINERBASE_CACHE_DIR -w "/tmp/github/some/repo" containerbase/sidecar bash -l -c "install-tool python 3.10.2 && pip install --user pipenv==2020.8.13 && pipenv lock"",
+    "cmd": "docker run --rm --name=renovate_sidecar --label=renovate_child -v "/tmp/github/some/repo":"/tmp/github/some/repo" -v "/tmp/renovate/cache":"/tmp/renovate/cache" -e PIPENV_CACHE_DIR -e BUILDPACK_CACHE_DIR -e CONTAINERBASE_CACHE_DIR -w "/tmp/github/some/repo" containerbase/sidecar bash -l -c "install-tool python 3.10.2 && install-tool pipenv 2020.8.13 && pipenv lock"",
     "options": {
       "cwd": "/tmp/github/some/repo",
       "encoding": "utf-8",
@@ -188,7 +188,7 @@ exports[`modules/manager/pipenv/artifacts uses pipenv version from Pipfile dev p
     },
   },
   {
-    "cmd": "docker run --rm --name=renovate_sidecar --label=renovate_child -v "/tmp/github/some/repo":"/tmp/github/some/repo" -v "/tmp/renovate/cache":"/tmp/renovate/cache" -e PIPENV_CACHE_DIR -e BUILDPACK_CACHE_DIR -e CONTAINERBASE_CACHE_DIR -w "/tmp/github/some/repo" containerbase/sidecar bash -l -c "install-tool python 3.10.2 && pip install --user pipenv==2020.8.13 && pipenv lock"",
+    "cmd": "docker run --rm --name=renovate_sidecar --label=renovate_child -v "/tmp/github/some/repo":"/tmp/github/some/repo" -v "/tmp/renovate/cache":"/tmp/renovate/cache" -e PIPENV_CACHE_DIR -e BUILDPACK_CACHE_DIR -e CONTAINERBASE_CACHE_DIR -w "/tmp/github/some/repo" containerbase/sidecar bash -l -c "install-tool python 3.10.2 && install-tool pipenv 2020.8.13 && pipenv lock"",
     "options": {
       "cwd": "/tmp/github/some/repo",
       "encoding": "utf-8",
@@ -226,7 +226,7 @@ exports[`modules/manager/pipenv/artifacts uses pipenv version from config 1`] =
     },
   },
   {
-    "cmd": "docker run --rm --name=renovate_sidecar --label=renovate_child -v "/tmp/github/some/repo":"/tmp/github/some/repo" -v "/tmp/renovate/cache":"/tmp/renovate/cache" -e PIPENV_CACHE_DIR -e BUILDPACK_CACHE_DIR -e CONTAINERBASE_CACHE_DIR -w "/tmp/github/some/repo" containerbase/sidecar bash -l -c "install-tool python 3.10.2 && pip install --user pipenv==2020.1.1 && pipenv lock"",
+    "cmd": "docker run --rm --name=renovate_sidecar --label=renovate_child -v "/tmp/github/some/repo":"/tmp/github/some/repo" -v "/tmp/renovate/cache":"/tmp/renovate/cache" -e PIPENV_CACHE_DIR -e BUILDPACK_CACHE_DIR -e CONTAINERBASE_CACHE_DIR -w "/tmp/github/some/repo" containerbase/sidecar bash -l -c "install-tool python 3.10.2 && install-tool pipenv 2020.1.1 && pipenv lock"",
     "options": {
       "cwd": "/tmp/github/some/repo",
       "encoding": "utf-8",
diff --git a/lib/modules/manager/pipenv/artifacts.spec.ts b/lib/modules/manager/pipenv/artifacts.spec.ts
index 55718c39d64a3c2fe6bf5d8299b76a2c71258062..5f8d14acd0be4c1c549b87f41e4748bcb5070244 100644
--- a/lib/modules/manager/pipenv/artifacts.spec.ts
+++ b/lib/modules/manager/pipenv/artifacts.spec.ts
@@ -1,14 +1,24 @@
 import { join } from 'upath';
 import { envMock, mockExecAll } from '../../../../test/exec-util';
-import { env, fs, git, mockedFunction, partial } from '../../../../test/util';
+import {
+  env,
+  fs,
+  git,
+  mocked,
+  mockedFunction,
+  partial,
+} from '../../../../test/util';
 import { GlobalConfig } from '../../../config/global';
 import type { RepoGlobalConfig } from '../../../config/types';
 import * as docker from '../../../util/exec/docker';
 import type { StatusResult } from '../../../util/git/types';
 import { getPkgReleases as _getPkgReleases } from '../../datasource';
+import * as _datasource from '../../datasource';
 import type { UpdateArtifactsConfig } from '../types';
 import * as pipenv from '.';
 
+const datasource = mocked(_datasource);
+
 jest.mock('../../../util/exec/env');
 jest.mock('../../../util/git');
 jest.mock('../../../util/fs');
@@ -141,6 +151,10 @@ describe('modules/manager/pipenv/artifacts', () => {
     );
     fs.ensureCacheDir.mockResolvedValueOnce('/tmp/renovate/cache/others/pip');
     fs.readLocalFile.mockResolvedValueOnce(JSON.stringify(pipFileLock));
+    // pipenv
+    datasource.getPkgReleases.mockResolvedValueOnce({
+      releases: [{ version: '2023.1.2' }],
+    });
     const execSnapshots = mockExecAll();
     git.getRepoStatus.mockResolvedValue(
       partial<StatusResult>({
@@ -167,6 +181,10 @@ describe('modules/manager/pipenv/artifacts', () => {
     );
     fs.ensureCacheDir.mockResolvedValueOnce('/tmp/renovate/cache/others/pip');
     fs.readLocalFile.mockResolvedValueOnce(JSON.stringify(pipFileLock));
+    // pipenv
+    datasource.getPkgReleases.mockResolvedValueOnce({
+      releases: [{ version: '2023.1.2' }],
+    });
     const execSnapshots = mockExecAll();
     git.getRepoStatus.mockResolvedValue(
       partial<StatusResult>({
@@ -184,7 +202,7 @@ describe('modules/manager/pipenv/artifacts', () => {
     ).not.toBeNull();
     expect(execSnapshots).toMatchObject([
       { cmd: 'install-tool python 3.7.6' },
-      { cmd: 'pip install --user pipenv' },
+      { cmd: 'install-tool pipenv 2023.1.2' },
       { cmd: 'pipenv lock', options: { cwd: '/tmp/github/some/repo' } },
     ]);
   });
diff --git a/lib/modules/manager/pipenv/artifacts.ts b/lib/modules/manager/pipenv/artifacts.ts
index 50692ec341312ea0cc75624ab3ca2c478b34f446..d2f3ea3363199d85b87d88278e7b7242d93b936f 100644
--- a/lib/modules/manager/pipenv/artifacts.ts
+++ b/lib/modules/manager/pipenv/artifacts.ts
@@ -1,4 +1,3 @@
-import { quote } from 'shlex';
 import { TEMPORARY_ERROR } from '../../../constants/error-messages';
 import { logger } from '../../../logger';
 import { exec } from '../../../util/exec';
@@ -114,12 +113,15 @@ export async function updateArtifacts({
         PIP_CACHE_DIR: await ensureCacheDir('pip'),
       },
       docker: {},
-      preCommands: [`pip install --user ${quote(`pipenv${pipenvConstraint}`)}`],
       toolConstraints: [
         {
           toolName: 'python',
           constraint: tagConstraint,
         },
+        {
+          toolName: 'pipenv',
+          constraint: pipenvConstraint,
+        },
       ],
     };
     logger.trace({ cmd }, 'pipenv lock command');
diff --git a/lib/util/exec/containerbase.ts b/lib/util/exec/containerbase.ts
index d9efe6285ac82b9a1b67b44666187fce5ffeb2ff..165d362288e0420b4cc1569e63f960bcffd00dca 100644
--- a/lib/util/exec/containerbase.ts
+++ b/lib/util/exec/containerbase.ts
@@ -254,7 +254,7 @@ export async function resolveConstraint(
   if (constraint) {
     if (versioning.isValid(constraint)) {
       if (versioning.isSingleVersion(constraint)) {
-        return constraint;
+        return constraint.replace(/^=+/, '').trim();
       }
     } else {
       logger.warn(