Skip to main content

Add a FnCollector for Ryanvk Flywheel

Project description

Flywheel-FnCollector

可能是个设想:通过设计一个FnCollector,简化现有Ryanvk Flywheel中定义Fn的流程。

此外添加了一些对后续工作可能有用的东西。

Project Structure

注:标记为分发包未提供的文件需要自行从仓库获取,且相关链接失效。

Flywheel-FnCollector
├── demo_*.py ················· 示例代码 (分发包未提供)
├── pdm.lock ·················· PDM 锁定文件 (分发包未提供)
├── pyproject.toml ············ 项目依赖 (PDM)
├── README.md ················· 项目介绍
└── src ······················· 项目源码
    └── flywheel_extras ······· 模块名
        ├── __init__.py ······· 模块入口
        ├── collector.py ······ FnCollector 相关定义
        ├── deprecated.py ····· 已弃用类/函数定义
        ├── instance.py ······· InstanceOf 扩展
        ├── overload.py ······· FnOverload 扩展
        ├── utils.py ·········· 工具函数定义
        ├── protocol.py ······· 内部定义 Protocol 相关
        └── typing.py ········· 类型提示/检查相关

Usage

FnCollector

from flywheel import SimpleOverload

from flywheel_extras import FnCollector


@FnCollector.set(SimpleOverload('name'), as_default=True)
def greet(name: str) -> str:  # This will become default implementation
    return f'Ordinary, {name}.'


@greet.collect(name='Teague')
def greet_teague(name: str) -> str:
    return 'Stargaztor, but in name only.'


@greet.collect(name='Grey')
def greet_grey(name: str) -> str:
    return 'Symbol, the Founder.'
>>> greet('Teague')
'Stargaztor, but in name only.'
>>> greet('Grey')
'Symbol, the Founder.'
>>> greet('Hizuki')
'Ordinary, Hizuki.'

可以输入多个FnOverload,调用时会采取一些数学手段匹配最佳实现; 也可以不输入任何FnOverload,此时会自动创建空的SimpleOverload

FnCollector支持在类中定义,调用时会自动添加self参数。

from flywheel import SimpleOverload

from flywheel_extras import FnCollector


class Action:
    @FnCollector.set(SimpleOverload('name'))
    def func_n(self, name: str) -> str: ...

    @classmethod
    @FnCollector.set(SimpleOverload('name'))
    def func_c(cls, name: str) -> str: ...

    @property  # 可以定义,但没什么用,也不推荐这么做
    @FnCollector.set(as_default=True)
    def func_p(self) -> str:
        return ''

    @staticmethod
    @FnCollector.set(SimpleOverload('name'))
    def func_s(name: str) -> str: ...


# FnCollector.collect(Ellipsis) will not raise error, see below.
@Action.func_n.collect(...)
def impl_n(self: Action, name: str) -> str: ...


# property.fget here
@Action.func_p.fget.collect(...)  # noqa
def impl_p(self: Action) -> str: ...

[!WARNING]

FnCollector改变了存在重复实现时调用顺序:在同一个CollectContext下,优先选择最后定义的实现; 不同CollectContext下逻辑与原版一致。

这么做是为了方便后续在其他项目中实现外挂重载功能。

Namespace & Context

FnCollector采用动态定义FnCollectEndpoint的方式,这意味着你可以放心在全局上下文中使用相同命名的FnOverload

此外项目加入了Namespace用于模拟Legacy Ryanvk中Perform

>>> @greet.collect(123, name='Grey')  # Namespace is 123
... def greet_grey_123(name: str) -> str:
...     return '1111'
... 
>>> greet('Grey')
'Symbol, the Founder.'
>>> greet.call(None, 'Grey')  # Same as greet('Grey'), namespace is None
'Symbol, the Founder.'
>>> greet.call(123, 'Grey')  # Namespace is 123
'1111'

默认上下文收集方式与local_collect相同。 根据文档说明, 项目将避免使用scoped_collect

对于CollectContextInstanceContext,写法与原版一致,具体示例见demo_collector.py

FnOverload

FnOverload的本质是根据call_valuescope中查找对应collect_value的函数。 SimpleOverloadcollect_valuecall_value是等价的。

因此,根据collect_valuecall_value之间的关系, 项目参考SimpleOverload实现了基于映射关系的MappingOverload和基于谓词的PredicateOverload

FnOverload匹配方式如下:

SimpleOverload: call_value == collect_value
TypeOverload: type(call_value) == collect_value
MappingOverload: mapping[call_value] == collect_value
PredicateOverload: predicate(collect_value, call_value) == True

具体示例见demo_overload.py

InstanceOf

项目添加了OptionalInstanceOf描述符,在找不到实例时使用默认值。

具体示例见demo_collector.py

[!WARNING]

据魔女所述,InstanceOf可能会在未来被弃用,因此不再推荐使用。

作为替代,下文实现了一种类似于Staff的跨类读取实例的方法。

Cross Collection

大概是一种Staff/InstanceOf的替代方案。

你可以在一个类里定义重载函数,在另一个类里定义实现。这两个类要求继承自同一个数据类,且该数据类实现了__cross__方法。

class SomePerform:
    ...

    @classmethod
    def __cross__(cls, other: 'SomePerform') -> 'SomePerform':
        ...

数据类就是字面意思,不需要dataclass

具体示例见demo_cross_class.py

可以不要求同一个数据类,但在需要调用__cross__的场合至少不应该报错。

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flywheel_fncollector-0.4.0.tar.gz (9.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flywheel_fncollector-0.4.0-py3-none-any.whl (9.5 kB view details)

Uploaded Python 3

File details

Details for the file flywheel_fncollector-0.4.0.tar.gz.

File metadata

  • Download URL: flywheel_fncollector-0.4.0.tar.gz
  • Upload date:
  • Size: 9.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: pdm/2.22.1 CPython/3.12.8 Linux/6.8.0-1017-azure

File hashes

Hashes for flywheel_fncollector-0.4.0.tar.gz
Algorithm Hash digest
SHA256 cf9828c5a492c1e4557efcd7b24272ca167a71488ef58937a99775c2f8b564f0
MD5 593e053e74fe3307aed20dc2a850797b
BLAKE2b-256 4b2014e94df765ceaf4137c530bdb133a3790833058fcbeebbc0be60ee6acd52

See more details on using hashes here.

File details

Details for the file flywheel_fncollector-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: flywheel_fncollector-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 9.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: pdm/2.22.1 CPython/3.12.8 Linux/6.8.0-1017-azure

File hashes

Hashes for flywheel_fncollector-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 55ebec5b5ce6cb287a8277538977c8ef6d47fd42f0c8543ee44763b32f97c04d
MD5 ae9185abbc1dbfb6fbaa1aae84d1b173
BLAKE2b-256 34fa978ab5b5495462333eae9dfae12cf054552d3b783ab92679a11e9baf6fca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page