Skip to content

Comments

feat: call .name if it's a SettingsBase + Path support#4932

Open
Gobot1234 wants to merge 6 commits intomainfrom
jhilton/less-stringly-typoed
Open

feat: call .name if it's a SettingsBase + Path support#4932
Gobot1234 wants to merge 6 commits intomainfrom
jhilton/less-stringly-typoed

Conversation

@Gobot1234
Copy link
Collaborator

@Gobot1234 Gobot1234 commented Feb 16, 2026

Context

Currently you have to retype the name of a setting object if you reference that same object in another place. E.g. think report plots and report files. Closes #4844

Change Summary

A small check to set_state to call .name if it's a SettingsObject.

Rationale

This makes the settings api less stringly typed

Impact

Just flobject and a few tests.

Further Expansion of this could be to type the dependant relations e.g. a report file can only take a report plot object and not another settings object.

Copilot AI review requested due to automatic review settings February 16, 2026 14:22
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to reduce “stringly typed” usage in the settings API by allowing string-valued settings to accept a settings object reference and automatically convert it to its .name().

Changes:

  • Update Textual.set_state to convert SettingsBase inputs with .name() into a string before setting state.
  • Introduce a SettingsBaseWithName Protocol to reflect the new accepted input shape in type hints.
  • Add a Filename.set_state override intending to accept pathlib.Path inputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +702 to +703
if isinstance(state, SettingsBase) and hasattr(state, "name"):
state = state.name()
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New behavior: allowing a SettingsBase instance to be passed into Textual.set_state and converting it via .name() is not covered by the existing flobject unit tests (e.g., tests/test_flobject.py exercises string settings but never passes another settings object). Add a focused test that passes a named settings object and asserts the resulting stored string matches its name, including a negative case where .name() is absent.

Copilot uses AI. Check for mistakes.
Comment on lines 72 to 73
override,
)
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typing.override is only available in Python 3.12+, but this project supports Python >=3.10 (pyproject.toml requires-python = ">=3.10"). Importing it from typing will raise ImportError on 3.10/3.11. Use typing_extensions.override (with a dependency) or remove the decorator / guard the import.

Suggested change
override,
)
)
from typing_extensions import override

Copilot uses AI. Check for mistakes.
_state_type = str

@override
def set_state(self, state: Path | str | None = None, **kwargs):
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filename.set_state now accepts a Path, but it forwards the Path directly to Textual.set_state, which only allows str/VariableDescriptor and will raise TypeError. Convert Path to str (or extend the allowed types) before calling super().set_state.

Suggested change
def set_state(self, state: Path | str | None = None, **kwargs):
def set_state(self, state: Path | str | None = None, **kwargs):
if isinstance(state, Path):
state = str(state)

Copilot uses AI. Check for mistakes.
Comment on lines 688 to 701
@@ -691,6 +699,9 @@ def set_state(self, state: StateT | None = None, **kwargs):
TypeError
If state is not a string.
"""
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Textual.set_state docstring and Raises section no longer match the accepted inputs: the signature now includes SettingsBaseWithName, and the runtime also accepts VariableDescriptor, but the docs still say "Either str or VariableDescriptor" and "If state is not a string." Update the documentation/error wording to reflect the actual accepted types/behavior.

Copilot uses AI. Check for mistakes.
@Gobot1234 Gobot1234 changed the title feat: call .name if it's a SettingsBase feat: call .name if it's a SettingsBase + Path support Feb 16, 2026
Copilot AI review requested due to automatic review settings February 16, 2026 15:15
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +709 to +710
if isinstance(state, SettingsBase) and hasattr(state, "name"):
state = state.name()
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no tests added to verify that the new feature works correctly. Based on the issue description and PR description, users should now be able to pass settings objects directly (e.g., param_1.report_definition = drag instead of param_1.report_definition = drag.name()). Consider adding tests to verify this functionality works as expected, for example by creating a settings object with a name() method and passing it directly to another setting that expects a string.

Suggested change
if isinstance(state, SettingsBase) and hasattr(state, "name"):
state = state.name()
name_attr = getattr(state, "name", None)
if callable(name_attr):
state = name_attr()

Copilot uses AI. Check for mistakes.


class Filename(SettingsBase[str], Textual):
class Filename(SettingsBase[PathType], Textual):
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generic type parameter has been changed from SettingsBase[str] to SettingsBase[PathType], but this creates a type inconsistency. The get_state() method inherited from SettingsBase is typed to return StateT (which would be PathType here), but Fluent's API actually returns strings, not PathType objects. The _state_type = str on line 967 correctly indicates that Fluent stores strings internally. Consider keeping the generic parameter as SettingsBase[str] since that's what Fluent actually returns, and handle PathType conversion only in set_state() (which is already done). The type hint for set_state can still accept PathType as shown on line 970.

Suggested change
class Filename(SettingsBase[PathType], Textual):
class Filename(SettingsBase[str], Textual):

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 16, 2026 16:34
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +970 to +973
def set_state(self, state: PathType | None = None, **kwargs):
if state is not None:
state = os.fspath(state)
return super().set_state(state, **kwargs)
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Path support added to Filename.set_state() lacks test coverage. Consider adding a test that verifies pathlib.Path objects and other PathLike types can be passed to Filename settings objects. This would ensure the os.fspath() conversion works correctly for different PathType variants (Path objects, strings, bytes, etc.).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for a less stringly-typed settings api

2 participants