-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
make x509.name.NameAttribute use Generic to overload get_attributes_for_oid #12068
Conversation
Okay, this is way harder than I thought initially. Subtyping |
Hmm, |
A |
By which you mean, if it subclassed |
Hmm yeah after trying it out I see what you mean @alex - one would have to drag @typing.overload
def get_attributes_for_oid(
self,
oid: Literal[NameOID.X500_UNIQUE_IDENTIFIER],
) -> list[NameAttribute[bytes]]: ...
@typing.overload
def get_attributes_for_oid(
self,
oid: Literal[NameOID.COUNTRY_NAME]
| Literal[NameOID.COMMON_NAME]
... # every NameOID besides X500_UNIQUE_IDENTIFIER goes in the union here
| ObjectIdentifier,
) -> list[NameAttribute[str]]: ...
def get_attributes_for_oid(
self, oid: NameOID | ObjectIdentifier
) -> list[NameAttribute[AnyStr]]:
return [i for i in self if i.oid == oid] Sadly there is no obvious way of telling mypy "the return type is special for this special enum value, use the general one for the rest". |
This is the better variant of what I mean, with better visibility on both issues: # overload for the special value
@typing.overload
def get_attributes_for_oid(
self,
oid: Literal[NameOID.X500_UNIQUE_IDENTIFIER],
) -> list[NameAttribute[bytes]]: ...
# overload for the rest
@typing.overload
def get_attributes_for_oid(
self,
oid: Literal[
NameOID.COUNTRY_NAME,
NameOID.COMMON_NAME,
NameOID.LOCALITY_NAME,
NameOID.ORGANIZATION_NAME,
NameOID.GIVEN_NAME,
... # every NameOID besides X500_UNIQUE_IDENTIFIER goes in the union here
],
) -> list[NameAttribute[str]]: ...
# overload for the arbitrary OID
@typing.overload
def get_attributes_for_oid(
self,
oid: ObjectIdentifier,
) -> list[NameAttribute[AnyStr]]: ...
# implementation
def get_attributes_for_oid(self, oid):
return [i for i in self if i.oid == oid] |
Here's an idea: What if we added the type parameter on `NameAttribute`, but
had get_attribtues_for_oid always return `NameAttribute[bytes | str]`.
Users could then `typing.cast(NameAttribyte[str], ...)` it as appropriate.
This isn't as good as a full solution, but is better than the status quo
where `.value` is always `str| bytes`.
…On Mon, Dec 2, 2024 at 4:15 PM Oleg Höfling ***@***.***> wrote:
This is the better variant of what I mean, with better visibility on both
issues:
# overload for the special value
@typing.overload
def get_attributes_for_oid(
self,
oid: Literal[NameOID.X500_UNIQUE_IDENTIFIER],
) -> list[NameAttribute[bytes]]: ...
# overload for the rest
@typing.overload
def get_attributes_for_oid(
self,
oid: Literal[
NameOID.COUNTRY_NAME,
NameOID.COMMON_NAME,
NameOID.LOCALITY_NAME,
NameOID.ORGANIZATION_NAME,
NameOID.GIVEN_NAME,
... # every NameOID besides X500_UNIQUE_IDENTIFIER goes in the union here
],
) -> list[NameAttribute[str]]: ...
# overload for the arbitrary OID
@typing.overload
def get_attributes_for_oid(
self,
oid: ObjectIdentifier,
) -> list[NameAttribute[AnyStr]]: ...
# implementation
def get_attributes_for_oid(self, oid):
return [i for i in self if i.oid == oid]
—
Reply to this email directly, view it on GitHub
<#12068 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAAGBDSSPK7E3TZKDSMLID2DTEVZAVCNFSM6AAAAABSWUIWX2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMJSHA3DGNRQGU>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
--
All that is necessary for evil to succeed is for good people to do nothing.
|
I think the cleanest way would be to add a keyword-argument |
I removed the ugly parts and produced a base plate for future discussion - and while I was on it, I did a rebase against |
I think this looks good to me, but @reaperhulk how do you feel? |
This approach seems fine to me, feel free to mark it ready if it is and we can get it merged 😄 |
Just to propose the alternative option, I crafted c4a2a5f: This adds |
I don't really like having kwargs whose sole purpose is to improve hinting -- while the other approach isn't ideal, it is an improvement and doesn't create arguments with no runtime purpose. |
I tend to agree
…On Wed, Dec 4, 2024, 10:56 PM Paul Kehrer ***@***.***> wrote:
I don't really like having kwargs whose sole purpose is to improve hinting
-- while the other approach isn't ideal, it is an improvement and doesn't
create arguments with no runtime purpose.
—
Reply to this email directly, view it on GitHub
<#12068 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAAGBHQMTTNX2F2MEOQJUT2D7FFLAVCNFSM6AAAAABSWUIWX2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMJZGAZTIMJRGE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
This reverts commit c4a2a5f.
This reverts commit b79a4ec.
Thanks for your opinion - I agree with it not being the nicest solution, I tried to think about something like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
see #12056: As
NameAttribute.value
is specified asstr | bytes
, but only usesbytes
withNameOID.X500_UNIQUE_IDENTIFIER
, usingNameAttribute.value
and expecting a string (which is correct for all other cases) leads to typing-errors.By using a
overload
onget_attribute_for_oid
with aGeneric
this can be avoided. I used theGeneric
syntax as defined in PEP-484 - while Python 3.12 introduced support for PEP-659 syntax, this would void support for older python versions, which is probably not wanted (now).Consider this PR a first draft - I ran ruff and tests on my machine against them, but am more than happy for your remarks.