Upgrade python packaging and tooling - #136
Conversation
7aec32c to
ac0b574
Compare
| push: | ||
| pull_request: | ||
| schedule: | ||
| - cron: "0 6 * * 1" |
There was a problem hiding this comment.
Is that really useful? The project hardly ever moves and I don't see it failing in-between modifications.
| matrix: | ||
| python-version: ["3.9"] | ||
| steps: | ||
| - uses: actions/checkout@v3 |
There was a problem hiding this comment.
We're at actions/checkout@v7 nowadays, otherwise you get various warnings from GitHub.
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| python-version: ["3.9"] |
There was a problem hiding this comment.
It might be valuable to have at least the minimum supported version and the latest available Python version in the matrix. Intermediary versions could be nice too, but less valuable.
There was a problem hiding this comment.
Oh wait, that's the tooling, not the tests 🤔
Scratch that.
|
Thanks! :-) Can you move the linting stuff in the github actions workflow to the other (test) workflow so we only have one checking everything? And since you asked, would you agree to set the build system to hatchling? :-) I'm using uv for another project, I like their approach (and we can benefit from their python-version and uv.lock files as well) :-) I'll try to find some time to merge the other pr today. No promise :-) |
|
I've just merged the other PR. Thanks @Morwenn for the changes! @RobLevv if we migrate to Oh, and when you have time and if you're willing to, could you tell me what is your use case with sismic? (academia?) :-) |
3052f35 to
e17e289
Compare
We're actually from a small company making solar power plant control software, and more generally an Energy Management System. We use sismic at the heart of our controller to orchestrate the different parts of the plant. Unfortunately I don't think I can tell much more about the component in which we use it exactly. I suppose that it's the kind of specific information that would fall under industrial property secrets. I can tell you that we've been using it a lot for around 5 years, without any major issue. The recent pull requests were not done on company time; we individually decided that it was time to give back to the FOSS commons, and smooth out the library's experience a bit without fundamentally changing it. |
|
Thanks a lot! I'm really glad to see that what started as a kind of toy/scientific project is actually used and useful in production :-) What drove you to use sismic compared to, e.g., Rhapsody or Yakindu? Its support for testing/validating statecharts? (that's something missing from "compellers" :-)) |
|
I have no idea to be frank. It was chosen before I joined the company, and we don't make use of advanced features. I suppose that it's the ability to inject Python locals into the statechart and execute code there. But I haven't checked alternatives myself so I don't even know what more they have to offer. We don't really use the validation tools even though the extra validation statecharts look cool. We do perform statuc analysis to ensure that our statecharts always follow some patterns that make reasoning easier (such as avoiding that two parallel statecharts access the same resource). |
|
Hi again,
Some choices that can still be made:
Finally the technical direct choices I need your decision on:
Side note: |
7b12814 to
f5d0144
Compare
|
Thanks! I'll get back to you soon for the various choices we have to make :-) |
Actually, I might have been a bit over zealous with all the questions and propositions of improvements I was just thinking since we upgrade some we could upgrade everything at once. I can always follow up later with more :) depending on what you want for sismic |
|
(Sorry, I had to edit this message, I don't know what happened but only parts of my initial answer were saved by GitHub ^^) Hi,
I have no strong opinion on this. I'm using hatchling in other projects, but mostly because it is "fast and lightweight" compared to other build backend. I wasn't aware that uv released its own build backend and, for what I see, it seems even faster and more lightweight, so I'm fine with using it :-)
I'll have a look at zuban, I don't know about it. For now, mypy is enough. Let's consider it as the "de facto" standard for type checking in Python. If we need something more powerful (but I don't think it's the case with Sismic) we may decide to go for another tool.
The basic one should be enough, just executing
I'm not a user of mypy so I don't know what are the differences between the "normal" and "strict" mode. Again, my suggestion is to "just support
I prefer avoiding
Could you pinpoint these cases so I can see what the problem is?
Thank you very much :-) |
|
Ok great, thank you for your answers. I am quite used to using pre-commit everytime now but I don't want to impose a new workflow for you. I have used the basic config for ruff and mypy, like you said. I will clean a bit my work and the commits and will pinpoint the tricky places, then you will be good for review (in a few days maybe) |
|
Hi, I'm not used to precommits (I have used them only one tbh) but I don't mind having them for portion. It is doesn't hurt those who don't want to use them :-) I'm not sure we need to update the documentation (I don't remember having provided instructions for contributing so far and, in any case, the current/future setup remains quite common and quite visible even if not explicit in the doc). |
7cb0dac to
eabed94
Compare
eabed94 to
db8fa25
Compare
RobLevv
left a comment
There was a problem hiding this comment.
every end of file/ end of line is fixed automatically, if some places feels odd, there may be some configurations to improve the behavior of the formatters.
Overall almost no ignore, and some got removed.
| ): | ||
| try: | ||
| import ipdb as pdb | ||
| import ipdb as pdb # type: ignore # noqa |
There was a problem hiding this comment.
ipdb is not installed, I suppose it is only possible to use when it is installed by some other package (so the try ... except)
Anyway, mypy complains import is not possible (which is logic), type: ignore is mandatory here
| import ipdb as pdb # type: ignore # noqa | ||
| except ImportError: | ||
| import pdb | ||
| import pdb # noqa |
There was a problem hiding this comment.
ruff complain about pdb and ipdb https://docs.astral.sh/ruff/rules/debugger/
But I am pretty sure the goal here is to drop into the debugger so noqa
| @@ -1,4 +1,6 @@ | |||
| from behave import given, when, then # type: ignore | |||
| # mypy: disable-error-code="operator" | |||
There was a problem hiding this comment.
here a tricky one:
mypy complains error: "_StepDecorator" not callable [operator] on all @given, @when, @then which is correct https://github.com/behave/behave/blob/4387315f12299d4b0b2ec5bf0b399e2366a99f5e/behave/step_registry.py#L224
I check with ty and zuban, they both infer the same.
only pyrefly bundles a typeshed for behave which infers def given(step_text: str, **kwargs) -> Callable[[_F], _F]: ... https://github.com/python/typeshed/blob/a2811326ffe3c0e69c4624de1d6b199a3c1f4ace/stubs/behave/behave/step_registry.pyi#L9
this line disables the error for the entire file, no other error was found.
| @@ -1,22 +1,24 @@ | |||
| import ruamel.yaml as yaml | |||
| import schema | |||
| # mypy: disable-error-code="arg-type" | |||
There was a problem hiding this comment.
Another tricky one:
mypy raises "Or" has incompatible type "str"; expected "Callable[..., Any]" on every schema.Or
because it is waiting on a callable. already flagged and fixed keleshev/schema#342
waiting for a new tag
| interpreter = statechart | ||
| DeprecationWarning, | ||
| ) | ||
| interpreter: Interpreter = statechart |
There was a problem hiding this comment.
here I add a type hint because otherwise mypy infer this as Statechart which created an error at line 260 with interpreter = interpreter_klass() was erroring cannot assign Statechart to Interpreter
|
I have finished applying all the ruff + mypy fixes. I think it is ready for review, don't hesitate to challenge a bit the changes. I explained the mypy errors that are unfixable. As you said, pre-commit is entirely opt-in (the lint action will sometimes complain more for people who do not use it, same for ruff and mypy if someone does not use it) |
|
Thanks! I'll review "ASAP" :-) I'm sorry to take that much time for every step ;-) |
|
Take all the time you need :) I am on vacation. |
Morwenn
left a comment
There was a problem hiding this comment.
I had filed a few review comments some time ago, but only realized today that I had to click "Submit review" for them to show -_-
|
|
||
|
|
||
| def map_assertion(step_text: str, existing_step_or_steps: Union[str, list[str]]) -> None: | ||
| def map_assertion(step_text: str, existing_step_or_steps: str | list[str]) -> None: |
There was a problem hiding this comment.
X | Y for type unions is only available in Python 3.10, but sismic claims Python 3.9 support.
There was a problem hiding this comment.
Actually, with using from __future__ import annotations this syntax becomes available in the file.
This is only possible for type hints because the evaluation is deferred but does not work for runtime types where I still used Union.
https://docs.python.org/3.7/whatsnew/3.7.html#pep-563-postponed-evaluation-of-annotations
There was a problem hiding this comment.
Oh wow, so we're assuming that only type checkers will only read it? That's pretty cool :o
There was a problem hiding this comment.
Another possibility would be to drop python 3.9 officially... That version is eol.
There was a problem hiding this comment.
That's true. The main risk is if other libraries relying on sismic still guarantee 3.9 compatibility, or if some companies using the project are stuck on 3.9 for some reason. I don't know how likely it is though, I guess that somebody who really cares could open an issue later anyway.
| cd examples/microwave/ | ||
| pytest |
There was a problem hiding this comment.
| cd examples/microwave/ | |
| pytest | |
| pytest examples/microwave |
There was a problem hiding this comment.
I actually tried that at one point, but the tests still did not pass because the statechart used in the test is not found.
I tried many commands to try and run it from the root of the repo like you suggest but did not succeed, I might give it another go.
There was a problem hiding this comment.
Oh, so there are test files that depend on where the command is run instead of where the executed tests are? Sounds like something that ought to be fixed. Whether that's for the current PR or not depends on how complicated it is I guess 🤔
There was a problem hiding this comment.
I'm surprised by the behaviour. Could you provide more details? Is this something new due to the change or some old stuff impacting the recent change?
| uses: actions/setup-python@v7 | ||
| with: | ||
| python-version-file: ".python-version" | ||
| - uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 |
There was a problem hiding this comment.
Why use a commit reference here?
There was a problem hiding this comment.
I struggled a bit to find the correct version of this action, when looking on the marketplace, they declare that this action is at v9 but I tried it and this version did not exist.
The only non-hash version was v7 and it seemed quite old so I just used the value recommended on the marketplace page.
There was a problem hiding this comment.
Looking at the project's tags, it would be v9.0.0 instead of v7. It looks like they stopped maintained "major version" tags. That's an odd choice though.
There was a problem hiding this comment.
Ah, I found the marketplace description, which corroborates what you said. I guess it's to avoid supply chain attacks, which is fine. Could you add least add a comment to specify the target version?
| def __init__(self) -> None: | ||
| self._entry_time = dict() # type: dict[str, float] | ||
| self._idle_time = dict() # type: dict[str, float] | ||
| self._entry_time = {} # type: dict[str, float] |
There was a problem hiding this comment.
Here we use comments for type hints, and below level-language type hints. It would be nice to choose just one and stick to it.
There was a problem hiding this comment.
Just to remind the pros and cons since it's mostly the same thing:
- Comments are parsed as comments and entirely discarded by CPython, so they don't end up in the AST. I guess it makes loading very slightly faster.
- Proper Python construct has fewer risks of pointing an incorrect line due to an overzealous code formatter, and reduces the chances of
importthat end up "unused" for linters because they're only used in comments.
| def _select_transitions( | ||
| self, | ||
| event: Event | None, | ||
| states: Iterable[str], |
There was a problem hiding this comment.
I think states would be better typed as set[str], the only type with which it is ever called: Iterable accepts a generator, and this function would fail with a generator because states would be consumed several times.
| '--show-description', | ||
| dest='statechart_description', | ||
| action='store_true', | ||
| default=False, |
There was a problem hiding this comment.
The actions store_true and store_false already have the defaults False and True respectively, so default is redundant for them, and the only difference is that it's more verbose and we have the opportunity to get it wrong.
I propose to remove it for all such actions, which will also save us a few lines :D
There was a problem hiding this comment.
Explicit is better than implicit. Let's keep the default values explicit :-)
| @@ -0,0 +1 @@ | |||
| 3.14 | |||
There was a problem hiding this comment.
Isn't that the file you need to change to make sure that it targets Python 3.9 instead?
There was a problem hiding this comment.
I think the minimal supported version is already defined in the pyproject.toml as 3.9
The maximal is not defined anymore so here seems a good place to define the "recommended python version to use, also the one you might use as a default when developing on this project"
There was a problem hiding this comment.
Okay, I didn't know that convention, cool 👍
| "Programming Language :: Python :: 3.11", | ||
| "Programming Language :: Python :: 3.12", | ||
| "Programming Language :: Python :: 3.13", | ||
| "Programming Language :: Python :: 3.14", |
There was a problem hiding this comment.
Python 3.15 has been out for some time, maybe it should be added here and tested in the CI too.
There was a problem hiding this comment.
We could add 3.14t too, I am not sure it adds much though
There was a problem hiding this comment.
Assuming that 3.14t is the multithreaded build of Python: there's at least the runner that uses multithreading, so maybe it's worth having at least one such threaded CI test.
There was a problem hiding this comment.
Let's ignore 3.14t at the moment. We don't know which of dependencies are compatible and not explicitly mentioning "t" doesn't mean it cannot be used :-) it's just we do not pretend everything will work fine :-)
|
Is there anything i/we should do before going further with this PR? (apart from updating the changelog and adding you as a contributor :-)) |
Hi, following this discussion #135 (comment)
I would be happy to upgrade the python tooling of sismic.
So here is the configuration I would like to apply:
This configuration will raise around 700+ linting/typing issues so it would be a good idea to let #135 be merged first to not apply twice some fixes and build on some improvements included in that PR.
I would like to let you discuss this configuration before applying all the fixes to the linting/typing issues as there will be many and review might be exhausting.
If you have any question or would like to have a different or be even more ambitious with the upgrade please let me know :)
have a nice night,
Rob.