When we talk about art, we usually ponder if such artistic pieces will ever be in a gallery. Thanks to the Internet and the introduction of online art galleries, any art piece will have a chance to make it. Knowing that, I have decided that my project will be a small online art gallery called WonderPaint. An online art gallery that is inspired by existing online galleries like DeviantArt, ArtStation. WonderPaint will be a gallery made for all artists to join and share their pieces, no matter the types of art or the topics they will be about.
As one of the people who love and appreciate art, I find it very saddening when creators of all kinds from well-known galleries’, especially ones that have been around for a long time like DeviantArt, face common problems and struggles among artists: tracing, art theft, commission problems, and even harassment, etc. And the foundation of ArtStation (2014) does not seem to be enough, moreover, I think that we absolutely need more artist-friendly environments for artists to move to and for them to feel more comfortable to share their work. So I have decided to start out with a small and basic online art gallery. Even though it won’t be much, but it will be a great starting point for a future modern gallery.
The core features of WonderPaint will be a website similar to DeviantArt where artists and art enthusiasts will be able to publish their pieces of art, including traditional and digital drawings, paintings, sculptures, photography, filmmaking, etc., or even literature. In order to do that, a user can create a personal account simply by choosing themselves a username and a password of choice and by providing some other basic personal information like an email address, their date of birth, and their gender, and an additional feature is that they can also choose a profile picture to express themselves. After that, with an account created, they will finally have access to publish their works. They can do that on a page where they can upload and submit their works after giving them a description of what they are about.
With the publication of art pieces, artists will thrive, but they can only be able to grow the most if they receive constructive criticism. For such things to happen, a “comment section” will be added, where artists will be able to discuss their works with each other by providing feedback and criticism on one’s works.
There will also be one page dedicated to all the Guidelines of the gallery, where it will probably include mostly texts about all the rules. Rules about what are deemed to be safe to publish and comment, and what are not allowed, and even ban-worthy will be included. This page will appear when a user is about to create a new account on WonderPaint to ensure that they understand their rights and responsibilities before joining in the gallery, and after they have carefully read the Guidelines, they can continue to create their own account.
To ensure that everyone will follow the Guidelines in order to create a safe environment for artists to thrive, we will probably have an option to report any activities that violate the Guidelines. This applies for all contents in the website, including pictures posted and comments. This will be the core feature to protect and to prevent any harmful activities to artists alike, and a chance for them to be able to defend themselves and others.
Since WonderPaint will be published as a website, I will need some kind of software that will help me work in Hypertext Markup Language (HTML), Cascading Style Sheets (CSS), and JavaScripts (JS), and the best software that I will possibly stick with will be Visual Studio Code. This software will allow me to establish a webpage by building an HTML structure and through editing how the website will look with CSS and JS coding. Not only Visual Studio Code, but some other open-source tools also will be used for the development of this webpage, including Git and possibly Bootstrap. Git (and the use of GitHub) will be very important in creating a repository and publishing the website for that repository, as well as pulling and pushing codes from the repository. Bootstrap will come in handy for references on templates and designs.
To establish a website, the most important skills that one needs to master is definitely programming skills. Many programming languages exist, but we need to know at least a few in order to code a website, especially HTML, CSS, and JS. Secondly, users would like to look at a beautiful and neatly organized website when they visit WonderPaint, so we need basic knowledge of designing as well. We don’t need to know too much about designing, but knowing some will be essential, and a small step to get creative as well.
If WonderPaint becomes successful or in my words, widely recognized, chances are I will start to develop the website more and more so lots of users can join and experience their fullest potential during their stay in the gallery. I don’t have very high hopes that my website will be successful, but if it does, it probably will create a big impact in the artist community. And I know that WonderPaint won’t be stopping there. It will continue to flourish into an art gallery where artists and art enthusiasts from all over the world can come together and enjoy art.


Class S2Shape
The purpose of S2Shape is to represent polygonal geometry in a flexible way. It is organized as a collection of edges that optionally defines an interior. All geometry represented by an S2Shape must have the same dimension, which means that an S2Shape can represent either a set of points, a set of polylines, or a set of polygons.
class S2Shape
;
S2Shape is defined as an abstract base class in order to give clients control over the underlying data representation. Sometimes an S2Shape does not have any data of its own, but instead "wraps" some other class. There are various useful subtypes defined in *shape.h, and some S2 classes also have a nested "Shape" class (e.g., S2Polygon::Shape). It is easy for clients to implement their own subtypes, since the interface is minimal.
S2Shape operations are typically defined on S2ShapeIndex objects rather than individual shapes. An S2ShapeIndex is simply a collection of S2Shapes, possibly of different dimensions (e.g. 10 points and 3 polygons), organized into a data structure for efficient edge access.
The edges of an S2Shape are identified by a contiguous range of "edge ids" starting at 0. The edges are further subdivided into "chains", where each chain consists of a sequence of edges connected end-to-end (a polyline). For example, an S2Shape representing two polylines AB and CDE would have three edges (AB, CD, DE) grouped into two chains: (AB) and (CD, DE). Similarly, an S2Shape representing 5 points would have 5 chains consisting of one edge each.
S2Shape has methods that allow edges to be accessed either using the global numbering (edge id) or within a particular chain. The global numbering is sufficient for most purposes, but the chain representation is useful for certain algorithms such as intersection (see S2BooleanOperation).
Methods
| Name | Description |
|---|---|
chain
(chain_id)
|
Returns the range of edge ids corresponding to the given edge chain. The edge chains must form contiguous, non-overlapping ranges that cover the entire range of edge ids. This is spelled out more formally below: |
chainEdge
(chain_id, offset)
|
Returns the edge at offset "offset" within edge chain "chain_id". Equivalent to "shape.edge(shape.chain(chain_id).start + offset)" but may be more efficient. |
chainPosition
(edge_id)
|
Finds the chain containing the given edge, and returns the position of that edge as a (chain_id, offset) pair. |
dimension
()
|
Returns the dimension of the geometry represented by this shape. |
edge
(edge_id)
|
Returns the endpoints of the given edge id. |
getReferencePoint
()
|
Returns an arbitrary point P along with a boolean indicating whether P is contained by the shape. (The boolean value must be false for shapes that do not have an interior.) |
hasInterior
()
|
Convenience function that returns true if this shape has an interior. |
id
()
|
A unique id assigned to this shape by S2ShapeIndex. Shape ids are assigned sequentially starting from 0 in the order shapes are added. |
numChains
()
|
Returns the number of contiguous edge chains in the shape. For example, a shape whose edges are [AB, BC, CD, AE, EF] would consist of two chains (AB,BC,CD and AE,EF). Every chain is assigned a "chain id" numbered sequentially starting from zero. |
numEdges
()
|
Returns the number of edges in this shape. Edges have ids ranging from 0 to num_edges() - 1. |
userData
()
|
Virtual methods that return pointers of your choice. |
Inner structs
| Name | Description |
|---|---|
Chain
|
A range of edge ids corresponding to a chain of zero or more connected edges, specified as a (start, length) pair. The chain is defined to consist of edge ids {start, start + 1, ..., start + length - 1}. |
ChainPosition
|
The position of an edge within a given edge chain, specified as a (chain_id, offset) pair. Chains are numbered sequentially starting from zero, and offsets are measured from the start of each chain. |
Edge
|
An edge, consisting of two vertices "v0" and "v1". Zero-length edges are allowed, and can be used to represent points. |
ReferencePoint
|
A ReferencePoint consists of a point P and a boolean indicating whether P is contained by a particular shape. |


--- title: "4.5 — Products Liability — Class Content" citeproc: false bibliography: ../../static/bib/references.bib csl: ../../static/bib/chicago-syllabus-no-bib.csl output: blogdown::html_page: template: ../../pandoc/toc-title_html.template toc: true editor_options: chunk_output_type: console ---
Thursday, May 6, 2021
TBD
The economic model of a risky product comes from Thomas Miceli’s textbook. Unfortunately, it is not in our textbook by Cooter & Ulen. So I have posted the relevant excerpt from the Miceli textbook.
Liebeck v. McDonald’s Restaurants (1994) [ Wikipedia]
BMW of North America, Inc. v. Gore (1996) [ Wikipedia] [ Opinion]
Mathias v. Accor Economy Lodging, Inc. (2003) [ Opinion]
Problem Set 3 is due by PDF upload to Blackboard Assignments by 11:59 PM EST Sunday May 9th.


equals()
calls that compare two java.math.BigDecimal
numbers.
This is normally a mistake, as two java.math.BigDecimal
numbers are only equal if
they are equal in both value and scale.
Example:
if (new BigDecimal("2.0").equals(
new BigDecimal("2.00"))) {} // false
After the quick-fix is applied:
if (new BigDecimal("2.0").compareTo(
new BigDecimal("2.00")) == 0) {} // true


Loading, please wait...
Not logged in. Please
login
or
register
.
Register new user
Username:
Password:
Repeat password:
Real name:
Country:
State:
Real name:
Register
{{message}}
User login
Username:
Password:
Log in
{{message}}
Edit profile
Sign out
Welcome, {{user.realname}}!
Edit profile
New password:
Repeat password:
Real name:
Country:
State:
City:
Current password:
Update
{{errorMessage}}
User settings successfully updated!


