Comments (5)
Thanks @janluke for the code example! I'm quite bad at decorators so it took me a while to digest and integrate. I took the liberty to reuse some of your proposed code to add to click_extra
at: https://github.com/kdeldycke/click-extra/blob/bceac30592e67f262a87af1e8cdbcf4bcac0e15e/click_extra/decorators.py#L31-L76 .
This helped me to clone @command
and @group
decorators from cloup
while allowing their usage without parenthesis.
Thanks again @janluke ! 🤗
from cloup.
I know they added it some time ago but I don't like this pattern:
- it complicates the code and the type annotations for no practical benefit
- I think it manages to confuse both beginners (making decorators appear more magical than they actually are) and more intermediate programmers (who wonder wtf is going on :)).
I know some popular libraries like pytest use it (but this is probably the least magical thing about pytest), but I'd gladly avoid it.
A good reason to add it is to be consistent with Click. And that's a pretty good reason. Still, I'd rather provide a good error message as the original issue and PR proposed. This is somewhat needed now that the syntax is allowed in Click.
from cloup.
I might change my mind on this, given that even the standard library embraces this pattern (e.g. @dataclass
). I still think the way it complicates the code (and the way it complicates the semantics of the decorator giving it a sort of "double nature" (*)) is absolutely not worthwhile.
(*) it's basically overloading with radically different return types, something similar to Union return types, which I consider code smell.
from cloup.
Oh yes. I agree with you sentiment. Implementing these naked decorators is a chore, even if it makes them beautiful from the user point of view. That's why I classify them as nice-to-have, not critical. I don't even have a clue on how to implement them! 😅
Good point on @dataclass
. If they're part of the standard library maybe will see some stuff in the future to make these easier to implement. In the mean I guess we'll have to sacrifice purity for convenience and user-friendliness.
from cloup.
When you don't care about static typing and IDE autocompletion, it's pretty easy to implement. One can write a write a generic decorator, but you'll lose auto-completion:
from functools import wraps
from typing import Any, Callable, TypeVar
AnyCallable = Callable[..., Any]
F = TypeVar('F', bound=AnyCallable)
"""Type variable for a Callable."""
Decorator = Callable[[F], F]
DecoratorFactory = Callable[..., Decorator[F]]
def allow_missing_parenthesis(dec_factory):
@wraps(dec_factory)
def new_factory(*args, **kwargs):
if args and callable(args[0]):
return dec_factory(*args[1:], **kwargs)(args[0])
return dec_factory(*args, **kwargs)
return new_factory
#
# Usage example
#
@allow_missing_parenthesis
def decorator_factory(name="<default name>") -> Decorator[F]:
"""A dummy decorator factory."""
def decorator(f: F) -> F:
@wraps(f)
def wrapper(*args, **kwargs):
f(*args, **kwargs)
print(f"I'm {name}.")
print("---")
return wrapper
return decorator
@decorator_factory
def without_parenthesis(msg="[@decorator_factory]"):
print(msg)
@decorator_factory()
def empty_args(msg="[@decorator_factory()]"):
print(msg)
@decorator_factory("janluke")
def with_args(msg='[@decorator_factory("janluke")]'):
print(msg)
without_parenthesis()
empty_args()
with_args()
Integrating the feature into Cloup and make all mypy type checks pass is more complicated. I won't do that work for such a cosmetic feature (which I don't even want or like).
from cloup.
Related Issues (20)
- Minor language issue in documentation HOT 3
- Require one constraint prevents subcommand help from working HOT 5
- Consider renaming __constraints to __cloup_constraints__ HOT 4
- Test for Python 3.11
- Pytest: replace deprecated `pytest.warns(None)` with something else
- Rename `sorted` attribute of `Section` to `is_sorted` to solve conflict with `Section.sorted` static method HOT 6
- Use ruff and a code formatter HOT 1
- mutually_exclusive constraint doesn't work with multiple flags with flag_value HOT 1
- Styling of aliases HOT 1
- Custom MultiCommands (with styling) HOT 3
- Over-highlighting of heading's extra space HOT 2
- Change `HelpTheme` type to allow sub-classing HOT 3
- `cloup.Group` ignores `command_class` to produce sub-commands HOT 9
- Exception when creating copy of `Option` object with `Constraint` HOT 5
- Consider adding support to async commands
- Aliases not added if `Group` is initialized with a list of commands HOT 2
- Overwrite `to_info_dict()` method in `Context` and command classes HOT 3
- Drop support for python 3.7, add it for 3.12
- `cloup.Color` cannot be rendered by Sphinx: `Exception: you can't set attributes on this class` HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cloup.