dagster-cloud-cli 1.13.4__tar.gz → 1.13.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/PKG-INFO +2 -9
  2. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/ci/__init__.py +1 -1
  3. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/config.py +4 -1
  4. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/config/jinja_template_loader.py +1 -1
  5. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/config_utils.py +17 -13
  6. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/deps.py +26 -4
  7. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/entrypoint.py +2 -2
  8. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/gql.py +1 -1
  9. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/types.py +6 -4
  10. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/utils.py +2 -2
  11. dagster_cloud_cli-1.13.5/dagster_cloud_cli/version.py +1 -0
  12. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/config/test_config_loader.py +10 -6
  13. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/test_gql.py +1 -1
  14. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/test_pyproject_toml_support.py +58 -0
  15. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/pyproject.toml +10 -3
  16. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/tox.ini +6 -4
  17. dagster_cloud_cli-1.13.5/uv.lock +1107 -0
  18. dagster_cloud_cli-1.13.4/dagster_cloud_cli/version.py +0 -1
  19. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/.gitignore +0 -0
  20. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/LICENSE +0 -0
  21. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/__init__.py +0 -0
  22. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/__init__.py +0 -0
  23. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/branch_deployment/__init__.py +0 -0
  24. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/ci/checks.py +0 -0
  25. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/ci/report.py +0 -0
  26. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/ci/state.py +0 -0
  27. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/ci/utils.py +0 -0
  28. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/deployment/__init__.py +0 -0
  29. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/deployment/alert_policies/__init__.py +0 -0
  30. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/deployment/alert_policies/commands.py +0 -0
  31. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/integration/__init__.py +0 -0
  32. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/integration/atlan/__init__.py +0 -0
  33. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/job/__init__.py +0 -0
  34. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/metrics.py +0 -0
  35. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/organization/__init__.py +0 -0
  36. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/organization/saml/__init__.py +0 -0
  37. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/organization/saml/commands.py +0 -0
  38. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/run/__init__.py +0 -0
  39. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/serverless/Dockerfile +0 -0
  40. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/serverless/Dockerfile.dagster-cloud-cli +0 -0
  41. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/serverless/__init__.py +0 -0
  42. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/commands/workspace/__init__.py +0 -0
  43. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/config/__init__.py +0 -0
  44. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/config/list_merge_strategies.py +0 -0
  45. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/config/loader.py +0 -0
  46. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/config/merger.py +0 -0
  47. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/config/models.py +0 -0
  48. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/__init__.py +0 -0
  49. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/agent_queue.py +0 -0
  50. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/alert_types.py +0 -0
  51. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/artifacts.py +0 -0
  52. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/docker_runner.py +0 -0
  53. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/errors.py +0 -0
  54. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/graphql_client.py +0 -0
  55. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/headers/__init__.py +0 -0
  56. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/headers/auth.py +0 -0
  57. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/headers/impl.py +0 -0
  58. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/headers/versioning/__init__.py +0 -0
  59. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/headers/versioning/constants.py +0 -0
  60. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/__init__.py +0 -0
  61. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/code_location.py +0 -0
  62. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/deploy.py +0 -0
  63. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/git_context.py +0 -0
  64. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/github_context.py +0 -0
  65. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/gitlab_context.py +0 -0
  66. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/parse_workspace.py +0 -0
  67. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/pex_registry.py +0 -0
  68. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/platforms.py +0 -0
  69. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/selftest.py +0 -0
  70. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/source.py +0 -0
  71. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/pex_builder/util.py +0 -0
  72. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/core/workspace.py +0 -0
  73. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/docker_utils.py +0 -0
  74. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/pex_utils.py +0 -0
  75. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/py.typed +0 -0
  76. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli/ui.py +0 -0
  77. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/__init__.py +0 -0
  78. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/commands/ci/integration/__init__.py +0 -0
  79. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/commands/ci/test_ci_template.py +0 -0
  80. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/commands/integration/test_atlan_integration_cli.py +0 -0
  81. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/config/test_defaults_merging.py +0 -0
  82. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/config/test_template_loader.py +0 -0
  83. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/conftest.py +0 -0
  84. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/test_artifacts.py +0 -0
  85. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/test_check.py +0 -0
  86. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/test_ci_commands.py +0 -0
  87. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/test_metrics.py +0 -0
  88. {dagster_cloud_cli-1.13.4 → dagster_cloud_cli-1.13.5}/dagster_cloud_cli_tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dagster-cloud-cli