Internet Engineering Task Force (IETF) G. Zorn Request for Comments: 5904 Network Zen Category: Informational June 2010 ISSN: 2070-1721 RADIUS Attributes for IEEE 802.16 Privacy Key Management Version 1 (PKMv1) Protocol Support Abstract This document defines a set of Remote Authentication Dial-In User Service (RADIUS) Attributes that are designed to provide RADIUS support for IEEE 802.16 Privacy Key Management Version 1. Status of This Memo This document is not an Internet Standards Track specification; it is published for informational purposes. This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Not all documents approved by the IESG are a candidate for any level of Internet Standard; see Section 2 of RFC 5741. Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc5904. Copyright Notice Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License. Zorn Informational [Page 1] RFC 5904 RADIUS Attributes for PKMv1 June 2010 This document may contain material from IETF Documents or IETF Contributions published or made publicly available before November 10, 2008. The person(s) controlling the copyright in some of this material may not have granted the IETF Trust the right to allow modifications of such material outside the IETF Standards Process. Without obtaining an adequate license from the person(s) controlling the copyright in such materials, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process, except to format it for publication as an RFC or to translate it into languages other than English. Table of Contents 1.                     Introduction
Privacy Key Management Version 1 (PKMv1) [IEEE.802.16-2004] is a public-key-based authentication and key establishment protocol typically used in fixed wireless broadband network deployments. The protocol utilizes X.509 v3 certificates [RFC2459], RSA encryption [RFC2437], and a variety of secret key cryptographic methods to allow an 802.16 Base Station (BS) to authenticate a Subscriber Station (SS) and perform key establishment and maintenance between an SS and BS. This document defines a set of RADIUS Attributes that are designed to provide support for PKMv1. The target audience for this document consists of those developers implementing RADIUS support for PKMv1; therefore, familiarity with both RADIUS [RFC2865] and the IEEE 802.16-2004 standard is assumed. Please note that this document relies on IEEE.802.16-2004, which references RFC 2437 and RFC 2459, rather than any more recent RFCs on RSA and X.509 certificates (e.g., RFC 3447 and RFC 5280).2. Acronyms
CA Certification Authority; a trusted party issuing and signing X.509 certificates. For further information on the following terms, please see Section 7 of [IEEE.802.16-2004]. SA Security Association SAID Security Association Identifier TEK Traffic Encryption Key3. Attributes
The following subsections describe the Attributes defined by this document. This specification concerns the following values: 137 PKM-SS-Cert 138 PKM-CA-Cert 139 PKM-Config-Settings Zorn Informational [Page 3] RFC 5904 RADIUS Attributes for PKMv1 June 2010 140 PKM-Cryptosuite-List 141 PKM-SAID 142 PKM-SA-Descriptor 143 PKM-Auth-Key3.1. PKM-SS-Cert
Description The PKM-SS-Cert Attribute is variable length and MAY be transmitted in the Access-Request message. The Value field is of type string and contains the X.509 certificate [RFC2459] binding a public key to the identifier of the Subscriber Station. The minimum size of an SS certificate exceeds the maximum size of a RADIUS attribute. Therefore, the client MUST encapsulate the certificate in the Value fields of two or more instances of the PKM-SS-Cert Attribute, each (except possibly the last) having a length of 255 octets. These multiple PKM-SS-Cert Attributes MUST appear consecutively and in order within the packet. Upon receipt, the RADIUS server MUST recover the original certificate by concatenating the Value fields of the received PKM-SS-Cert Attributes in order. A summary of the PKM-SS-Cert Attribute format is shown below. The fields are transmitted from left to right. 1 2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Len | Value... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Type 137 for PKM-SS-Cert Len > 2 Value The Value field is variable length and contains a (possibly complete) portion of an X.509 certificate. Zorn Informational [Page 4] RFC 5904 RADIUS Attributes for PKMv1 June 20103.2. PKM-CA-Cert
Description The PKM-CA-Cert Attribute is variable length and MAY be transmitted in the Access-Request message. The Value field is of type string and contains the X.509 certificate [RFC2459] used by the CA to sign the SS certificate carried in the PKM-SS-Cert attribute (Section 3.1) in the same message. The minimum size of a CA certificate exceeds the maximum size of a RADIUS attribute. Therefore, the client MUST encapsulate the certificate in the Value fields of two or more instances of the PKM-CA-Cert Attribute, each (except possibly the last) having a length of 255 octets. These multiple PKM-CA-Cert Attributes MUST appear consecutively and in order within the packet. Upon receipt, the RADIUS server MUST recover the original certificate by concatenating the Value fields of the received PKM-CA-Cert Attributes in order. A summary of the PKM-CA-Cert Attribute format is shown below. The fields are transmitted from left to right. 1 2 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Len | Value... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Type 138 for PKM-CA-Cert Len > 2 Value The Value field is variable length and contains a (possibly complete) portion of an X.509 certificate. Zorn Informational [Page 5] RFC 5904 RADIUS Attributes for PKMv1 June 20103.3. PKM-Config-Settings
Description The PKM-Config-Settings Attribute is of type string [RFC2865]. It is 30 octets in length and consists of seven independent fields, each of which is conceptually an unsigned integer. Each of the fields contains a timeout value and corresponds to a Type-Length- Value (TLV) tuple encapsulated in the IEEE 802.16 "PKM configuration settings" attribute; for details on the contents of each field, see Section 11.9.19 of [IEEE.802.16-2004]. One instance of the PKM-Config-Settings Attribute MAY be included in the Access-Accept message. A summary of the PKM-Config-Settings Attribute format is shown below. The fields are transmitted from left to right. 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Len | Auth Wait Timeout +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Auth Wait Timeout (cont.) | Reauth Wait Timeout +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Reauth Wait Timeout (cont.) | Auth Grace Time +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Auth Grace Time (cont.) | Op Wait Timeout +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Op Wait Timeout (cont.) | Rekey Wait Timeout +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Rekey Wait Timeout (cont.) | TEK Grace Time +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ TEK Grace Time (cont.) | Auth Rej Wait Timeout +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Auth Rej Wait Timeout (cont.) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Type 139 for PKM-Config-Settings Len 30 Zorn Informational [Page 6] RFC 5904 RADIUS Attributes for PKMv1 June 2010 Auth Wait Timeout The Auth Wait Timeout field is 4 octets in length and corresponds to the "Authorize wait timeout" field of the 802.16 "PKM configuration settings" attribute. Reauth Wait Timeout The Reauth Wait Timeout field is 4 octets in length and corresponds to the "Reauthorize wait timeout" field of the 802.16 "PKM configuration settings" attribute. Auth Grace Time The Auth Grace Time field is 4 octets in length and corresponds to the "Authorize grace time" field of the 802.16 "PKM configuration settings" attribute. Op Wait Timeout The Op Wait Timeout field is 4 octets in length and corresponds to the "Operational wait timeout" field of the 802.16 "PKM configuration settings" attribute. Rekey Wait Timeout The Rekey Wait Timeout field is 4 octets in length and corresponds to the "Rekey wait timeout" field of the 802.16 "PKM configuration settings" attribute. TEK Grace Time The TEK Grace Time field is 4 octets in length and corresponds to the "TEK grace time" field of the 802.16 "PKM configuration settings" attribute. Auth Rej Wait Timeout The Auth Rej Wait Timeout field is 4 octets in length and corresponds to the "Authorize reject wait timeout" field of the 802.16 "PKM configuration settings" attribute. Zorn Informational [Page 7] RFC 5904 RADIUS Attributes for PKMv1 June 20103.4. PKM-Cryptosuite-List
Description The PKM-Cryptosuite-List Attribute is of type string [RFC2865] and is variable length; it corresponds roughly to the "Cryptographic- Suite-List" 802.16 attribute (see Section 11.19.15 of [IEEE.802.16-2004]), the difference being that the RADIUS Attribute contains only the list of 3-octet cryptographic suite identifiers, omitting the IEEE Type and Length fields. The PKM-Cryptosuite-List Attribute MAY be present in an Access- Request message. Any message in which the PKM-Cryptosuite-List Attribute is present MUST also contain an instance of the Message- Authenticator Attribute [RFC3579]. Implementation Note The PKM-Cryptosuite-List Attribute is used as a building block to create the 802.16 "Security-Capabilities" attribute ([IEEE.802.16-2004], Section 11.9.13); since this document only pertains to PKM version 1, the "Version" sub-attribute in that structure MUST be set to 0x01 when the RADIUS client constructs it. A summary of the PKM-Cryptosuite-List Attribute format is shown below. The fields are transmitted from left to right. 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Len | Value... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Type 140 for PKM-Cryptosuite-List Len 2 + 3n < 39, where 'n' is the number of cryptosuite identifiers in the list. Zorn Informational [Page 8] RFC 5904 RADIUS Attributes for PKMv1 June 2010 Value The Value field is variable length and contains a sequence of one or more cryptosuite identifiers, each of which is 3 octets in length and corresponds to the Value field of an IEEE 802.16 Cryptographic-Suite attribute.3.5. PKM-SAID
Description The PKM-SAID Attribute is of type string [RFC2865]. It is 4 octets in length and contains a PKM Security Association Identifier ([IEEE.802.16-2004], Section 11.9.7). It MAY be included in an Access-Request message. A summary of the PKM-SAID Attribute format is shown below. The fields are transmitted from left to right. 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Len | SAID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Type 141 for PKM-SAID Len 4 SAID The SAID field is two octets in length and corresponds to the Value field of the 802.16 PKM SAID attribute3.6. PKM-SA-Descriptor
Description The PKM-SA-Descriptor Attribute is of type string and is 8 octets in length. It contains three fields, described below, which together specify the characteristics of a PKM security association. One or more instances of the PKM-SA-Descriptor Attribute MAY occur in an Access-Accept message. Zorn Informational [Page 9] RFC 5904 RADIUS Attributes for PKMv1 June 2010 A summary of the PKM-SA-Descriptor Attribute format is shown below. The fields are transmitted from left to right. 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Len | SAID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | SA Type | Cryptosuite | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Type 142 for PKM-SA-Descriptor Len 8 SAID The SAID field is two octets in length and contains a PKM SAID (Section 3.5). SA Type The SA Type field is one octet in length. The contents correspond to those of the Value field of an IEEE 802.16 SA-Type attribute. Cryptosuite The Cryptosuite field is 3 octets in length. The contents correspond to those of the Value field of an IEEE 802.16 Cryptographic-Suite attribute.3.7. PKM-AUTH-Key
Description The PKM-AUTH-Key Attribute is of type string, 135 octets in length. It consists of 3 fields, described below, which together specify the characteristics of a PKM authorization key. The PKM- AUTH-Key Attribute MAY occur in an Access-Accept message. Any packet that contains an instance of the PKM-AUTH-Key Attribute MUST also contain an instance of the Message-Authenticator Attribute [RFC3579]. Zorn Informational [Page 10] RFC 5904 RADIUS Attributes for PKMv1 June 2010 A summary of the PKM-AUTH-Key Attribute format is shown below. The fields are transmitted from left to right. 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type | Len | Lifetime +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Lifetime (cont.) | Sequence | Key... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Type 143 for PKM-AUTH-Key Len 135 Lifetime The Lifetime field is 4 octets in length and represents the lifetime, in seconds, of the authorization key. For more information, see Section 11.9.4 of [IEEE.802.16-2004]. Sequence The Sequence field is one octet in length. The contents correspond to those of the Value field of an IEEE 802.16 Key- Sequence-Number attribute (see [IEEE.802.16-2004], Section 11.9.5). Key The Key field is 128 octets in length. The contents correspond to those of the Value field of an IEEE 802.16 AUTH-Key attribute. The Key field MUST be encrypted under the public key from the Subscriber Station certificate (Section 3.1) using RSA encryption [RFC2437]; see Section 7.5 of [IEEE.802.16-2004] for further details. Implementation Note It is necessary that a plaintext copy of this field be returned in the Access-Accept message; appropriate precautions MUST be taken to ensure the confidentiality of the key. Zorn Informational [Page 11] RFC 5904 RADIUS Attributes for PKMv1 June 20103.7.1. AUTH-Key Protection
The AUTH-Key">PKM-AUTH-Key Attribute (Section 3.7) contains the AUTH-Key encrypted with the SS's public key. The BS also needs the AK, so a second copy of the AK needs to be returned in the Access-Accept message. It is RECOMMENDED that the AK is encapsulated in an instance of the MS-MPPE-Send-Key Attribute [RFC2548]. However, see Section 4.3.4 of RFC 3579 [RFC3579] for details regarding weaknesses in the encryption scheme used. If better means for protecting the Auth-Key are available (such as RADIUS key attributes with better security properties, or means of protecting the whole Access-Accept message), they SHOULD be used instead of (or in addition to) the MS-MPPE-Send-Key Attribute.4. Table of Attributes
The following table provides a guide to which attributes may be found in which kinds of packets, and in what quantity. Request Accept Reject Challenge Acct-Req # Attribute 0+ 0 0 0 0 137 PKM-SS-Cert [Note 1] 0+ 0 0 0 0 138 PKM-CA-Cert [Note 2] 0 0-1 0 0 0 139 PKM-Config-Settings 0-1 0 0 0 0 140 PKM-Cryptosuite-List 0-1 0 0 0 0 141 PKM-SAID 0 0+ 0 0 0 142 PKM-SA-Descriptor 0 0-1 0 0 0 143 PKM-Auth-Key 0 0-1 0 0 0 MS-MPPE-Send-Key [Note 3] [Note 1] No more than one Subscriber Station Certificate may be transferred in an Access-Request packet. [Note 2] No more than one CA Certificate may be transferred in an Access- Request packet. [Note 3] MS-MPPE-Send-Key is one possible attribute that can be used to convey the AK to the BS; other attributes can be used instead (see Section 3.7.1). Zorn Informational [Page 12] RFC 5904 RADIUS Attributes for PKMv1 June 2010 The following table defines the meaning of the above table entries. 0 This attribute MUST NOT be present in packet 0+ Zero or more instances of this attribute MAY be present in packet 0-1 Zero or one instance of this attribute MAY be present in packet 1 Exactly one instance of this attribute MUST be present in packet5. Diameter Considerations
Since the Attributes defined in this document are allocated from the standard RADIUS type space (see Section 7), no special handling is required by Diameter nodes.6. Security Considerations
Section 4 of RFC 3579 [RFC3579] discusses vulnerabilities of the RADIUS protocol. Section 3 of the paper "Security Enhancements for Privacy and Key Management Protocol in IEEE 802.16e-2005" [SecEn] discusses the operation and vulnerabilities of the PKMv1 protocol. If the Access-Request message is not subject to strong integrity protection, an attacker may be able to modify the contents of the PKM-Cryptosuite-List Attribute, weakening 802.16 security or disabling data encryption altogether. If the Access-Accept message is not subject to strong integrity protection, an attacker may be able to modify the contents of the PKM-Auth-Key Attribute. For example, the Key field could be replaced with a key known to the attacker. See Section 3.7.1 for security considerations of sending the authorization key to the BS.7. IANA Considerations
IANA has assigned numbers for the following Attributes: 137 PKM-SS-Cert 138 PKM-CA-Cert 139 PKM-Config-Settings 140 PKM-Cryptosuite-List 141 PKM-SAID Zorn Informational [Page 13] RFC 5904 RADIUS Attributes for PKMv1 June 2010 142 PKM-SA-Descriptor 143 PKM-Auth-Key The Attribute numbers are to be allocated from the standard RADIUS Attribute type space according to the "IETF Review" policy [RFC5226].8. Contributors
Pasi Eronen provided most of the text in Section <IP_ADDRESS>. Acknowledgements
Thanks (in no particular order) to Bernard Aboba, Donald Eastlake, Dan Romascanu, Avshalom Houri, Juergen Quittek, Pasi Eronen, and Alan DeKok for their mostly useful reviews of this document.10. References
10.1. Normative References
[IEEE.802.16-2004] Institute of Electrical and Electronics Engineers, "IEEE Standard for Local and metropolitan area networks, Part 16: Air Interface for Fixed Broadband Wireless Access Systems", IEEE Standard 802.16, October 2004. [RFC2865] Rigney, C., Willens, S., Rubens, A., and W. Simpson, "Remote Authentication Dial In User Service (RADIUS)", RFC 2865, June 2000. [RFC3579] Aboba, B. and P. Calhoun, "RADIUS (Remote Authentication Dial In User Service) Support For Extensible Authentication Protocol (EAP)", RFC 3579, September 2003. [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, May 2008.10.2. Informative References
[RFC2437] Kaliski, B. and J. Staddon, "PKCS #1: RSA Cryptography Specifications Version 2.0", RFC 2437, October 1998. [RFC2459] Housley, R., Ford, W., Polk, T., and D. Solo, "Internet X.509 Public Key Infrastructure Certificate and CRL Profile", RFC 2459, January 1999. Zorn Informational [Page 14] RFC 5904 RADIUS Attributes for PKMv1 June 2010 [RFC2548] Zorn, G., "Microsoft Vendor-specific RADIUS Attributes", RFC 2548, March 1999. [SecEn] Altaf, A., Jawad, M., and A. Ahmed, "Security Enhancements for Privacy and Key Management Protocol in IEEE 802.16e- 2005", Ninth ACIS International Conference on Software Engineering, Artificial Intelligence, Networking, and Parallel/Distributed Computing, 2008. Author's Address Glen Zorn Network Zen 1463 East Republican Street #358 Seattle, WA 98112 US EMail<EMAIL_ADDRESS>Zorn Informational [Page 15]


{%- block items -%}
{%- for entry in data.widget._pieces -%}
{# Works whether there's a relationship in the join or not. Normally there always #}
{# is for slideshows, but just in case someone really hates cropping... -Tom #}
{%- set image = entry.item or entry -%}
{%- set relationship = entry.relationship -%}
{%- block title -%}
{%- endblock -%}
{%- block credit -%}
{%- if image.credit -%}
{%- if image.creditUrl -%}
{%- endif -%}
{{ image.credit }}
{%- if image.creditUrl -%}
{%- endif -%}
{%- endif -%}
{%- endblock -%}
{%- block description -%}
{%- if image.description -%}
{{ image.description | nlbr }}
{%- endif -%}
{%- endblock -%}
{%- endfor -%}
{%- endblock -%}


According to our model
\(T_E \)
would increase from 248.6 K to 252.6 K or from
\(11.6^o C \)
to
\(15.6 ^o C \)
so would increase
\(4^oC\text{.}\)
\(T_a \)
would increase from


Huschle Guitars are built by hand from the finest materials on the market.
Each one of our instruments is equipped with the highest quality pickups on the market. Whether you're playing a strat or sitting heavy on some humbuckers, your tone will elevate instantly.
We get all of our wood from private lumber establishements that only manufacture at the highest quality. From bright maple to gorgeous rosewood, you'll be sure to find the right fit for you.
We are able to paint our guitars any color and still maintain a premium finish quality. Our paint comes in shine, matte, or metallic finish, and we offer test sample so that you can make the right choice.
See what our customers have to say about our products


|
Boost Sort Parallel
Sorting Algorithms for the Boost Library
|
Namespaces | |
| detail | |
Functions | |
| template<class Iter_t , typename Compare = compare_iter< Iter_t >> | |
| void | sort (Iter_t first, Iter_t last, Compare comp=Compare()) |
| non stable sort, based internally in the intro_sort algorithm More... | |
| template<class Iter_t , typename Compare = compare_iter< Iter_t >> | |
| void | indirect_sort (Iter_t first, Iter_t last, Compare comp=Compare()) |
| : indirect sort. This function sort a vector of iterators to the elements. And after, move the elements, for to be phisically sorted. This is useful with big objects More... | |
| template<class Iter_t > | |
| void | parallel_sort (Iter_t first, Iter_t last) |
| this function implement a non stable parallel sort. The number of threads to use is the HW threads of the machine More... | |
| template<class Iter_t > | |
| void | parallel_sort (Iter_t first, Iter_t last, uint32_t nthread) |
| this function implement a non stable parallel sort. More... | |
| template<class Iter_t , class Compare > | |
| void | parallel_sort (Iter_t first, Iter_t last, Compare comp, uint32_t nthread) |
| this function implement a non stable parallel sort. More... | |
| template<class Iter_t , class Compare , enable_if_not_integral< Compare > * = nullptr> | |
| void | parallel_sort (Iter_t first, Iter_t last, Compare comp) |
| : non stable parallel sort. More... | |
| template<class Iter_t , class Compare = compare_iter< Iter_t >> | |
| void | stable_sort (Iter_t first, Iter_t last, Compare comp=Compare()) |
| this function implement a single thread stable sort More... | |
| template<class Iter_t , class Compare = compare_iter< Iter_t >> | |
| void | indirect_stable_sort (Iter_t first, Iter_t last, Compare comp=Compare()) |
| : indirect stable sort. This function make a stable sort of a vector of iterators to the elements. And after, move the elements, for to be phisically sorted. This is useful with big objects More... | |
| template<class Iter_t > | |
| void | parallel_stable_sort (Iter_t first, Iter_t last) |
| : parallel stable sort algorithm. More... | |
| template<class Iter_t > | |
| void | parallel_stable_sort (Iter_t first, Iter_t last, uint32_t nthread) |
| parallel stable sort. More... | |
| template<class Iter_t , class Compare , enable_if_not_integral< Compare > * = nullptr> | |
| void | parallel_stable_sort (Iter_t first, Iter_t last, Compare comp) |
| : parallel stable sort. More... | |
| template<class Iter_t , typename Compare > | |
| void | parallel_stable_sort (Iter_t first, Iter_t last, Compare comp, uint32_t nthread) |
| parallel stable sort More... | |
| template<class Iter_t > | |
| void | sample_sort (Iter_t first, Iter_t last) |
| parallel sample sort algorithm (stable sort) More... | |
| template<class Iter_t > | |
| void | sample_sort (Iter_t first, Iter_t last, uint32_t nthread) |
| parallel sample sort algorithm (stable sort) More... | |
| template<class Iter_t , class Compare , enable_if_not_integral< Compare > * = nullptr> | |
| void | sample_sort (Iter_t first, Iter_t last, Compare comp) |
| parallel sample sort algorithm (stable sort) More... | |
| template<class Iter_t , class Compare > | |
| void | sample_sort (Iter_t first, Iter_t last, Compare comp, uint32_t nthread) |
| parallel sample sort algorithm (stable sort) More... | |
| void boost::sort::parallel::indirect_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp = Compare ( ) |
||
| ) |
: indirect sort. This function sort a vector of iterators to the elements. And after, move the elements, for to be phisically sorted. This is useful with big objects
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |
| void boost::sort::parallel::indirect_stable_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp = Compare ( ) |
||
| ) |
: indirect stable sort. This function make a stable sort of a vector of iterators to the elements. And after, move the elements, for to be phisically sorted. This is useful with big objects
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |
| void boost::sort::parallel::parallel_sort | ( | Iter_t | first, |
| Iter_t | last | ||
| ) |
this function implement a non stable parallel sort. The number of threads to use is the HW threads of the machine
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| void boost::sort::parallel::parallel_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| uint32_t | nthread | ||
| ) |
this function implement a non stable parallel sort.
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| nthread | : Number of threads to use in the process. When this value is lower than 2, the sorting is done with 1 thread |
| void boost::sort::parallel::parallel_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp, | ||
| uint32_t | nthread | ||
| ) |
this function implement a non stable parallel sort.
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |
| nthread | : Number of threads to use in the process. When this value is lower than 2, the sorting is done with 1 thread |
| void boost::sort::parallel::parallel_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp | ||
| ) |
: non stable parallel sort.
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |
| void boost::sort::parallel::parallel_stable_sort | ( | Iter_t | first, |
| Iter_t | last | ||
| ) |
: parallel stable sort algorithm.
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| void boost::sort::parallel::parallel_stable_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| uint32_t | nthread | ||
| ) |
parallel stable sort.
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| nthread | : Number of threads to use in the process. When this value is lower than 2, the sorting is done with 1 thread |
| void boost::sort::parallel::parallel_stable_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp | ||
| ) |
: parallel stable sort.
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |
| void boost::sort::parallel::parallel_stable_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp, | ||
| uint32_t | nthread | ||
| ) |
parallel stable sort
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |
| nthread | : Number of threads to use in the process. When this value is lower than 2, the sorting is done with 1 thread |
| void boost::sort::parallel::sample_sort | ( | Iter_t | first, |
| Iter_t | last | ||
| ) |
parallel sample sort algorithm (stable sort)
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| void boost::sort::parallel::sample_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| uint32_t | nthread | ||
| ) |
parallel sample sort algorithm (stable sort)
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| nthread | : Number of threads to use in the process. When this value is lower than 2, the sorting is done with 1 thread |
| void boost::sort::parallel::sample_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp | ||
| ) |
parallel sample sort algorithm (stable sort)
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |
| void boost::sort::parallel::sample_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp, | ||
| uint32_t | nthread | ||
| ) |
parallel sample sort algorithm (stable sort)
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |
| nthread | : Number of threads to use in the process. When this value is lower than 2, the sorting is done with 1 thread |
| void boost::sort::parallel::sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp = Compare ( ) |
||
| ) |
non stable sort, based internally in the intro_sort algorithm
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |
| void boost::sort::parallel::stable_sort | ( | Iter_t | first, |
| Iter_t | last, | ||
| Compare | comp = Compare ( ) |
||
| ) |
this function implement a single thread stable sort
| first | : iterator to the first element of the range to sort |
| last | : iterator after the last element to the range to sort |
| comp | : object for to compare two elements pointed by Iter_t iterators |


