diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..7b3a9b7 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,19 @@ + + +## What do these changes do? + + + +## Are there changes in behavior for the user? + + + +## Related issue number + + + +## Checklist + +- [ ] I think the code is well written +- [ ] Unit tests for the changes exist +- [ ] Documentation reflects the changes diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..4ac798a --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @penguinolog @kobe25 @dis-xcom diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..c688c65 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,73 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +education, socio-economic status, nationality, personal appearance, race, +religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project maintainers. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org diff --git a/setup.py b/setup.py index 7f724c6..ccb41d9 100644 --- a/setup.py +++ b/setup.py @@ -243,6 +243,10 @@ def get_simple_vars_from_src(src): name='threaded', author=variables['__author__'], author_email=variables['__author_email__'], + maintainer=', '.join( + '{name} <{email}>'.format(name=name, email=email) + for name, email in variables['__maintainers__'].items() + ), url=variables['__url__'], version=variables['__version__'], license=variables['__license__'], diff --git a/threaded/__init__.py b/threaded/__init__.py index 2d9eed0..ae87f8d 100644 --- a/threaded/__init__.py +++ b/threaded/__init__.py @@ -17,6 +17,7 @@ from __future__ import absolute_import import sys +import typing # noqa # pylint: disable=unused-import PY3 = sys.version_info[:2] > (3, 0) # type: bool @@ -52,7 +53,7 @@ __all__ = ( 'ThreadPooled', 'Threaded', 'threadpooled', 'threaded' -) +) # type: typing.Tuple[str, ...] if PY3: # pragma: no cover __all__ += ( @@ -68,6 +69,11 @@ __version__ = '1.0.0' __author__ = "Alexey Stepanov" __author_email__ = 'penguinolog@gmail.com' +__maintainers__ = { + 'Alexey Stepanov': 'penguinolog@gmail.com', + 'Antonio Esposito': 'esposito.cloud@gmail.com', + 'Dennis Dmitriev': 'dis-xcom@gmail.com', +} __url__ = 'https://github.com/python-useful-helpers/threaded' __description__ = ( "Decorators for running functions in Thread/ThreadPool/IOLoop" diff --git a/threaded/_base_gthreadpooled.py b/threaded/_base_gthreadpooled.py index a0e38ad..8a61d24 100644 --- a/threaded/_base_gthreadpooled.py +++ b/threaded/_base_gthreadpooled.py @@ -18,6 +18,7 @@ import typing # noqa # pylint: disable=unused-import +import gevent.event # noqa # pylint: disable=unused-import import gevent.threadpool import six diff --git a/threaded/_base_gthreadpooled.pyi b/threaded/_base_gthreadpooled.pyi index a87d371..eb1bb36 100644 --- a/threaded/_base_gthreadpooled.pyi +++ b/threaded/_base_gthreadpooled.pyi @@ -1,3 +1,4 @@ +import gevent.event import gevent.threadpool import typing from . import _base_threaded @@ -15,3 +16,5 @@ class BaseGThreadPooled(_base_threaded.APIPooled): @property def executor(self) -> gevent.threadpool.ThreadPool: ... + + def _get_function_wrapper(self, func: typing.Callable) -> typing.Callable[..., gevent.event.AsyncResult]: ... diff --git a/threaded/_base_threaded.pyi b/threaded/_base_threaded.pyi index 72a4514..894a400 100644 --- a/threaded/_base_threaded.pyi +++ b/threaded/_base_threaded.pyi @@ -1,7 +1,9 @@ import concurrent.futures +import threading import typing from . import _class_decorator -from multiprocessing import cpu_count as cpu_count + +def cpu_count() -> int: ... class APIPooled(_class_decorator.BaseDecorator): @classmethod @@ -23,6 +25,8 @@ class BasePooled(APIPooled): @property def executor(self) -> ThreadPoolExecutor: ... + def _get_function_wrapper(self, func: typing.Callable) -> typing.Callable[..., concurrent.futures.Future]: ... + class BaseThreaded(_class_decorator.BaseDecorator): def __init__( self, @@ -40,6 +44,8 @@ class BaseThreaded(_class_decorator.BaseDecorator): @property def started(self) -> bool: ... + def _get_function_wrapper(self, func: typing.Callable) -> typing.Callable[..., threading.Thread]: ... + class ThreadPoolExecutor(concurrent.futures.ThreadPoolExecutor): def __init__(self, max_workers: typing.Optional[int]=...) -> None: ... diff --git a/threaded/_class_decorator.pyi b/threaded/_class_decorator.pyi index e5163f5..0dc4410 100644 --- a/threaded/_class_decorator.pyi +++ b/threaded/_class_decorator.pyi @@ -1,3 +1,4 @@ +import abc import typing PY3: bool @@ -5,4 +6,11 @@ PY3: bool class BaseDecorator: __wrapped__: typing.Optional[typing.Callable] = ... def __init__(self, func: typing.Optional[typing.Callable]=...) -> None: ... + + @property + def _func(self) -> typing.Optional[typing.Callable]: ... + + @abc.abstractmethod + def _get_function_wrapper(self, func: typing.Callable) -> typing.Callable: ... + def __call__(self, *args: typing.Any, **kwargs: typing.Any) -> typing.Any: ... diff --git a/threaded/_threaded3.pyi b/threaded/_threaded3.pyi index 0ce980d..bd30da5 100644 --- a/threaded/_threaded3.pyi +++ b/threaded/_threaded3.pyi @@ -19,7 +19,10 @@ class ThreadPooled(_base_threaded.BasePooled): @property def loop_getter_need_context(self) -> bool: ... -class Threaded(_base_threaded.BaseThreaded): ... + def _get_function_wrapper(self, func: typing.Callable) -> typing.Callable[..., typing.Union[concurrent.futures.Future, asyncio.Task]]: ... + +class Threaded(_base_threaded.BaseThreaded): + def _get_function_wrapper(self, func: typing.Callable) -> typing.Callable[..., threading.Thread]: ... class AsyncIOTask(_class_decorator.BaseDecorator): def __init__( @@ -36,6 +39,8 @@ class AsyncIOTask(_class_decorator.BaseDecorator): @property def loop_getter_need_context(self) -> bool: ... + def _get_function_wrapper(self, func: typing.Callable) -> typing.Callable[..., asyncio.Task]: ... + def threadpooled( func: typing.Optional[typing.Callable]=..., *,