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

Fix #1186: list-methods of type-annotated class #1188

Merged
merged 6 commits into from
Jan 10, 2019

Conversation

drewrisinger
Copy link
Contributor

ARTIQ Pull Request

Description of Changes

Change how pc_rpc process annotations. Essentially annotations -> str(annotations) which can be serialized by pyon.

Related Issue

Closes #1186

Type of Changes

Type
🐛 Bug fix

Steps (Choose relevant, delete irrelevant before submitting)

All Pull Requests

  • Use correct spelling and grammar.
  • Update RELEASE_NOTES.md if there are noteworthy changes, especially if there are changes to existing APIs.
  • Close/update issues.
  • Check the copyright situation of your changes and sign off your patches (git commit --signoff, see copyright).

Code Changes

  • Run flake8 to check code style (follow PEP-8 style). flake8 has issues with parsing Migen/gateware code, ignore as necessary.
  • Test your changes or have someone test them. Mention what was tested and how.
    • Added unittest to check this. Manually tested as well with artiq_rpctool SERVER list-methods
  • Add and check docstrings and comments
  • Check, test, and update the unittests in /artiq/test/ or gateware simulations in /artiq/gateware/test

Documentation Changes

None

Git Logistics

  • Split your contribution into logically separate changes (git rebase --interactive). Merge/squash/fixup commits that just fix or amend previous commits. Remove unintended changes & cleanup. See tutorial.
  • Write short & meaningful commit messages. Review each commit for messages (git show). Format:

Turn annotations into a string which PYON can encode.
Test pc_rpc can correctly process an annotated function.
Also check pyon can encode & decode the annotated function.

