Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.10/site-packages/zmq/sugar/attrsettr.py: 33%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

43 statements  

1"""Mixin for mapping set/getattr to self.set/get""" 

2 

3# Copyright (C) PyZMQ Developers 

4# Distributed under the terms of the Modified BSD License. 

5from __future__ import annotations 

6 

7import errno 

8from typing import TypeVar, Union 

9 

10from .. import constants 

11 

12T = TypeVar("T") 

13OptValT = Union[str, bytes, int] 

14 

15 

16class AttributeSetter: 

17 def __setattr__(self, key: str, value: OptValT) -> None: 

18 """set zmq options by attribute""" 

19 

20 if key in self.__dict__: 

21 object.__setattr__(self, key, value) 

22 return 

23 # regular setattr only allowed for class-defined attributes 

24 for cls in self.__class__.mro(): 

25 if key in cls.__dict__ or key in getattr(cls, "__annotations__", {}): 

26 object.__setattr__(self, key, value) 

27 return 

28 

29 upper_key = key.upper() 

30 try: 

31 opt = getattr(constants, upper_key) 

32 except AttributeError: 

33 raise AttributeError( 

34 f"{self.__class__.__name__} has no such option: {upper_key}" 

35 ) 

36 else: 

37 self._set_attr_opt(upper_key, opt, value) 

38 

39 def _set_attr_opt(self, name: str, opt: int, value: OptValT) -> None: 

40 """override if setattr should do something other than call self.set""" 

41 self.set(opt, value) 

42 

43 def __getattr__(self, key: str) -> OptValT: 

44 """get zmq options by attribute""" 

45 upper_key = key.upper() 

46 try: 

47 opt = getattr(constants, upper_key) 

48 except AttributeError: 

49 raise AttributeError( 

50 f"{self.__class__.__name__} has no such option: {upper_key}" 

51 ) from None 

52 else: 

53 from zmq import ZMQError 

54 

55 try: 

56 return self._get_attr_opt(upper_key, opt) 

57 except ZMQError as e: 

58 # EINVAL will be raised on access for write-only attributes. 

59 # Turn that into an AttributeError 

60 # necessary for mocking 

61 if e.errno in {errno.EINVAL, errno.EFAULT}: 

62 raise AttributeError(f"{key} attribute is write-only") 

63 else: 

64 raise 

65 

66 def _get_attr_opt(self, name, opt) -> OptValT: 

67 """override if getattr should do something other than call self.get""" 

68 return self.get(opt) 

69 

70 def get(self, opt: int) -> OptValT: 

71 """Override in subclass""" 

72 raise NotImplementedError("override in subclass") 

73 

74 def set(self, opt: int, val: OptValT) -> None: 

75 """Override in subclass""" 

76 raise NotImplementedError("override in subclass") 

77 

78 

79__all__ = ['AttributeSetter']