• No results found

pyattributes Release Patrick Lehmann Jul 22, 2021

N/A
N/A
Protected

Academic year: 2021

Share "pyattributes Release Patrick Lehmann Jul 22, 2021"

Copied!
36
0
0

Loading.... (view fulltext now)

Full text

(1)

pyAttributes

Release 2.2.1

Patrick Lehmann

Jul 22, 2021

(2)
(3)

1 Use Cases 3

2 Technique 5

3 Common Attributes 7

4 Special Attributes 9

5 Contributors 11

6 License 13

6.1 Installation/Updates . . . 13

6.2 Dependencies. . . 13

6.3 ArgParse . . . 15

6.4 pyAttributes Module . . . 20

6.5 ArgParseAttributes Module . . . 21

6.6 Apache License 2.0. . . 25

6.7 Index . . . 28

6.8 Python Module Index . . . 28

Python Module Index 29

Index 31

i

(4)

ii

(5)

_ _ _ _ _ _

_ __ _ _ / \ | |_| |_ _ __(_) |__ _ _| |_ ___ ___

| '_ \| | | | / _ \| __| __| '__| | '_ \| | | | __/ _ \/ __|

| |_) | |_| |/ ___ \ |_| |_| | | | |_) | |_| | || __/\__ \

| .__/ \__, /_/ \_\__|\__|_| |_|_.__/ \__,_|\__\___||___/

|_| |___/

The Python package pyAttributes offers implementations of .NET-like attributes realized with Python decorators. The package also offers a mixin-class to ease using classes having annotated methods.

In addition, an ArgParseAttributes module is provided, which allows users to describe complex argparse commond-line argument parser structures in a declarative way.

Attributes can create a complex class hierarchy. This helps in finding and filtering for annotated properties and user- defined data. These search operations can be called globally on the attribute classes or locally within an annotated class. Therefore the provided helper-mixin should be inherited.

OVERVIEW 1

(6)

pyAttributes, Release 2.2.1

2 OVERVIEW

(7)

ONE

USE CASES

Annotate properties and user-defined data to methods.

• Describe a command line argument parser (argparse). SeepyAttributes Documentation -> ArgParse Examples

• Mark class members for documentation. SeeSphinxExtensions-> DocumentMemberAttribute

• Annotate user-defined data to classes.

• Describe test cases and test suits to get a cleaner syntax for Python’s unit tests.

3

(8)

pyAttributes, Release 2.2.1

4 Chapter 1. Use Cases

(9)

TWO

TECHNIQUE

The annotated data is stored in an additional __dict__ entry for each annotated method. By default the entry is called __pyattr__. Multiple attributes can be applied to the same method.

5

(10)

pyAttributes, Release 2.2.1

6 Chapter 2. Technique

(11)

THREE

COMMON ATTRIBUTES

• Attribute class

• AttributeHelperMixin class

7

(12)

pyAttributes, Release 2.2.1

8 Chapter 3. Common Attributes

(13)

FOUR

SPECIAL ATTRIBUTES

This package brings special attribute implementations for:

• Python’s ArgParse including sub-parser support.

9

(14)

pyAttributes, Release 2.2.1

10 Chapter 4. Special Attributes

(15)

FIVE

CONTRIBUTORS

• Patrick Lehmann(Maintainer)

• and more...

11

(16)

pyAttributes, Release 2.2.1

12 Chapter 5. Contributors

(17)

SIX

LICENSE

This Python package (source code) is licensed under Apache License 2.0. The accompanying documentation is li- censed under Creative Commons - Attribution 4.0 (CC-BY 4.0).

6.1 Installation/Updates

6.1.1 Using PIP

Installation using PIP pip3 install pyAttributes

Updating using PIP

pip3 install -U pyAttributes

6.2 Dependencies

Libraries.io Requires.io

6.2.1 pyAttributes Package (Mandatory)

Manually Installing Package Requirements

Use the requirements.txt file to install all dependencies via pip3 or install the package directly from PyPI (see Installation/Updates).

pip3 install -U -r requirements.txt

13

(18)

pyAttributes, Release 2.2.1

Dependency List

Package Version License Dependencies

pydecor 2.0.1 MIT • dill(BSD 3-clause)

