pyAttributes
Release 2.2.1
Patrick Lehmann
Jul 22, 2021
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
ii
_ _ _ _ _ _
_ __ _ _ / \ | |_| |_ _ __(_) |__ _ _| |_ ___ ___
| '_ \| | | | / _ \| __| __| '__| | '_ \| | | | __/ _ \/ __|
| |_) | |_| |/ ___ \ |_| |_| | | | |_) | |_| | || __/\__ \
| .__/ \__, /_/ \_\__|\__|_| |_|_.__/ \__,_|\__\___||___/
|_| |___/
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
pyAttributes, Release 2.2.1
2 OVERVIEW
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
pyAttributes, Release 2.2.1
4 Chapter 1. Use Cases
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
pyAttributes, Release 2.2.1
6 Chapter 2. Technique
THREE
COMMON ATTRIBUTES
• Attribute class
• AttributeHelperMixin class
7
pyAttributes, Release 2.2.1
8 Chapter 3. Common Attributes
FOUR
SPECIAL ATTRIBUTES
This package brings special attribute implementations for:
• Python’s ArgParse including sub-parser support.
9
pyAttributes, Release 2.2.1
10 Chapter 4. Special Attributes
FIVE
CONTRIBUTORS
• Patrick Lehmann(Maintainer)
• and more...
11
pyAttributes, Release 2.2.1
12 Chapter 5. Contributors
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
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
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
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
(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
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
(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
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
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
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
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
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
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
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
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
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
p
pyAttributes,20
pyAttributes.ArgParseAttributes,21
29
pyAttributes, Release 2.2.1
30 Python Module Index
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
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