-
Notifications
You must be signed in to change notification settings - Fork 4
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
Use proper typing #4
Conversation
regexfactory/patterns.py
Outdated
@staticmethod | ||
def parse_init_args(*args, **kwargs): | ||
s1 = inspect.Signature( | ||
parameters=( | ||
inspect.Parameter("repetitions", kind=inspect.Parameter.POSITIONAL_OR_KEYWORD), | ||
inspect.Parameter("or_more", kind=inspect.Parameter.POSITIONAL_OR_KEYWORD) | ||
) | ||
) | ||
s2 = inspect.Signature( | ||
parameters=( | ||
inspect.Parameter("minimum", kind=inspect.Parameter.POSITIONAL_OR_KEYWORD), | ||
inspect.Parameter("maximum", kind=inspect.Parameter.POSITIONAL_OR_KEYWORD) | ||
) | ||
) | ||
try: | ||
bound = s1.bind(*args, **kwargs) | ||
i = bound.arguments["repetitions"] | ||
j = None | ||
or_more = bound.arguments["or_more"] | ||
except TypeError: | ||
bound = s2.bind(*args, **kwargs) | ||
i = bound.arguments["minimum"] | ||
j = bound.arguments["maximum"] | ||
or_more = False | ||
|
||
return i, j, or_more |
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.
This may be a bit over-the-top for what it's doing, so I will understand if instead of complex logic like this, you'd prefer this code without any overloads and just have less descriptive and less strict function parameters.
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.
Another option to avoid this mess would be to convert this into 2 separate class methods instead of having both logic for minimum and maximum or for range with optional or_more
attribute. This could look like this:
class Amount:
def __init__(i: int, j: Optional[int] = None, or_more: bool = False):
if j is not None and or_more:
raise ValueError("You can't specify both the maximum value and set or_more to True.")
... # The original logic
@classmethod
def from_range(cls, minimum: int, maximum: int) -> "Amount":
return cls(minimum, maximum, False)
@classmethod
def from_repetitions(cls, repetitions: int, or_more: bool = False) -> "Amount":
return cls(repetitions, None, or_more)
However this will result in having 2 class methods acting very similarly to __init__
at which point it may not even be worth it to do this:
x = Amount(1, 15)
x = Amount.from_range(1, 15)
y = Amount(15, or_more=True)
y = Amount.from_repetitions(15, or_more=True)
The decision is up to you, I'll adapt the code to whichever option you pick.
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.
Let's go with the overloading direction. It distinguishes the the arguments that can be passed explicitly rather than implying those parameters with less strict default arguments.
Later today I'll implement pyright into a CI/CD workflow that'll run along the same triggers as the flake8 workflow. |
Are there any more changes that you are intending to make before merging this? |
Follow PEP 484 and add type hints to all functions in the code-base. These type-hints are currently compatible with both
mypy
andpyright
.Now that the code-base is compatible with these, you should consider also integrating them into the automated CI/CD github workflows. (If you don't know how to, let me know if you want them added)
Note: I've renamed
ormore
attribute forAmount
class to a more pythonicor_more
name and I've also changed the parameter names forRange
class froma
andz
tostart
andstop