Signed-off-by: Drew Risinger <drewrisinger@users.noreply.github.com>
@@ -487,6 +487,17 @@ def __init__(self, targets, description=None, builtin_terminate=False,
else:
self._noparallel = asyncio.Lock()

@staticmethod
def _document_function(function: typing.Callable) -> typing.Tuple[dict, str]:
Copy link
Member

Choose a reason for hiding this comment

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

Please remove the type annotations.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you explain why the type annotations should be removed? Other than not being used elsewhere in ARTIQ (#1181 (comment))?

There is no downside to using type annotations, it makes the code more understandable, and it helps IDEs with autocomplete. Guido van Rossum supports them, and they are making their way into more projects as Python2 support is dropped. Some projects that use them:

Overview of type hints and their benefits; https://stackoverflow.com/questions/32557920/what-are-type-hints-in-python-3-5

Copy link
Member

Choose a reason for hiding this comment

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

They are not used anywhere else in ARTIQ, they are not used by most other Python projects, they are difficult to write, some functions may return different types depending on the context, and annotations are ignored by the interpreter and are (currently at least) not checked automatically.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Discussion continued below in #1188 (comment)

Copy link
Member

@jordens jordens left a comment

Choose a reason for hiding this comment

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

Thanks. Apart from the one style thing this LGTM

artiq/protocols/pc_rpc.py Outdated Show resolved Hide resolved
@drewrisinger
Copy link
Contributor Author

@jordens FYI, I found a few other instances of that same return style in that file.

return (self.__target_names, self.__description)

return (self.__target_names, self.__description)

@jordens
Copy link
Member

jordens commented Nov 5, 2018

@drewrisinger touché. Then either style is fine.

@drewrisinger
Copy link
Contributor Author

@drewrisinger touché. Then either style is fine.

Just wanted to let you know since fixing them would be out of scope for this PR

return arg1

argspec, docstring = pc_rpc.Server._document_function(_annotated_function)
print(argspec) # for debug
Copy link
Member

Choose a reason for hiding this comment

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

Prints in tests are generally "for debug", this comment doesn't provide much info.

@sbourdeauducq
Copy link
Member

@drewrisinger To clarify my position: while i am opposed to using type annotations inside ARTIQ, merging this and having pc_rpc handle them for user code is totally fine.

Copy link
Member

@sbourdeauducq sbourdeauducq left a comment

Choose a reason for hiding this comment

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

See comments above.

@drewrisinger
Copy link
Contributor Author

drewrisinger commented Jan 4, 2019

Continuing the discussion on type annotations:

They are not used anywhere else in ARTIQ,

My understanding is that this is due to the nature of ARTIQ. ARTIQ has received contributions from people with varying levels of programming experience, who might be unaware that type annotations exist.

they are not used by most other Python projects,

This is mostly due to them being a new/less-documented feature in Python 3. Their usage is spreading as more projects transition to Python 3. Similar features like generators & async code are not widely used in beginner projects, but have their usage in large & advanced projects. And projects that do not use them, like matplotlib, scipy, numpy have extensive documentation to explain every function, which ARTIQ lacks.

they are difficult to write,

I disagree: no more difficult than a comment once you know how to use them. Proper usage can be learned in about 10-15 mins for 95% of use cases.

some functions may return different types depending on the context,

Not an issue, and easily handled. Returns can be of the form typing.Union[int, str, ...]

and annotations are ignored by the interpreter and are (currently at least) not checked automatically.

This is one of the main benefits. Type annotations can be statically checked to catch obvious mistakes (e.g. mypy), while still being optional.

In summary, I strongly believe that type annotations are best practice and very useful for documentation and code understandability. Especially in Python when it is nearly impossible to tell what data type a function expects, combined with a general lack of function documentation in ARTIQ. As such, all my code does and will continue to use type annotations, because to my cost-benefit analysis their marginal cost comes with a large comprehensibility benefit for users and future maintainability.

@sbourdeauducq
Copy link
Member

My understanding is that this is due to the nature of ARTIQ. ARTIQ has received contributions from people with varying levels of programming experience, who might be unaware that type annotations exist.

I started writing ARTIQ and wrote large parts of it, and I am obviously aware of type annotations since I've been using them in the compiler. I just don't want them elsewhere.

Similar features like generators & async code are not widely used in beginner projects, but have their usage in large & advanced projects.

Generators add useful features and are not similar to useless type annotations.

And projects that do not use them, like matplotlib, scipy, numpy have extensive documentation to explain every function, which ARTIQ lacks.

Then write or fund such documentation instead of adding those cryptic type annotations.

As such, all my code does and will continue to use type annotations, because to my cost-benefit analysis their marginal cost comes with a large comprehensibility benefit for users and future maintainability.

As such, your code will continue to get rejected.

@sbourdeauducq
Copy link
Member

This is one of the main benefits. Type annotations can be statically checked to catch obvious mistakes (e.g. mypy), while still being optional.

If those tools were good, I'd be all for using them. This is why we switched the firmware from C to Rust, for example. But with Python they are half-baked hacks that are not really worth the effort.

@jbqubit
Copy link
Contributor

jbqubit commented Jan 8, 2019

@drewrisinger Thanks for keeping the conversation on this going.

@sbourdeauducq said

I started writing ARTIQ and wrote large parts of it, and I am obviously aware of type annotations since I've been using them in the compiler. I just don't want them elsewhere.

Type annotations were supported in Python 3.5 which was released in autumn 2015. By that time @sbourdeauducq already had spent two years on ARTIQ -- v1 was released May 2016. So it wasn't really an option for most of the early ARTIQ infrastructure.

But with Python they are half-baked hacks that are not really worth the effort.

There's a nice medium post discussing additional benefits of type annotations.

Cleaner code/the code is self-documenting  -- Comments tend to wear out and rot, while code is alive and must stay fresh. Change the types of the variables without changing the comment specifying the type — nothing happens. Change it without changing the type annotation? Your static analysis tool, whichever it may be, will shout at you.

Automatic code completion is another great IDE feature that works better with type annotations. The same Medium post provides an example illustrating this. This could really make learning and writing in ARTIQ Python much easier.

@sbourdeauducq
Copy link
Member

Change it without changing the type annotation? Your static analysis tool, whichever it may be, will shout at you.

When they work! Which isn't always the case with the Python tools unlike e.g. Rust.

Removed comment per @sbourdeauducq.
Clarify variable names b/c they didn't make sense when re-reading
months later.
Type annotations removed per @sbourdeauducq, so no longer used.
@sbourdeauducq
Copy link
Member

@drewrisinger Thanks!

@sbourdeauducq sbourdeauducq merged commit 721c6f3 into m-labs:master Jan 10, 2019
@sbourdeauducq
Copy link
Member

@drewrisinger Please run tests before submitting PRs. You ticked the box but your unit test fails.
http://buildbot.m-labs.hk/builders/artiq/builds/2808/steps/python_unittest_1/logs/stdio

@sbourdeauducq
Copy link
Member

@drewrisinger Please submit a fix.

drewrisinger added a commit to drewrisinger/artiq that referenced this pull request Jan 10, 2019
Fixes bug from 5108ed8. Truth value of multi-element numpy array is
not defined. Completes m-labs#1186 and fixes/amends m-labs#1188.

Signed-off-by: Drew Risinger <drewrisinger@users.noreply.github.com>
@drewrisinger
Copy link
Contributor Author

#1239. Had tested originally, forgot why I couldn't add extra element to array.

sbourdeauducq pushed a commit that referenced this pull request Jan 11, 2019
Fixes bug from 5108ed8. Truth value of multi-element numpy array is
not defined. Completes #1186 and fixes/amends #1188.

Signed-off-by: Drew Risinger <drewrisinger@users.noreply.github.com>
jbroz11 pushed a commit to HaeffnerLab/artiq that referenced this pull request Feb 25, 2020
Fixes bug from 5108ed8. Truth value of multi-element numpy array is
not defined. Completes m-labs#1186 and fixes/amends m-labs#1188.

Signed-off-by: Drew Risinger <drewrisinger@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PYON: PYON can't serialize type annotations in list-methods
4 participants