Skip to content
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

Set SpecificFlowClient default scope object and adjust utils.classproperty #793

Merged

Commits on Jul 26, 2023

  1. utils.classproperty now prefers the object

    The behavior of preferring an instance over a class, although valid
    and normal for a descriptor, is unlike classmethod and therefore may
    be surprising. However, it better allows us to define differentiated
    behaviors between instances and their classes, especially with respect
    to the `scopes` object on client classes.
    
    Without this change, it is not possible for a classproperty, when
    called, to refer back to the instance on which it was invoked.
    However, it is always possible to find the class via the instance, so
    expressive power is only increased by this change.
    
    Institute a convention of the classproperty decorated method accepting
    `self_or_cls` to clarify this at the usage sites.
    
    Comments on `classproperty` are updated. In particular, make sure that
    the current status of `classmethod(property(...))` stacking is
    reflected in those comments.
    
    A new test validates that the class attribute remains valid but the
    instance attribute is preferred when a classproperty is used to access
    an attribute.
    sirosen committed Jul 26, 2023
    Configuration menu
    Copy the full SHA
    3dbdec6 View commit details
    Browse the repository at this point in the history
  2. Improve SpecificFlowClient.scopes typing

    `mypy` would flag the `scopes` object as `ScopeBuilder | None` even
    though the class always defined a de-facto value for this attribute on
    init.
    
    To resolve, insert a stub object as a class variable. Not only does
    this pacify mypy, but it also allows us to raise more useful errors
    when the classvar is accessed.
    Define the stub and several tests for it, including a typing test.
    sirosen committed Jul 26, 2023
    Configuration menu
    Copy the full SHA
    1cbb95f View commit details
    Browse the repository at this point in the history
  3. Minor change to stub scopes object to pass pylint

    pylint complains about an `__init__` not invoking `super().__init__`.
    If we do the "obvious" thing and call the superclass init with a
    placeholder value, attribute access patterns change.
    
    In particular, `self.resource_server` is assigned as an attribute,
    meaning that the concrete value there is discovered by the default
    `__getattribute__` before `__getattr__` can be invoked. To solve this,
    intercept that access with a custom `__getattribute__` to raise an
    error. The error will implicitly be handled and trigger a call of
    `__getattr__`, resulting in the desired `AttributeError` for
    `resource_server` access.
    sirosen committed Jul 26, 2023
    Configuration menu
    Copy the full SHA
    d790bfc View commit details
    Browse the repository at this point in the history