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 Aqua's reported piracies and method ambiguities #85

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Omar-Elrefaei
Copy link

@Omar-Elrefaei Omar-Elrefaei commented Oct 19, 2024

Fix all of Aqua's reported piracies and method ambiguities. (#65)

Precisely 37 out of the 39 potential piracies are avoided by informing Aqua that types from QuantumInterface are in fact our own. The last two are fixed by adjusting the * and + functions that accept a Vararg, it had a problem for the case when N=0. This solution avoids both the unbound_type_param and the piracy, and seems to be a reasonable design to not allow zero arguments passed to the function (similar to Base operators themselves)

PR checklist
  • The code is properly formatted and commented.
  • Substantial new functionality is documented within the docs.
  • [] All new functionality is tested.
  • All of the automated tests on github pass.
  • We recently started enforcing formatting checks. If formatting issues are reported in the new code you have written, please correct them. There will be plenty of old code that is flagged as we are slowly transitioning to enforced formatting. Please do not worry about or address older formatting issues -- keep your PR just focused on your planned contribution.

Copy link

codecov bot commented Oct 19, 2024

Codecov Report

Attention: Patch coverage is 77.77778% with 2 lines in your changes missing coverage. Please review.

Project coverage is 75.46%. Comparing base (c41ff6b) to head (2e9dfb7).

Files with missing lines Patch % Lines
src/QSymbolicsBase/basic_superops.jl 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #85      +/-   ##
==========================================
- Coverage   75.50%   75.46%   -0.04%     
==========================================
  Files          19       19              
  Lines         800      803       +3     
==========================================
+ Hits          604      606       +2     
- Misses        196      197       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Omar-Elrefaei Omar-Elrefaei marked this pull request as ready for review October 30, 2024 20:52
Copy link
Member

@Krastanov Krastanov left a comment

Choose a reason for hiding this comment

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

Thank you for taking care of this! I have some minor questions about the types marked as own but on a quick skim the rest looks good.

@@ -1,7 +1,9 @@
@testitem "Aqua" tags=[:aqua] begin
using Aqua
import QuantumInterface as QI
own_types = [QI.AbstractBra, QI.AbstractKet, QI.AbstractSuperOperator, QI.AbstractOperator]
Copy link
Member

Choose a reason for hiding this comment

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

Could you elaborate why these need to be marked as own? I am not sure whether this would be consistent with how independent packages downstream of QuantumInterface (e.g. QuantumOptics or QuantumCummulants) -- I want to make sure there are some precautions put in place for potential future issues.

Copy link
Author

Choose a reason for hiding this comment

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

If I understand correctly, a type pyracy is when we expand a function definition with methods that take a certain type, but we neither defined the original function nor the type.
That was occurring all the time in files such as basic_ops_homogeneous.jl, basic_ops_inhomogeneous.jl, basic_superops.jl with methods that extend Base.(*) or Base.(+)

The last paragraph in the piracy section here gave me the impression that this was indeed happening intentionally. QuantumInterface defines the interface that is then used in other packages. So we tell Aqua that QuantumInterface and QuantumSymbolics are really cousin packages (since we avoided extending Base in QuantumInterface by design)

Aqua docs stating the following too gave me assurance that this is right.

this is useful for testing packages that deliberately commit some type piracies

Note: the functions really take Symbolic{T} not T directly, this seems to be worked around somewhere (same with Vector{T}) such that piracy detection is not tripped by these simple wrapper types.

@Krastanov
Copy link
Member

Hi! Just a friendly bump on this. I see most of the piracies were masked by marking a bunch of types as owned. This will be a bit fragile. Do you have any insight into which piracies this addresses -- upstreaming them to QuantumInterface would be a safer long-term solution.

@Omar-Elrefaei
Copy link
Author

Omar-Elrefaei commented Nov 14, 2024

Hi @Krastanov, I replied to your code review itself a while ago. Maybe GitHub doesn't show it too clearly #85 (comment)

Edit: wow it seems that I'm the one who has been duped by GitHub's UI, my apologies.

@Krastanov
Copy link
Member

No worries, I have made the same mistake in the past.

@@ -40,9 +40,9 @@ function Base.:(*)(c, x::Symbolic{T}) where {T<:QObj}
SScaled{T}(c, x)
end
end
Base.:(*)(x::Symbolic{T}, c) where {T<:QObj} = c*x
Base.:(*)(x::Symbolic{T}, c::Number) where {T<:QObj} = c*x
Copy link
Author

Choose a reason for hiding this comment

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

Motivation here was to avoid ambiguities with other packages,

But I'm not sure if it should be ::Number or ::{Union{Number, Symbolic{Number}}} to allow p*tr(q) just as tr(q)*p is allowed. The test suits for QuantumSymbolics and QuantumSavory pass right now, but I wasn't sure if that is a valid operation since it was allowed before my changes.

@@ -1,7 +1,9 @@
@testitem "Aqua" tags=[:aqua] begin
using Aqua
import QuantumInterface as QI
own_types = [QI.AbstractBra, QI.AbstractKet, QI.AbstractSuperOperator, QI.AbstractOperator]
Copy link
Author

Choose a reason for hiding this comment

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

If I understand correctly, a type pyracy is when we expand a function definition with methods that take a certain type, but we neither defined the original function nor the type.
That was occurring all the time in files such as basic_ops_homogeneous.jl, basic_ops_inhomogeneous.jl, basic_superops.jl with methods that extend Base.(*) or Base.(+)

The last paragraph in the piracy section here gave me the impression that this was indeed happening intentionally. QuantumInterface defines the interface that is then used in other packages. So we tell Aqua that QuantumInterface and QuantumSymbolics are really cousin packages (since we avoided extending Base in QuantumInterface by design)

Aqua docs stating the following too gave me assurance that this is right.

this is useful for testing packages that deliberately commit some type piracies

Note: the functions really take Symbolic{T} not T directly, this seems to be worked around somewhere (same with Vector{T}) such that piracy detection is not tripped by these simple wrapper types.

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.

2 participants