Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type hints, and use mypy to enforce in CI #16

Closed
karalekas opened this issue Nov 10, 2020 · 41 comments
Closed

Add type hints, and use mypy to enforce in CI #16

karalekas opened this issue Nov 10, 2020 · 41 comments

Comments

@karalekas
Copy link
Contributor

Python is a dynamically-typed language (see: duck typing), but Python 3.5 and pep-484 introduced type hints as a way to annotate Python code with types. These are not enforced by the language at runtime, but they can be checked by third-party libraries such as mypy. The impetus for adding type hints and using mypy is that they generally encourage developers to write saner, simpler code (the flexibility of Python is a double-edged sword). This issue is mostly about good code style and therefore is optional -- it doesn't block CI setup (but once it is complete, the CI can be used to do this type checking automatically).

@TripleRD
Copy link
Contributor

Hi @HGSilveri @karalekas, I went through the issue and would like to work on it. I have a few questions, I found this GitHub Action which can be used to implement the type hint ci, so can it be used? or do it need to be implemented using shell script?

@LaurentAjdnik
Copy link
Collaborator

Hi @TripleR47, I've done it for the Register class (I will PR #132 tomorrow) but I did it manually 🤨, while adding "Enhanced ErrorValue messages" (#148) at the same time.

@HGSilveri
Copy link
Collaborator

Hi @TripleR47, no preference regarding how the mypy checks are occur, as long as they are programmed into the existing workflow, if that's what you're asking. But bear in mind that is not the crux of the PR, but rather going through the existing code and adding the appropriate type hints to each function and method. After that's done, then you can incorporate mypy into the CI routine.
I realize it's quite a bit of work, but that's why there's a bounty on it!

@TripleRD
Copy link
Contributor

Okay, I'll ask in the unitaryHack's server if anyone wants to collaborate on this issue. Can it be assigned to me?

@TripleRD
Copy link
Contributor

Hi @LaurentAjdnik, wanna collaborate on this issue?

@LaurentAjdnik
Copy link
Collaborator

Hi @LaurentAjdnik, wanna collaborate on this issue?

👍

@TripleRD
Copy link
Contributor

Hi @LaurentAjdnik, wanna collaborate on this issue?

👍

Are you in unitaryfund's discord server? If you are then DM me on discord, we can discuss further on this.

@HGSilveri
Copy link
Collaborator

@TripleR47 @LaurentAjdnik So, can I assign it to you both?

@TripleRD
Copy link
Contributor

Sure

@LaurentAjdnik
Copy link
Collaborator

@TripleR47 @LaurentAjdnik So, can I assign it to you both?

Yup!

Your feedback on #155, in which I added type hints, will be insightful for the current issue.

Then, we can sync with @TripleR47.

@TripleRD
Copy link
Contributor

Hi @LaurentAjdnik, wanna collaborate on this issue?

👍

Are you in unitaryfund's discord server? If you are then DM me on discord, we can discuss further on this.

@LaurentAjdnik

@LaurentAjdnik
Copy link
Collaborator

@TripleR47: Nope, not on Discord. I'm waiting for the feedback on #155 and we can move on from there.

Adding type hints will be pretty straightforward. Maybe we can dispatch classes between us.

@HGSilveri: Will you be in charge of adding mypy to CI workflow ?

@HGSilveri
Copy link
Collaborator

@LaurentAjdnik : I'll review #155 first thing on Monday. And yes, I can add it to the CI no problem. I would advise you to use it to test your own typing as you go. Did you try it already on #155?

@LaurentAjdnik
Copy link
Collaborator

LaurentAjdnik commented May 16, 2021

Running MyPy on #155 (screenshots below):

  • Register class: No errors in my code (or in the signatures I updated)
  • Register class: Error in from_coordinates() on qubits = dict(enumerate(coords))
  • A few errors in other modules
  • Lots of errors on imports with modules having no type hints

With the --ignore-missing-imports option:

MyPy-2021-05-16ignore

Without the --ignore-missing-imports option:

MyPy-2021-05-16

