mirror of
https://github.com/dbt-labs/dbt-core
synced 2025-12-20 07:51:27 +00:00
Compare commits
10 Commits
enable-pos
...
jerco/fun-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2f6e5445a | ||
|
|
3c2a373b0a | ||
|
|
51faf1d718 | ||
|
|
59e5fc5f86 | ||
|
|
eebb1d3ab6 | ||
|
|
0952e8b003 | ||
|
|
649fc51af8 | ||
|
|
cf4b2c2dbd | ||
|
|
914f23d859 | ||
|
|
1ec9888e17 |
6
.changes/unreleased/Features-20230208-090751.yaml
Normal file
6
.changes/unreleased/Features-20230208-090751.yaml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
kind: Features
|
||||||
|
body: enhance package mismatch deps error
|
||||||
|
time: 2023-02-08T09:07:51.254423-06:00
|
||||||
|
custom:
|
||||||
|
Author: jtcohen6 dave-connors-3 dbeatty10
|
||||||
|
Issue: "4775"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
from typing import List
|
from typing import List, Dict, Optional
|
||||||
|
|
||||||
from dbt import semver
|
from dbt import semver
|
||||||
from dbt.flags import get_flags
|
from dbt.flags import get_flags
|
||||||
@@ -59,22 +59,50 @@ class RegistryPinnedPackage(RegistryPackageMixin, PinnedPackage):
|
|||||||
def install(self, project, renderer):
|
def install(self, project, renderer):
|
||||||
self._install(project, renderer)
|
self._install(project, renderer)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"{self.package}@{self.version}"
|
||||||
|
|
||||||
|
|
||||||
class RegistryUnpinnedPackage(RegistryPackageMixin, UnpinnedPackage[RegistryPinnedPackage]):
|
class RegistryUnpinnedPackage(RegistryPackageMixin, UnpinnedPackage[RegistryPinnedPackage]):
|
||||||
def __init__(
|
def __init__(
|
||||||
self, package: str, versions: List[semver.VersionSpecifier], install_prerelease: bool
|
self,
|
||||||
|
package: str,
|
||||||
|
versions: List[semver.VersionSpecifier],
|
||||||
|
install_prerelease: bool,
|
||||||
|
by_whom: str = "user",
|
||||||
|
who_wants_which: Optional[Dict[str, List[semver.VersionSpecifier]]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(package)
|
super().__init__(package)
|
||||||
self.versions = versions
|
self.versions = versions
|
||||||
self.install_prerelease = install_prerelease
|
self.install_prerelease = install_prerelease
|
||||||
|
self.by_whom = by_whom
|
||||||
|
self.who_wants_which = who_wants_which
|
||||||
|
|
||||||
|
if not self.who_wants_which:
|
||||||
|
self.who_wants_which = {self.by_whom: self.versions}
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
version_list = []
|
||||||
|
for version in self.versions:
|
||||||
|
version_list.append(version.to_version_string())
|
||||||
|
return f"{self.name} : {version_list}"
|
||||||
|
|
||||||
def _check_in_index(self):
|
def _check_in_index(self):
|
||||||
index = registry.index_cached()
|
index = registry.index_cached()
|
||||||
if self.package not in index:
|
if self.package not in index:
|
||||||
raise PackageNotFoundError(self.package)
|
raise PackageNotFoundError(self.package)
|
||||||
|
|
||||||
|
def package_requests(self):
|
||||||
|
message = ""
|
||||||
|
for who, which in self.who_wants_which.items():
|
||||||
|
version_list = []
|
||||||
|
for version in which:
|
||||||
|
version_list.append(version.to_version_string())
|
||||||
|
message = message + f"\n Required by {who}: {version_list}"
|
||||||
|
return message
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_contract(cls, contract: RegistryPackage) -> "RegistryUnpinnedPackage":
|
def from_contract(cls, contract: RegistryPackage, by_whom="user") -> "RegistryUnpinnedPackage":
|
||||||
raw_version = contract.get_versions()
|
raw_version = contract.get_versions()
|
||||||
|
|
||||||
versions = [semver.VersionSpecifier.from_version_string(v) for v in raw_version]
|
versions = [semver.VersionSpecifier.from_version_string(v) for v in raw_version]
|
||||||
@@ -82,13 +110,16 @@ class RegistryUnpinnedPackage(RegistryPackageMixin, UnpinnedPackage[RegistryPinn
|
|||||||
package=contract.package,
|
package=contract.package,
|
||||||
versions=versions,
|
versions=versions,
|
||||||
install_prerelease=bool(contract.install_prerelease),
|
install_prerelease=bool(contract.install_prerelease),
|
||||||
|
by_whom=by_whom,
|
||||||
)
|
)
|
||||||
|
|
||||||
def incorporate(self, other: "RegistryUnpinnedPackage") -> "RegistryUnpinnedPackage":
|
def incorporate(self, other: "RegistryUnpinnedPackage") -> "RegistryUnpinnedPackage":
|
||||||
|
who_wants_which = (self.who_wants_which or {}) or (other.who_wants_which or {})
|
||||||
return RegistryUnpinnedPackage(
|
return RegistryUnpinnedPackage(
|
||||||
package=self.package,
|
package=self.package,
|
||||||
install_prerelease=self.install_prerelease,
|
install_prerelease=self.install_prerelease,
|
||||||
versions=self.versions + other.versions,
|
versions=self.versions + other.versions,
|
||||||
|
who_wants_which=who_wants_which,
|
||||||
)
|
)
|
||||||
|
|
||||||
def resolved(self) -> RegistryPinnedPackage:
|
def resolved(self) -> RegistryPinnedPackage:
|
||||||
@@ -96,7 +127,8 @@ class RegistryUnpinnedPackage(RegistryPackageMixin, UnpinnedPackage[RegistryPinn
|
|||||||
try:
|
try:
|
||||||
range_ = semver.reduce_versions(*self.versions)
|
range_ = semver.reduce_versions(*self.versions)
|
||||||
except VersionsNotCompatibleError as e:
|
except VersionsNotCompatibleError as e:
|
||||||
new_msg = "Version error for package {}: {}".format(self.name, e)
|
new_msg = f"Version error for package {self.name}: {self.package_requests()}"
|
||||||
|
print(f"--- in resolved. new_msg: {new_msg}")
|
||||||
raise DependencyError(new_msg) from e
|
raise DependencyError(new_msg) from e
|
||||||
flags = get_flags()
|
flags = get_flags()
|
||||||
should_version_check = bool(flags.VERSION_CHECK)
|
should_version_check = bool(flags.VERSION_CHECK)
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class PackageListing:
|
|||||||
else:
|
else:
|
||||||
self.packages[key] = package
|
self.packages[key] = package
|
||||||
|
|
||||||
def update_from(self, src: List[PackageContract]) -> None:
|
def update_from(self, src: List[PackageContract], by_whom="user") -> None:
|
||||||
pkg: UnpinnedPackage
|
pkg: UnpinnedPackage
|
||||||
for contract in src:
|
for contract in src:
|
||||||
if isinstance(contract, LocalPackage):
|
if isinstance(contract, LocalPackage):
|
||||||
@@ -78,7 +78,7 @@ class PackageListing:
|
|||||||
elif isinstance(contract, GitPackage):
|
elif isinstance(contract, GitPackage):
|
||||||
pkg = GitUnpinnedPackage.from_contract(contract)
|
pkg = GitUnpinnedPackage.from_contract(contract)
|
||||||
elif isinstance(contract, RegistryPackage):
|
elif isinstance(contract, RegistryPackage):
|
||||||
pkg = RegistryUnpinnedPackage.from_contract(contract)
|
pkg = RegistryUnpinnedPackage.from_contract(contract, by_whom)
|
||||||
else:
|
else:
|
||||||
raise DbtInternalError("Invalid package type {}".format(type(contract)))
|
raise DbtInternalError("Invalid package type {}".format(type(contract)))
|
||||||
self.incorporate(pkg)
|
self.incorporate(pkg)
|
||||||
@@ -128,8 +128,9 @@ def resolve_packages(
|
|||||||
# resolve the dependency in question
|
# resolve the dependency in question
|
||||||
for package in pending:
|
for package in pending:
|
||||||
final.incorporate(package)
|
final.incorporate(package)
|
||||||
target = final[package].resolved().fetch_metadata(project, renderer)
|
resolved = final[package].resolved()
|
||||||
next_pending.update_from(target.packages)
|
target = resolved.fetch_metadata(project, renderer)
|
||||||
|
next_pending.update_from(target.packages, by_whom=str(resolved))
|
||||||
pending = next_pending
|
pending = next_pending
|
||||||
|
|
||||||
resolved = final.resolved()
|
resolved = final.resolved()
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ flake8
|
|||||||
flaky
|
flaky
|
||||||
freezegun==0.3.12
|
freezegun==0.3.12
|
||||||
ipdb
|
ipdb
|
||||||
mypy==0.981
|
mypy==0.942
|
||||||
pip-tools
|
pip-tools
|
||||||
pre-commit
|
pre-commit
|
||||||
protobuf
|
protobuf
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ from copy import deepcopy
|
|||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
from dbt.flags import set_from_args
|
||||||
|
from argparse import Namespace
|
||||||
import dbt.deps
|
import dbt.deps
|
||||||
import dbt.exceptions
|
import dbt.exceptions
|
||||||
from dbt.deps.git import GitUnpinnedPackage
|
from dbt.deps.git import GitUnpinnedPackage
|
||||||
@@ -23,6 +25,8 @@ from dbt.version import get_installed_version
|
|||||||
|
|
||||||
from dbt.dataclass_schema import ValidationError
|
from dbt.dataclass_schema import ValidationError
|
||||||
|
|
||||||
|
set_from_args(Namespace(SEND_ANONYMOUS_USAGE_STATS=False), None)
|
||||||
|
|
||||||
|
|
||||||
class TestLocalPackage(unittest.TestCase):
|
class TestLocalPackage(unittest.TestCase):
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
@@ -300,10 +304,8 @@ class TestHubPackage(unittest.TestCase):
|
|||||||
|
|
||||||
with self.assertRaises(dbt.exceptions.DependencyError) as exc:
|
with self.assertRaises(dbt.exceptions.DependencyError) as exc:
|
||||||
c.resolved()
|
c.resolved()
|
||||||
msg = (
|
msg = "Version error for package dbt-labs-test/a: \n Required by user: ['=0.1.3']"
|
||||||
"Version error for package dbt-labs-test/a: Could not "
|
print(f"--- from str(exc.exception): {str(exc.exception)}")
|
||||||
"find a satisfactory version from options: ['=0.1.2', '=0.1.3']"
|
|
||||||
)
|
|
||||||
self.assertEqual(msg, str(exc.exception))
|
self.assertEqual(msg, str(exc.exception))
|
||||||
|
|
||||||
def test_resolve_ranges(self):
|
def test_resolve_ranges(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user