?BOTANICAL
New
York
Botanical
Garden
Oplismenus
hirtellus
(L.)
P.
Beauv.
subsp.
hirtellus
Luis
catass
Guerra
2006
seen
for
monograph
U.Scholz
1977/78
PLANTS
OF
CUBA
...LMamaça.
LOMAS
DE
BANAO
[SANTA
CLARA]
COLLECTED
BY.....
COM.
BY
FR.
LEON
ANTONIO
LUNA
lb0M3?0
1604370
Legend -
Level of confidence that token is an accurately-transcribed word
extremely low
very low
low
undetermined
medium
high
very high


1
Alan slipped and fell down.
2
An aeroplane flies above
the clouds.
3
The train went through
a long tunnel.
4
She ran to her
father.
5
Tony is coming back from the library.
6
The ball rolled under
the couch.
7
The little boy is sitting between his parents.
8
Dora’s pencil is in
the box.
9
My family eats dinner at eight o’clock.
10
The horse jumped over
the fence.


childprocess module
import io
import os
import shlex
import signal
import subprocess
import sys
from enum import Enum
from typing import Dict, List, Tuple, Union
class ChildProcessIO(Enum):
"""The desired creation behavior for a ChildProcess's standard input/output/error file descriptors.
Can be supplied to ChildProcessBuilder.stdin, ChildProcessBuidler.stdout, or ChildProcessBuilder.stderr.
Values:
PIPE - Open a pipe to the I/O stream, and make it accessible via ChildProcess.stdin/stdout/stderr
INHERIT - Upon creation, inherit the corresponding I/O stream from the parent process
NULL - Provide empty input, or ignore output
STDOUT - Redirect STDERR to the same file descriptor as STDOUT. Only valid for ChildProcessBuilder.stderr"""
PIPE = 1
INHERIT = 2
NULL = 3
STDOUT = 4
class ChildProcess():
"""A child process.
Should not be instantiated directly - instead, use ChildProcessBuilder.spawn() to get an instance.
May be used with Python's `with` statement - upon the exit of the block, the process will be terminated non-forcefully.
See `ChildProcess.terminate`"""
def __init__(self, args, env, cwd, stdin, stdout, stderr):
self._args = args
self._env = env
self._cwd = cwd
popen_stdin, deferred_input = self._make_stdin(stdin)
popen_stdout = self._make_stdout(stdout)
popen_stderr = self._make_stderr(stderr)
self._is_stopped = False
self._popen = subprocess.Popen(
args, cwd=cwd, env=env,
stdin=popen_stdin, stdout=popen_stdout, stderr=popen_stderr)
if deferred_input:
self._popen.stdin.write(deferred_input)
@property
def args(self):
"""The argument array provided upon the ChildProcess's creation. Read-only."""
return self._args
@property
def env(self):
"""The environment variable definitions provided upon the ChildProcess's creation. Read-only."""
return self._env
@property
def cwd(self):
"""The working directory of the ChildProcess, provided upon the ChildProcess's creation. Read-only."""
return self._cwd
@property
def pid(self):
"""The system's pid for the child process. Read-only."""
return self._popen.pid
@property
def exit_code(self):
"""Either the integer exit code of the child process, or None if it is still running. Read-only.
One can spin-wait for a child process to exit with `while process.exit_code is None`."""
self._popen.poll()
return self._popen.returncode
@property
def stdin(self):
"""The input stream for the child process, if it was created by ChildProcessIO.PIPE.
Also accessible if input was provided in string format.
Attempts to access an inaccessible child process file descriptor result in a RuntimeError."""
if not self._stdin_writeable:
raise RuntimeError("The process's stdin pipe is inaccessible")
return self._popen.stdin
@property
def stdout(self):
"""The output stream for the child process, if it was created by ChildProcessIO.PIPE.
Attempts to access an inaccessible child process file descriptor result in a RuntimeError."""
if not self._stdout_readable:
raise RuntimeError("The process's stdout pipe is inaccessible")
return self._popen.stdout
@property
def stderr(self):
"""The error output stream for the child process, if it was created by ChildProcessIO.PIPE.
Attempts to access an inaccessible child process file descriptor result in a RuntimeError."""
if not self._stderr_readable:
raise RuntimeError("The process's stderr pipe is inaccessible")
return self._popen.stderr
def _make_stdin(self, stdin):
if stdin == ChildProcessIO.PIPE:
self._stdin_writeable = True
return subprocess.PIPE, None
elif stdin == ChildProcessIO.INHERIT:
self._stdin_writeable = False
return sys.stdin, None
elif stdin == ChildProcessIO.NULL:
self._stdin_writeable = False
return open(os.devnull, 'r'), None
elif isinstance(stdin, io.IOBase):
self._stdin_writeable = False
return stdin, None
else:
self._stdin_writeable = True
return subprocess.PIPE, stdin
def _make_stdout(self, stdout):
if stdout == ChildProcessIO.PIPE or stdout == ChildProcessIO.STDOUT:
self._stdout_readable = True
return subprocess.PIPE
elif stdout == ChildProcessIO.INHERIT:
self._stdout_readable = False
return sys.stdout
elif stdout == ChildProcessIO.NULL:
self._stdout_readable = False
return open(os.devnull, 'w')
else:
self._stdout_readable = False
return stdout
def _make_stderr(self, stderr):
if stderr == ChildProcessIO.PIPE:
self._stderr_readable = True
return subprocess.PIPE
elif stderr == ChildProcessIO.STDOUT:
self._stderr_readable = False
return subprocess.STDOUT
elif stderr == ChildProcessIO.INHERIT:
self._stderr_readable = False
return sys.stderr
elif stderr == ChildProcessIO.NULL:
self._stderr_readable = False
return open(os.devnull, 'w')
else:
self._stderr_readable = False
return stderr
def start(self):
"""Resume execution of a process which has previously been stopped.
Requires platform support - if unsupported on this platform, raises an OSError."""
if not hasattr(signal, "SIGCONT"):
raise OSError("No platform support for stopping/starting processes")
self._is_stopped = False
self.kill(signal.SIGCONT)
def stop(self):
"""Suspend execution of a running process.
Requires platform support - if unsupported on this platform, raises an OSError."""
if not hasattr(signal, "SIGTSTP"):
raise OSError("No platform support for stopping/starting processes")
self.kill(signal.SIGTSTP)
self._is_stopped = True
def terminate(self, force=False):
"""Request that a process terminate execution.
Requests to terminate may be ignored by the child process, and may not be serviced
if the process is stopped. If this is undesirable, a process may be forced to exit
(even when stopped) by the `force` argument, though this may result in the process
failing to close open files or database connections.
Parameters
----------
force: bool, optional
Terminate the process immediately in a way that cannot be ignored.
"""
if force:
self._popen.kill()
else:
self._popen.terminate()
def is_running(self):
"""Return true if the process is executing, and false otherwise"""
return not (self.is_finished() or self.is_stopped())
def is_stopped(self):
"""Return true if the process is suspended but not yet finished, and false otherwise"""
return not self.is_finished() and self._is_stopped
def is_finished(self):
"""Return true if the process has exited, and false otherwise"""
return self.exit_code is not None
def wait_for_finish(self, timeout=None):
"""Block until the process finishes. May optionally wait up to a maximum length of time
If the process does not terminate after `timeout` seconds, raise a
`subprocess.TimeoutExpired` exception. It is safe to catch this exception and retry.
Returns the process.
Parameters
----------
timeout: int, optional
Amount of time in seconds to wait for the process to finish.
Returns
-------
ChildProcess
The process on which it was called, in order to enable 'fluent programming'
"""
self._popen.wait(timeout)
def kill(self, signal):
"""Send a signal to the process.
The available signals are defined in the `signal` module"""
self._popen.send_signal(signal)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
if not self.is_finished():
self._popen.kill()
class ChildProcessBuilder():
"""Builder to obtain instances of ChildProcess.
One ChildProcessBuilder may be used to obtain any number of ChildProcess instances."""
def __init__(self, args, env=None, cwd=None, stdin=None, stdout=None, stderr=None):
"""Initialize the attributes of the builder.
Refer to documentation for each attribute for their default behavior and the particulars of their usage.
Parameters
----------
`args`: required. The desired value of the arguments (see ChildProcessBuilder.args).
`env`: optional. The desired environment variable definitions (see ChildProcessBuilder.env).
`cwd`: optional. The desired current working directory (see ChildProcessBuilder.cwd).
`stdin`: optional. The desired standard input (see ChildProcessBuilder.stdin).
`stdout`: optional. The desired standard output (see ChildProcessBuilder.stdout).
`stderr`: optional. The desired standard error output (see ChildProcessBuilder.stderr).
"""
self.args = args
"""The arguments with which the child process will be created, as a list of string tokens.
As is convention, args[0] is the name of the executable that should be invoked.
May be provided as a List of tokens, each of which will be converted to a string.
May be provided as a string, which will be tokenized in a Posix-compatible manner."""
self.env = env
"""Definitions of environment variables with which the child process will be created.
The environment variables are a mapping of KEY to VALUE, where both KEY and VALUE are strings.
The default behavior is to inherit the environment variable definitions from its parent process.
May be modified in-place by dictionary methods (`builder.env[key] = value`), or a new dictionary may
be provided.
"""
self.cwd = cwd
"""The current working directory for the child process.
The basis of any relative paths used by the child process.
The default behavior is to inherit the current working directory from its parent process.
May be provided in a format convertible to a normalized `os.path`"""
self.stdin = stdin
"""The desired standard input creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible writeable pipe to the stdin fd
ChildProcessIO.INHERIT - use the parent process's standard input fd
ChildProcessIO.NULL - provide null input (EOF)
A Python string - Open a PIPE to the stdin fd, and write the contents of the string upon creation
A file-like object - the contents read from the object will be provided to the process as input
It is the client's responsibility to make sure that standard input is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
self.stdout = stdout
"""The desired standard output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stdout fd
ChildProcessIO.INHERIT - use the parent process's standard output fd
ChildProcessIO.NULL - ignore output
A file-like object - the contents output by the process will be written to the object
It is the client's responsibility to make sure that standard output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
self.stderr = stderr
"""The desired standard error output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stderr fd
ChildProcessIO.INHERIT - use the parent process's standard error output fd
ChildProcessIO.NULL - ignore error output
A file-like object - the contents output by the process to stderr will be written to the object
It is the client's responsibility to make sure that standard error output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
def spawn(self):
"""Create a child process from the current ChildProcessBuilder attributes.
Returns
-------
ChildProcess
The spawned ChildProcess
"""
return ChildProcess(self.args, self.env, self.cwd, self.stdin, self.stdout, self.stderr)
@property
def args(self) -> List[str]:
"""The arguments with which the child process will be created, as a list of string tokens.
As is convention, args[0] is the name of the executable that should be invoked.
May be provided as a List of tokens, each of which will be converted to a string.
May be provided as a string, which will be tokenized in a Posix-compatible manner."""
return self._args
@args.setter
def args(self, value: Union[str, List, Tuple]):
if isinstance(value, str):
self._args = shlex.split(value)
elif isinstance(value, list) or isinstance(value, tuple):
try:
self._args = [str(obj) for obj in value]
except:
raise TypeError("Arguments must be convertible to strings")
@property
def env(self) -> Dict[str, str]:
"""Definitions of environment variables with which the child process will be created.
The environment variables are a mapping of KEY to VALUE, where both KEY and VALUE are strings.
The default behavior is to inherit the environment variable definitions from its parent process.
May be modified in-place by dictionary methods (`builder.env[key] = value`), or a new dictionary may
be provided.
"""
return self._env
@env.setter
def env(self, value: Dict[str, str]):
if value is None:
value = dict(os.environ)
if isinstance(value, dict):
try:
self._env = {str(k):str(v) for k,v in value.items()}
except:
raise TypeError("Environment variable names and values must be convertible to strings")
else:
raise TypeError("Environment variable definitions must be a dictionary")
@property
def cwd(self):
"""The current working directory for the child process.
The basis of any relative paths used by the child process.
The default behavior is to inherit the current working directory from its parent process.
May be provided in a format convertible to a normalized `os.path`"""
return self._cwd
@cwd.setter
def cwd(self, value):
if value is None:
value = os.getcwd()
try:
self._cwd = os.path.normpath(value)
except:
raise TypeError("Child process's current working directory must be a path-like object")
@property
def stdin(self):
"""The desired standard input creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible writeable pipe to the stdin fd
ChildProcessIO.INHERIT - use the parent process's standard input fd
ChildProcessIO.NULL - provide null input (EOF)
A Python string - Open a PIPE to the stdin fd, and write the contents of the string upon creation
A file-like object - the contents read from the object will be provided to the process as input
It is the client's responsibility to make sure that standard input is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
return self._stdin
@stdin.setter
def stdin(self, value):
if value is None:
value = ChildProcessIO.PIPE
if isinstance(value, io.BufferedReader):
self._stdin = value.raw
elif isinstance(value, str) or isinstance(value, io.IOBase):
self._stdin = value
elif value in ChildProcessIO:
if value == ChildProcessIO.STDOUT:
raise ValueError("Cannot pipe a process's output to its own input")
else:
self._stdin = value
else:
raise TypeError("Input can be redirected from a string, a file-like object, or a ChildProcessIO special value")
@property
def stdout(self):
"""The desired standard output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stdout fd
ChildProcessIO.INHERIT - use the parent process's standard output fd
ChildProcessIO.NULL - ignore output
A file-like object - the contents output by the process will be written to the object
It is the client's responsibility to make sure that standard output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
return self._stdout
@stdout.setter
def stdout(self, value):
if value is None:
value = ChildProcessIO.PIPE
if isinstance(value, io.IOBase) or value in ChildProcessIO:
self._stdout = value
else:
raise TypeError("Output can be redirected to a file-like object, or a ChildProcessIO special value")
@property
def stderr(self):
"""The desired standard error output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stderr fd
ChildProcessIO.INHERIT - use the parent process's standard error output fd
ChildProcessIO.NULL - ignore error output
A file-like object - the contents output by the process to stderr will be written to the object
It is the client's responsibility to make sure that standard error output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
return self._stderr
@stderr.setter
def stderr(self, value):
if value is None:
value = ChildProcessIO.PIPE
if isinstance(value, io.IOBase) or value in ChildProcessIO:
self._stderr = value
else:
raise TypeError("Error output can be redirected to a file-like object, or a ChildProcessIO special value")
class PipelineBuilder():
"""A convenience wrapper for ChildProcessBuilder to construct a pipeline of processes with each's output piped to the next's input."""
def __init__(self, commands, env=None, cwd=None, stdin=None, stdout=None, stderr=None):
if env is None:
env = dict(os.environ)
if cwd is None:
cwd = os.getcwd()
if stdin is None:
stdin = ChildProcessIO.PIPE
if stdout is None:
stdout = ChildProcessIO.PIPE
if stderr is None:
stderr = ChildProcessIO.PIPE
self.commands = commands
""" List of commands to execute. May be a list, or a string where commands are separated by pipe characters."""
self.env = env
""" Environment variable definitions. Shared by all processes in the pipeline"""
self.cwd = cwd
""" Current working directory. Shared by all processes in the pipeline """
self.stdin = stdin
""" Input to the first process in the pipeline """
self.stdout = stdout
""" Output destination for the last process in the pipeline """
self.stderr = stderr
""" Stderr output destination. Shared by all processes in the pipeline """
def spawn_all(self):
"""Create the processes for the pipeline.
Returns
-------
list
A list of the created processes in order
"""
res = []
next_input = self.stdin
builder = ChildProcessBuilder([], env=self.env, cwd=self.cwd, stderr=self.stderr)
for command in self.commands[:-1]:
builder.args = command
builder.stdin = next_input
proc = builder.spawn()
res.append(proc)
next_input = proc.stdout
builder.args = self.commands[-1]
builder.stdin = next_input
builder.stdout = self.stdout
proc = builder.spawn()
res.append(proc)
return res
@property
def commands(self):
"""The commands for the processes in the pipeline to execute.
Commands may be provided as a list where each will be provided to the 'args' parameter of the ChildProcessBuilder,
or as a string separated by pipe characters."""
return self._commands
@commands.setter
def commands(self, value):
if isinstance(value, str):
value = value.split("|")
if isinstance(value, list):
if not value:
raise ValueError("At least one command must be supplied")
self._commands = value
else:
raise TypeError("The commands should be supplied as a list or as a string with pipe characters")
Classes
class ChildProcess
A child process.
Should not be instantiated directly - instead, use ChildProcessBuilder.spawn() to get an instance.
May be used with Python's with
statement - upon the exit of the block, the process will be terminated non-forcefully.
See ChildProcess.terminate
class ChildProcess():
"""A child process.
Should not be instantiated directly - instead, use ChildProcessBuilder.spawn() to get an instance.
May be used with Python's `with` statement - upon the exit of the block, the process will be terminated non-forcefully.
See `ChildProcess.terminate`"""
def __init__(self, args, env, cwd, stdin, stdout, stderr):
self._args = args
self._env = env
self._cwd = cwd
popen_stdin, deferred_input = self._make_stdin(stdin)
popen_stdout = self._make_stdout(stdout)
popen_stderr = self._make_stderr(stderr)
self._is_stopped = False
self._popen = subprocess.Popen(
args, cwd=cwd, env=env,
stdin=popen_stdin, stdout=popen_stdout, stderr=popen_stderr)
if deferred_input:
self._popen.stdin.write(deferred_input)
@property
def args(self):
"""The argument array provided upon the ChildProcess's creation. Read-only."""
return self._args
@property
def env(self):
"""The environment variable definitions provided upon the ChildProcess's creation. Read-only."""
return self._env
@property
def cwd(self):
"""The working directory of the ChildProcess, provided upon the ChildProcess's creation. Read-only."""
return self._cwd
@property
def pid(self):
"""The system's pid for the child process. Read-only."""
return self._popen.pid
@property
def exit_code(self):
"""Either the integer exit code of the child process, or None if it is still running. Read-only.
One can spin-wait for a child process to exit with `while process.exit_code is None`."""
self._popen.poll()
return self._popen.returncode
@property
def stdin(self):
"""The input stream for the child process, if it was created by ChildProcessIO.PIPE.
Also accessible if input was provided in string format.
Attempts to access an inaccessible child process file descriptor result in a RuntimeError."""
if not self._stdin_writeable:
raise RuntimeError("The process's stdin pipe is inaccessible")
return self._popen.stdin
@property
def stdout(self):
"""The output stream for the child process, if it was created by ChildProcessIO.PIPE.
Attempts to access an inaccessible child process file descriptor result in a RuntimeError."""
if not self._stdout_readable:
raise RuntimeError("The process's stdout pipe is inaccessible")
return self._popen.stdout
@property
def stderr(self):
"""The error output stream for the child process, if it was created by ChildProcessIO.PIPE.
Attempts to access an inaccessible child process file descriptor result in a RuntimeError."""
if not self._stderr_readable:
raise RuntimeError("The process's stderr pipe is inaccessible")
return self._popen.stderr
def _make_stdin(self, stdin):
if stdin == ChildProcessIO.PIPE:
self._stdin_writeable = True
return subprocess.PIPE, None
elif stdin == ChildProcessIO.INHERIT:
self._stdin_writeable = False
return sys.stdin, None
elif stdin == ChildProcessIO.NULL:
self._stdin_writeable = False
return open(os.devnull, 'r'), None
elif isinstance(stdin, io.IOBase):
self._stdin_writeable = False
return stdin, None
else:
self._stdin_writeable = True
return subprocess.PIPE, stdin
def _make_stdout(self, stdout):
if stdout == ChildProcessIO.PIPE or stdout == ChildProcessIO.STDOUT:
self._stdout_readable = True
return subprocess.PIPE
elif stdout == ChildProcessIO.INHERIT:
self._stdout_readable = False
return sys.stdout
elif stdout == ChildProcessIO.NULL:
self._stdout_readable = False
return open(os.devnull, 'w')
else:
self._stdout_readable = False
return stdout
def _make_stderr(self, stderr):
if stderr == ChildProcessIO.PIPE:
self._stderr_readable = True
return subprocess.PIPE
elif stderr == ChildProcessIO.STDOUT:
self._stderr_readable = False
return subprocess.STDOUT
elif stderr == ChildProcessIO.INHERIT:
self._stderr_readable = False
return sys.stderr
elif stderr == ChildProcessIO.NULL:
self._stderr_readable = False
return open(os.devnull, 'w')
else:
self._stderr_readable = False
return stderr
def start(self):
"""Resume execution of a process which has previously been stopped.
Requires platform support - if unsupported on this platform, raises an OSError."""
if not hasattr(signal, "SIGCONT"):
raise OSError("No platform support for stopping/starting processes")
self._is_stopped = False
self.kill(signal.SIGCONT)
def stop(self):
"""Suspend execution of a running process.
Requires platform support - if unsupported on this platform, raises an OSError."""
if not hasattr(signal, "SIGTSTP"):
raise OSError("No platform support for stopping/starting processes")
self.kill(signal.SIGTSTP)
self._is_stopped = True
def terminate(self, force=False):
"""Request that a process terminate execution.
Requests to terminate may be ignored by the child process, and may not be serviced
if the process is stopped. If this is undesirable, a process may be forced to exit
(even when stopped) by the `force` argument, though this may result in the process
failing to close open files or database connections.
Parameters
----------
force: bool, optional
Terminate the process immediately in a way that cannot be ignored.
"""
if force:
self._popen.kill()
else:
self._popen.terminate()
def is_running(self):
"""Return true if the process is executing, and false otherwise"""
return not (self.is_finished() or self.is_stopped())
def is_stopped(self):
"""Return true if the process is suspended but not yet finished, and false otherwise"""
return not self.is_finished() and self._is_stopped
def is_finished(self):
"""Return true if the process has exited, and false otherwise"""
return self.exit_code is not None
def wait_for_finish(self, timeout=None):
"""Block until the process finishes. May optionally wait up to a maximum length of time
If the process does not terminate after `timeout` seconds, raise a
`subprocess.TimeoutExpired` exception. It is safe to catch this exception and retry.
Returns the process.
Parameters
----------
timeout: int, optional
Amount of time in seconds to wait for the process to finish.
Returns
-------
ChildProcess
The process on which it was called, in order to enable 'fluent programming'
"""
self._popen.wait(timeout)
def kill(self, signal):
"""Send a signal to the process.
The available signals are defined in the `signal` module"""
self._popen.send_signal(signal)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
if not self.is_finished():
self._popen.kill()
Ancestors (in MRO)
- ChildProcess
- builtins.object
Static methods
def __init__(
self, args, env, cwd, stdin, stdout, stderr)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, args, env, cwd, stdin, stdout, stderr):
self._args = args
self._env = env
self._cwd = cwd
popen_stdin, deferred_input = self._make_stdin(stdin)
popen_stdout = self._make_stdout(stdout)
popen_stderr = self._make_stderr(stderr)
self._is_stopped = False
self._popen = subprocess.Popen(
args, cwd=cwd, env=env,
stdin=popen_stdin, stdout=popen_stdout, stderr=popen_stderr)
if deferred_input:
self._popen.stdin.write(deferred_input)
def is_finished(
self)
Return true if the process has exited, and false otherwise
def is_finished(self):
"""Return true if the process has exited, and false otherwise"""
return self.exit_code is not None
def is_running(
self)
Return true if the process is executing, and false otherwise
def is_running(self):
"""Return true if the process is executing, and false otherwise"""
return not (self.is_finished() or self.is_stopped())
def is_stopped(
self)
Return true if the process is suspended but not yet finished, and false otherwise
def is_stopped(self):
"""Return true if the process is suspended but not yet finished, and false otherwise"""
return not self.is_finished() and self._is_stopped
def kill(
self, signal)
Send a signal to the process.
The available signals are defined in the signal
module
def kill(self, signal):
"""Send a signal to the process.
The available signals are defined in the `signal` module"""
self._popen.send_signal(signal)
def start(
self)
Resume execution of a process which has previously been stopped.
Requires platform support - if unsupported on this platform, raises an OSError.
def start(self):
"""Resume execution of a process which has previously been stopped.
Requires platform support - if unsupported on this platform, raises an OSError."""
if not hasattr(signal, "SIGCONT"):
raise OSError("No platform support for stopping/starting processes")
self._is_stopped = False
self.kill(signal.SIGCONT)
def stop(
self)
Suspend execution of a running process.
Requires platform support - if unsupported on this platform, raises an OSError.
def stop(self):
"""Suspend execution of a running process.
Requires platform support - if unsupported on this platform, raises an OSError."""
if not hasattr(signal, "SIGTSTP"):
raise OSError("No platform support for stopping/starting processes")
self.kill(signal.SIGTSTP)
self._is_stopped = True
def terminate(
self, force=False)
Request that a process terminate execution.
Requests to terminate may be ignored by the child process, and may not be serviced
if the process is stopped. If this is undesirable, a process may be forced to exit
(even when stopped) by the force
argument, though this may result in the process
failing to close open files or database connections.
Parameters
force: bool, optional Terminate the process immediately in a way that cannot be ignored.
def terminate(self, force=False):
"""Request that a process terminate execution.
Requests to terminate may be ignored by the child process, and may not be serviced
if the process is stopped. If this is undesirable, a process may be forced to exit
(even when stopped) by the `force` argument, though this may result in the process
failing to close open files or database connections.
Parameters
----------
force: bool, optional
Terminate the process immediately in a way that cannot be ignored.
"""
if force:
self._popen.kill()
else:
self._popen.terminate()
def wait_for_finish(
self, timeout=None)
Block until the process finishes. May optionally wait up to a maximum length of time
If the process does not terminate after timeout
seconds, raise a
subprocess.TimeoutExpired
exception. It is safe to catch this exception and retry.
Returns the process.
Parameters
timeout: int, optional Amount of time in seconds to wait for the process to finish.
Returns
ChildProcess The process on which it was called, in order to enable 'fluent programming'
def wait_for_finish(self, timeout=None):
"""Block until the process finishes. May optionally wait up to a maximum length of time
If the process does not terminate after `timeout` seconds, raise a
`subprocess.TimeoutExpired` exception. It is safe to catch this exception and retry.
Returns the process.
Parameters
----------
timeout: int, optional
Amount of time in seconds to wait for the process to finish.
Returns
-------
ChildProcess
The process on which it was called, in order to enable 'fluent programming'
"""
self._popen.wait(timeout)
Instance variables
var args
The argument array provided upon the ChildProcess's creation. Read-only.
var cwd
The working directory of the ChildProcess, provided upon the ChildProcess's creation. Read-only.
var env
The environment variable definitions provided upon the ChildProcess's creation. Read-only.
var exit_code
Either the integer exit code of the child process, or None if it is still running. Read-only.
One can spin-wait for a child process to exit with while process.exit_code is None
.
var pid
The system's pid for the child process. Read-only.
var stderr
The error output stream for the child process, if it was created by ChildProcessIO.PIPE.
Attempts to access an inaccessible child process file descriptor result in a RuntimeError.
var stdin
The input stream for the child process, if it was created by ChildProcessIO.PIPE.
Also accessible if input was provided in string format.
Attempts to access an inaccessible child process file descriptor result in a RuntimeError.
var stdout
The output stream for the child process, if it was created by ChildProcessIO.PIPE.
Attempts to access an inaccessible child process file descriptor result in a RuntimeError.
class ChildProcessBuilder
Builder to obtain instances of ChildProcess.
One ChildProcessBuilder may be used to obtain any number of ChildProcess instances.
class ChildProcessBuilder():
"""Builder to obtain instances of ChildProcess.
One ChildProcessBuilder may be used to obtain any number of ChildProcess instances."""
def __init__(self, args, env=None, cwd=None, stdin=None, stdout=None, stderr=None):
"""Initialize the attributes of the builder.
Refer to documentation for each attribute for their default behavior and the particulars of their usage.
Parameters
----------
`args`: required. The desired value of the arguments (see ChildProcessBuilder.args).
`env`: optional. The desired environment variable definitions (see ChildProcessBuilder.env).
`cwd`: optional. The desired current working directory (see ChildProcessBuilder.cwd).
`stdin`: optional. The desired standard input (see ChildProcessBuilder.stdin).
`stdout`: optional. The desired standard output (see ChildProcessBuilder.stdout).
`stderr`: optional. The desired standard error output (see ChildProcessBuilder.stderr).
"""
self.args = args
"""The arguments with which the child process will be created, as a list of string tokens.
As is convention, args[0] is the name of the executable that should be invoked.
May be provided as a List of tokens, each of which will be converted to a string.
May be provided as a string, which will be tokenized in a Posix-compatible manner."""
self.env = env
"""Definitions of environment variables with which the child process will be created.
The environment variables are a mapping of KEY to VALUE, where both KEY and VALUE are strings.
The default behavior is to inherit the environment variable definitions from its parent process.
May be modified in-place by dictionary methods (`builder.env[key] = value`), or a new dictionary may
be provided.
"""
self.cwd = cwd
"""The current working directory for the child process.
The basis of any relative paths used by the child process.
The default behavior is to inherit the current working directory from its parent process.
May be provided in a format convertible to a normalized `os.path`"""
self.stdin = stdin
"""The desired standard input creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible writeable pipe to the stdin fd
ChildProcessIO.INHERIT - use the parent process's standard input fd
ChildProcessIO.NULL - provide null input (EOF)
A Python string - Open a PIPE to the stdin fd, and write the contents of the string upon creation
A file-like object - the contents read from the object will be provided to the process as input
It is the client's responsibility to make sure that standard input is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
self.stdout = stdout
"""The desired standard output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stdout fd
ChildProcessIO.INHERIT - use the parent process's standard output fd
ChildProcessIO.NULL - ignore output
A file-like object - the contents output by the process will be written to the object
It is the client's responsibility to make sure that standard output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
self.stderr = stderr
"""The desired standard error output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stderr fd
ChildProcessIO.INHERIT - use the parent process's standard error output fd
ChildProcessIO.NULL - ignore error output
A file-like object - the contents output by the process to stderr will be written to the object
It is the client's responsibility to make sure that standard error output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
def spawn(self):
"""Create a child process from the current ChildProcessBuilder attributes.
Returns
-------
ChildProcess
The spawned ChildProcess
"""
return ChildProcess(self.args, self.env, self.cwd, self.stdin, self.stdout, self.stderr)
@property
def args(self) -> List[str]:
"""The arguments with which the child process will be created, as a list of string tokens.
As is convention, args[0] is the name of the executable that should be invoked.
May be provided as a List of tokens, each of which will be converted to a string.
May be provided as a string, which will be tokenized in a Posix-compatible manner."""
return self._args
@args.setter
def args(self, value: Union[str, List, Tuple]):
if isinstance(value, str):
self._args = shlex.split(value)
elif isinstance(value, list) or isinstance(value, tuple):
try:
self._args = [str(obj) for obj in value]
except:
raise TypeError("Arguments must be convertible to strings")
@property
def env(self) -> Dict[str, str]:
"""Definitions of environment variables with which the child process will be created.
The environment variables are a mapping of KEY to VALUE, where both KEY and VALUE are strings.
The default behavior is to inherit the environment variable definitions from its parent process.
May be modified in-place by dictionary methods (`builder.env[key] = value`), or a new dictionary may
be provided.
"""
return self._env
@env.setter
def env(self, value: Dict[str, str]):
if value is None:
value = dict(os.environ)
if isinstance(value, dict):
try:
self._env = {str(k):str(v) for k,v in value.items()}
except:
raise TypeError("Environment variable names and values must be convertible to strings")
else:
raise TypeError("Environment variable definitions must be a dictionary")
@property
def cwd(self):
"""The current working directory for the child process.
The basis of any relative paths used by the child process.
The default behavior is to inherit the current working directory from its parent process.
May be provided in a format convertible to a normalized `os.path`"""
return self._cwd
@cwd.setter
def cwd(self, value):
if value is None:
value = os.getcwd()
try:
self._cwd = os.path.normpath(value)
except:
raise TypeError("Child process's current working directory must be a path-like object")
@property
def stdin(self):
"""The desired standard input creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible writeable pipe to the stdin fd
ChildProcessIO.INHERIT - use the parent process's standard input fd
ChildProcessIO.NULL - provide null input (EOF)
A Python string - Open a PIPE to the stdin fd, and write the contents of the string upon creation
A file-like object - the contents read from the object will be provided to the process as input
It is the client's responsibility to make sure that standard input is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
return self._stdin
@stdin.setter
def stdin(self, value):
if value is None:
value = ChildProcessIO.PIPE
if isinstance(value, io.BufferedReader):
self._stdin = value.raw
elif isinstance(value, str) or isinstance(value, io.IOBase):
self._stdin = value
elif value in ChildProcessIO:
if value == ChildProcessIO.STDOUT:
raise ValueError("Cannot pipe a process's output to its own input")
else:
self._stdin = value
else:
raise TypeError("Input can be redirected from a string, a file-like object, or a ChildProcessIO special value")
@property
def stdout(self):
"""The desired standard output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stdout fd
ChildProcessIO.INHERIT - use the parent process's standard output fd
ChildProcessIO.NULL - ignore output
A file-like object - the contents output by the process will be written to the object
It is the client's responsibility to make sure that standard output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
return self._stdout
@stdout.setter
def stdout(self, value):
if value is None:
value = ChildProcessIO.PIPE
if isinstance(value, io.IOBase) or value in ChildProcessIO:
self._stdout = value
else:
raise TypeError("Output can be redirected to a file-like object, or a ChildProcessIO special value")
@property
def stderr(self):
"""The desired standard error output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stderr fd
ChildProcessIO.INHERIT - use the parent process's standard error output fd
ChildProcessIO.NULL - ignore error output
A file-like object - the contents output by the process to stderr will be written to the object
It is the client's responsibility to make sure that standard error output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
return self._stderr
@stderr.setter
def stderr(self, value):
if value is None:
value = ChildProcessIO.PIPE
if isinstance(value, io.IOBase) or value in ChildProcessIO:
self._stderr = value
else:
raise TypeError("Error output can be redirected to a file-like object, or a ChildProcessIO special value")
Ancestors (in MRO)
- ChildProcessBuilder
- builtins.object
Static methods
def __init__(
self, args, env=None, cwd=None, stdin=None, stdout=None, stderr=None)
Initialize the attributes of the builder.
Refer to documentation for each attribute for their default behavior and the particulars of their usage.
Parameters
args
: required. The desired value of the arguments (see ChildProcessBuilder.args).
env
: optional. The desired environment variable definitions (see ChildProcessBuilder.env).
cwd
: optional. The desired current working directory (see ChildProcessBuilder.cwd).
stdin
: optional. The desired standard input (see ChildProcessBuilder.stdin).
stdout
: optional. The desired standard output (see ChildProcessBuilder.stdout).
stderr
: optional. The desired standard error output (see ChildProcessBuilder.stderr).
def __init__(self, args, env=None, cwd=None, stdin=None, stdout=None, stderr=None):
"""Initialize the attributes of the builder.
Refer to documentation for each attribute for their default behavior and the particulars of their usage.
Parameters
----------
`args`: required. The desired value of the arguments (see ChildProcessBuilder.args).
`env`: optional. The desired environment variable definitions (see ChildProcessBuilder.env).
`cwd`: optional. The desired current working directory (see ChildProcessBuilder.cwd).
`stdin`: optional. The desired standard input (see ChildProcessBuilder.stdin).
`stdout`: optional. The desired standard output (see ChildProcessBuilder.stdout).
`stderr`: optional. The desired standard error output (see ChildProcessBuilder.stderr).
"""
self.args = args
"""The arguments with which the child process will be created, as a list of string tokens.
As is convention, args[0] is the name of the executable that should be invoked.
May be provided as a List of tokens, each of which will be converted to a string.
May be provided as a string, which will be tokenized in a Posix-compatible manner."""
self.env = env
"""Definitions of environment variables with which the child process will be created.
The environment variables are a mapping of KEY to VALUE, where both KEY and VALUE are strings.
The default behavior is to inherit the environment variable definitions from its parent process.
May be modified in-place by dictionary methods (`builder.env[key] = value`), or a new dictionary may
be provided.
"""
self.cwd = cwd
"""The current working directory for the child process.
The basis of any relative paths used by the child process.
The default behavior is to inherit the current working directory from its parent process.
May be provided in a format convertible to a normalized `os.path`"""
self.stdin = stdin
"""The desired standard input creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible writeable pipe to the stdin fd
ChildProcessIO.INHERIT - use the parent process's standard input fd
ChildProcessIO.NULL - provide null input (EOF)
A Python string - Open a PIPE to the stdin fd, and write the contents of the string upon creation
A file-like object - the contents read from the object will be provided to the process as input
It is the client's responsibility to make sure that standard input is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
self.stdout = stdout
"""The desired standard output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stdout fd
ChildProcessIO.INHERIT - use the parent process's standard output fd
ChildProcessIO.NULL - ignore output
A file-like object - the contents output by the process will be written to the object
It is the client's responsibility to make sure that standard output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
self.stderr = stderr
"""The desired standard error output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stderr fd
ChildProcessIO.INHERIT - use the parent process's standard error output fd
ChildProcessIO.NULL - ignore error output
A file-like object - the contents output by the process to stderr will be written to the object
It is the client's responsibility to make sure that standard error output is used in a safe manner.
Particular concerns include the limitations of system I/O buffers and the safe sharing of files."""
def spawn(
self)
Create a child process from the current ChildProcessBuilder attributes.
Returns
ChildProcess The spawned ChildProcess
def spawn(self):
"""Create a child process from the current ChildProcessBuilder attributes.
Returns
-------
ChildProcess
The spawned ChildProcess
"""
return ChildProcess(self.args, self.env, self.cwd, self.stdin, self.stdout, self.stderr)
Instance variables
var args
The arguments with which the child process will be created, as a list of string tokens.
As is convention, args[0] is the name of the executable that should be invoked.
May be provided as a List of tokens, each of which will be converted to a string. May be provided as a string, which will be tokenized in a Posix-compatible manner.
var cwd
The current working directory for the child process.
The basis of any relative paths used by the child process. The default behavior is to inherit the current working directory from its parent process.
May be provided in a format convertible to a normalized os.path
var env
Definitions of environment variables with which the child process will be created.
The environment variables are a mapping of KEY to VALUE, where both KEY and VALUE are strings. The default behavior is to inherit the environment variable definitions from its parent process.
May be modified in-place by dictionary methods (builder.env[key] = value
), or a new dictionary may
be provided.
var stderr
The desired standard error output creation behavior for the child process.
Values include: ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stderr fd ChildProcessIO.INHERIT - use the parent process's standard error output fd ChildProcessIO.NULL - ignore error output A file-like object - the contents output by the process to stderr will be written to the object
It is the client's responsibility to make sure that standard error output is used in a safe manner. Particular concerns include the limitations of system I/O buffers and the safe sharing of files.
var stdin
The desired standard input creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible writeable pipe to the stdin fd
ChildProcessIO.INHERIT - use the parent process's standard input fd
ChildProcessIO.NULL - provide null input (EOF)
A Python string - Open a PIPE to the stdin fd, and write the contents of the string upon creation
A file-like object - the contents read from the object will be provided to the process as input
It is the client's responsibility to make sure that standard input is used in a safe manner. Particular concerns include the limitations of system I/O buffers and the safe sharing of files.
var stdout
The desired standard output creation behavior for the child process.
Values include:
ChildProcessIO.PIPE (default) - open a parent-accessible readable pipe to the stdout fd
ChildProcessIO.INHERIT - use the parent process's standard output fd
ChildProcessIO.NULL - ignore output
A file-like object - the contents output by the process will be written to the object
It is the client's responsibility to make sure that standard output is used in a safe manner. Particular concerns include the limitations of system I/O buffers and the safe sharing of files.
class ChildProcessIO
The desired creation behavior for a ChildProcess's standard input/output/error file descriptors.
Can be supplied to ChildProcessBuilder.stdin, ChildProcessBuidler.stdout, or ChildProcessBuilder.stderr.
Values:
PIPE - Open a pipe to the I/O stream, and make it accessible via ChildProcess.stdin/stdout/stderr
INHERIT - Upon creation, inherit the corresponding I/O stream from the parent process
NULL - Provide empty input, or ignore output
STDOUT - Redirect STDERR to the same file descriptor as STDOUT. Only valid for ChildProcessBuilder.stderr
class ChildProcessIO(Enum):
"""The desired creation behavior for a ChildProcess's standard input/output/error file descriptors.
Can be supplied to ChildProcessBuilder.stdin, ChildProcessBuidler.stdout, or ChildProcessBuilder.stderr.
Values:
PIPE - Open a pipe to the I/O stream, and make it accessible via ChildProcess.stdin/stdout/stderr
INHERIT - Upon creation, inherit the corresponding I/O stream from the parent process
NULL - Provide empty input, or ignore output
STDOUT - Redirect STDERR to the same file descriptor as STDOUT. Only valid for ChildProcessBuilder.stderr"""
PIPE = 1
INHERIT = 2
NULL = 3
STDOUT = 4
Ancestors (in MRO)
- ChildProcessIO
- enum.Enum
- builtins.object
Class variables
var INHERIT
var NULL
var PIPE
var STDOUT
var name
var value
class PipelineBuilder
A convenience wrapper for ChildProcessBuilder to construct a pipeline of processes with each's output piped to the next's input.
class PipelineBuilder():
"""A convenience wrapper for ChildProcessBuilder to construct a pipeline of processes with each's output piped to the next's input."""
def __init__(self, commands, env=None, cwd=None, stdin=None, stdout=None, stderr=None):
if env is None:
env = dict(os.environ)
if cwd is None:
cwd = os.getcwd()
if stdin is None:
stdin = ChildProcessIO.PIPE
if stdout is None:
stdout = ChildProcessIO.PIPE
if stderr is None:
stderr = ChildProcessIO.PIPE
self.commands = commands
""" List of commands to execute. May be a list, or a string where commands are separated by pipe characters."""
self.env = env
""" Environment variable definitions. Shared by all processes in the pipeline"""
self.cwd = cwd
""" Current working directory. Shared by all processes in the pipeline """
self.stdin = stdin
""" Input to the first process in the pipeline """
self.stdout = stdout
""" Output destination for the last process in the pipeline """
self.stderr = stderr
""" Stderr output destination. Shared by all processes in the pipeline """
def spawn_all(self):
"""Create the processes for the pipeline.
Returns
-------
list
A list of the created processes in order
"""
res = []
next_input = self.stdin
builder = ChildProcessBuilder([], env=self.env, cwd=self.cwd, stderr=self.stderr)
for command in self.commands[:-1]:
builder.args = command
builder.stdin = next_input
proc = builder.spawn()
res.append(proc)
next_input = proc.stdout
builder.args = self.commands[-1]
builder.stdin = next_input
builder.stdout = self.stdout
proc = builder.spawn()
res.append(proc)
return res
@property
def commands(self):
"""The commands for the processes in the pipeline to execute.
Commands may be provided as a list where each will be provided to the 'args' parameter of the ChildProcessBuilder,
or as a string separated by pipe characters."""
return self._commands
@commands.setter
def commands(self, value):
if isinstance(value, str):
value = value.split("|")
if isinstance(value, list):
if not value:
raise ValueError("At least one command must be supplied")
self._commands = value
else:
raise TypeError("The commands should be supplied as a list or as a string with pipe characters")
Ancestors (in MRO)
- PipelineBuilder
- builtins.object
Static methods
def __init__(
self, commands, env=None, cwd=None, stdin=None, stdout=None, stderr=None)
Initialize self. See help(type(self)) for accurate signature.
def __init__(self, commands, env=None, cwd=None, stdin=None, stdout=None, stderr=None):
if env is None:
env = dict(os.environ)
if cwd is None:
cwd = os.getcwd()
if stdin is None:
stdin = ChildProcessIO.PIPE
if stdout is None:
stdout = ChildProcessIO.PIPE
if stderr is None:
stderr = ChildProcessIO.PIPE
self.commands = commands
""" List of commands to execute. May be a list, or a string where commands are separated by pipe characters."""
self.env = env
""" Environment variable definitions. Shared by all processes in the pipeline"""
self.cwd = cwd
""" Current working directory. Shared by all processes in the pipeline """
self.stdin = stdin
""" Input to the first process in the pipeline """
self.stdout = stdout
""" Output destination for the last process in the pipeline """
self.stderr = stderr
""" Stderr output destination. Shared by all processes in the pipeline """
def spawn_all(
self)
Create the processes for the pipeline.
Returns
list A list of the created processes in order
def spawn_all(self):
"""Create the processes for the pipeline.
Returns
-------
list
A list of the created processes in order
"""
res = []
next_input = self.stdin
builder = ChildProcessBuilder([], env=self.env, cwd=self.cwd, stderr=self.stderr)
for command in self.commands[:-1]:
builder.args = command
builder.stdin = next_input
proc = builder.spawn()
res.append(proc)
next_input = proc.stdout
builder.args = self.commands[-1]
builder.stdin = next_input
builder.stdout = self.stdout
proc = builder.spawn()
res.append(proc)
return res
Instance variables
var commands
List of commands to execute. May be a list, or a string where commands are separated by pipe characters.
var cwd
Current working directory. Shared by all processes in the pipeline
var env
Environment variable definitions. Shared by all processes in the pipeline
var stderr
Stderr output destination. Shared by all processes in the pipeline
var stdin
Input to the first process in the pipeline
var stdout
Output destination for the last process in the pipeline


A Week in Antiques: Dirty tricks and past political campaigns
Des O'Sullivan examines the lots up for auction in Bray.
There is nothing new about dirty tricks in political campaigns as illustrated by lot 48 at Mullen’s Collectors Cabinet auction at Laurel Park, Bray, Co Wicklow, next Saturday.
The newspaper billboard poster for The Star headlines: “Parnell cross-examined”. This was at a special commission set up by Gladstone’s government to investigate various charges against Parnell and his Home Rule party.
The basis was a letter in The Times in which Parnell appeared to give explicit support, after the fact, to the Phoenix Park murders.
The commission sat for 128 days to November 1889. The following February one of the witnesses, Richard Piggott, admitted having forged the letters, then fled to Madrid and shot himself. Parnell’s name was fully cleared.
A first edition of Ulysses, a pro-Treaty campaign poster for the 1922 general election, an electric guitar signed by Mark Knopfler of Dire Straits and a leather flying helmet from a Polish Air Force bomber which crashed on the Carlow Laois border in 1943 are among the lots. Viewing is from Wednesday and the auction is at 11am on Saturday.


Packed with the trends, news & links you need to be smart, informed, and ahead of the curve.
If these newsletters reach their goals (or get a sponsorship), we’ll bring on expert writers and launch them. Vote for all your favorites:
The news, trends and tech that are reshaping the rapidly changing world of Washington DC
The news, trends and tech that is reshaping the rapidly changing world of Facebook, Amazon, Netflix and Google
The news, trends and tech that is reshaping the rapidly changing world of CPG
New releases, author news, and bestsellers, delivered straight to your inbox.
The latest news, scores and controversies in professional and collegiate sports thrown right into your inbox
News, reviews, updates and more for fans and developers alike. Why, what's app wit you?
The news, trends and tech that is reshaping the rapidly changing world of Financial Markets
Here's what our subscribers say