• six(MIT)

6.2.2 Unit Testing / Coverage (Optional)

Additional Python packages needed for testing and code coverage collection. These packages are only needed for developers or on a CI server, thus sub-dependencies are not evaluated further.

Manually Installing Test Requirements

Use the tests/requirements.txt file to install all dependencies via pip3. The file will recursively install the mandatory dependencies too.

pip3 install -U -r tests/requirements.txt

Dependency List

Package Version License Dependencies

pytest 6.2.4 MIT Not yet evaluated.

pytest-cov 2.12.1 MIT Not yet evaluated.

Coverage 5.5 Apache License, 2.0 Not yet evaluated.

6.2.3 Sphinx Documentation (Optional)

Additional Python packages needed for documentation generation. These packages are only needed for developers or on a CI server, thus sub-dependencies are not evaluated further.

Manually Installing Documentation Requirements

Use the doc/requirements.txt file to install all dependencies via pip3. The file will recursively install the manda- tory dependencies too.

pip3 install -U -r doc/requirements.txt

14 Chapter 6. License

(19)

Dependency List

Package Version License Dependencies

Sphinx 4.1.1 BSD 3-Clause Not yet evaluated.

sphinx_btd_theme 0.5.2 MIT Not yet evaluated.

!!sphinx_fontawesome 0.0.6 GPL 2.0 Not yet evaluated.

sphinx_autodoc_typehints 1.12.0 MIT Not yet evaluated.

Pygments 2.9.0 BSD 2-Clause Not yet evaluated.

6.3 ArgParse

Many people use Python’sargparsecommand line argument parser. This parser can handle sub-commands like git commit -m "message"where commit is a sub-command and -m <message> is an argument of this sub-command parser. It’s possible to assign a callback function to each individual sub-command parser.

• Declarative description instead of imperative form.

• All options from argparse can be used.

• Declare accepted command-line arguments close to the responsible handler method

• Complex parsers can be distributed accross multiple classes and merged via multiple inheritance.

• Pre-defined argument templates like switch parameters (--help).

6.3.1 Classic argparse Example

Listing 1: tests/example/OldStyle.py

1 import textwrap

2 from argparse import ArgumentParser, RawDescriptionHelpFormatter

3 from typing import List, Dict

4 5

6 class ProgramBase():

7 HeadLine = "Simple ArgParse Test Program"

8

9 def __init__(self):

10 pass

11

12 def PrintHeadline(self):

13 print("{line}".format(line="=" * 80))

14 print("{headline: ^80s}".format(headline=self.HeadLine))

15 print("{line}".format(line="=" * 80))

16 17

18 class Program(ProgramBase):

19 MainParser: ArgumentParser = None

20 SubParsers: Dict[str, ArgumentParser] = None

21

22 def __init__(self):

23 super().__init__()

(continues on next page)

6.3. ArgParse 15

(20)

pyAttributes, Release 2.2.1

(continued from previous page)

24

25 self._ConstructParser()

26

27 def _ConstructParser(self):

28 # create a commandline argument parser