HGSilveri pushed a commit that referenced this issue May 18, 2021
…), Enhanced `ValueError` messages (#148), Type hinting for `Register` (#16) (#155)

* Update register.py

* Add max_connectivy()

* Test

* Adding hexagon() and max_connectivity()

* Type hinting and parameters checks

* Shift atom generation in full layers for consistency

* Remove unused variables to avoid flake8 warnings

* Corrections for PR #155
@LaurentAjdnik
Copy link
Collaborator

Hi @TripleR47!

Have you been working on it ?

PR #155 has been approved and type-checked with MyPy beforehand. We could use it as an inspiration.

@TripleRD
Copy link
Contributor

Yes, I have been going through mypy and Pulser documentations and have started working on the devices module.

@LaurentAjdnik, let's split up the rest of the modules.

@LaurentAjdnik
Copy link
Collaborator

Yes, I have been going through mypy and Pulser documentations and have started working on the devices module.

@LaurentAjdnik, let's split up the rest of the modules.

Great! I'll start working on waveforms.py then.

@LaurentAjdnik
Copy link
Collaborator

Hi again @TripleR47!

I just PR-ed #163 on waveforms.py for a feedback from experts, that we can use for further work.

@LaurentAjdnik
Copy link
Collaborator

Hi again @TripleR47 and @HGSilveri, I start working on sequence.py.

@TripleRD
Copy link
Contributor

Okay, I'm almost done with the devices module, will start working on parametrized and simulation after that.

@LaurentAjdnik
Copy link
Collaborator

Great! I'll start working on _seq_drawer.py, channels.py and pulse.py so that the root directory is done.

@TripleRD
Copy link
Contributor

Okay! I'm done with the parametrized module, start working on simulation next.

@HGSilveri
Copy link
Collaborator

Hi @LaurentAjdnik , @TripleR47 ! Glad to see you're making progress.

I just wanted to clarify a few things:

  • The order of the PRs should be in order of increased dependency on other modules. This means, for example, that pulse.py should be merged after waveforms.py but before sequence.py. Also, pulser.parametrized should come soon as it is frequently imported but does not import any other module. Inversely, pulser.simulation should be one of the last modules to be merged, as it is not imported but imports Sequence, which in turn imports almost everything else. Thus, the next modules to merge should be:
    1. pulser.channels and pulser.parametrized
    2. pulser.waveforms
    3. pulser.pulse
  • You'll find in Setting up mypy #168 that I setup a config file for mypy. Once that PR is merged with develop, you can start type checking locally just by running mypy inside the Pulser folder, but make sure you have numpy >= 1.20 installed beforehand.
  • You'll also find that I added some type checks in Setting up mypy #168, mostly to get rid of all the mypy errors. Beware of potential merge conflicts.

Keep up the good work!

@LaurentAjdnik
Copy link
Collaborator

  • The order of the PRs should be in order of increased dependency on other modules.

Sorry, I started PR-ing without respecting this order...

And the branch I'm working on will include all remaining files in the root directory...

I feel like type-hinting everything will soon be over. Hence, if the corresponding PRs pass the existing checks (without mypy enabled), can we merge them into develop, use mypy locally on a copy of develop, adjust everything that's needed and finally enable mypy in CI ?

@HGSilveri
Copy link
Collaborator

HGSilveri commented May 20, 2021

I'd rather not merge to develop without mypy in the CI... What might happen is that you find, as the modules are incrementally merged into develop, that conflicts in modules that were already type-hinted will arise. This means that these PRs will need to include modifications to files that should already be dealt with. It will make things a bit messier, but I guess it's too late now to go back. Just try to stick to the order laid out above as much as possible. I will also try to order the merging of the PRs accordingly.

@TripleRD
Copy link
Contributor

Okay @HGSilveri, @LaurentAjdnik if you haven't started working on pulse.py yet, can I take over that module? After that, I can go for pulser.simulation.

@LaurentAjdnik
Copy link
Collaborator

if you haven't started working on pulse.py

Well, I've finished working on it. All files in root are done. I might have to split this unique new branch so that @HGSilveri can arrange the merging order.

@TripleRD
Copy link
Contributor

Okay, I have also finished the pulser.simlation. Let's start working on the test module then.

HGSilveri added a commit that referenced this issue May 21, 2021
* Add type hints

* Set @DataClass to init=True

Co-authored-by: Henrique Silvério <[email protected]>
HGSilveri added a commit that referenced this issue May 21, 2021
* Add type hints to `waveforms.py`

* PR #163 after comments

* Remove "import Union" no longer necessary

* Change `Callable` to `FunctionType`

* list[Waveform]

* List[Waveform]

* Add type hints for `Parametrized`

* Add Parametrized hints to each __init__

* Add more type hints

* Add more type hints

* Change __init__ for BlackmanWaveForm

* Update type hints

* Update type hints

* Check type of area

* Update type hints

* Correct last typo

Co-authored-by: Henrique Silvério <[email protected]>
HGSilveri added a commit that referenced this issue May 22, 2021
* Add type hints in pulser.parametrized

* Update style and type hints in pulser.parametrized

* Update type hints in pulser.parametrized

* Update test_parametrized.py

* Update type hints in paramobj.py and variable.py

* Update type hint in paramabc.py and paramobj.py

* Update in paramabc.py

* Update in paramabc.py

* Update paramabc.py

* Update paramobj.py

* Update paramobj.py

* Update paramabc.py and paramobj.py

Co-authored-by: Henrique Silvério <[email protected]>
@TripleRD
Copy link
Contributor

Hey @LaurentAjdnik, which test modules are you working on?

@LaurentAjdnik
Copy link
Collaborator

Hey @LaurentAjdnik, which test modules are you working on?

Hi @TripleR47, I'm done with all files in the root directory.

I haven't planned working on test files.

@HGSilveri: Does it make sense anyway?

@HGSilveri
Copy link
Collaborator

@HGSilveri: Does it make sense anyway?

I would say no, not really.

@TripleRD
Copy link
Contributor

Okay

HGSilveri added a commit that referenced this issue May 25, 2021
…16) (#169)

* Add type hints in _device_datacls.py

* Add type hints in coders.py

* Update style edits in _device_datacls.py and coders.py

* Update type hints in _device_datacls.py

* Update type hints in coders.py

* Update type hints in coders.py

* Update coders.py

Co-authored-by: Henrique Silvério <[email protected]>
HGSilveri pushed a commit that referenced this issue May 25, 2021
* Add type hints

* Update type hints in `pulse.py`

* Add Parametrized hints to Waveform parameters
@HGSilveri
Copy link
Collaborator

So, I was convinced that using "parametrized generics" for type-hinting using built-ins (e.g. dict[str, Any] instead of Dict[str, Any]) would only work from Python 3.9, but apparently, according to PEP 585 that's not the case if annotations are imported from __future__, which can be done since Python version 3.7.

I don't like the inconsistency of having both forms, so I guess we should adopt the most modern one throughout, which is to use the built-ins (i.e., dict, list, tuple, ...).

I have been asking you to do the opposite up until now, so it's only fair I make a PR enforcing these changes for all the type-hints that have already been merged. However, it would be good if you could change this on the PRs that are still open.

@TripleRD
Copy link
Contributor

Okay

@HGSilveri
Copy link
Collaborator

@TripleR47, bear in mind that you still can only do this in the type annotations. This means, for example, that you can't do cast(list[int], x), you'll have to use List. But you can type a return or a variable as list[int]. Hope that makes sense

@TripleRD
Copy link
Contributor

Okay, and what about the special types like Callable, Union etc. Do we have their alternatives in the built-ins?

@HGSilveri
Copy link
Collaborator

No, those stay the same. Refer to this list for the built-in generics that replace those in typing.

@TripleRD
Copy link
Contributor

Okay, thanks!

@HGSilveri
Copy link
Collaborator

@TripleR47 : From that list, notice that Callable actually does change (should be imported from collections.abc instead).

HGSilveri added a commit that referenced this issue May 28, 2021
* Add type hints to sequence.py

* Update type hints in `sequence.py`

* Update type hints in `sequence.py`

* Introduce QubitId type

* Update QubitId definition

* Use built-in type hints

* Resolve merge conflicts

* Switch tuple to Tuple

* Update with PR comments

* Update with PR comments

* Add NamedTuple type hint

* Import Literal from typing_extensions

* Update with PR comments

* Change Set back to Iterable

* Change Iterable[QubitId] to Iterable

* Change comment to docstring

* Import Literal and get_args depending on version

* Add another # pragma: no cover

* Rearrange imports

* Rearrange imports

* Add a line, just a line

Co-authored-by: Henrique Silvério <[email protected]>
HGSilveri added a commit that referenced this issue May 29, 2021
* Add type hints in pulser.simulation

* Update type hints in simresults.py

* Update type hints in simulation.py

Co-authored-by: Henrique Silvério <[email protected]>
HGSilveri added a commit that referenced this issue May 29, 2021
* Add type hints

* Add type hints

* Merge branch

* Sync branches

* Resolve conflicts

* Update _seq_drawer.py

* Update _seq_drawer.py

* Update _seq_drawer.py

Co-authored-by: Henrique Silvério <[email protected]>
@HGSilveri
Copy link
Collaborator

Solved by @LaurentAjdnik and @TripleR47 , thank you both for your patience and hard work!

@TripleRD
Copy link
Contributor

@HGSilveri, thanks for your guidance! 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants