Skip to content

Commit

Permalink
Rename atools -> funktools everywhere
Browse files Browse the repository at this point in the history
  • Loading branch information
LoganEvans committed Mar 18, 2024
1 parent 9a23484 commit 84962d0
Show file tree
Hide file tree
Showing 21 changed files with 226 additions and 204 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![Coverage Status](https://coveralls.io/repos/github/cevans87/atools/badge.svg?branch=master&kill_cache=1)](https://coveralls.io/github/cevans87/atools?branch=master)
# atools
[![Coverage Status](https://coveralls.io/repos/github/cevans87/funktools/badge.svg?branch=master&kill_cache=1)](https://coveralls.io/github/cevans87/funktools?branch=master)
# funktools
Python 3.9+ decorators including

- `@memoize` - a function decorator for sync and async functions that memoizes results.
Expand Down
15 changes: 0 additions & 15 deletions atools/__init__.py

This file was deleted.

4 changes: 2 additions & 2 deletions demo/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@

import logging

import atools
import funktools

from . import advanced, cli, first_example, memoize, rate

logging.basicConfig(level=logging.CRITICAL, format='%(levelname)s: %(message)s')

atools.CLI(__package__).run()
funktools.CLI(__package__).run()
10 changes: 5 additions & 5 deletions demo/advanced.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#!/usr/bin/env python3
"""Demos for advanced composition of atools decorators.
"""Demos for advanced composition of funktools decorators.
"""

import atools
import funktools


# Run with any of the following:
# - python3 -m demo.advanced entrypoint
# - python3 -m demo advanced entrypoint
@atools.CLI()
@funktools.CLI()
def entrypoint() -> None:
print('haha')

Expand All @@ -19,11 +19,11 @@ def entrypoint() -> None:
#
# A few cool things to try:
# - python3 -m demo advanced burst
@atools.CLI()
@funktools.CLI()
def burst(foo: int) -> None:
...


# Enables this CLI to be run with `python3 -m demo.advanced`.
if __name__ == '__main__':
atools.CLI(__name__).run()
funktools.CLI(__name__).run()
52 changes: 26 additions & 26 deletions demo/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
import logging
import typing

import atools
import funktools

logger = logging.getLogger(__name__)
logger.setLevel('ERROR')


@atools.CLI()
@funktools.CLI()
def simple_arg(arg: str) -> None:
"""Demo for CLI with an arg.
Expand All @@ -19,7 +19,7 @@ def simple_arg(arg: str) -> None:
print(locals())


@atools.CLI()
@funktools.CLI()
def simple_arg_with_help_text(
arg: typing.Annotated[str, 'typing.Annotated[<T>, help_text] allows you to give CLI help text for parameter.'],
) -> None:
Expand All @@ -31,7 +31,7 @@ def simple_arg_with_help_text(
print(locals())


@atools.CLI()
@funktools.CLI()
def positional_only_without_defaults(
foo: typing.Annotated[int, 'A positional-only foo without default. Is positional-only in CLI.'],
bar: typing.Annotated[str, 'A positional-only bar without default. Is positional-only in CLI.'],
Expand All @@ -45,7 +45,7 @@ def positional_only_without_defaults(
print(locals())


@atools.CLI()
@funktools.CLI()
def positional_or_keyword_without_defaults(
foo: typing.Annotated[float, 'A positional-or-keyword foo without default. Is positional-only in CLI.'],
bar: typing.Annotated[bool, 'A positional-or-keyword bar without default. Is positional-only in CLI.'],
Expand All @@ -58,7 +58,7 @@ def positional_or_keyword_without_defaults(
print(locals())


@atools.CLI()
@funktools.CLI()
def keyword_only_without_defaults(
*,
foo: typing.Annotated[float, 'A keyword-only foo without default. Is keyword-only in CLI.'],
Expand All @@ -72,7 +72,7 @@ def keyword_only_without_defaults(
print(locals())


@atools.CLI()
@funktools.CLI()
def positional_only_with_defaults(
foo: typing.Annotated[int, 'A positional-only foo with default. Is positional-only in CLI.'] = 0,
bar: typing.Annotated[str, 'A positional-only bar with default. Is positional-only in CLI.'] = 'Bye!',
Expand All @@ -88,7 +88,7 @@ def positional_only_with_defaults(
print(locals())


@atools.CLI()
@funktools.CLI()
def positional_or_keyword_with_defaults(
foo: typing.Annotated[float, 'A positional-or-keyword foo with default. Is keyword-only in CLI.'] = 0.0,
bar: typing.Annotated[bool, 'A positional-or-keyword bar with default. Is keyword-only in CLI.'] = False,
Expand All @@ -105,7 +105,7 @@ def positional_or_keyword_with_defaults(
print(locals())


@atools.CLI()
@funktools.CLI()
def keyword_only_with_defaults(
*,
foo: typing.Annotated[float, 'A keyword-only foo with default. Is keyword-only in CLI.'] = 0.0,
Expand All @@ -129,7 +129,7 @@ class MetasyntacticEnum(enum.Enum):
baz = 3


@atools.CLI()
@funktools.CLI()
def enum(
arg: typing.Annotated[MetasyntacticEnum, 'An enum. Enter in any of the value name strings in CLI.'],
) -> None:
Expand All @@ -143,7 +143,7 @@ def enum(
print(locals())


@atools.CLI()
@funktools.CLI()
def optional(
arg: typing.Annotated[typing.Optional[int | str], 'An optional. CLI arg may be any of these types or None.'],
) -> None:
Expand All @@ -158,7 +158,7 @@ def optional(
print(f'{arg=!r}')


@atools.CLI()
@funktools.CLI()
def union_type(
arg: typing.Annotated[bool | float | int | str | None, 'A union. CLI arg may be any of these types.'],
) -> None:
Expand All @@ -180,7 +180,7 @@ def union_type(
print(locals())


@atools.CLI()
@funktools.CLI()
def literal(
arg: typing.Annotated[typing.Literal['foo', 'bar', 'baz'], 'A literal. CLI arg may be any of these choices.'],
) -> None:
Expand All @@ -199,7 +199,7 @@ class CustomType:
data: bool | float | int | str | None | dict | list | set | tuple


@atools.CLI()
@funktools.CLI()
def custom_type(
arg: typing.Annotated[
CustomType,
Expand All @@ -223,7 +223,7 @@ def custom_type(
print(locals())


@atools.CLI()
@funktools.CLI()
def var_positional(
*args: typing.Annotated[int | float, 'A var-positional arg. Is any remaining positional args in CLI.'],
) -> None:
Expand All @@ -236,7 +236,7 @@ def var_positional(
print(locals())


@atools.CLI()
@funktools.CLI()
def var_keyword(
**kwargs: typing.Annotated[int | float | str, 'A var-keyword arg. Is any remaining flag args in CLI.'],
) -> None:
Expand All @@ -248,7 +248,7 @@ def var_keyword(
print(locals())


@atools.CLI()
@funktools.CLI()
def _hidden_subcommand(foo: int) -> None:
"""Demo for CLI entrypoint where `_hidden_subcommand` does not show as a subcommand in help text.
Expand All @@ -259,8 +259,8 @@ def _hidden_subcommand(foo: int) -> None:
print(locals())


@atools.CLI()
def log_level_with_bound_logger(log_level: atools.CLI.Annotated.log_level(logger) = 'NOTSET') -> None:
@funktools.CLI()
def log_level_with_bound_logger(log_level: funktools.CLI.Annotated.log_level(logger) = 'NOTSET') -> None:
"""Demo for CLI entrypoint where bound logger has level set to parsed `log_level` value.
Ex:
Expand All @@ -278,8 +278,8 @@ def log_level_with_bound_logger(log_level: atools.CLI.Annotated.log_level(logger
logger.critical('If you can see this log line, your log_level is at least CRITICAL.')


@atools.CLI()
def log_level_with_bound_logger_name(log_level: atools.CLI.Annotated.log_level(__name__) = 'NOTSET') -> None:
@funktools.CLI()
def log_level_with_bound_logger_name(log_level: funktools.CLI.Annotated.log_level(__name__) = 'NOTSET') -> None:
"""Demo for CLI entrypoint where logger with bound name has level set to parsed `log_level` value.
Ex:
Expand All @@ -297,8 +297,8 @@ def log_level_with_bound_logger_name(log_level: atools.CLI.Annotated.log_level(_
logging.getLogger(__name__).critical('If you can see this log line, your log_level is at least CRITICAL.')


@atools.CLI()
def quiet_with_bound_logger(quiet: atools.CLI.Annotated.quiet(logger) = logging.DEBUG) -> None:
@funktools.CLI()
def quiet_with_bound_logger(quiet: funktools.CLI.Annotated.quiet(logger) = logging.DEBUG) -> None:
"""Demo for CLI entrypoint where bound logger has level set to parsed `quiet` value.
Ex:
Expand All @@ -318,8 +318,8 @@ def quiet_with_bound_logger(quiet: atools.CLI.Annotated.quiet(logger) = logging.
logger.critical('If you can see this log line, your log_level is at least CRITICAL.')


@atools.CLI()
def verbose_with_bound_logger(verbose: atools.CLI.Annotated.verbose(logger) = logging.CRITICAL + 10) -> None:
@funktools.CLI()
def verbose_with_bound_logger(verbose: funktools.CLI.Annotated.verbose(logger) = logging.CRITICAL + 10) -> None:
"""Demo for CLI entrypoint where bound logger has level set to parsed `verbose` value.
Ex:
Expand All @@ -340,4 +340,4 @@ def verbose_with_bound_logger(verbose: atools.CLI.Annotated.verbose(logger) = lo


if __name__ == '__main__':
atools.CLI(__name__).run()
funktools.CLI(__name__).run()
6 changes: 3 additions & 3 deletions demo/first_example.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import atools
import funktools


@atools.CLI(__name__)
@funktools.CLI(__name__)
def entrypoint() -> None:
print('haha')


if __name__ == '__main__':
atools.CLI(__name__).run()
funktools.CLI(__name__).run()
6 changes: 3 additions & 3 deletions demo/memoize.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import pathlib
import pprint

import atools
import funktools


@atools.CLI(__name__)
@funktools.CLI(__name__)
def entrypoint() -> None:
pprint.pprint(f'{os.environ.__dict__=}')


if __name__ == '__main__':
import sys
atools.CLI(__name__).run()
funktools.CLI(__name__).run()
Binary file added funktools/.__init__.py.swp
Binary file not shown.
Binary file added funktools/._template.py.swp
Binary file not shown.
37 changes: 37 additions & 0 deletions funktools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import typing

def __getattr__(attr: str) -> typing.Callable:
if attr == "CLI":
from ._cli import CLI
return CLI
elif attr == "Key":
from ._key import Decorator as Key
return Key
elif attr == "Memoize":
from ._memoize import Decorator as Memoize
return Memoize
elif attr == "rate":
from ._rate_decorator import rate
return rate
elif attr == "Register":
from ._register import Decorator as Register
return Register
elif attr == "Throttle":
from ._throttle import Throttle
return Throttle
elif attr == "template":
from ._template import _template
return _template()

__all__ = [
'CLI',
'Memoize',
'Key',
'rate',
'Register',
'Throttle',
'template',
]

def __dir__():
return __all__
24 changes: 12 additions & 12 deletions atools/_cli.py → funktools/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Single-entrypoint example:
- file: foo.py
from atools.cli import CLI
from funktools.cli import CLI
@CLI() # This will add `.cli` decoration to `entrypoint`.
Expand All @@ -24,10 +24,10 @@ def entrypoint(a: int, /, b: str, c: bool = True, *, d: float, e: tuple = tuple(
Multiple-entrypoint example:
- file: prog/__init__.py
import atools
import funktools
@atools.CLI(submodules=True) # This will find entrypoints in submodules named `entrypoint`.
@funktools.CLI(submodules=True) # This will find entrypoints in submodules named `entrypoint`.
def entrypoint(a: int, /, b: str, c: bool = True, *, d: float, e: tuple = tuple()) -> ...:
...
Expand Down Expand Up @@ -375,25 +375,25 @@ def run(self, args: typing.Sequence[str] = ...) -> object:
Ex.
Given the following registered entrypoints.
@atools.CLI() # Automatically registered as f'{__name__}.foo'
@funktools.CLI() # Automatically registered as f'{__name__}.foo'
def foo(arg: int) -> ...: ...
@atools.CLI() # Automatically registered as f'{__name__}.bar'
@funktools.CLI() # Automatically registered as f'{__name__}.bar'
def bar(arg: float) -> ...: ...
@atools.CLI(f'{__name__}.qux') # Manually registered as f'{__name__}.qux'
@funktools.CLI(f'{__name__}.qux') # Manually registered as f'{__name__}.qux'
async def baz(arg: str) -> ...: ... # Async entrypoints are also fine.
Entrypoints may be called like so.
atools.CLI(__name__).run(['foo', '42'])
atools.CLI(f'{__name__}.foo').run(['42']) # Equivalent to previous line.
funktools.CLI(__name__).run(['foo', '42'])
funktools.CLI(f'{__name__}.foo').run(['42']) # Equivalent to previous line.
atools.CLI(__name__).run(['bar', '3.14'])
atools.CLI(f'{__name__}.foo').run(['3.14']) # Equivalent to previous line.
funktools.CLI(__name__).run(['bar', '3.14'])
funktools.CLI(f'{__name__}.foo').run(['3.14']) # Equivalent to previous line.
atools.CLI(__name__).run(['qux', 'Hi!'])
atools.CLI(f'{__name__}.qux').run(['Hi!']) # Equivalent to previous line.
funktools.CLI(__name__).run(['qux', 'Hi!'])
funktools.CLI(f'{__name__}.qux').run(['Hi!']) # Equivalent to previous line.
If the entrypoint a couroutinefunction, it will be run via `asyncio.run`.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 84962d0

Please sign in to comment.