29 self.MainParser = ArgumentParser(

30 description=textwrap.dedent('''\

31 This is the test program.

32 '''),

33 epilog=textwrap.fill("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed␣

˓→diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam."),

34 formatter_class=RawDescriptionHelpFormatter,

35 add_help=False

36 )

37

38 self.MainParser.add_argument("-q", "--quiet", dest="quiet", action="store_const",

˓→ const=True, default=False, help="Reduce messages to a minimum.")

39 self.MainParser.add_argument("-v", "--verbose", dest="verbose", action="store_const",

˓→ const=True, default=False, help="Print out detailed messages.")

40 self.MainParser.add_argument("-d", "--debug", dest="debug", action="store_const",

˓→ const=True, default=False, help="Enable debug mode.")

41

42 # create subparsers

43 subParsers = self.MainParser.add_subparsers(help='sub-command help')

44 self.SubParsers = {}

45

46 # Default handler

47 self.MainParser.set_defaults(func=self.HandleDefault)

48

49 # Help handler

50 HelpParser = subParsers.add_parser("help", help = "Display help page(s) for the␣

˓→given command name.")

51 HelpParser.add_argument(metavar = "Command", dest = "Command", type = str, nargs = "?

˓→", help = "Print help page(s) for a command.")

52 HelpParser.set_defaults(func=self.HandleHelp)

53 self.SubParsers["help"] = HelpParser

54

55 # UserManagement commands

56 CreateUserParser = subParsers.add_parser("new-user", help="Create a new user.")

57 CreateUserParser.add_argument(metavar='<UserID>', dest="UserID", type=str, help=

˓→"UserID - unique identifier")

58 CreateUserParser.add_argument(metavar='<Name>', dest="Name", type=str, help="The user

˓→'s display name.")

59 CreateUserParser.set_defaults(func=self.HandleNewUser)

60 self.SubParsers["new-user"] = CreateUserParser

61

62 RemoveUserParser = subParsers.add_parser("delete-user", help="Delete a user.")

63 RemoveUserParser.add_argument(metavar='<UserID>', dest="UserID", type=str, help=

˓→"UserID - unique identifier")

64 RemoveUserParser.set_defaults(func=self.HandleDeleteUser)

65 self.SubParsers["delete-user"] = RemoveUserParser

66

(continues on next page)

16 Chapter 6. License

(21)

(continued from previous page)

67 RemoveUserParser = subParsers.add_parser("list-user", help="List users.")

68 RemoveUserParser.add_argument('--all', dest="all", help='List all users.')

69 RemoveUserParser.set_defaults(func=self.HandleListUser)

70 self.SubParsers["list-user"] = RemoveUserParser

71

72 def Run(self):

73 args = self.MainParser.parse_args()

74 args.func(args)

75

76 def HandleDefault(self, args):

77 self.PrintHeadline()

78

79 print("HandleDefault:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}".format(args.

˓→quiet, args.verbose, args.debug))

80

81 def HandleHelp(self, args):

82 self.PrintHeadline()

83

84 print("HandleHelp:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}\n\n command={3!s}\

˓→n\n".format(args.quiet, args.verbose, args.debug, args.Command))

85

86 if (args.Command is None):

87 self.MainParser.print_help()

88 elif (args.Command == "help"):

89 print("This is a recursion ...")

90 else:

91 try:

92 self.SubParsers[args.Command].print_help()

93 except KeyError:

94 print("Command {0} is unknown.".format(args.Command))

95

96 def HandleNewUser(self, args):

97 self.PrintHeadline()

98

99 print("HandleHelp:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}\n\n UserID={3!s} ␣

˓→Name={4!s}".format(args.quiet, args.verbose, args.debug, args.UserID, args.Name))

100

101 def HandleDeleteUser(self, args):

102 self.PrintHeadline()

103

104 print("HandleHelp:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}\n\n UserID={3!s}".

˓→format(args.quiet, args.verbose, args.debug, args.UserID))

105

106 def HandleListUser(self, args):

107 self.PrintHeadline()

108

109 print("HandleHelp:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}\n\n all={3!s}".

˓→format(args.quiet, args.verbose, args.debug, args.all))

110 111

112 if __name__ == "__main__":

113 prog = Program()

(continues on next page)

6.3. ArgParse 17

(22)

pyAttributes, Release 2.2.1

(continued from previous page)

114 prog.Run()

6.3.2 New pyAttributes Approach

A better and more descriptive solution could look like this:

Listing 2: tests/example/UserManager.py

1 from argparse import ArgumentDefaultsHelpFormatter

2

3 from pyAttributes.ArgParseAttributes import ArgParseMixin, CommonSwitchArgumentAttribute,

˓→ DefaultAttribute, CommandAttribute, CommonArgumentAttribute, ArgumentAttribute,␣

˓→SwitchArgumentAttribute

4 5

6 class ProgramBase():

7 HeadLine = "Simple ArgParse Test Program"

8

9 def __init__(self):

10 pass

11

12 def PrintHeadline(self):

13 print("{line}".format(line="="*80))

14 print("{headline: ^80s}".format(headline=self.HeadLine))

15 print("{line}".format(line="="*80))

16 17

18 class Program(ProgramBase, ArgParseMixin):

19 def __init__(self):

20 import textwrap

21

22 # call constructor of the main inheritance tree

23 super().__init__()

24

25 # Call the constructor of the ArgParseMixin

26 ArgParseMixin.__init__(

27 self,

28 description=textwrap.dedent('''\

29 This is the test program.

30 '''),

31 epilog=textwrap.fill("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed␣

˓→diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam."),

32 formatter_class=ArgumentDefaultsHelpFormatter,

33 add_help=False

34 )

35

36 @CommonSwitchArgumentAttribute("-q", "--quiet", dest="quiet", help="Reduce␣

˓→messages to a minimum.")

37 @CommonSwitchArgumentAttribute("-v", "--verbose", dest="verbose", help="Print out␣

˓→detailed messages.")

38 @CommonSwitchArgumentAttribute("-d", "--debug", dest="debug", help="Enable debug␣

˓→mode.") (continues on next page)

18 Chapter 6. License

(23)

(continued from previous page)

39 def Run(self):

40 ArgParseMixin.Run(self)

41 42

43 @DefaultAttribute()

44 def HandleDefault(self, args):

45 self.PrintHeadline()

46

47 print("HandleDefault:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}".format(args.

˓→quiet, args.verbose, args.debug))

48 49

50 @CommandAttribute("help", help="Display help page(s) for the given command name.")

51 @ArgumentAttribute(metavar="Command", dest="Command", type=str, nargs="?", help="Print␣

˓→help page(s) for a command.")

52 def HandleHelp(self, args):

53 self.PrintHeadline()

54

55 print("HandleHelp:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}\n\n command={3!s}\

˓→n\n".format(args.quiet, args.verbose, args.debug, args.Command))

56

57 if (args.Command is None):

58 self.MainParser.print_help()

59 elif (args.Command == "help"):

60 print("This is a recursion ...")

61 else:

62 try:

63 self.SubParsers[args.Command].print_help()

64 except KeyError:

65 print("Command {0} is unknown.".format(args.Command))

66 67

68 @CommandAttribute("new-user", help="Create a new user.")

69 @ArgumentAttribute(metavar='<UserID>', dest="UserID", type=str, help="UserID - unique␣

˓→identifier")

70 @ArgumentAttribute(metavar='<Name>', dest="Name", type=str, help="The user's display␣

˓→name.")

71 def HandleNewUser(self, args):

72 self.PrintHeadline()

73

74 print("HandleNewUser:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}\n\n UserID={3!

˓→s} Name={4!s} Limit={5!s}".format(args.quiet, args.verbose, args.debug, args.UserID,␣

˓→args.Name, args.Limit))

75 76

77 @CommandAttribute("delete-user", help="Delete a user.")

78 @ArgumentAttribute(metavar='<UserID>', dest="UserID", type=str, help="UserID - unique␣

˓→identifier")

79 def HandleDeleteUser(self, args):

80 self.PrintHeadline()

81

82 print("HandleDeleteUser:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}\n\n UserID=

˓→{3!s}".format(args.quiet, args.verbose, args.debug, args.UserID)) (continues on next page)

6.3. ArgParse 19

(24)

pyAttributes, Release 2.2.1

(continued from previous page)

83 84

85 @CommandAttribute("list-user", help="List users.")

86 @SwitchArgumentAttribute('--all', dest="all", help='List all users.')

87 def HandleListUser(self, args):

88 self.PrintHeadline()

89

90 print("HandleListUser:\n quiet={0!s}\n verbose={1!s}\n debug={2!s}\n\n all={3!s}

˓→".format(args.quiet, args.verbose, args.debug, args.all))

91 92

93 if __name__ == "__main__":

94 prog = Program()

95 prog.Run()

6.4 pyAttributes Module

6.4.1 pyAttributes

This Python module offers the base implementation of .NET-like attributes realized with Python decorators. This module comes also with a mixin-class to ease using classes having annotated methods.

The decorators in pyAttributes are implemented as class-based decorators.

The annotated data is stored in an additional __dict__ entry for each annotated method. By default the entry is called __pyattr__.

pyAttributes.Func

A type variable for functions. Here it’s used for methods.

alias of TypeVar(‘Func’) pyAttributes.TAttr

A type variable forAttribute.

alias of TypeVar(‘TAttr’, bound=Attribute) pyAttributes.TAttributeFilter

A type hint for a filter parameter that accepts either a singleAttributeor an iterable of those.

alias ofOptional[Union[pyAttributes.TAttr,Iterable[pyAttributes.TAttr]]]

6.4.2 Attribute

class pyAttributes.Attribute Bases:object

Base-class for all pyAttributes.

__call__(func)

Make all classes derived from Attribute callable, so they can be used as a decorator.

Return type ~Func

20 Chapter 6. License

(25)

classmethod GetAttributes(method, includeSubClasses=True) Returns attached attributes for a given method.

Return type List[Attribute]

6.4.3 AttributeHelperMixin

class pyAttributes.AttributeHelperMixin Bases:object

A mixin class to ease finding methods with attached pyAttributes.

static HasAttribute(method, filter=<class 'pyAttributes.Attribute'>) Returns true, if the given method has pyAttributes attached.

Return type bool

static GetAttributes(method, filter=<class 'pyAttributes.Attribute'>) Returns a list of pyAttributes attached to the given method.

Return type List[~TAttr]

6.5 ArgParseAttributes Module

This module implements attribute-classes and a mixin-class which describe options to construct aargparse-based command line processor. All attributes in this module are sub-classes of Attribute.

6.5.1 Base-Classes

ArgParseAttribute

class pyAttributes.ArgParseAttributes.ArgParseAttribute Bases:pyAttributes.Attribute

Base-class for all attributes to describe aargparse-base command line argument parser.

Inheritance diagram:

ArgParseAttribute

ArgumentAttribute CommandAttribute CommandGroupAttribute

DefaultAttribute

CommonArgumentAttribute

SwitchArgumentAttribute CommonSwitchArgumentAttribute

6.5. ArgParseAttributes Module 21

(26)

pyAttributes, Release 2.2.1

6.5.2 MixIns

_HandlerMixin

class pyAttributes.ArgParseAttributes._HandlerMixin Bases:object

A mixin-class that offers a class field for a reference to a handler method and a matching property.

_handler: Callable = None

Reference to a method that is called to handle e.g. a sub-command.

property Handler: Callable Returns the handler method.

Return type Callable

_KwArgsMixin

class pyAttributes.ArgParseAttributes._KwArgsMixin Bases:object

A mixin-class that offers a class field for named parameters (`**kwargs) and a matching property.

_kwargs: Dict = None

A dictionary of additional keyword parameters.

property KWArgs: Dict

A dictionary of additional named parameters (**kwargs) passed to the attribute. These additional param- eters are passed without modification to ArgumentParser.

Return type Dict

_ArgsMixin

class pyAttributes.ArgParseAttributes._ArgsMixin Bases:pyAttributes.ArgParseAttributes._KwArgsMixin

A mixin-class that offers a class field for positional parameters (`*args) and a matching property.

_args: Tuple = None

A tuple of additional positional parameters.

property Args: Tuple

A tuple of additional positional parameters (*args) passed to the attribute. These additional parameters are passed without modification to ArgumentParser.

Return type Tuple

22 Chapter 6. License

(27)

6.5.3 Helper-Classes

ArgParseMixin

class pyAttributes.ArgParseAttributes.ArgParseMixin(**kwargs) Bases:pyAttributes.AttributeHelperMixin

Mixin-class to implement anargparse-base command line argument processor.

__init__(**kwargs)

The mixin-constructor expects an optional list of named parameters which are passed without modification to the ArgumentParser constructor.

property MainParser: argparse.ArgumentParser Returns the main parser.

Return type ArgumentParser property SubParsers

Returns the sub-parsers.

6.5.4 Attributes

CommandGroupAttribute

class pyAttributes.ArgParseAttributes.CommandGroupAttribute(groupName) Bases:pyAttributes.ArgParseAttributes.ArgParseAttribute

Experimental attribute to group sub-commands in groups for better readability in a prog.py --help call.

__init__(groupName)

The constructor expects a ‘groupName’ which can be used to group sub-commands for better readability.

property GroupName: str

Returns the name of the command group.

Return type str

DefaultAttribute

class pyAttributes.ArgParseAttributes.DefaultAttribute

Bases: pyAttributes.ArgParseAttributes.ArgParseAttribute, pyAttributes.

ArgParseAttributes._HandlerMixin

Marks a handler method is default handler. This method is called if no sub-command is given. It’s an error if more then one method is annotated with this attribute.

6.5. ArgParseAttributes Module 23

(28)

pyAttributes, Release 2.2.1

CommandAttribute

class pyAttributes.ArgParseAttributes.CommandAttribute(command, **kwargs)

Bases: pyAttributes.ArgParseAttributes.ArgParseAttribute, pyAttributes.

ArgParseAttributes._HandlerMixin,pyAttributes.ArgParseAttributes._KwArgsMixin

Marks a handler method as responsible for the given ‘command’. This constructs a sub-command parser using add_subparsers().

__init__(command, **kwargs)

The constructor expects a ‘command’ and an optional list of named parameters (keyword arguments) which are passed without modification to add_subparsers().

property Command: str

Returns the ‘command’ a sub-command parser adheres to.

Return type str

ArgumentAttribute

class pyAttributes.ArgParseAttributes.ArgumentAttribute(*args, **kwargs)

Bases: pyAttributes.ArgParseAttributes.ArgParseAttribute, pyAttributes.

ArgParseAttributes._ArgsMixin Base-class for all attributes storing arguments.

__init__(*args, **kwargs)

The constructor expects positional (*args) and/or named parameters (**kwargs) which are passed without modification to add_argument().

SwitchArgumentAttribute

class pyAttributes.ArgParseAttributes.SwitchArgumentAttribute(*args, dest, **kwargs) Bases:pyAttributes.ArgParseAttributes.ArgumentAttribute

Defines a switch argument like --help.

Some of the named parameters passed to add_argument() are predefined (or overwritten) to create a boolean parameter passed to the registered handler method. The boolean parameter is True if the switch argument is present in the commandline arguments, otherwise False.

__init__(*args, dest, **kwargs)

The constructor expects positional (*args), the destination parameter name dest and/or named parameters (**kwargs) which are passed to add_argument().

To implement a switch argument, the following named parameters are predefined:

• action="store_const"

• const=True

• default=False

This implements a boolean parameter passed to the handler method.

24 Chapter 6. License

(29)

CommonArgumentAttribute

class pyAttributes.ArgParseAttributes.CommonArgumentAttribute(*args, **kwargs) Bases:pyAttributes.ArgParseAttributes.ArgumentAttribute

CommonSwitchArgumentAttribute

class pyAttributes.ArgParseAttributes.CommonSwitchArgumentAttribute(*args, dest, **kwargs) Bases:pyAttributes.ArgParseAttributes.SwitchArgumentAttribute

See also:

Base attribute classAttribute Base-class for all attributes.

Helper mixin classAttributeHelperMixin Base-class for all helper mixins.

Note: This is a local copy of theApache License Version 2.0.

6.6 Apache License 2.0

Version 2.0, January 2004

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

6.6.1 1. Definitions.

“License”shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

“Licensor”shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

“Legal Entity”shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

“You”(or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License.

“Source”form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

“Object”form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

“Work”shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

“Derivative Works”shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

“Contribution”shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the

6.6. Apache License 2.0 25

(30)

pyAttributes, Release 2.2.1

Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner.

For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.”

“Contributor”shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

6.6.2 2. Grant of Copyright License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non- exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

6.6.3 3. Grant of Patent License.

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

6.6.4 4. Redistribution.

You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

• You must give any other recipients of the Work or Derivative Works a copy of this License; and

• You must cause any modified files to carry prominent notices stating that You changed the files; and

• You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

• If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You dis- tribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places:

within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wher- ever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

26 Chapter 6. License

(31)

6.6.5 5. Submission of Contributions.

Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwith- standing the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

6.6.6 6. Trademarks.

This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

6.6.7 7. Disclaimer of Warranty.

Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permis- sions under this License.

6.6.8 8. Limitation of Liability.

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

6.6.9 9. Accepting Warranty or Additional Liability.

While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

Appendix: How to apply the Apache License to your work

To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets

“[]” replaced with your own identifying information. (Don’t include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives.

6.6. Apache License 2.0 27

(32)

pyAttributes, Release 2.2.1

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and limitations under the License.

6.7 Index

6.8 Python Module Index

28 Chapter 6. License

(33)

p

pyAttributes,20

pyAttributes.ArgParseAttributes,21

29

(34)

pyAttributes, Release 2.2.1

30 Python Module Index

(35)

Symbols

_ArgsMixin (class in pyAttributes.ArgParseAttributes), 22

_HandlerMixin (class in pyAt-

tributes.ArgParseAttributes),22

_KwArgsMixin (class in pyAt-

tributes.ArgParseAttributes),22 __call__()(pyAttributes.Attribute method),20

__init__()(pyAttributes.ArgParseAttributes.ArgParseMixin method),23

__init__()(pyAttributes.ArgParseAttributes.ArgumentAttribute method),24

__init__()(pyAttributes.ArgParseAttributes.CommandAttribute method),24

__init__()(pyAttributes.ArgParseAttributes.CommandGroupAttribute method),23

__init__()(pyAttributes.ArgParseAttributes.SwitchArgumentAttribute method),24

_args (pyAttributes.ArgParseAttributes._ArgsMixin at- tribute),22

_handler(pyAttributes.ArgParseAttributes._HandlerMixin attribute),22

_kwargs(pyAttributes.ArgParseAttributes._KwArgsMixin attribute),22

A

ArgParseAttribute (class in pyAt-

tributes.ArgParseAttributes),21

ArgParseMixin (class in pyAt-

tributes.ArgParseAttributes),23

Args(pyAttributes.ArgParseAttributes._ArgsMixin prop- erty),22

ArgumentAttribute (class in pyAt-

tributes.ArgParseAttributes),24 Attribute(class in pyAttributes),20

AttributeHelperMixin(class in pyAttributes),21

C

Command(pyAttributes.ArgParseAttributes.CommandAttribute property),24

CommandAttribute (class in pyAt-

tributes.ArgParseAttributes),24

CommandGroupAttribute (class in pyAt- tributes.ArgParseAttributes),23

CommonArgumentAttribute (class in pyAt- tributes.ArgParseAttributes),25

CommonSwitchArgumentAttribute (class in pyAt- tributes.ArgParseAttributes),25

D

DefaultAttribute (class in pyAt-

tributes.ArgParseAttributes),23

F

Func(in module pyAttributes),20

G

GetAttributes()(pyAttributes.Attribute class method), 20

GetAttributes() (pyAttributes.AttributeHelperMixin static method),21

GroupName(pyAttributes.ArgParseAttributes.CommandGroupAttribute property),23

H

Handler(pyAttributes.ArgParseAttributes._HandlerMixin property),22

HasAttribute() (pyAttributes.AttributeHelperMixin static method),21

K

KWArgs (pyAttributes.ArgParseAttributes._KwArgsMixin property),22

M

MainParser(pyAttributes.ArgParseAttributes.ArgParseMixin property),23

module

pyAttributes,20

pyAttributes.ArgParseAttributes,21

P

pyAttributes

31

(36)

pyAttributes, Release 2.2.1

module,20

pyAttributes.ArgParseAttributes module,21

S

SubParsers(pyAttributes.ArgParseAttributes.ArgParseMixin property),23

SwitchArgumentAttribute (class in pyAt- tributes.ArgParseAttributes),24

T

TAttr(in module pyAttributes),20

TAttributeFilter(in module pyAttributes),20

32 Index

References

Related documents

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright

Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable

Subject to the terms and conditions of the LGPL and this Agreement, CKSource hereby grants You a non-exclusive, perpetual, irrevocable, royalty free, worldwide license (“License”)

Based on a review of various bond covenants 1 , and to comply with the requirements of AB 26, as amended by AB 1484, to make payment for all “indebtedness obligations” to

Everest permits students to request a leave of absence (LOA) as long as the leave does not exceed a total of 180 days during any 12-month period, starting from the first day of

After a moment, Spock said slowly, “I cannot see that there is a Vulcan science and a human science—or any other kind.. There is

If a student with an IEP engages in conduct which endangers or may endanger the health, safety, or property of the student, other students, staff members, or school property,