ops 2.23.0.dev0__tar.gz → 3.0.0__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 (102) hide show
  1. {ops-2.23.0.dev0 → ops-3.0.0}/CHANGES.md +66 -0
  2. {ops-2.23.0.dev0 → ops-3.0.0}/PKG-INFO +4 -4
  3. {ops-2.23.0.dev0 → ops-3.0.0}/ops/charm.py +2 -2
  4. {ops-2.23.0.dev0/test/charms/test_main/lib → ops-3.0.0}/ops/model.py +18 -14
  5. {ops-2.23.0.dev0/test/charms/test_main/lib → ops-3.0.0}/ops/version.py +1 -1
  6. {ops-2.23.0.dev0 → ops-3.0.0}/ops.egg-info/PKG-INFO +4 -4
  7. {ops-2.23.0.dev0 → ops-3.0.0}/ops.egg-info/requires.txt +2 -2
  8. {ops-2.23.0.dev0 → ops-3.0.0}/pyproject.toml +5 -4
  9. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/charm.py +2 -2
  10. {ops-2.23.0.dev0 → ops-3.0.0/test/charms/test_main/lib}/ops/model.py +18 -14
  11. {ops-2.23.0.dev0 → ops-3.0.0/test/charms/test_main/lib}/ops/version.py +1 -1
  12. {ops-2.23.0.dev0 → ops-3.0.0}/tox.ini +2 -2
  13. {ops-2.23.0.dev0 → ops-3.0.0}/CODE_OF_CONDUCT.md +0 -0
  14. {ops-2.23.0.dev0 → ops-3.0.0}/CONTRIBUTING.md +0 -0
  15. {ops-2.23.0.dev0 → ops-3.0.0}/HACKING.md +0 -0
  16. {ops-2.23.0.dev0 → ops-3.0.0}/LICENSE.txt +0 -0
  17. {ops-2.23.0.dev0 → ops-3.0.0}/MANIFEST.in +0 -0
  18. {ops-2.23.0.dev0 → ops-3.0.0}/README.md +0 -0
  19. {ops-2.23.0.dev0 → ops-3.0.0}/SECURITY.md +0 -0
  20. {ops-2.23.0.dev0 → ops-3.0.0}/STYLE.md +0 -0
  21. {ops-2.23.0.dev0 → ops-3.0.0}/ops/__init__.py +0 -0
  22. {ops-2.23.0.dev0 → ops-3.0.0}/ops/_main.py +0 -0
  23. {ops-2.23.0.dev0 → ops-3.0.0}/ops/_private/__init__.py +0 -0
  24. {ops-2.23.0.dev0 → ops-3.0.0}/ops/_private/harness.py +0 -0
  25. {ops-2.23.0.dev0 → ops-3.0.0}/ops/_private/timeconv.py +0 -0
  26. {ops-2.23.0.dev0 → ops-3.0.0}/ops/_private/yaml.py +0 -0
  27. {ops-2.23.0.dev0 → ops-3.0.0}/ops/framework.py +0 -0
  28. {ops-2.23.0.dev0 → ops-3.0.0}/ops/jujucontext.py +0 -0
  29. {ops-2.23.0.dev0 → ops-3.0.0}/ops/jujuversion.py +0 -0
  30. {ops-2.23.0.dev0 → ops-3.0.0}/ops/lib/__init__.py +0 -0
  31. {ops-2.23.0.dev0 → ops-3.0.0}/ops/log.py +0 -0
  32. {ops-2.23.0.dev0 → ops-3.0.0}/ops/main.py +0 -0
  33. {ops-2.23.0.dev0 → ops-3.0.0}/ops/pebble.py +0 -0
  34. {ops-2.23.0.dev0 → ops-3.0.0}/ops/py.typed +0 -0
  35. {ops-2.23.0.dev0 → ops-3.0.0}/ops/storage.py +0 -0
  36. {ops-2.23.0.dev0 → ops-3.0.0}/ops/testing.py +0 -0
  37. {ops-2.23.0.dev0 → ops-3.0.0}/ops.egg-info/SOURCES.txt +0 -0
  38. {ops-2.23.0.dev0 → ops-3.0.0}/ops.egg-info/dependency_links.txt +0 -0
  39. {ops-2.23.0.dev0 → ops-3.0.0}/ops.egg-info/top_level.txt +0 -0
  40. {ops-2.23.0.dev0 → ops-3.0.0}/setup.cfg +0 -0
  41. {ops-2.23.0.dev0 → ops-3.0.0}/test/__init__.py +0 -0
  42. {ops-2.23.0.dev0 → ops-3.0.0}/test/benchmark/__init__.py +0 -0
  43. {ops-2.23.0.dev0 → ops-3.0.0}/test/bin/relation-ids +0 -0
  44. {ops-2.23.0.dev0 → ops-3.0.0}/test/bin/relation-ids.bat +0 -0
  45. {ops-2.23.0.dev0 → ops-3.0.0}/test/bin/relation-list +0 -0
  46. {ops-2.23.0.dev0 → ops-3.0.0}/test/bin/relation-list.bat +0 -0
  47. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/actions.yaml +0 -0
  48. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/config.yaml +0 -0
  49. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/__init__.py +0 -0
  50. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/__init__.py +0 -0
  51. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/_main.py +0 -0
  52. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/_private/__init__.py +0 -0
  53. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/_private/harness.py +0 -0
  54. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/_private/timeconv.py +0 -0
  55. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/_private/yaml.py +0 -0
  56. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/framework.py +0 -0
  57. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/jujucontext.py +0 -0
  58. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/jujuversion.py +0 -0
  59. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/lib/__init__.py +0 -0
  60. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/log.py +0 -0
  61. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/main.py +0 -0
  62. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/pebble.py +0 -0
  63. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/py.typed +0 -0
  64. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/storage.py +0 -0
  65. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/lib/ops/testing.py +0 -0
  66. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/metadata.yaml +0 -0
  67. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_main/src/charm.py +0 -0
  68. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_relation/.gitignore +0 -0
  69. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_relation/charmcraft.yaml +0 -0
  70. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_relation/src/charm.py +0 -0
  71. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_smoke/README.md +0 -0
  72. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_smoke/metadata.yaml +0 -0
  73. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_smoke/src/charm.py +0 -0
  74. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_tracing/.gitignore +0 -0
  75. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_tracing/charmcraft.yaml +0 -0
  76. {ops-2.23.0.dev0 → ops-3.0.0}/test/charms/test_tracing/src/charm.py +0 -0
  77. {ops-2.23.0.dev0 → ops-3.0.0}/test/conftest.py +0 -0
  78. {ops-2.23.0.dev0 → ops-3.0.0}/test/fake_pebble.py +0 -0
  79. {ops-2.23.0.dev0 → ops-3.0.0}/test/integration/conftest.py +0 -0
  80. {ops-2.23.0.dev0 → ops-3.0.0}/test/integration/test_relation.py +0 -0
  81. {ops-2.23.0.dev0 → ops-3.0.0}/test/integration/test_tracing.py +0 -0
  82. {ops-2.23.0.dev0 → ops-3.0.0}/test/pebble_cli.py +0 -0
  83. {ops-2.23.0.dev0 → ops-3.0.0}/test/smoke/test_smoke.py +0 -0
  84. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_charm.py +0 -0
  85. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_framework.py +0 -0
  86. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_helpers.py +0 -0
  87. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_infra.py +0 -0
  88. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_jujucontext.py +0 -0
  89. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_jujuversion.py +0 -0
  90. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_lib.py +0 -0
  91. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_log.py +0 -0
  92. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_main.py +0 -0
  93. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_main_invocation.py +0 -0
  94. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_main_type_hint.py +0 -0
  95. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_model.py +0 -0
  96. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_model_relation_data_class.py +0 -0
  97. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_pebble.py +0 -0
  98. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_real_pebble.py +0 -0
  99. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_storage.py +0 -0
  100. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_testing.py +0 -0
  101. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_timeconv.py +0 -0
  102. {ops-2.23.0.dev0 → ops-3.0.0}/test/test_yaml.py +0 -0