3
- Version: 1.13.4
3
+ Version: 1.13.5
4
4
  Project-URL: Homepage, https://github.com/dagster-io/dagster/tree/master/python_modules/libraries/dagster-cloud-cli
5
5
  Author-email: Dagster Labs <hello@dagsterlabs.com>
6
6
  License-Expression: Apache-2.0
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.12
12
12
  Classifier: Programming Language :: Python :: 3.13
13
13
  Classifier: Programming Language :: Python :: 3.14
14
14
  Requires-Dist: click
15
- Requires-Dist: dagster-shared==1.13.4
15
+ Requires-Dist: dagster-shared==1.13.5
16
16
  Requires-Dist: github3-py
17
17
  Requires-Dist: jinja2
18
18
  Requires-Dist: packaging>=20.9
@@ -23,10 +23,3 @@ Requires-Dist: setuptools
23
23
  Requires-Dist: tomli>=1.1.0; python_version < '3.11'
24
24
  Requires-Dist: typer>=0.15.0
25
25
  Requires-Dist: validators
26
- Provides-Extra: test
27
- Requires-Dist: flaky; extra == 'test'
28
- Requires-Dist: freezegun; extra == 'test'
29
- Requires-Dist: pex<2.60.0,>=2.1.132; extra == 'test'
30
- Requires-Dist: pip; extra == 'test'
31
- Requires-Dist: pytest-mock==3.14.0; extra == 'test'
32
- Requires-Dist: pytest>=8; extra == 'test'
@@ -1060,7 +1060,7 @@ def _deploy(
1060
1060
  else {}
1061
1061
  ),
1062
1062
  }
1063
- if build_output.strategy == "python-executable":
1063
+ if isinstance(build_output, state.PexBuildOutput):
1064
1064
  metrics.instrument_add_tags([CliEventTags.server_strategy.pex])
1065
1065
  location_args["pex_tag"] = build_output.pex_tag
1066
1066
  location_args["python_version"] = build_output.python_version
@@ -32,7 +32,10 @@ def set_deployment(
32
32
 
33
33
  config = read_config()
34
34
  new_config = DagsterPlusCliConfig(
35
- **{**config.__dict__, "default_deployment": deployment},
35
+ **{ # ty: ignore[invalid-argument-type]
36
+ **config.__dict__,
37
+ "default_deployment": deployment,
38
+ },
36
39
  )
37
40
  write_config(new_config)
38
41
 
@@ -40,6 +40,6 @@ class JinjaTemplateLoader:
40
40
 
41
41
  env = Environment(loader=FileSystemLoader(template_path))
42
42
  env.filters["to_yaml"] = self.to_yaml
43
- env.globals["get_env"] = self.get_env
43
+ env.globals["get_env"] = self.get_env # ty: ignore[invalid-assignment]
44
44
  template = env.get_template(filename)
45
45
  return template.render(context)
@@ -3,7 +3,10 @@ import functools
3
3
  import inspect
4
4
  import os
5
5
  from pathlib import Path
6
- from typing import Any, cast
6
+ from typing import TYPE_CHECKING, Any
7
+
8
+ if TYPE_CHECKING:
9
+ from typer.models import OptionInfo
7
10
 
8
11
  import yaml
9
12
  from click import Context
@@ -98,7 +101,7 @@ def get_location_load_timeout() -> int:
98
101
 
99
102
  env_val = os.getenv(LOCATION_LOAD_TIMEOUT_ENV_VAR_NAME)
100
103
 
101
- return int(cast("str", env_val)) if env_val is not None else default_timeout
104
+ return int(env_val) if env_val is not None else default_timeout
102
105
 
103
106
 
104
107
  def get_agent_heartbeat_timeout(default_timeout: int | None) -> int | None:
@@ -108,7 +111,7 @@ def get_agent_heartbeat_timeout(default_timeout: int | None) -> int | None:
108
111
  """
109
112
  env_val = os.getenv(AGENT_HEARTBEAT_TIMEOUT_ENV_VAR_NAME)
110
113
 
111
- return int(cast("str", env_val)) if env_val is not None else None
114
+ return int(env_val) if env_val is not None else None
112
115
 
113
116
 
114
117
  def get_user_token(ctx: Context | None = None) -> str | None:
@@ -151,20 +154,20 @@ def get_org_url(organization: str, dagster_env: str | None):
151
154
 
152
155
 
153
156
  # Typer Option definitions for common CLI config options (organization, deployment, user token)
154
- ORGANIZATION_OPTION = Option(
157
+ ORGANIZATION_OPTION = Option( # ty: ignore[no-matching-overload]
155
158
  get_organization,
156
159
  "--organization",
157
160
  "-o",
158
161
  help="Organization to target.",
159
- show_default=get_organization(), # type: ignore
162
+ show_default=get_organization(),
160
163
  )
161
- DEPLOYMENT_OPTION = Option(
164
+ DEPLOYMENT_OPTION = Option( # ty: ignore[no-matching-overload]
162
165
  get_deployment,
163
166
  "--deployment",
164
167
  "-d",
165
168
  help="Deployment to target.",
166
169
  autocompletion=available_deployment_names,
167
- show_default=get_deployment(), # type: ignore
170
+ show_default=get_deployment(),
168
171
  )
169
172
 
170
173
  DAGSTER_ENV_OPTION = Option(
@@ -174,13 +177,14 @@ DAGSTER_ENV_OPTION = Option(
174
177
  envvar="DAGSTER_CLOUD_ENV",
175
178
  )
176
179
 
177
- USER_TOKEN_OPTION = Option(
180
+ _user_token = get_user_token()
181
+ USER_TOKEN_OPTION = Option( # ty: ignore[no-matching-overload]
178
182
  get_user_token,
179
183
  "--api-token",
180
184
  "--user-token",
181
185
  "-u",
182
186
  help="Cloud user token.",
183
- show_default=ui.censor_token(get_user_token()) if get_user_token() else None, # type: ignore
187
+ show_default=ui.censor_token(_user_token) if _user_token else None,
184
188
  )
185
189
  URL_OPTION = Option(
186
190
  get_url,
@@ -235,7 +239,7 @@ def dagster_cloud_options(
235
239
  wrapped_sig = inspect.signature(to_wrap)
236
240
  params = collections.OrderedDict(wrapped_sig.parameters)
237
241
 
238
- options = {
242
+ options: dict[str, tuple[Any, OptionInfo]] = {
239
243
  ORGANIZATION_CLI_ARGUMENT: (str, ORGANIZATION_OPTION),
240
244
  TOKEN_CLI_ARGUMENT_VAR: (str, USER_TOKEN_OPTION),
241
245
  }
@@ -254,13 +258,13 @@ def dagster_cloud_options(
254
258
 
255
259
  has_location_load_timeout_param = LOCATION_LOAD_TIMEOUT_ARGUMENT_VAR in params
256
260
  if has_location_load_timeout_param:
257
- options[LOCATION_LOAD_TIMEOUT_ARGUMENT_VAR] = ( # pyright: ignore[reportArgumentType]
261
+ options[LOCATION_LOAD_TIMEOUT_ARGUMENT_VAR] = (
258
262
  int,
259
263
  LOCATION_LOAD_TIMEOUT_OPTION,
260
264
  )
261
265
  has_agent_heartbeat_timeout_param = AGENT_HEARTBEAT_TIMEOUT_ARGUMENT_VAR in params
262
266
  if has_agent_heartbeat_timeout_param:
263
- options[AGENT_HEARTBEAT_TIMEOUT_ARGUMENT_VAR] = ( # pyright: ignore[reportArgumentType]
267
+ options[AGENT_HEARTBEAT_TIMEOUT_ARGUMENT_VAR] = (
264
268
  int,
265
269
  get_agent_heartbeat_timeout_option(default_timeout=60),
266
270
  )
@@ -278,7 +282,7 @@ def dagster_cloud_options(
278
282
  and kwargs.get(DEPLOYMENT_CLI_ARGUMENT)
279
283
  ):
280
284
  kwargs[URL_CLI_ARGUMENT] = gql.url_from_config(
281
- organization=kwargs.get(ORGANIZATION_CLI_ARGUMENT), # pyright: ignore[reportArgumentType]
285
+ organization=kwargs.get(ORGANIZATION_CLI_ARGUMENT), # ty: ignore[invalid-argument-type]
282
286
  deployment=kwargs.get(DEPLOYMENT_CLI_ARGUMENT),
283
287
  )
284
288
 
@@ -16,9 +16,11 @@ from dataclasses import dataclass
16
16
  import click
17
17
  from dagster_shared.utils import find_uv_workspace_root
18
18
  from packaging import version
19
+ from packaging.requirements import InvalidRequirement, Requirement
20
+ from packaging.utils import canonicalize_name
19
21
 
20
22
  try:
21
- import tomllib # pyright: ignore[reportMissingImports]
23
+ import tomllib # ty: ignore[unresolved-import]
22
24
  except ImportError:
23
25
  # Python < 3.11 fallback
24
26
  import tomli as tomllib
@@ -460,19 +462,39 @@ def get_pyproject_toml_deps(code_directory: str) -> list[str]:
460
462
  else:
461
463
  lines.append(dep_name)
462
464
 
463
- # Handle [tool.uv.sources] - resolve workspace and path dependencies to local paths
465
+ # Handle [tool.uv.sources] - resolve workspace and path dependencies to local paths.
466
+ # Match by canonical package name so version specifiers and extras in the requirement
467
+ # line don't defeat the lookup. Skip entries gated on a `group =` qualifier: pex builds
468
+ # have no active group context, so group-conditional sources must not be applied
469
+ # (otherwise a test-only local-path override would leak into the production deps pex).
464
470
  uv_sources = pyproject_data.get("tool", {}).get("uv", {}).get("sources", {})
465
471
  if uv_sources:
472
+ sources_by_canonical = {
473
+ canonicalize_name(name): cfg for name, cfg in uv_sources.items() if "group" not in cfg
474
+ }
466
475
  resolved_lines = []
467
476
  for line in lines:
468
- source_config = uv_sources.get(line)
477
+ try:
478
+ package_name = canonicalize_name(Requirement(line).name)
479
+ except InvalidRequirement:
480
+ ui.print(
481
+ f"[uv.sources] could not parse requirement line {line!r}; "
482
+ "passing through unchanged"
483
+ )
484
+ resolved_lines.append(line)
485
+ continue
486
+ source_config = sources_by_canonical.get(package_name)
469
487
  if source_config:
470
488
  if source_config.get("workspace"):
471
- resolved_path = _resolve_uv_workspace_dep(line, code_directory)
489
+ resolved_path = _resolve_uv_workspace_dep(package_name, code_directory)
472
490
  if resolved_path:
491
+ ui.print(
492
+ f"[uv.sources] resolved {line!r} to workspace path {resolved_path}"
493
+ )
473
494
  resolved_lines.append(resolved_path)
474
495
  continue
475
496
  elif "path" in source_config:
497
+ ui.print(f"[uv.sources] resolved {line!r} to path {source_config['path']}")
476
498
  resolved_lines.append(source_config["path"])
477
499
  continue
478
500
  resolved_lines.append(line)
@@ -33,8 +33,8 @@ has_dagster_cloud = importlib.util.find_spec("dagster_cloud") is not None
33
33
 
34
34
 
35
35
  if has_dagster_cloud:
36
- from dagster_cloud.agent.cli import app as agent_app # type: ignore
37
- from dagster_cloud.pex.grpc.server.cli import app as pex_app # type: ignore
36
+ from dagster_cloud.agent.cli import app as agent_app
37
+ from dagster_cloud.pex.grpc.server.cli import app as pex_app
38
38
  else:
39
39
  agent_app = create_stub_app("dagster-cloud")
40
40
  pex_app = create_stub_app("dagster-cloud")
@@ -682,7 +682,7 @@ def launch_run(
682
682
  config: dict[str, Any],
683
683
  asset_keys: list[str] | None,
684
684
  ) -> str:
685
- formatted_tags = [{"key": cast("str", k), "value": cast("str", v)} for k, v in tags.items()]
685
+ formatted_tags = [{"key": k, "value": v} for k, v in tags.items()]
686
686
 
687
687
  params: dict[str, Any] = {
688
688
  "selector": {
@@ -9,13 +9,15 @@ class CliEventType(Enum):
9
9
 
10
10
 
11
11
  AgentStrategyTags = Enum(
12
- "agent-strategy", {"hybrid": "agent-strategy:hybrid", "serverless": "agent-strategy:serverless"}
12
+ "agent-strategy", # ty: ignore[mismatched-type-name]
13
+ {"hybrid": "agent-strategy:hybrid", "serverless": "agent-strategy:serverless"},
13
14
  )
14
15
  ServerStrategyTags = Enum(
15
- "server-strategy", {"docker": "server-strategy:docker", "pex": "server-strategy:pex"}
16
+ "server-strategy", # ty: ignore[mismatched-type-name]
17
+ {"docker": "server-strategy:docker", "pex": "server-strategy:pex"},
16
18
  )
17
19
  SourceTags = Enum(
18
- "source",
20
+ "source", # ty: ignore[mismatched-type-name]
19
21
  {
20
22
  "bitbucket": "source:bitbucket",
21
23
  "buildkite": "source:buildkite",
@@ -30,7 +32,7 @@ SourceTags = Enum(
30
32
  },
31
33
  )
32
34
  SubcommandTags = Enum(
33
- "subcommand",
35
+ "subcommand", # ty: ignore[mismatched-type-name]
34
36
  {
35
37
  "dagster_cloud_ci": "subcommand:dagster-cloud-ci",
36
38
  "dagster_cloud_serverless": "subcommand:dagster-cloud-serverless",
@@ -87,8 +87,8 @@ def add_options(options: dict[str, tuple[Any, "OptionInfo"]]):
87
87
  }
88
88
  return to_wrap(*args, **modified_kwargs)
89
89
 
90
- wrap_function.__signature__ = sig # pyright: ignore[reportAttributeAccessIssue]
91
- wrap_function.modified_options = True # pyright: ignore[reportAttributeAccessIssue]
90
+ wrap_function.__signature__ = sig # ty: ignore[unresolved-attribute]
91
+ wrap_function.modified_options = True # ty: ignore[unresolved-attribute]
92
92
  return wrap_function
93
93
 
94
94
  return decorator
@@ -0,0 +1 @@
1
+ __version__ = "1.13.5"
@@ -104,18 +104,22 @@ def test_config_loader(tmpdir):
104
104
  result = loader.load_from_template(template_file, context)
105
105
  assert isinstance(result, ProcessedDagsterCloudConfig)
106
106
  assert len(result.locations) == 1
107
- assert result.locations[0].location_name == "foo"
108
- assert result.locations[0].code_source.package_name == "foo"
109
- assert result.locations[0].build.model_dump() == {
107
+ location = result.locations[0]
108
+ assert location.location_name == "foo"
109
+ assert location.code_source is not None
110
+ assert location.code_source.package_name == "foo"
111
+ assert location.build is not None
112
+ assert location.build.model_dump() == {
110
113
  "directory": "foo",
111
114
  "registry": "my-registry.io/my-org",
112
115
  }
113
- assert result.locations[0].image == "foo"
114
- assert set(result.locations[0].container_context["k8s"]["env_vars"]) == {
116
+ assert location.image == "foo"
117
+ assert location.container_context is not None
118
+ assert set(location.container_context["k8s"]["env_vars"]) == {
115
119
  "foo=foo",
116
120
  "global=overridden",
117
121
  }
118
- assert result.locations[0].container_context["k8s"]["resources"] == {
122
+ assert location.container_context["k8s"]["resources"] == {
119
123
  "requests": {"cpu": "1", "memory": "32Gi"},
120
124
  "limits": {"cpu": "2", "memory": "32Gi"},
121
125
  }
@@ -18,7 +18,7 @@ def test_mark_cli_event_doesnt_raise():
18
18
 
19
19
  mark_cli_event(
20
20
  client=client,
21
- event_type=MagicMock(),
21
+ event_type=MagicMock(), # ty: ignore[invalid-argument-type]
22
22
  duration_seconds=MagicMock(),
23
23
  tags=MagicMock(),
24
24
  )
@@ -612,6 +612,64 @@ build-backend = "hatchling.build"
612
612
  )
613
613
 
614
614
 
615
+ def test_get_deps_requirements_uv_sources_path_with_version_specifier(tmp_path):
616
+ """[tool.uv.sources] entries must resolve even when the dependency line carries a
617
+ version specifier or extras (e.g. `pkg==1.0.0`, `pkg[test]`).
618
+ """
619
+ python_version = version.Version(f"{sys.version_info.major}.{sys.version_info.minor}")
620
+
621
+ app_dir = tmp_path / "my-app"
622
+ app_dir.mkdir()
623
+ (app_dir / "my_app").mkdir()
624
+ (app_dir / "my_app" / "__init__.py").write_text("")
625
+ (app_dir / "pyproject.toml").write_text("""
626
+ [project]
627
+ name = "my-app"
628
+ version = "0.1.0"
629
+ dependencies = [
630
+ "local-utils==1!0+dev",
631
+ "Local-Utils-Extras[test]",
632
+ ]
633
+
634
+ [tool.uv.sources]
635
+ local-utils = { path = "../local-utils" }
636
+ local-utils-extras = { path = "../local-utils-extras" }
637
+
638
+ [build-system]
639
+ requires = ["hatchling"]
640
+ build-backend = "hatchling.build"
641
+ """)
642
+
643
+ for name in ("local-utils", "local-utils-extras"):
644
+ d = tmp_path / name
645
+ d.mkdir()
646
+ (d / name.replace("-", "_")).mkdir()
647
+ (d / name.replace("-", "_") / "__init__.py").write_text("")
648
+ (d / "pyproject.toml").write_text(f"""
649
+ [project]
650
+ name = "{name}"
651
+ version = "0.1.0"
652
+ dependencies = []
653
+
654
+ [build-system]
655
+ requires = ["hatchling"]
656
+ build-backend = "hatchling.build"
657
+ """)
658
+
659
+ local_packages, deps_requirements = deps.get_deps_requirements(str(app_dir), python_version)
660
+ deps_lines = [
661
+ line.strip()
662
+ for line in deps_requirements.requirements_txt.strip().split("\n")
663
+ if line.strip()
664
+ ]
665
+
666
+ assert str(tmp_path / "local-utils") in local_packages.local_package_paths
667
+ assert str(tmp_path / "local-utils-extras") in local_packages.local_package_paths
668
+ assert not any("local-utils" in dep for dep in deps_lines), (
669
+ f"local-utils* should resolve to local paths, not deps: {deps_lines}"
670
+ )
671
+
672
+
615
673
  def test_get_deps_requirements_uv_workspace(tmp_path):
616
674
  """Test get_deps_requirements correctly handles uv workspace local dependencies.
617
675
 
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "dagster-cloud-cli"
9
- version = "1.13.4"
9
+ version = "1.13.5"
10
10
  description = ""
11
11
  authors = [
12
12
  { name = "Dagster Labs", email = "hello@dagsterlabs.com" },
@@ -21,7 +21,7 @@ classifiers = [
21
21
  "Operating System :: OS Independent",
22
22
  ]
23
23
  dependencies = [
24
- "dagster-shared==1.13.4",
24
+ "dagster-shared==1.13.5",
25
25
  "packaging>=20.9",
26
26
  "questionary",
27
27
  "requests",
@@ -43,11 +43,18 @@ dagster-cloud = "dagster_cloud_cli.entrypoint:app"
43
43
  dagster-plus = "dagster_cloud_cli.entrypoint:app"
44
44
 
45
45
  [project.optional-dependencies]
46
+
47
+ [dependency-groups]
46
48
  test = [
49
+ "dagster-shared",
47
50
  "freezegun",
48
51
  "pytest>=8",
49
52
  "pytest-mock==3.14.0",
50
- "flaky",
53
+ "pytest-rerunfailures",
51
54
  "pex>=2.1.132,<2.60.0",
52
55
  "pip",
53
56
  ]
57
+
58
+ [tool.uv.sources.dagster-shared]
59
+ path = "../../../python_modules/libraries/dagster-shared"
60
+ editable = true
@@ -1,10 +1,13 @@
1
1
  [tox]
2
2
  requires =
3
- tox-uv>=1
3
+ tox-uv>=1.16
4
4
  envlist=py311
5
5
  skipsdist = True
6
6
 
7
7
  [testenv]
8
+ runner = uv-venv-lock-runner
9
+ uv_sync_locked = false
10
+ uv_sync_flags = --frozen
8
11
  download = True
9
12
  setenv =
10
13
  DD_DOGSTATSD_DISABLE = true
@@ -21,9 +24,8 @@ passenv =
21
24
  POSTGRES_FUNCTION_SCOPED_TEST_DB_HOST
22
25
  UV_CACHE_DIR
23
26
  DAGSTER_INTERNAL_GIT_REPO_DIR
24
- deps =
25
- -e .[test]
26
- -e ../../../python_modules/libraries/dagster-shared
27
+ dependency_groups =
28
+ test
27
29
  allowlist_externals =
28
30
  /bin/bash
29
31
  echo