@@ -1,3 +1,69 @@
1
+ # 3.0.0 - 02 July 2025
2
+
3
+ The minimum version of Python for Ops 3.x is 3.10.
4
+
5
+ ## Documentation
6
+
7
+ * Be consistent with recommending self.app and self.unit (#1856)
8
+
9
+ ## CI
10
+
11
+ * Hotfix, publish job for ops-tracing (#1865)
12
+
13
+ # 2.23.0 - 30 June 2025
14
+
15
+ ## Features
16
+
17
+ * Support for config schema as Python classes (#1741)
18
+ * Support for action parameter schema as Python classes (#1756)
19
+ * Ops[tracing] compatibility with jhack (#1806)
20
+ * Support for relation data schema as Python classes (#1701)
21
+ * Add CheckInfo.successes field and .has_run property (#1819)
22
+ * Provide a method to create a testing.State from a testing.Context (#1797)
23
+ * Expose trace data in testing (#1842)
24
+ * Add a helper to generate a Layer from rockcraft.yaml (#1831)
25
+
26
+ ## Fixes
27
+
28
+ * Correctly load an empty Juju config options map (#1778)
29
+ * Fix type annotation of container check_infos in ops.testing (#1784)
30
+ * Restrict the version of a dependency, opentelemetry-sdk (#1794)
31
+ * Remote unit data is available in relation-departed (#1364)
32
+ * Juju allows access to the remote app databag in relation-broken, so Harness should too (#1787)
33
+ * Don't use private OpenTelemetry API (#1798)
34
+ * Do not return this unit in a mocked peer relation (#1828)
35
+ * Testing.PeerRelation properly defaults to no peers (#1832)
36
+ * In meter-status-changed JUJU_VERSION is not set (#1840)
37
+ * Only provide the units belonging to the app in Relation.units (#1837)
38
+
39
+ ## Documentation
40
+
41
+ * Remove two best practices, and drop two to tips (#1758)
42
+ * Update link to Charmcraft for managing app config (#1763)
43
+ * Update link to Juju documentation for setting up deployment (#1781)
44
+ * Fix external OTLP link (#1786)
45
+ * Distribute the ops-scenario README content across the ops docs (#1773)
46
+ * Improve testing.errors.UncaughtCharmError message (#1795)
47
+ * In the "manage the charm version" how-to, give an example of using override-build (#1802)
48
+ * Small adjustments to the 'how to trace charm code' doc (#1792)
49
+ * Replace Harness example and fix links in README (#1820)
50
+ * Add httpbin charm from Charmcraft as an example charm (#1743)
51
+ * Fix on_collect mistake in sample code (#1829)
52
+ * Update code in K8s tutorial, with source in repo (part 2) (#1734)
53
+ * Update Loki section on charming zero-to-hero tutorial (#1847)
54
+ * Remove expandable boxes of text (#1844)
55
+ * Improve httpbin charm by removing defer() and adding collect_status (#1833)
56
+ * Move {posargs} to the end of pytest command lines in tox.ini (#1854)
57
+
58
+ ## CI
59
+
60
+ * Install the ops[tracing] dependencies for the TIOBE action (#1761)
61
+ * Add ops-scenario and ops-tracing as explicit installs for TIOBE (#1764)
62
+ * Persist credentials for update-charm-pins workflow (#1766)
63
+ * Stop smoke testing Charmcraft 2 (#1782)
64
+ * Use Charmcraft 3.x for smoke testing 20.04 and 22.04 (#1821)
65
+ * Enable xdist for the 'unit' tox environments (#1830)
66
+
1
67
  # 2.22.0 - 29 May 2025
2
68
 
3
69
  ## Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ops
3
- Version: 2.23.0.dev0
3
+ Version: 3.0.0
4
4
  Summary: The Python library behind great charms
5
5
  Author: The Charm Tech team at Canonical Ltd.
6
6
  Project-URL: Homepage, https://ops.readthedocs.io/en/latest/
@@ -15,7 +15,7 @@ Classifier: Intended Audience :: Developers
15
15
  Classifier: Intended Audience :: System Administrators
16
16
  Classifier: Operating System :: MacOS :: MacOS X
17
17
  Classifier: Operating System :: POSIX :: Linux
18
- Requires-Python: >=3.8
18
+ Requires-Python: >=3.10
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE.txt
21
21
  Requires-Dist: PyYAML==6.*
@@ -23,9 +23,9 @@ Requires-Dist: websocket-client==1.*
23
23
  Requires-Dist: opentelemetry-api~=1.0
24
24
  Requires-Dist: importlib-metadata
25
25
  Provides-Extra: testing
26
- Requires-Dist: ops-scenario==7.23.0.dev0; extra == "testing"
26
+ Requires-Dist: ops-scenario==8.0.0; extra == "testing"
27
27
  Provides-Extra: tracing
28
- Requires-Dist: ops-tracing==2.23.0.dev0; extra == "tracing"
28
+ Requires-Dist: ops-tracing==3.0.0; extra == "tracing"
29
29
  Provides-Extra: harness
30
30
  Dynamic: license-file
31
31
 
@@ -1467,12 +1467,12 @@ class CharmBase(Object):
1467
1467
 
1468
1468
  @property
1469
1469
  def app(self) -> model.Application:
1470
- """Application that this unit is part of."""
1470
+ """The application that this unit is part of."""
1471
1471
  return self.framework.model.app
1472
1472
 
1473
1473
  @property
1474
1474
  def unit(self) -> model.Unit:
1475
- """Unit that this execution is responsible for."""
1475
+ """The current unit."""
1476
1476
  return self.framework.model.unit
1477
1477
 
1478
1478
  @property
@@ -159,17 +159,17 @@ class Model:
159
159
 
160
160
  @property
161
161
  def unit(self) -> Unit:
162
- """The unit that is running this code.
162
+ """The current unit. Equivalent to :attr:`CharmBase.unit`.
163
163
 
164
- Use :meth:`get_unit` to get an arbitrary unit by name.
164
+ To get a unit by name, use :meth:`get_unit`.
165
165
  """
166
166
  return self._unit
167
167
 
168
168
  @property
169
169
  def app(self) -> Application:
170
- """The application this unit is a part of.
170
+ """The application that this unit is part of. Equivalent to :attr:`CharmBase.app`.
171
171
 
172
- Use :meth:`get_app` to get an arbitrary application by name.
172
+ To get an application by name, use :meth:`get_app`.
173
173
  """
174
174
  return self._unit.app
175
175
 
@@ -238,22 +238,22 @@ class Model:
238
238
  return self._backend._juju_context.version
239
239
 
240
240
  def get_unit(self, unit_name: str) -> Unit:
241
- """Get an arbitrary unit by name.
242
-
243
- Use :attr:`unit` to get the current unit.
241
+ """Get a unit by name.
244
242
 
245
243
  Internally this uses a cache, so asking for the same unit two times will
246
244
  return the same object.
245
+
246
+ To get the current unit, use :attr:`CharmBase.unit` or :attr:`unit`.
247
247
  """
248
248
  return self._cache.get(Unit, unit_name)
249
249
 
250
250
  def get_app(self, app_name: str) -> Application:
251
251
  """Get an application by name.
252
252
 
253
- Use :attr:`app` to get this charm's application.
254
-
255
253
  Internally this uses a cache, so asking for the same application two times will
256
254
  return the same object.
255
+
256
+ To get the application that this unit is part of, use :attr:`CharmBase.app` or :attr:`app`.
257
257
  """
258
258
  return self._cache.get(Application, app_name)
259
259
 
@@ -380,9 +380,10 @@ class Application:
380
380
  """Represents a named application in the model.
381
381
 
382
382
  This might be this charm's application, or might be an application this charm is integrated
383
- with. Charmers should not instantiate Application objects directly, but should use
384
- :attr:`Model.app` to get the application this unit is part of, or
385
- :meth:`Model.get_app` if they need a reference to a given application.
383
+ with.
384
+
385
+ Don't instantiate Application objects directly. To get the application that this unit is
386
+ part of, use :attr:`CharmBase.app`. To get an application by name, use :meth:`Model.get_app`.
386
387
  """
387
388
 
388
389
  name: str
@@ -426,7 +427,7 @@ class Application:
426
427
 
427
428
  Example::
428
429
 
429
- self.model.app.status = ops.BlockedStatus('I need a human to come help me')
430
+ self.app.status = ops.BlockedStatus('I need a human to come help me')
430
431
  """
431
432
  if not self._is_our_app:
432
433
  return UnknownStatus()
@@ -556,6 +557,9 @@ class Unit:
556
557
 
557
558
  This might be the current unit, another unit of the charm's application, or a unit of
558
559
  another application that the charm is integrated with.
560
+
561
+ Don't instantiate Unit objects directly. To get the current unit, use :attr:`CharmBase.unit`.
562
+ To get a unit by name, use :meth:`Model.get_unit`.
559
563
  """
560
564
 
561
565
  name: str
@@ -609,7 +613,7 @@ class Unit:
609
613
 
610
614
  Example::
611
615
 
612
- self.model.unit.status = ops.MaintenanceStatus('reconfiguring the frobnicators')
616
+ self.unit.status = ops.MaintenanceStatus('reconfiguring the frobnicators')
613
617
  """
614
618
  if not self._is_our_unit:
615
619
  return UnknownStatus()
@@ -19,4 +19,4 @@ This module is NOT to be used when developing charms using ops.
19
19
 
20
20
  from __future__ import annotations
21
21
 
22
- version: str = '2.23.0.dev0'
22
+ version: str = '3.0.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ops
3
- Version: 2.23.0.dev0
3
+ Version: 3.0.0
4
4
  Summary: The Python library behind great charms
5
5
  Author: The Charm Tech team at Canonical Ltd.
6
6
  Project-URL: Homepage, https://ops.readthedocs.io/en/latest/
@@ -15,7 +15,7 @@ Classifier: Intended Audience :: Developers
15
15
  Classifier: Intended Audience :: System Administrators
16
16
  Classifier: Operating System :: MacOS :: MacOS X
17
17
  Classifier: Operating System :: POSIX :: Linux
18
- Requires-Python: >=3.8
18
+ Requires-Python: >=3.10
19
19
  Description-Content-Type: text/markdown
20
20
  License-File: LICENSE.txt
21
21
  Requires-Dist: PyYAML==6.*
@@ -23,9 +23,9 @@ Requires-Dist: websocket-client==1.*
23
23
  Requires-Dist: opentelemetry-api~=1.0
24
24
  Requires-Dist: importlib-metadata
25
25
  Provides-Extra: testing
26
- Requires-Dist: ops-scenario==7.23.0.dev0; extra == "testing"
26
+ Requires-Dist: ops-scenario==8.0.0; extra == "testing"
27
27
  Provides-Extra: tracing
28
- Requires-Dist: ops-tracing==2.23.0.dev0; extra == "tracing"
28
+ Requires-Dist: ops-tracing==3.0.0; extra == "tracing"
29
29
  Provides-Extra: harness
30
30
  Dynamic: license-file
31
31
 
@@ -6,7 +6,7 @@ importlib-metadata
6
6
  [harness]
7
7
 
8
8
  [testing]
9
- ops-scenario==7.23.0.dev0
9
+ ops-scenario==8.0.0
10
10
 
11
11
  [tracing]
12
- ops-tracing==2.23.0.dev0
12
+ ops-tracing==3.0.0
@@ -2,7 +2,7 @@
2
2
  name = "ops"
3
3
  description = "The Python library behind great charms"
4
4
  readme = "README.md"
5
- requires-python = ">=3.8"
5
+ requires-python = ">=3.10"
6
6
  authors = [
7
7
  {name="The Charm Tech team at Canonical Ltd."},
8
8
  ]
@@ -26,10 +26,10 @@ dynamic = ["version"]
26
26
 
27
27
  [project.optional-dependencies]
28
28
  testing = [
29
- "ops-scenario==7.23.0.dev0",
29
+ "ops-scenario==8.0.0",
30
30
  ]
31
31
  tracing = [
32
- "ops-tracing==2.23.0.dev0",
32
+ "ops-tracing==3.0.0",
33
33
  ]
34
34
  # Empty for now, because Harness is bundled with the base install, but allow
35
35
  # specifying the extra to ease transition later.
@@ -133,6 +133,7 @@ aggressive = 3
133
133
  # Linting tools configuration
134
134
  [tool.ruff]
135
135
  line-length = 99
136
+ # FIXME
136
137
  target-version = "py38"
137
138
  extend-exclude = ["docs/conf.py", "docs/.sphinx/"]
138
139
 
@@ -321,7 +322,7 @@ builtins-ignorelist = ["id", "min", "map", "range", "type", "TimeoutError", "Con
321
322
  include = ["ops/*.py", "ops/_private/*.py", "test/*.py", "test/charms/*/src/*.py", "testing/src/*.py"]
322
323
  exclude = ["tracing/*"]
323
324
  extraPaths = ["testing", "tracing"]
324
- pythonVersion = "3.8" # check no python > 3.8 features are used
325
+ pythonVersion = "3.10" # check no python > 3.10 features are used
325
326
  pythonPlatform = "All"
326
327
  typeCheckingMode = "strict"
327
328
  reportIncompatibleMethodOverride = false
@@ -1467,12 +1467,12 @@ class CharmBase(Object):
1467
1467
 
1468
1468
  @property
1469
1469
  def app(self) -> model.Application:
1470
- """Application that this unit is part of."""
1470
+ """The application that this unit is part of."""
1471
1471
  return self.framework.model.app
1472
1472
 
1473
1473
  @property
1474
1474
  def unit(self) -> model.Unit:
1475
- """Unit that this execution is responsible for."""
1475
+ """The current unit."""
1476
1476
  return self.framework.model.unit
1477
1477
 
1478
1478
  @property
@@ -159,17 +159,17 @@ class Model:
159
159
 
160
160
  @property
161
161
  def unit(self) -> Unit:
162
- """The unit that is running this code.
162
+ """The current unit. Equivalent to :attr:`CharmBase.unit`.
163
163
 
164
- Use :meth:`get_unit` to get an arbitrary unit by name.
164
+ To get a unit by name, use :meth:`get_unit`.
165
165
  """
166
166
  return self._unit
167
167
 
168
168
  @property
169
169
  def app(self) -> Application:
170
- """The application this unit is a part of.
170
+ """The application that this unit is part of. Equivalent to :attr:`CharmBase.app`.
171
171
 
172
- Use :meth:`get_app` to get an arbitrary application by name.
172
+ To get an application by name, use :meth:`get_app`.
173
173
  """
174
174
  return self._unit.app
175
175
 
@@ -238,22 +238,22 @@ class Model:
238
238
  return self._backend._juju_context.version
239
239
 
240
240
  def get_unit(self, unit_name: str) -> Unit:
241
- """Get an arbitrary unit by name.
242
-
243
- Use :attr:`unit` to get the current unit.
241
+ """Get a unit by name.
244
242
 
245
243
  Internally this uses a cache, so asking for the same unit two times will
246
244
  return the same object.
245
+
246
+ To get the current unit, use :attr:`CharmBase.unit` or :attr:`unit`.
247
247
  """
248
248
  return self._cache.get(Unit, unit_name)
249
249
 
250
250
  def get_app(self, app_name: str) -> Application:
251
251
  """Get an application by name.
252
252
 
253
- Use :attr:`app` to get this charm's application.
254
-
255
253
  Internally this uses a cache, so asking for the same application two times will
256
254
  return the same object.
255
+
256
+ To get the application that this unit is part of, use :attr:`CharmBase.app` or :attr:`app`.
257
257
  """
258
258
  return self._cache.get(Application, app_name)
259
259
 
@@ -380,9 +380,10 @@ class Application:
380
380
  """Represents a named application in the model.
381
381
 
382
382
  This might be this charm's application, or might be an application this charm is integrated
383
- with. Charmers should not instantiate Application objects directly, but should use
384
- :attr:`Model.app` to get the application this unit is part of, or
385
- :meth:`Model.get_app` if they need a reference to a given application.
383
+ with.
384
+
385
+ Don't instantiate Application objects directly. To get the application that this unit is
386
+ part of, use :attr:`CharmBase.app`. To get an application by name, use :meth:`Model.get_app`.
386
387
  """
387
388
 
388
389
  name: str
@@ -426,7 +427,7 @@ class Application:
426
427
 
427
428
  Example::
428
429
 
429
- self.model.app.status = ops.BlockedStatus('I need a human to come help me')
430
+ self.app.status = ops.BlockedStatus('I need a human to come help me')
430
431
  """
431
432
  if not self._is_our_app:
432
433
  return UnknownStatus()
@@ -556,6 +557,9 @@ class Unit:
556
557
 
557
558
  This might be the current unit, another unit of the charm's application, or a unit of
558
559
  another application that the charm is integrated with.
560
+
561
+ Don't instantiate Unit objects directly. To get the current unit, use :attr:`CharmBase.unit`.
562
+ To get a unit by name, use :meth:`Model.get_unit`.
559
563
  """
560
564
 
561
565
  name: str
@@ -609,7 +613,7 @@ class Unit:
609
613
 
610
614
  Example::
611
615
 
612
- self.model.unit.status = ops.MaintenanceStatus('reconfiguring the frobnicators')
616
+ self.unit.status = ops.MaintenanceStatus('reconfiguring the frobnicators')
613
617
  """
614
618
  if not self._is_our_unit:
615
619
  return UnknownStatus()
@@ -19,4 +19,4 @@ This module is NOT to be used when developing charms using ops.
19
19
 
20
20
  from __future__ import annotations
21
21
 
22
- version: str = '2.23.0.dev0'
22
+ version: str = '3.0.0'
@@ -75,7 +75,7 @@ allowlist_externals = cp
75
75
  dependency_groups = unit, static
76
76
  commands = pyright {posargs}
77
77
 
78
- [testenv:py{3.8,3.10,3.12}-unit]
78
+ [testenv:py{3.10,3.12}-unit]
79
79
  runner = uv-venv-lock-runner
80
80
  base=unit
81
81
 
@@ -151,7 +151,7 @@ commands =
151
151
  {[vars]testing_tst_path}benchmark \
152
152
  {posargs}
153
153
 
154
- [testenv:py{3.8,3.10,3.12}-pebble]
154
+ [testenv:py{3.10,3.12}-pebble]
155
155
  runner = uv-venv-lock-runner
156
156
  base=pebble
157
157
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes